Browse Source

资料管理

master
luoweijian 3 months ago
parent
commit
4ee06bfff8
  1. 7
      src/main/java/com/project/information/application/DraftReviewApplicationService.java
  2. 5
      src/main/java/com/project/information/application/KnowledgePointApplicationService.java
  3. 117
      src/main/java/com/project/information/application/impl/DraftReviewApplicationServiceImpl.java
  4. 66
      src/main/java/com/project/information/application/impl/KnowledgePointApplicationServiceImpl.java
  5. 31
      src/main/java/com/project/information/controller/InformationController.java

7
src/main/java/com/project/information/application/DraftReviewApplicationService.java

@ -1,6 +1,7 @@
package com.project.information.application; package com.project.information.application;
import com.project.base.domain.result.Result; import com.project.base.domain.result.Result;
import com.project.information.domain.dto.DraftSaveDTO;
import com.project.information.domain.entity.KnowledgePointDraftEntity; import com.project.information.domain.entity.KnowledgePointDraftEntity;
import java.util.List; import java.util.List;
@ -19,4 +20,10 @@ public interface DraftReviewApplicationService {
Result<String> addDraft(Long informationId, String content, Integer knowledgeType); Result<String> addDraft(Long informationId, String content, Integer knowledgeType);
Result<String> confirm(Long informationId); Result<String> confirm(Long informationId);
/**
* 批量保存草稿并确认替代逐条编辑+单独确认
* 前端编辑完所有草稿后一次性提交提交后自动固化
*/
Result<String> batchSaveAndConfirm(Long informationId, List<DraftSaveDTO> draftList);
} }

5
src/main/java/com/project/information/application/KnowledgePointApplicationService.java

@ -11,4 +11,9 @@ public interface KnowledgePointApplicationService {
Result<KnowledgePointStatisticsDTO> classicStatistics(Long subLineId) throws Exception; Result<KnowledgePointStatisticsDTO> classicStatistics(Long subLineId) throws Exception;
void parse(Map<Long, String> fileMap,Map<Long, String> fileNameMa); void parse(Map<Long, String> fileMap,Map<Long, String> fileNameMa);
/**
* 模拟算法服务提取知识点草稿测试用
*/
Result<String> mockAiExtract(Long informationId, Integer count);
} }

117
src/main/java/com/project/information/application/impl/DraftReviewApplicationServiceImpl.java

