Browse Source

算法服务对接修改

master
luoweijian 2 months ago
parent
commit
aaa989fd1e
  1. 17
      src/main/java/com/project/interaction/application/TriggerAiExtractApplicationService.java
  2. 110
      src/main/java/com/project/interaction/application/impl/TriggerAiExtractApplicationServiceImpl.java
  3. 13
      src/main/java/com/project/interaction/controller/InteractionController.java
  4. 9
      src/main/java/com/project/interaction/domain/dto/AiExtractRequestDTO.java
  5. 49
      src/main/java/com/project/interaction/domain/dto/AiExtractTriggerResultDTO.java
  6. 6
      src/main/java/com/project/interaction/domain/dto/GenerateQuestionRequestDTO.java
  7. 9
      src/main/java/com/project/interaction/domain/service/SaveDataExtractResultDomainService.java
  8. 5
      src/main/java/com/project/interaction/domain/service/impl/PostToGenerateQuestionDomainServiceImpl.java
  9. 46
      src/main/java/com/project/interaction/domain/service/impl/SaveDataExtractResultDomainServiceImpl.java

17
src/main/java/com/project/interaction/application/TriggerAiExtractApplicationService.java

@ -0,0 +1,17 @@
package com.project.interaction.application;
import com.project.interaction.domain.dto.AiExtractTriggerResultDTO;
/**
* 手动触发知识点提取应用服务
*/
public interface TriggerAiExtractApplicationService {
/**
* 手动触发知识点提取
* 校验子文件是否全部解析完成完成则调用算法服务
* @param informationId 虚拟资料ID
* @return 触发结果含各文件解析状态
*/
AiExtractTriggerResultDTO trigger(Long informationId);
}

110
src/main/java/com/project/interaction/application/impl/TriggerAiExtractApplicationServiceImpl.java

@ -0,0 +1,110 @@
package com.project.interaction.application.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.project.information.domain.entity.InformationFileEntity;
import com.project.information.domain.enums.FileParseStatusEnum;
import com.project.information.domain.service.InformationFileBaseService;
import com.project.interaction.application.TriggerAiExtractApplicationService;
import com.project.interaction.domain.dto.AiExtractRequestDTO;
import com.project.interaction.domain.dto.AiExtractTriggerResultDTO;
import com.project.interaction.domain.service.PostToAiExtractDomainService;
import com.project.interaction.domain.service.SaveDataExtractResultDomainService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* 手动触发知识点提取应用服务实现
*/
@Service
@Slf4j
public class TriggerAiExtractApplicationServiceImpl implements TriggerAiExtractApplicationService {
@Autowired
private InformationFileBaseService informationFileBaseService;
@Autowired
private PostToAiExtractDomainService postToAiExtractDomainService;
@Autowired
private SaveDataExtractResultDomainService saveDataExtractResultDomainService;
@Override
public AiExtractTriggerResultDTO trigger(Long informationId) {
// 1. 查询该虚拟资料下所有子文件
List<InformationFileEntity> allFiles = informationFileBaseService.list(
new LambdaQueryWrapper<InformationFileEntity>()
.eq(InformationFileEntity::getInformationId, informationId)
.orderByAsc(InformationFileEntity::getCreateTime));
if (allFiles.isEmpty()) {
return new AiExtractTriggerResultDTO(true, null, "该虚拟资料下没有子文件", new ArrayList<>());
}
// 2. 构建各文件状态
List<AiExtractTriggerResultDTO.FileStatus> fileStatuses = new ArrayList<>();
boolean allDone = true;
boolean allSuccess = true;
for (InformationFileEntity f : allFiles) {
Integer parseStatus = f.getParseStatus();
String statusText = getStatusText(parseStatus);
AiExtractTriggerResultDTO.FileStatus fs =
new AiExtractTriggerResultDTO.FileStatus(f.getId(), f.getFileName(), parseStatus, statusText);
fileStatuses.add(fs);
if (!FileParseStatusEnum.Success.getValue().equals(parseStatus)
&& !FileParseStatusEnum.Failed.getValue().equals(parseStatus)) {
allDone = false;
}
if (!FileParseStatusEnum.Success.getValue().equals(parseStatus)) {
allSuccess = false;
}
}
// 3. 未全部完成
if (!allDone) {
String message = "子文件尚未全部解析完成,共 " + allFiles.size() + " 个文件,"
+ allFiles.stream().filter(f -> FileParseStatusEnum.Success.getValue().equals(f.getParseStatus())).count()
+ " 个已完成";
return new AiExtractTriggerResultDTO(false, null, message, fileStatuses);
}
// 4. 全部完成但有失败
if (!allSuccess) {
String message = "存在解析失败的子文件,无法调用算法服务";
return new AiExtractTriggerResultDTO(true, false, message, fileStatuses);
}
// 5. 全部成功 → 调用算法服务
log.info(">>> [手动触发] 虚拟资料 {} 下所有子文件解析完成,开始调用算法服务", informationId);
AiExtractRequestDTO extractRequest = saveDataExtractResultDomainService.buildExtractRequest(informationId);
if (extractRequest == null) {
return new AiExtractTriggerResultDTO(true, true, "所有子文件解析成功,但无有效文本内容", fileStatuses);
}
postToAiExtractDomainService.postToAiExtract(extractRequest);
String message = "已成功触发算法服务,共 " + extractRequest.getSegments().size() + " 个文本片段";
return new AiExtractTriggerResultDTO(true, true, message, fileStatuses);
}
private String getStatusText(Integer status) {
if (status == null) {
return "未知";
}
return switch (status) {
case 0 -> "未开始";
case 1 -> "进行中";
case 2 -> "成功";
case -1 -> "失败";
default -> "未知";
};
}
}

