package com.gxwebsoft.ai.service.impl; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.gxwebsoft.ai.constants.AuditContent3TripleConstants; import com.gxwebsoft.ai.service.AuditContent3TripleService; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import cn.hutool.core.util.StrUtil; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; @Slf4j @Service public class AuditContent3TripleServiceImpl extends AbstractAuditContentService implements AuditContent3TripleService { // 工作流配置 private static final String DIFY_WORKFLOW_TOKEN = "Bearer app-tjXbmHDE6daMbYOT4O13ev2X"; // 三重一大分类定义 - 按照要求的顺序 private static final List CATEGORY_ORDER = Arrays.asList( AuditContent3TripleConstants.CATEGORY_MAJOR_DECISION, AuditContent3TripleConstants.CATEGORY_PERSONNEL_APPOINTMENT, AuditContent3TripleConstants.CATEGORY_MAJOR_PROJECT, AuditContent3TripleConstants.CATEGORY_LARGE_FUND_OPERATION, AuditContent3TripleConstants.CATEGORY_DECISION_PROCEDURE ); @Override public JSONObject generateTripleOneTableData(String kbIds, String libraryKbIds, String projectLibrary, String userName, String history, String suggestion) { log.info("开始生成三重一大制度对比分析表数据 - 用户: {}, kbIds: {}, libraryIds: {}, projectLibrary: {}", userName, kbIds, libraryKbIds, projectLibrary); long startTime = System.currentTimeMillis(); try { // 异步并行处理每个分类 Map> futures = processCategoriesAsync( CATEGORY_ORDER, category -> generateCategoryDataAsync(category, kbIds, libraryKbIds, projectLibrary, userName, history, suggestion) ); // 等待所有异步任务完成 CompletableFuture.allOf(futures.values().toArray(new CompletableFuture[0])).join(); // 合并所有分类的结果 JSONArray allData = mergeCategoryResults(CATEGORY_ORDER, futures); log.info("三重一大制度对比分析表生成成功 - 记录数: {}, 处理时间: {}ms", allData.size(), (System.currentTimeMillis() - startTime)); return buildSuccessResponse(allData, startTime, "triple_one_audit"); } catch (Exception e) { log.error("生成三重一大制度对比分析表失败", e); return buildErrorResponse("生成三重一大制度对比分析表失败: " + e.getMessage()); } } /** * 异步生成单个分类的数据 */ @Async public CompletableFuture generateCategoryDataAsync(String category, String kbIds, String libraryKbIds, String projectLibrary, String userName, String history, String suggestion) { return CompletableFuture.supplyAsync(() -> { try { log.info("开始生成分类 {} 的数据", category); // 1. 为当前分类召回相关知识 Map> knowledgeSources = retrieveKnowledgeForCategory( category, kbIds, libraryKbIds, projectLibrary ); // 2. 构建完整的知识上下文(包含固定内容和动态内容) String knowledgeContext = buildCompleteKnowledgeContext( category, knowledgeSources, history, suggestion ); // 3. 调用工作流生成数据 JSONObject requestBody = buildWorkflowRequest(knowledgeContext, userName); JSONArray categoryData = callWorkflow(DIFY_WORKFLOW_URL, DIFY_WORKFLOW_TOKEN, requestBody, "三重一大-" + category); log.info("分类 {} 数据生成完成,生成 {} 条记录", category, categoryData.size()); return categoryData; } catch (Exception e) { log.error("生成分类 {} 数据失败", category, e); return new JSONArray(); } }); } /** * 为单个分类检索相关知识 */ private Map> retrieveKnowledgeForCategory(String category, String kbIds, String libraryKbIds, String projectLibrary) { Map> knowledgeSources = new HashMap<>(); knowledgeSources.put("enterprise", new ArrayList<>()); knowledgeSources.put("regulation", new ArrayList<>()); knowledgeSources.put("auditCase", new ArrayList<>()); // 构建当前分类的查询词 List categoryQueries = buildCategoryQueries(category); // 企业单位库检索 if (StrUtil.isNotBlank(kbIds)) { Arrays.stream(kbIds.split(",")) .map(String::trim) .filter(StrUtil::isNotBlank) .forEach(kbId -> knowledgeSources.get("enterprise") .addAll(queryKnowledgeBase(kbId, categoryQueries, 100))); } // 公共法律法规库检索 if (StrUtil.isNotBlank(libraryKbIds)) { Arrays.stream(libraryKbIds.split(",")) .map(String::trim) .filter(StrUtil::isNotBlank) .forEach(libId -> knowledgeSources.get("regulation") .addAll(queryKnowledgeBase(libId, categoryQueries, 80))); } // 审计案例库检索 if (StrUtil.isNotBlank(projectLibrary)) { knowledgeSources.get("auditCase").addAll( queryKnowledgeBase(projectLibrary, categoryQueries, 60)); } // 智能去重和排序 knowledgeSources.forEach((key, list) -> { List processed = list.stream() .distinct() .sorted(this::tripleOneComparator) .limit(getLimitBySourceType(key)) .collect(Collectors.toList()); knowledgeSources.put(key, processed); }); log.debug("分类 {} 知识检索完成 - 企业: {}条, 法规: {}条, 案例: {}条", category, knowledgeSources.get("enterprise").size(), knowledgeSources.get("regulation").size(), knowledgeSources.get("auditCase").size()); return knowledgeSources; } /** * 构建分类特定的查询词 */ private List buildCategoryQueries(String category) { switch (category) { case AuditContent3TripleConstants.CATEGORY_MAJOR_DECISION: return Arrays.asList("重大决策事项 决策范围 决策程序", "重大决策制度 集体决策规定"); case AuditContent3TripleConstants.CATEGORY_PERSONNEL_APPOINTMENT: return Arrays.asList("重要人事任免 人事任免范围", "中层管理人员 领导班子成员 任免"); case AuditContent3TripleConstants.CATEGORY_MAJOR_PROJECT: return Arrays.asList("重大项目安排 项目安排范围", "年度投资计划 融资担保项目"); case AuditContent3TripleConstants.CATEGORY_LARGE_FUND_OPERATION: return Arrays.asList("大额度资金运作 资金运作范围", "年度预算 大额度资金使用"); case AuditContent3TripleConstants.CATEGORY_DECISION_PROCEDURE: return Arrays.asList("决策权力主体 决策程序", "集体决策 前置程序"); default: return Arrays.asList(category + " 制度规定"); } } /** * 构建完整的知识上下文 - 包含固定内容和动态内容 */ private String buildCompleteKnowledgeContext(String category, Map> knowledgeSources, String history, String suggestion) { StringBuilder context = new StringBuilder(); // 1. 三重一大制度对比分析要求 context.append("## 三重一大制度对比分析要求 - ").append(category).append("\n"); context.append("请基于以下知识生成").append(category).append("相关的三重一大制度对比分析表数据:\n\n"); context.append("1. 仅关注与").append(category).append("直接相关的制度内容,过滤不相关制度\n"); context.append("2. 对比分析政策内容、集团制度、公司制度的差异\n"); context.append("3. 重点关注决策范围、金额标准、程序要求的差异\n"); context.append("4. 识别制度执行中的风险和问题\n"); context.append("5. 严格判断测试结果,只有证据充分才能判定为通过,证据不足或存在差异必须判定为不通过\n\n"); // 2. 数据格式要求 context.append("## 数据格式要求\n"); context.append("需要生成").append(category).append("分类的数据,尽可能生成多个实例、多条记录:\n"); context.append("- ").append(category).append(":").append(AuditContent3TripleConstants.CATEGORY_DESCRIPTIONS.get(category)).append("\n"); context.append("\n"); context.append("每条记录应包含6个字段:\n"); context.append("- policyContent:国家法律法规和政策规定,需引用具体法规名称和条款\n"); context.append("- groupSystem:集团层面的三重一大相关制度规定,非相关制度不得纳入\n"); context.append("- companyFormulation:公司层面的三重一大相关制度规定及执行情况,需包含详细分析过程和查阅依据\n"); context.append("- checkEvidence:审计检查的证据,需详细描述查阅过程、查阅的具体文件和内容\n"); context.append("- testResult:审计测试的结果(通过/不通过),严格判断,从严掌握通过标准\n"); context.append("- workPaperIndex:相关《参考文件名FileId》,必须是实际存在的完整文件FileId,不能使用附表标题,确保能在文件夹中搜索到\n"); context.append("\n注意:\n"); context.append("1. 请根据知识库内容尽可能全面地生成所有相关制度规定和检查点\n"); context.append("2. 公司执行情况分析需包含:查阅了哪些文件、发现了什么内容、与制度的差异点、分析判断过程\n"); context.append("3. 工作底稿索引必须准确对应实际文件名称,避免使用附表或章节标题\n"); context.append("4. 测试结果判定需严格,对于制度不一致、执行不到位、证据不充分的情况必须判定为不通过\n"); context.append("5. 审计检查的证据主要按公司制度为主,政策内容和集团制度为次要\n"); context.append("6. 审计检查的证据增加判断公司制度是否与政策内容和集团制度相符\n\n"); // 3. 参考数据(从常量类中获取) context.append("## 参考数据\n"); context.append("### 政策内容\n").append(AuditContent3TripleConstants.POLICY_CONTENTS.get(category)).append("\n\n"); context.append("### 集团制度\n").append(AuditContent3TripleConstants.GROUP_SYSTEMS.get(category)).append("\n\n"); context.append("### 公司制度\n").append(AuditContent3TripleConstants.COMPANY_FORMULATIONS.get(category)).append("\n\n"); // 4. 历史内容 if (StrUtil.isNotBlank(history)) { context.append("## 历史生成内容\n"); context.append("以下是之前生成的内容,请基于此进行优化:\n"); context.append(history).append("\n\n"); } // 5. 用户建议 if (StrUtil.isNotBlank(suggestion)) { context.append("## 用户优化建议\n"); context.append("请根据以下建议对生成内容进行调整:\n"); context.append(suggestion).append("\n\n"); } // 6. 企业单位知识 if (!knowledgeSources.get("enterprise").isEmpty()) { context.append("## 企业单位知识\n"); knowledgeSources.get("enterprise").forEach(knowledge -> context.append(knowledge).append("\n")); context.append("\n"); } // 7. 法律法规知识 if (!knowledgeSources.get("regulation").isEmpty()) { context.append("## 法律法规知识\n"); knowledgeSources.get("regulation").forEach(knowledge -> context.append(knowledge).append("\n")); context.append("\n"); } // 8. 审计案例知识 if (!knowledgeSources.get("auditCase").isEmpty()) { context.append("## 审计案例知识\n"); knowledgeSources.get("auditCase").forEach(knowledge -> context.append(knowledge).append("\n")); } return context.toString(); } /** * 三重一大相关性比较器 */ private int tripleOneComparator(String reg1, String reg2) { int score1 = calculateTripleOneRelevanceScore(reg1); int score2 = calculateTripleOneRelevanceScore(reg2); return Integer.compare(score2, score1); } /** * 计算三重一大相关性分数 */ private int calculateTripleOneRelevanceScore(String content) { return AuditContent3TripleConstants.KEYWORD_WEIGHTS.entrySet().stream() .filter(entry -> content.contains(entry.getKey())) .mapToInt(Map.Entry::getValue) .sum(); } private int getLimitBySourceType(String sourceType) { switch (sourceType) { case "enterprise": return 100; case "regulation": return 80; case "auditCase": return 60; default: return 50; } } }