|
|
@@ -0,0 +1,198 @@
|
|
|
+package com.lingyue.parse.service;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.lingyue.parse.entity.ParseTask;
|
|
|
+import com.lingyue.parse.repository.ParseTaskRepository;
|
|
|
+import com.lingyue.parse.vo.ParseTaskCenterVO;
|
|
|
+import com.lingyue.parse.vo.ParseTaskStageVO;
|
|
|
+import com.lingyue.parse.vo.ParseTaskStatisticsVO;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 解析任务中心 Service
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+@RequiredArgsConstructor
|
|
|
+public class ParseTaskCenterService {
|
|
|
+
|
|
|
+ private final ParseTaskRepository parseTaskRepository;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 分页查询任务列表
|
|
|
+ */
|
|
|
+ public Page<ParseTaskCenterVO> getTaskList(String status, Integer pageNum, Integer pageSize) {
|
|
|
+ if (pageNum == null || pageNum < 1) {
|
|
|
+ pageNum = 1;
|
|
|
+ }
|
|
|
+ if (pageSize == null || pageSize < 1) {
|
|
|
+ pageSize = 10;
|
|
|
+ }
|
|
|
+
|
|
|
+ LambdaQueryWrapper<ParseTask> wrapper = new LambdaQueryWrapper<>();
|
|
|
+ if (status != null && !status.isBlank()) {
|
|
|
+ wrapper.eq(ParseTask::getStatus, status);
|
|
|
+ }
|
|
|
+ wrapper.orderByDesc(ParseTask::getCreateTime);
|
|
|
+
|
|
|
+ Page<ParseTask> page = new Page<>(pageNum, pageSize);
|
|
|
+ Page<ParseTask> taskPage = parseTaskRepository.selectPage(page, wrapper);
|
|
|
+
|
|
|
+ Page<ParseTaskCenterVO> result = new Page<>();
|
|
|
+ result.setCurrent(taskPage.getCurrent());
|
|
|
+ result.setSize(taskPage.getSize());
|
|
|
+ result.setTotal(taskPage.getTotal());
|
|
|
+
|
|
|
+ List<ParseTaskCenterVO> voList = new ArrayList<>();
|
|
|
+ for (ParseTask task : taskPage.getRecords()) {
|
|
|
+ voList.add(toCenterVO(task));
|
|
|
+ }
|
|
|
+ result.setRecords(voList);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询任务详情
|
|
|
+ */
|
|
|
+ public ParseTaskCenterVO getTaskDetail(String taskId) {
|
|
|
+ ParseTask task = parseTaskRepository.selectById(taskId);
|
|
|
+ if (task == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return toCenterVO(task);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据文档ID查询任务详情
|
|
|
+ */
|
|
|
+ public ParseTaskCenterVO getTaskDetailByDocumentId(String documentId) {
|
|
|
+ ParseTask task = parseTaskRepository.findByDocumentId(documentId);
|
|
|
+ if (task == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return toCenterVO(task);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 统计信息
|
|
|
+ */
|
|
|
+ public ParseTaskStatisticsVO getTaskStatistics() {
|
|
|
+ ParseTaskStatisticsVO vo = new ParseTaskStatisticsVO();
|
|
|
+ vo.setTotal(countByStatus(null));
|
|
|
+ vo.setPending(countByStatus("pending"));
|
|
|
+ vo.setProcessing(countByStatus("processing"));
|
|
|
+ vo.setCompleted(countByStatus("completed"));
|
|
|
+ vo.setFailed(countByStatus("failed"));
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private long countByStatus(String status) {
|
|
|
+ LambdaQueryWrapper<ParseTask> wrapper = new LambdaQueryWrapper<>();
|
|
|
+ if (status != null) {
|
|
|
+ wrapper.eq(ParseTask::getStatus, status);
|
|
|
+ }
|
|
|
+ return parseTaskRepository.selectCount(wrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 删除任务(进行中的任务不允许删除)
|
|
|
+ */
|
|
|
+ public boolean deleteTask(String taskId) {
|
|
|
+ ParseTask task = parseTaskRepository.selectById(taskId);
|
|
|
+ if (task == null) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if ("processing".equals(task.getStatus())) {
|
|
|
+ throw new IllegalStateException("运行中的任务不允许删除");
|
|
|
+ }
|
|
|
+ return parseTaskRepository.deleteById(taskId) > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Entity -> VO 映射 + 阶段列表组装
|
|
|
+ */
|
|
|
+ private ParseTaskCenterVO toCenterVO(ParseTask task) {
|
|
|
+ ParseTaskCenterVO vo = new ParseTaskCenterVO();
|
|
|
+ vo.setId(task.getId());
|
|
|
+ vo.setDocumentId(task.getDocumentId());
|
|
|
+ vo.setStatus(task.getStatus());
|
|
|
+ vo.setProgress(task.getProgress());
|
|
|
+ vo.setCurrentStep(task.getCurrentStep());
|
|
|
+ vo.setErrorMessage(task.getErrorMessage());
|
|
|
+ vo.setStartedAt(task.getStartedAt());
|
|
|
+ vo.setCompletedAt(task.getCompletedAt());
|
|
|
+ vo.setCreatedAt(task.getCreateTime());
|
|
|
+ vo.setUpdatedAt(task.getUpdateTime());
|
|
|
+ vo.setName("ParseTask-" + task.getDocumentId());
|
|
|
+ vo.setStages(buildStages(task));
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 简单阶段构建:上传、OCR+TXT、NER、图构建
|
|
|
+ */
|
|
|
+ private List<ParseTaskStageVO> buildStages(ParseTask task) {
|
|
|
+ List<ParseTaskStageVO> stages = new ArrayList<>();
|
|
|
+
|
|
|
+ ParseTaskStageVO upload = new ParseTaskStageVO();
|
|
|
+ upload.setStageName("upload");
|
|
|
+ upload.setDisplayName("文件上传");
|
|
|
+ upload.setStatus("completed");
|
|
|
+ upload.setProgress(100);
|
|
|
+ upload.setStartedAt(task.getCreateTime());
|
|
|
+ upload.setEndedAt(task.getCreateTime());
|
|
|
+ stages.add(upload);
|
|
|
+
|
|
|
+ ParseTaskStageVO ocr = new ParseTaskStageVO();
|
|
|
+ ocr.setStageName("ocr");
|
|
|
+ ocr.setDisplayName("OCR解析 & 文本存储");
|
|
|
+ ocr.setStartedAt(task.getStartedAt());
|
|
|
+
|
|
|
+ String status = task.getStatus();
|
|
|
+ if ("pending".equals(status)) {
|
|
|
+ ocr.setStatus("pending");
|
|
|
+ ocr.setProgress(0);
|
|
|
+ } else if ("processing".equals(status)) {
|
|
|
+ ocr.setStatus("in_progress");
|
|
|
+ ocr.setProgress(task.getProgress() != null ? task.getProgress() : 0);
|
|
|
+ } else if ("completed".equals(status)) {
|
|
|
+ ocr.setStatus("completed");
|
|
|
+ ocr.setProgress(100);
|
|
|
+ ocr.setEndedAt(task.getCompletedAt());
|
|
|
+ } else if ("failed".equals(status)) {
|
|
|
+ ocr.setStatus("failed");
|
|
|
+ ocr.setProgress(task.getProgress() != null ? task.getProgress() : 0);
|
|
|
+ ocr.setEndedAt(task.getCompletedAt());
|
|
|
+ ocr.setErrorMessage(task.getErrorMessage());
|
|
|
+ } else {
|
|
|
+ ocr.setStatus("pending");
|
|
|
+ ocr.setProgress(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ stages.add(ocr);
|
|
|
+
|
|
|
+ ParseTaskStageVO ner = new ParseTaskStageVO();
|
|
|
+ ner.setStageName("ner");
|
|
|
+ ner.setDisplayName("实体提取(NER)");
|
|
|
+ ner.setStatus("pending");
|
|
|
+ ner.setProgress(0);
|
|
|
+ stages.add(ner);
|
|
|
+
|
|
|
+ ParseTaskStageVO graph = new ParseTaskStageVO();
|
|
|
+ graph.setStageName("graph");
|
|
|
+ graph.setDisplayName("图构建");
|
|
|
+ graph.setStatus("pending");
|
|
|
+ graph.setProgress(0);
|
|
|
+ stages.add(graph);
|
|
|
+
|
|
|
+ return stages;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|