@ -2,25 +2,35 @@ package com.project.information.application.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.project.base.domain.exception.BusinessErrorException; import com.project.base.domain.exception.BusinessErrorException;
import com.project.base.config.CustomIdGenerator;
import com.project.base.domain.result.Result; import com.project.base.domain.result.Result;
import com.project.information.application.DraftReviewApplicationService; import com.project.information.application.DraftReviewApplicationService;
import com.project.information.domain.dto.DraftSaveDTO;
import com.project.information.domain.entity.InformationEntity; import com.project.information.domain.entity.InformationEntity;
import com.project.information.domain.entity.KnowledgePointDraftEntity; import com.project.information.domain.entity.KnowledgePointDraftEntity;
import com.project.information.domain.entity.KnowledgePointEntity;
import com.project.information.domain.enums.AuditStatusEnum; import com.project.information.domain.enums.AuditStatusEnum;
import com.project.information.domain.enums.DraftStatusEnum; import com.project.information.domain.enums.DraftStatusEnum;
import com.project.information.domain.service.ConfirmKnowledgePointDraftDomainService; import com.project.information.domain.service.ConfirmKnowledgePointDraftDomainService;
import com.project.information.domain.service.InformationBaseService; import com.project.information.domain.service.InformationBaseService;
import com.project.information.domain.service.KnowledgePointBaseService;
import com.project.information.domain.service.KnowledgePointDraftBaseService; import com.project.information.domain.service.KnowledgePointDraftBaseService;
import com.project.interaction.application.AlgorithmApplicationService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
/** /**
* 知识点草稿审核应用服务实现 * 知识点草稿审核应用服务实现
* 简单 CRUD 直接调 BaseService确认固化调 DomainService * 简单 CRUD 直接调 BaseService确认固化调 DomainService
*/ */
@Service @Service
@Slf4j
public class DraftReviewApplicationServiceImpl implements DraftReviewApplicationService { public class DraftReviewApplicationServiceImpl implements DraftReviewApplicationService {
@Autowired @Autowired
@ -32,6 +42,15 @@ public class DraftReviewApplicationServiceImpl implements DraftReviewApplication
@Autowired @Autowired
private ConfirmKnowledgePointDraftDomainService confirmKnowledgePointDraftDomainService; private ConfirmKnowledgePointDraftDomainService confirmKnowledgePointDraftDomainService;
@Autowired
private KnowledgePointBaseService knowledgePointBaseService;
@Autowired
private AlgorithmApplicationService algorithmApplicationService;
@Autowired
private CustomIdGenerator customIdGenerator;
@Override @Override
public Result<List<KnowledgePointDraftEntity>> listDrafts(Long informationId) { public Result<List<KnowledgePointDraftEntity>> listDrafts(Long informationId) {
if (informationId == null) { if (informationId == null) {
@ -103,4 +122,102 @@ public class DraftReviewApplicationServiceImpl implements DraftReviewApplication
public Result<String> confirm(Long informationId) { public Result<String> confirm(Long informationId) {
return confirmKnowledgePointDraftDomainService.confirm(informationId); return confirmKnowledgePointDraftDomainService.confirm(informationId);
} }
/**
* 批量保存草稿并确认替代逐条编辑+单独确认
* 前端编辑完所有草稿后一次性提交提交后自动固化
*/
@Override
public Result<String> batchSaveAndConfirm(Long informationId, List<DraftSaveDTO> draftList) {
if (informationId == null) {
throw new BusinessErrorException("资料ID不能为空");
}
if (draftList == null || draftList.isEmpty()) {
throw new BusinessErrorException("草稿数据不能为空");
}
// 1. 校验资料状态
InformationEntity information = informationBaseService.getById(informationId);
if (information == null) {
throw new BusinessErrorException("资料不存在");
}
if (DraftStatusEnum.APPROVED.getValue().equals(information.getDraftStatus())) {
return Result.success("该资料已审核通过,无需重复操作");
}
if (!DraftStatusEnum.PENDING.getValue().equals(information.getDraftStatus())) {
throw new BusinessErrorException("该资料不在待审核状态");
}
// 2. 获取该资料下所有待审核草稿
List<KnowledgePointDraftEntity> existingDrafts = knowledgePointDraftBaseService.list(
new LambdaQueryWrapper<KnowledgePointDraftEntity>()
.eq(KnowledgePointDraftEntity::getInformationId, informationId)
.eq(KnowledgePointDraftEntity::getAuditStatus, AuditStatusEnum.PENDING.getValue()));
List<Long> existingIds = existingDrafts.stream()
.map(KnowledgePointDraftEntity::getId).toList();
// 3. 用户传来的草稿ID集合
List<Long> incomingIds = draftList.stream()
.map(DraftSaveDTO::getId)
.filter(Objects::nonNull)
.toList();
// 4. 计算用户删除的草稿ID
List<Long> deletedIds = existingIds.stream()
.filter(id -> !incomingIds.contains(id))
.toList();
// 5. 逻辑删除(deleted=1),保留审计记录
if (!deletedIds.isEmpty()) {
knowledgePointDraftBaseService.lambdaUpdate()
.set(KnowledgePointDraftEntity::getDeleted, true)
.in(KnowledgePointDraftEntity::getId, deletedIds)
.update();
}
// 6. 更新/编辑草稿
List<KnowledgePointDraftEntity> confirmedDrafts = new ArrayList<>();
for (DraftSaveDTO dto : draftList) {
if (dto.getId() != null) {
// 编辑现有草稿
KnowledgePointDraftEntity oldDraft = knowledgePointDraftBaseService.getById(dto.getId());
if (oldDraft != null && AuditStatusEnum.PENDING.getValue().equals(oldDraft.getAuditStatus())) {
oldDraft.setContent(dto.getContent());
oldDraft.setKnowledgeType(dto.getKnowledgeType() != null ? dto.getKnowledgeType() : oldDraft.getKnowledgeType());
// aiContent 保留不动(AI原始返回用于审计对比)
oldDraft.setAuditStatus(AuditStatusEnum.APPROVED.getValue());
knowledgePointDraftBaseService.updateById(oldDraft);
confirmedDrafts.add(oldDraft);
}
}
}
// 7. 复制草稿content到正式知识点表
List<KnowledgePointEntity> knowledgePoints = new ArrayList<>();
for (KnowledgePointDraftEntity draft : confirmedDrafts) {
KnowledgePointEntity kp = new KnowledgePointEntity();
kp.setId(customIdGenerator.nextId(kp));
kp.setContent(draft.getContent());
kp.setKnowledgeType(draft.getKnowledgeType());
kp.setInformationId(informationId);
kp.setParseName(draft.getParseName());
knowledgePoints.add(kp);
}
knowledgePointBaseService.saveBatch(knowledgePoints);
// 8. 更新资料状态为已审核通过(终态)
informationBaseService.lambdaUpdate()
.eq(InformationEntity::getId, informationId)
.set(InformationEntity::getDraftStatus, DraftStatusEnum.APPROVED.getValue())
.update();
// 9. 触发聚类
List<com.project.information.domain.dto.KnowledgePointDTO> kpList = knowledgePoints.stream()
.map(entity -> entity.toDTO(com.project.information.domain.dto.KnowledgePointDTO::new))
.toList();
algorithmApplicationService.postToClusteringByInformationId(informationId, kpList);
log.info(">>> [草稿审核] 批量保存并确认完成, informationId={}, 草稿数={}", informationId, confirmedDrafts.size());
return Result.success("保存成功,已审核通过");
}
} }

66
src/main/java/com/project/information/application/impl/KnowledgePointApplicationServiceImpl.java

@ -4,16 +4,21 @@ import cn.hutool.core.collection.CollUtil;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.project.base.domain.exception.BusinessErrorException;
import com.project.base.domain.result.Result; import com.project.base.domain.result.Result;
import com.project.information.application.KnowledgePointApplicationService; import com.project.information.application.KnowledgePointApplicationService;
import com.project.information.domain.dto.KnowledgePointDTO; import com.project.information.domain.dto.KnowledgePointDTO;
import com.project.information.domain.dto.KnowledgePointStatisticsDTO; import com.project.information.domain.dto.KnowledgePointStatisticsDTO;
import com.project.information.domain.entity.InformationEntity; import com.project.information.domain.entity.InformationEntity;
import com.project.information.domain.entity.KnowledgePointDraftEntity;
import com.project.information.domain.entity.KnowledgePointEntity; import com.project.information.domain.entity.KnowledgePointEntity;
import com.project.information.domain.enums.DraftStatusEnum;
import com.project.information.domain.enums.InformationParseStatusEnum; import com.project.information.domain.enums.InformationParseStatusEnum;
import com.project.information.domain.service.GetStatisticsKnowledgePointDomainService; import com.project.information.domain.service.GetStatisticsKnowledgePointDomainService;
import com.project.information.domain.service.InformationBaseService; import com.project.information.domain.service.InformationBaseService;
import com.project.information.domain.service.KnowledgePointBaseService; import com.project.information.domain.service.KnowledgePointBaseService;
import com.project.information.domain.service.KnowledgePointDraftBaseService;
import com.project.base.config.CustomIdGenerator;
import com.project.information.utils.MinIoUtils; import com.project.information.utils.MinIoUtils;
import com.project.interaction.application.AlgorithmApplicationService; import com.project.interaction.application.AlgorithmApplicationService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -45,6 +50,9 @@ public class KnowledgePointApplicationServiceImpl implements KnowledgePointAppli
@Autowired @Autowired
private KnowledgePointBaseService knowledgePointBaseService; private KnowledgePointBaseService knowledgePointBaseService;
@Autowired
private KnowledgePointDraftBaseService knowledgePointDraftBaseService;
@Autowired @Autowired
private InformationBaseService informationBaseService; private InformationBaseService informationBaseService;
@ -66,6 +74,9 @@ public class KnowledgePointApplicationServiceImpl implements KnowledgePointAppli
@Autowired @Autowired
private AlgorithmApplicationService algorithmApplicationService; private AlgorithmApplicationService algorithmApplicationService;
@Autowired
private CustomIdGenerator customIdGenerator;
@Override @Override
public Result<KnowledgePointStatisticsDTO> getStatistics(Long subLineId) throws Exception { public Result<KnowledgePointStatisticsDTO> getStatistics(Long subLineId) throws Exception {
return getStatisticsKnowledgePointDomainService.getStatistics(subLineId); return getStatisticsKnowledgePointDomainService.getStatistics(subLineId);
@ -228,4 +239,59 @@ public class KnowledgePointApplicationServiceImpl implements KnowledgePointAppli
informationEntity.setParseStatus(status); informationEntity.setParseStatus(status);
informationBaseService.updateById(informationEntity); informationBaseService.updateById(informationEntity);
} }
// =============== 测试用:模拟算法服务提取知识点草稿 ===============
@Override
public Result<String> mockAiExtract(Long informationId, Integer count) {
if (informationId == null) {
throw new BusinessErrorException("资料ID不能为空");
}
// 校验资料是否存在
InformationEntity information = informationBaseService.getById(informationId);
if (information == null) {
throw new BusinessErrorException("资料不存在");
}
// 如果已经审核通过,不允许重复模拟
if (DraftStatusEnum.APPROVED.getValue().equals(information.getDraftStatus())) {
return Result.success("该资料已审核通过,无需重复模拟");
}
// 生成模拟草稿数据(原始资料解析结果:全部精准,{{}}包裹考点)
// AI原始返回也带{{}},content和aiContent保持一致
List<KnowledgePointDraftEntity> drafts = new ArrayList<>();
String[] mockData = {
"{{Vue3}}组合式API核心函数包括{{ref()}}、{{reactive()}}和{{computed()}}",
"{{Spring Boot}}的{{@RestController}}注解等同于{{@Controller}}加{{@ResponseBody}}",
"{{MySQL}}的{{InnoDB}}引擎支持{{事务}}和{{外键}},{{MyISAM}}不支持",
"{{Redis}}持久化策略包括{{RDB}}和{{AOF}}两种方式",
"{{Docker}}容器使用{{UnionFS}}联合文件系统,{{镜像}}只读、{{容器}}可写"
};
int realCount = Math.min(count, mockData.length);
for (int i = 0; i < realCount; i++) {
KnowledgePointDraftEntity entity = new KnowledgePointDraftEntity();
entity.setId(customIdGenerator.nextId(entity));
entity.setInformationId(informationId);
entity.setKnowledgeType(0); // 原始资料解析结果:全部精准
entity.setParseName("mock_parse_" + informationId);
entity.setAiContent(mockData[i]); // AI原始返回,带{{}}
entity.setAuditStatus(0); // 待审核
drafts.add(entity);
}
// 批量保存到草稿表
knowledgePointDraftBaseService.saveBatch(drafts);
// 更新资料状态为:待审核
informationBaseService.lambdaUpdate()
.eq(InformationEntity::getId, informationId)
.set(InformationEntity::getDraftStatus, DraftStatusEnum.PENDING.getValue())
.set(InformationEntity::getParseStatus, InformationParseStatusEnum.Success.getValue())
.update();
log.info(">>> [模拟算法回调] 已生成{}条草稿, informationId={}", realCount, informationId);
return Result.success("模拟生成" + realCount + "条草稿成功");
}
} }

31
src/main/java/com/project/information/controller/InformationController.java

@ -1,14 +1,17 @@
package com.project.information.controller; package com.project.information.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.project.base.domain.result.PageResult; import com.project.base.domain.result.PageResult;
import com.project.base.domain.result.Result; import com.project.base.domain.result.Result;
import com.project.information.application.DraftReviewApplicationService; import com.project.information.application.DraftReviewApplicationService;
import com.project.information.application.GenerateFromFilesApplicationService; import com.project.information.application.GenerateFromFilesApplicationService;
import com.project.information.application.InformationApplicationService; import com.project.information.application.InformationApplicationService;
import com.project.information.application.KnowledgePointApplicationService;
import com.project.information.application.ProductLineApplicationService; import com.project.information.application.ProductLineApplicationService;
import com.project.information.application.UploadFilesApplicationService; import com.project.information.application.UploadFilesApplicationService;
import com.project.information.domain.dto.UploadedFileDTO; import com.project.information.domain.dto.UploadedFileDTO;
import com.project.information.domain.dto.DraftSaveDTO;
import com.project.information.domain.dto.InformationDTO; import com.project.information.domain.dto.InformationDTO;
import com.project.information.domain.dto.ProductLineDTO; import com.project.information.domain.dto.ProductLineDTO;
import com.project.information.domain.entity.KnowledgePointDraftEntity; import com.project.information.domain.entity.KnowledgePointDraftEntity;
@ -40,6 +43,9 @@ public class InformationController {
@Autowired @Autowired
private GenerateFromFilesApplicationService generateFromFilesApplicationService; private GenerateFromFilesApplicationService generateFromFilesApplicationService;
@Autowired
private KnowledgePointApplicationService knowledgePointApplicationService;
@Autowired @Autowired
private UploadFilesApplicationService uploadFilesApplicationService; private UploadFilesApplicationService uploadFilesApplicationService;
@ -125,4 +131,29 @@ public class InformationController {
public Result<String> confirmDraft(Long informationId) { public Result<String> confirmDraft(Long informationId) {
return draftReviewApplicationService.confirm(informationId); return draftReviewApplicationService.confirm(informationId);
} }
/**
* 批量保存草稿并确认替代逐条编辑+单独确认
* 前端编辑完所有草稿后一次性提交提交后自动固化
* 使用 form-data 传参informationId + draftListJSON字符串
*/
@PostMapping("/draft/batchSaveAndConfirm")
public Result<String> batchSaveAndConfirm(Long informationId, @RequestParam("draftList") String draftListJson) throws Exception {
// Postman form-data 会对 JSON 字符串做 URL 编码,先解码
String decodedJson = java.net.URLDecoder.decode(draftListJson, java.nio.charset.StandardCharsets.UTF_8);
ObjectMapper objectMapper = new ObjectMapper();
List<DraftSaveDTO> draftList = objectMapper.readValue(decodedJson,
objectMapper.getTypeFactory().constructCollectionType(List.class, DraftSaveDTO.class));
return draftReviewApplicationService.batchSaveAndConfirm(informationId, draftList);
}
// =============== 测试用:模拟算法服务回调生成草稿 ===============
/**
* 模拟算法服务提取知识点草稿算法服务未就绪时使用
*/
@PostMapping("/mockAiExtract")
public Result<String> mockAiExtract(Long informationId, @RequestParam(required = false, defaultValue = "5") Integer count) {
return knowledgePointApplicationService.mockAiExtract(informationId, count);
}
} }

Loading…
Cancel
Save