13
src/main/java/com/project/interaction/controller/InteractionController.java

@ -7,7 +7,9 @@ import com.project.base.domain.result.Result;
import com.project.interaction.application.AiExtractCallbackApplicationService;
import com.project.interaction.application.AlgorithmApplicationService;
import com.project.interaction.application.DataExtractCallbackApplicationService;
import com.project.interaction.application.TriggerAiExtractApplicationService;
import com.project.interaction.domain.dto.AiExtractCallbackDTO;
import com.project.interaction.domain.dto.AiExtractTriggerResultDTO;
import com.project.interaction.domain.dto.ClusterCallbackDTO;
import com.project.interaction.domain.dto.DataExtractCallbackDTO;
import com.project.interaction.domain.dto.QuestionCallBackDTO;
@ -39,6 +41,8 @@ public class InteractionController {
private DataExtractCallbackApplicationService dataExtractCallbackApplicationService;
@Autowired
private AiExtractCallbackApplicationService aiExtractCallbackApplicationService;
@Autowired
private TriggerAiExtractApplicationService triggerAiExtractApplicationService;
// @PostMapping("/saveCluster")
// public Result<String> saveCluster(ClusterCallbackDTO dto) throws Exception{
@ -102,6 +106,15 @@ public class InteractionController {
return Result.success("回调处理成功");
}
/**
* 手动触发知识点提取
* 校验子文件是否全部解析完成完成则调用算法服务
*/
@PostMapping("/triggerAiExtract")
public Result<AiExtractTriggerResultDTO> triggerAiExtract(@RequestParam("informationId") Long informationId) {
return Result.success(triggerAiExtractApplicationService.trigger(informationId));
}
/**
* 算法服务知识点提取回调
* 算法服务返回草稿知识点写入草稿表

9
src/main/java/com/project/interaction/domain/dto/AiExtractRequestDTO.java

@ -7,6 +7,7 @@ import java.util.List;
/**
* 算法服务 - 知识点提取请求 DTO
* 入参结构按算法接口确认
*/
@Data
public class AiExtractRequestDTO {
@ -15,10 +16,14 @@ public class AiExtractRequestDTO {
@JsonProperty("information_id")
private Long informationId;
/** 子文件解析后的分段列表(直接取 parsed_text 的 segments) */
/** 文件内容分类(产品类/知识类/规范类/流程类) */
@JsonProperty("chunk_size")
private Integer chunkSize = 80;
/** 子文件解析文本列表 */
private List<Segment> segments;
/** 回调URL(配置注入) */
/** 回调URL */
@JsonProperty("callback_url")
private String callbackUrl;

49
src/main/java/com/project/interaction/domain/dto/AiExtractTriggerResultDTO.java

@ -0,0 +1,49 @@
package com.project.interaction.domain.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* 手动触发知识点提取结果 DTO
*/
@Data
@AllArgsConstructor
public class AiExtractTriggerResultDTO {
/** 是否全部解析完成 */
private Boolean allDone;
/** 是否全部成功(allDone 为 true 时有效) */
private Boolean allSuccess;
/** 提示信息 */
private String message;
/** 各子文件解析状态 */
private List<FileStatus> fileStatuses;
@Data
public static class FileStatus {
/** 子文件ID */
private Long fileId;
/** 文件名 */
private String fileName;
/** 解析状态:0-未开始,1-进行中,2-成功,-1-失败 */
private Integer parseStatus;
/** 状态文本 */
private String statusText;
public FileStatus(Long fileId, String fileName, Integer parseStatus, String statusText) {
this.fileId = fileId;
this.fileName = fileName;
this.parseStatus = parseStatus;
this.statusText = statusText;
}
}
}

6
src/main/java/com/project/interaction/domain/dto/GenerateQuestionRequestDTO.java

@ -41,6 +41,12 @@ public class GenerateQuestionRequestDTO {
@JsonProperty("question_types")
private List<String> questionTypes;
/**
* 回调URL
*/
@JsonProperty("callback_url")
private String callbackUrl;
/**
* 聚类信息内部类
*/

9
src/main/java/com/project/interaction/domain/service/SaveDataExtractResultDomainService.java

@ -1,11 +1,20 @@
package com.project.interaction.domain.service;
import com.project.interaction.domain.dto.AiExtractRequestDTO;
import com.project.interaction.domain.dto.DataExtractCallbackDTO;
/**
* 保存数据服务解析结果域服务
* 更新子文件解析状态和文本检查批次完成触发算法服务
*/
public interface SaveDataExtractResultDomainService {
void handleCallback(DataExtractCallbackDTO callback);
/**
* 构建知识点提取请求从已解析完成的子文件列表
* @param informationId 虚拟资料ID
* @return 请求 DTOnull 表示无有效数据
*/
AiExtractRequestDTO buildExtractRequest(Long informationId);
}

5
src/main/java/com/project/interaction/domain/service/impl/PostToGenerateQuestionDomainServiceImpl.java

@ -44,6 +44,10 @@ public class PostToGenerateQuestionDomainServiceImpl implements PostToGenerateQu
@Value("${algo.apiUrl:http://172.16.25.174:8000}")
private String apiUrl;
/** 题目生成回调地址 */
@Value("${algo.generateQuestionCallbackUrl:http://172.16.204.50/evaluator-api}")
private String callbackUrl;
@Autowired
private SaveQuestionDomainService saveQuestionDomainService;
@ -159,6 +163,7 @@ public class PostToGenerateQuestionDomainServiceImpl implements PostToGenerateQu
// 构建请求
GenerateQuestionRequestDTO requestDTO = GenerateQuestionRequestDTO.builder()
.callbackUrl(callbackUrl)
.cluster(GenerateQuestionRequestDTO.ClusterInfo.builder()
.clusterId(clusterId)
.taskId(taskId)

46
src/main/java/com/project/interaction/domain/service/impl/SaveDataExtractResultDomainServiceImpl.java

@ -36,7 +36,7 @@ public class SaveDataExtractResultDomainServiceImpl implements SaveDataExtractRe
private ObjectMapper objectMapper;
/** 算法服务回调地址 */
@Value("${algo.callbackUrl:http://172.16.204.50/evaluator-api/api/interaction/aiExtractCallback}")
@Value("${algo.callbackUrl:http://172.16.204.50/evaluator-api}")
private String callbackUrl;
@Override
@ -82,47 +82,65 @@ public class SaveDataExtractResultDomainServiceImpl implements SaveDataExtractRe
return;
}
// 4. 全部成功 → 解析 parsedText JSON,构建 segments 列表,调用算法服务
// 4. 全部成功 → 构建请求并调用算法服务
log.info(">>> [数据服务回调] 虚拟资料 {} 下所有子文件解析成功,开始调用算法服务", informationId);
AiExtractRequestDTO request = buildExtractRequest(informationId);
if (request != null) {
postToAiExtractDomainService.postToAiExtract(request);
}
}
@Override
public AiExtractRequestDTO buildExtractRequest(Long informationId) {
List<InformationFileEntity> allFiles = informationFileBaseService.list(
new LambdaQueryWrapper<InformationFileEntity>()
.eq(InformationFileEntity::getInformationId, informationId));
if (allFiles.isEmpty()) {
return null;
}
List<AiExtractRequestDTO.Segment> allSegments = new ArrayList<>();
for (InformationFileEntity f : allFiles) {
if (f.getParsedText() == null || f.getParsedText().isBlank()) {
continue;
}
// 解析 parsed_text JSON: {"segments": [{"content": "...", "supplement": "", "chapter": "...", "content_type": "..."}]}
// 解析 parsed_text JSON: {"segments": [[{"content": "...", "supplement": "", "chapter": "...", "content_type": "..."}]]}
// segments 是双层数组:外层=每个子文件,内层=该文件的段落列表
try {
Map<String, List<Map<String, String>>> parsed = objectMapper.readValue(
f.getParsedText(), new TypeReference<Map<String, List<Map<String, String>>>>() {});
List<Map<String, String>> segments = parsed.get("segments");
if (segments == null || segments.isEmpty()) {
Map<String, List<List<Map<String, String>>>> parsed = objectMapper.readValue(
f.getParsedText(), new TypeReference<>() {
});
List<List<Map<String, String>>> fileGroups = parsed.get("segments");
if (fileGroups == null || fileGroups.isEmpty()) {
continue;
}
String fileName = f.getFileName();
for (Map<String, String> seg : segments) {
for (List<Map<String, String>> group : fileGroups) {
for (Map<String, String> seg : group) {
AiExtractRequestDTO.Segment segment = new AiExtractRequestDTO.Segment();
segment.setContent(seg.get("content"));
segment.setSupplement(seg.get("supplement"));
segment.setChapter(seg.get("chapter"));
segment.setParseName(fileName); // parseName = 文件名
segment.setParseName(fileName);
segment.setContentType(seg.get("content_type"));
allSegments.add(segment);
}
}
} catch (Exception e) {
log.error(">>> [数据服务回调] 解析 parsedText 失败, fileId={}, error={}", f.getId(), e.getMessage());
log.error(">>> [数据服务] 解析 parsedText 失败, fileId={}, error={}", f.getId(), e.getMessage());
}
}
if (allSegments.isEmpty()) {
log.warn(">>> [数据服务回调] 虚拟资料 {} 下所有子文件已解析但无有效 segments", informationId);
return;
return null;
}
AiExtractRequestDTO request = new AiExtractRequestDTO();
request.setInformationId(informationId);
request.setSegments(allSegments);
request.setCallbackUrl(callbackUrl);
postToAiExtractDomainService.postToAiExtract(request);
return request;
}
}

Loading…
Cancel
Save