From 2464e0e79159519f52d13c1a32c8eeb5945a340c Mon Sep 17 00:00:00 2001 From: yuance <182865460@qq.com> Date: Fri, 12 Dec 2025 15:57:47 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=AE=A1=E8=AE=A1=E5=86=85?= =?UTF-8?q?=E5=AE=B911-=E5=8E=86=E5=8F=B2=E5=AE=A1=E8=AE=A1=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E6=95=B4=E6=94=B9=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AuditContent11HistoryConstants.java | 90 ++++++ .../controller/AuditContent11Controller.java | 297 ++++++++++++++++++ .../dto/export/HistoryTableExportEntity.java | 46 +++ .../service/AuditContent11HistoryService.java | 23 ++ .../AuditContent11HistoryServiceImpl.java | 291 +++++++++++++++++ 5 files changed, 747 insertions(+) create mode 100644 src/main/java/com/gxwebsoft/ai/constants/AuditContent11HistoryConstants.java create mode 100644 src/main/java/com/gxwebsoft/ai/controller/AuditContent11Controller.java create mode 100644 src/main/java/com/gxwebsoft/ai/dto/export/HistoryTableExportEntity.java create mode 100644 src/main/java/com/gxwebsoft/ai/service/AuditContent11HistoryService.java create mode 100644 src/main/java/com/gxwebsoft/ai/service/impl/AuditContent11HistoryServiceImpl.java diff --git a/src/main/java/com/gxwebsoft/ai/constants/AuditContent11HistoryConstants.java b/src/main/java/com/gxwebsoft/ai/constants/AuditContent11HistoryConstants.java new file mode 100644 index 0000000..bae4425 --- /dev/null +++ b/src/main/java/com/gxwebsoft/ai/constants/AuditContent11HistoryConstants.java @@ -0,0 +1,90 @@ +package com.gxwebsoft.ai.constants; + +import java.util.HashMap; +import java.util.Map; + +/** + * 审计内容11-历史审计问题整改常量类 + */ +public class AuditContent11HistoryConstants { + + // 审计类型分类 + public static final String AUDIT_TYPE_INTERNAL = "内部审计"; + public static final String AUDIT_TYPE_EXTERNAL = "外部审计"; + public static final String AUDIT_TYPE_SPECIAL = "专项审计"; + public static final String AUDIT_TYPE_ECONOMIC = "经济责任审计"; + + // 整改状态 + public static final String STATUS_COMPLETED = "已完成"; + public static final String STATUS_IN_PROGRESS = "整改中"; + public static final String STATUS_NOT_STARTED = "未整改"; + public static final String STATUS_PARTIAL = "部分整改"; + + // 审计重点分类 + public static final String FOCUS_SYSTEM_MECHANISM = "制度机制建立情况"; + public static final String FOCUS_HISTORICAL_ISSUES = "历史遗留问题处理"; + public static final String FOCUS_RECTIFICATION_EFFECT = "整改数量及效果"; + public static final String FOCUS_SYSTEM_IMPROVEMENT = "制度完善情况"; + public static final String FOCUS_SELF_RECTIFICATION = "自行发现整改情况"; + + // 审计方法关键词 + public static final String METHOD_REVIEW_REPORT = "审阅审计报告"; + public static final String METHOD_REVIEW_RECTIFICATION = "审阅整改报告"; + public static final String METHOD_VERIFY_RECTIFICATION = "核实整改情况"; + public static final String METHOD_INTERVIEW = "个别访谈"; + public static final String METHOD_REVIEW_DOCS = "查阅相关资料"; + + // 分类描述 + public static final Map FOCUS_DESCRIPTIONS = new HashMap<>(); + static { + FOCUS_DESCRIPTIONS.put(FOCUS_SYSTEM_MECHANISM, "是否有处理历史遗留问题的制度机制"); + FOCUS_DESCRIPTIONS.put(FOCUS_HISTORICAL_ISSUES, "任期内是否有处理非任期的历史遗留问题"); + FOCUS_DESCRIPTIONS.put(FOCUS_RECTIFICATION_EFFECT, "对历次审计检查发现的问题整改的数量及效果"); + FOCUS_DESCRIPTIONS.put(FOCUS_SYSTEM_IMPROVEMENT, "历次审计检查发现问题后是否有完善相关制度"); + FOCUS_DESCRIPTIONS.put(FOCUS_SELF_RECTIFICATION, "历次审计没有发现的问题是否自行发现并整改完善"); + } + + // 审计方法描述 + public static final Map METHOD_DESCRIPTIONS = new HashMap<>(); + static { + METHOD_DESCRIPTIONS.put(METHOD_REVIEW_REPORT, "审阅任职期间审计报告"); + METHOD_DESCRIPTIONS.put(METHOD_REVIEW_RECTIFICATION, "审阅整改情况报告"); + METHOD_DESCRIPTIONS.put(METHOD_VERIFY_RECTIFICATION, "对提出问题整改情况逐一进行核实"); + METHOD_DESCRIPTIONS.put(METHOD_INTERVIEW, "通过个别访谈了解情况"); + METHOD_DESCRIPTIONS.put(METHOD_REVIEW_DOCS, "查阅相关资料了解单位存在的历年遗留问题和处理情况"); + } + + // 关键词权重(用于知识检索排序) + public static final Map KEYWORD_WEIGHTS = new HashMap<>(); + static { + KEYWORD_WEIGHTS.put("审计发现问题", 10); + KEYWORD_WEIGHTS.put("问题整改", 9); + KEYWORD_WEIGHTS.put("整改情况", 9); + KEYWORD_WEIGHTS.put("整改报告", 8); + KEYWORD_WEIGHTS.put("审计报告", 8); + KEYWORD_WEIGHTS.put("历史遗留问题", 9); + KEYWORD_WEIGHTS.put("制度机制", 7); + KEYWORD_WEIGHTS.put("整改措施", 7); + KEYWORD_WEIGHTS.put("整改责任人", 6); + KEYWORD_WEIGHTS.put("整改完成", 6); + KEYWORD_WEIGHTS.put("审计年度", 5); + KEYWORD_WEIGHTS.put("审计类型", 5); + KEYWORD_WEIGHTS.put("经济责任审计", 6); + } + + // 整改要求常见关键词 + public static final String[] RECTIFICATION_REQUIREMENT_KEYWORDS = { + "限期整改", "建立机制", "完善制度", "责任追究", "资金追回", + "规范管理", "加强内控", "落实责任", "建立台账", "跟踪检查" + }; + + // 整改措施常见关键词 + public static final String[] RECTIFICATION_MEASURES_KEYWORDS = { + "修订制度", "完善流程", "加强培训", "调整人员", "资金归还", + "建立台账", "完善手续", "强化监督", "责任追究", "定期检查" + }; + + private AuditContent11HistoryConstants() { + // 防止实例化 + } +} \ No newline at end of file diff --git a/src/main/java/com/gxwebsoft/ai/controller/AuditContent11Controller.java b/src/main/java/com/gxwebsoft/ai/controller/AuditContent11Controller.java new file mode 100644 index 0000000..9e23817 --- /dev/null +++ b/src/main/java/com/gxwebsoft/ai/controller/AuditContent11Controller.java @@ -0,0 +1,297 @@ +package com.gxwebsoft.ai.controller; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.gxwebsoft.ai.dto.AuditContentRequest; +import com.gxwebsoft.ai.dto.export.HistoryTableExportEntity; +import com.gxwebsoft.ai.entity.AiCloudDoc; +import com.gxwebsoft.ai.entity.AiCloudFile; +import com.gxwebsoft.ai.service.AiHistoryService; +import com.gxwebsoft.ai.utils.ExcelExportTool; +import com.gxwebsoft.common.core.web.ApiResult; +import com.gxwebsoft.common.core.web.BaseController; +import com.gxwebsoft.common.system.entity.User; +import com.gxwebsoft.pwl.entity.PwlProjectLibrary; +import com.gxwebsoft.pwl.service.PwlProjectLibraryService; +import com.gxwebsoft.ai.service.AiCloudDocService; +import com.gxwebsoft.ai.service.AiCloudFileService; +import com.gxwebsoft.ai.service.AuditContent11HistoryService; +import com.gxwebsoft.ai.service.KnowledgeBaseService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.digest.DigestUtil; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 审计内容11控制器 - 历史审计问题整改表 + */ +@Slf4j +@Tag(name = "审计内容11-历史审计问题整改") +@RestController +@RequestMapping("/api/ai/auditContent11") +public class AuditContent11Controller extends BaseController { + + @Autowired + private AuditContent11HistoryService auditContent11HistoryService; + + @Autowired + private AiCloudDocService aiCloudDocService; + + @Autowired + private AiCloudFileService aiCloudFileService; + + @Autowired + private KnowledgeBaseService knowledgeBaseService; + + @Autowired + private PwlProjectLibraryService pwlProjectLibraryService; + + @Autowired + private AiHistoryService aiHistoryService; + + // 历史记录有效期(分钟) + private static final int HISTORY_EXPIRE_MINUTES = 10; + + /** + * 生成历史审计问题整改表数据 + */ + @Operation(summary = "生成历史审计问题整改表") + @PostMapping("/generateHistoryTable") + public ApiResult generateHistoryTable(@RequestBody AuditContentRequest request, HttpServletRequest servletRequest) { + return generateTableData(request, servletRequest.getRequestURI(), + (params) -> auditContent11HistoryService.generateHistoryTableData( + params.knowledgeBaseId, params.libraryKbIds, params.projectLibrary, + params.username, params.history, params.suggestion + )); + } + + /** + * 导出历史审计问题整改表到Excel + */ + @Operation(summary = "导出历史审计问题整改表到Excel") + @PostMapping("/exportHistoryTable") + public void exportHistoryTable(@RequestBody Map request, HttpServletResponse response) { + List> dataList = (List>) request.get("data"); + String companyName = (String) request.get("companyName"); + String auditTime = (String) request.get("auditTime"); + + List exportData = convertToHistoryTableEntityList(dataList); + + String fileName = "历史审计问题整改表_" + (companyName != null ? companyName : "未知公司"); + String sheetName = "历史审计问题整改表"; + String title = companyName != null ? + companyName + " - 历史审计问题整改表" + (auditTime != null ? "(" + auditTime + ")" : "") : + "历史审计问题整改表"; + + ExcelExportTool.exportExcel(exportData, HistoryTableExportEntity.class, fileName, sheetName, title, response); + } + + /** + * 通用的表格数据生成方法 + */ + private ApiResult generateTableData(AuditContentRequest request, String interfaceName, Function generateFunction) { + final User loginUser = getLoginUser(); + String requestHistory = request.getHistory(); + request.setHistory(""); + + // 检查历史记录 + String requestHash = generateRequestHash(request, interfaceName); + var history = aiHistoryService.getValidHistory(requestHash, interfaceName, HISTORY_EXPIRE_MINUTES); + if (history != null) { + log.info("返回历史数据,请求哈希: {}", requestHash); + return success(JSONObject.parseObject(history.getResponseData())); + } + request.setHistory(requestHistory); + + String kbIdTmp = ""; + String libraryKbIds = ""; + + try { + // 创建临时知识库(如果需要) + if (hasUploadedFiles(request)) { + kbIdTmp = createTempKnowledgeBase(request); + } + + // 查询项目库信息 + libraryKbIds = getLibraryKbIds(request.getLibraryIds()); + + // 生成数据 + String knowledgeBaseId = getKnowledgeBaseId(kbIdTmp, request.getKbIds()); + GenerateParams params = new GenerateParams(knowledgeBaseId, libraryKbIds, request.getProjectLibrary(), loginUser.getUsername(), request.getHistory(), request.getSuggestion()); + + JSONObject result = generateFunction.apply(params); + + if(result.getBoolean("success")) { + // 保存到历史记录 + saveToHistory(request, interfaceName, requestHash, result, loginUser); + } + + return success(result); + } catch (Exception e) { + log.error("生成历史审计问题整改表数据失败", e); + return fail("生成历史审计问题整改表数据失败: " + e.getMessage()); + } finally { + cleanupTempKnowledgeBase(kbIdTmp); + } + } + + /** + * 生成请求哈希 + */ + private String generateRequestHash(AuditContentRequest request, String interfaceName) { + String requestJson = JSONObject.toJSONString(request); + return DigestUtil.md5Hex(interfaceName + ":" + requestJson); + } + + /** + * 保存到历史记录 + */ + private void saveToHistory(AuditContentRequest request, String interfaceName, String requestHash, JSONObject result, User loginUser) { + try { + aiHistoryService.saveHistory(requestHash, interfaceName, JSONObject.toJSONString(request), result.toJSONString(), loginUser.getUserId(), loginUser.getUsername(), loginUser.getTenantId()); + } catch (Exception e) { + log.warn("保存历史记录失败", e); + } + } + + /** + * 检查是否有上传的文件 + */ + private boolean hasUploadedFiles(AuditContentRequest request) { + return !request.getDocList().isEmpty() || !request.getFileList().isEmpty(); + } + + /** + * 获取知识库ID + */ + private String getKnowledgeBaseId(String tempKbId, String requestKbIds) { + return StrUtil.isNotBlank(tempKbId) ? tempKbId : requestKbIds; + } + + /** + * 获取项目库KB IDs + */ + private String getLibraryKbIds(String libraryIds) { + if (StrUtil.isBlank(libraryIds)) { + return ""; + } + List idList = StrUtil.split(libraryIds, ','); + List ret = pwlProjectLibraryService.list(new LambdaQueryWrapper().in(PwlProjectLibrary::getId, idList)); + return ret.stream().map(PwlProjectLibrary::getKbId).filter(StrUtil::isNotBlank).collect(Collectors.joining(",")); + } + + /** + * 创建临时知识库并提交文档 + */ + private String createTempKnowledgeBase(AuditContentRequest request) { + String kbIdTmp = knowledgeBaseService.createKnowledgeBaseTemp(); + // 收集文档ID + Set docIds = request.getDocList().stream().flatMap(docId -> aiCloudDocService.getSelfAndChildren(docId).stream()).map(AiCloudDoc::getId).collect(Collectors.toSet()); + // 查询相关文件 + List fileList = getRelatedFiles(docIds, request.getFileList()); + // 提取文件ID并提交到知识库 + Set kbFileIds = fileList.stream().map(AiCloudFile::getFileId).collect(Collectors.toSet()); + if (!kbFileIds.isEmpty()) { + knowledgeBaseService.submitDocuments(kbIdTmp, new ArrayList<>(kbFileIds)); + } + return kbIdTmp; + } + + /** + * 获取相关文件列表 + */ + private List getRelatedFiles(Set docIds, List fileList) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() + .in(!docIds.isEmpty(), AiCloudFile::getDocId, docIds) + .or(!fileList.isEmpty()) + .in(!fileList.isEmpty(), AiCloudFile::getId, fileList); + return aiCloudFileService.list(queryWrapper); + } + + /** + * 清理临时知识库 + */ + private void cleanupTempKnowledgeBase(String kbId) { + if (StrUtil.isNotBlank(kbId)) { + try { + knowledgeBaseService.deleteIndex(kbId); + } catch (Exception e) { + log.warn("删除临时知识库失败: {}", kbId, e); + } + } + } + + // ========== 数据转换方法 ========== + + private List convertToHistoryTableEntityList(List> originalData) { + return originalData.stream() + .map(this::convertToHistoryTableEntity) + .collect(Collectors.toList()); + } + + private HistoryTableExportEntity convertToHistoryTableEntity(Map item) { + HistoryTableExportEntity entity = new HistoryTableExportEntity(); + entity.setIndex(getStringValue(item, "index")); + entity.setAuditYear(getStringValue(item, "auditYear")); + entity.setAuditType(getStringValue(item, "auditType")); + entity.setProblemFound(getStringValue(item, "problemFound")); + entity.setRectificationRequirement(getStringValue(item, "rectificationRequirement")); + entity.setRectificationMeasures(getStringValue(item, "rectificationMeasures")); + entity.setRectificationStatus(getStringValue(item, "rectificationStatus")); + entity.setCompletionDate(getStringValue(item, "completionDate")); + entity.setResponsiblePerson(getStringValue(item, "responsiblePerson")); + entity.setRemark(getStringValue(item, "remark")); + entity.setWorkPaperIndex(formatWorkPaperIndex(item.get("workPaperIndex"))); + return entity; + } + + private String getStringValue(Map map, String key) { + Object value = map.get(key); + return value != null ? value.toString() : ""; + } + + private String formatWorkPaperIndex(Object workPaperIndex) { + if (workPaperIndex == null) { + return ""; + } + + if (workPaperIndex instanceof List) { + List list = (List) workPaperIndex; + return String.join(", ", list.stream() + .map(Object::toString) + .collect(Collectors.toList())); + } + + return workPaperIndex.toString(); + } + + /** + * 参数包装类 + */ + private static class GenerateParams { + final String knowledgeBaseId; + final String libraryKbIds; + final String projectLibrary; + final String username; + final String history; + final String suggestion; + + GenerateParams(String knowledgeBaseId, String libraryKbIds, String projectLibrary, String username, String history, String suggestion) { + this.knowledgeBaseId = knowledgeBaseId; + this.libraryKbIds = libraryKbIds; + this.projectLibrary = projectLibrary; + this.username = username; + this.history = history; + this.suggestion = suggestion; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/gxwebsoft/ai/dto/export/HistoryTableExportEntity.java b/src/main/java/com/gxwebsoft/ai/dto/export/HistoryTableExportEntity.java new file mode 100644 index 0000000..7571d28 --- /dev/null +++ b/src/main/java/com/gxwebsoft/ai/dto/export/HistoryTableExportEntity.java @@ -0,0 +1,46 @@ +package com.gxwebsoft.ai.dto.export; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import cn.afterturn.easypoi.excel.annotation.ExcelTarget; +import lombok.Data; + +/** + * 历史审计问题整改表导出实体 + */ +@Data +@ExcelTarget("HistoryTableExportEntity") +public class HistoryTableExportEntity { + + @Excel(name = "序号", orderNum = "1", width = 8) + private String index; + + @Excel(name = "审计年度", orderNum = "2", width = 12) + private String auditYear; + + @Excel(name = "审计类型", orderNum = "3", width = 15) + private String auditType; + + @Excel(name = "审计发现的问题", orderNum = "4", width = 40, needMerge = true) + private String problemFound; + + @Excel(name = "整改要求", orderNum = "5", width = 30, needMerge = true) + private String rectificationRequirement; + + @Excel(name = "整改措施", orderNum = "6", width = 30, needMerge = true) + private String rectificationMeasures; + + @Excel(name = "整改完成情况", orderNum = "7", width = 15) + private String rectificationStatus; + + @Excel(name = "整改完成时间", orderNum = "8", width = 15) + private String completionDate; + + @Excel(name = "整改责任人", orderNum = "9", width = 15) + private String responsiblePerson; + + @Excel(name = "备注", orderNum = "10", width = 20, needMerge = true) + private String remark; + + @Excel(name = "工作底稿索引", orderNum = "11", width = 25, needMerge = true) + private String workPaperIndex; +} \ No newline at end of file diff --git a/src/main/java/com/gxwebsoft/ai/service/AuditContent11HistoryService.java b/src/main/java/com/gxwebsoft/ai/service/AuditContent11HistoryService.java new file mode 100644 index 0000000..3a29fbd --- /dev/null +++ b/src/main/java/com/gxwebsoft/ai/service/AuditContent11HistoryService.java @@ -0,0 +1,23 @@ +package com.gxwebsoft.ai.service; + +import com.alibaba.fastjson.JSONObject; + +/** + * 审计内容11-历史审计问题整改服务接口 + */ +public interface AuditContent11HistoryService { + + /** + * 生成历史审计问题整改表数据 + * + * @param kbIds 知识库ID + * @param libraryKbIds 项目库知识库ID + * @param projectLibrary 项目库 + * @param userName 用户名 + * @param history 历史内容 + * @param suggestion 用户建议 + * @return JSON结果 + */ + JSONObject generateHistoryTableData(String kbIds, String libraryKbIds, String projectLibrary, + String userName, String history, String suggestion); +} \ No newline at end of file diff --git a/src/main/java/com/gxwebsoft/ai/service/impl/AuditContent11HistoryServiceImpl.java b/src/main/java/com/gxwebsoft/ai/service/impl/AuditContent11HistoryServiceImpl.java new file mode 100644 index 0000000..52da3f3 --- /dev/null +++ b/src/main/java/com/gxwebsoft/ai/service/impl/AuditContent11HistoryServiceImpl.java @@ -0,0 +1,291 @@ +package com.gxwebsoft.ai.service.impl; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.gxwebsoft.ai.constants.AuditContent11HistoryConstants; +import com.gxwebsoft.ai.service.AuditContent11HistoryService; +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.stream.Collectors; + +@Slf4j +@Service +public class AuditContent11HistoryServiceImpl extends AbstractAuditContentService implements AuditContent11HistoryService { + + // 工作流配置 + private static final String DIFY_WORKFLOW_TOKEN = "Bearer app-tMty75ly5NmqQXvBGZMxOKdk"; + + @Override + public JSONObject generateHistoryTableData(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 { + // 1. 检索相关知识 + Map> knowledgeSources = retrieveHistoryAuditKnowledge( + kbIds, libraryKbIds, projectLibrary + ); + + // 2. 构建完整的知识上下文 + String knowledgeContext = buildCompleteKnowledgeContext( + knowledgeSources, history, suggestion + ); + + // 3. 调用工作流生成数据 + JSONObject requestBody = buildWorkflowRequest(knowledgeContext, userName); + JSONArray tableData = callWorkflow(DIFY_WORKFLOW_URL, DIFY_WORKFLOW_TOKEN, requestBody, "历史审计问题整改"); + + // 4. 处理返回数据,确保格式正确 + JSONArray processedData = processTableData(tableData); + + log.info("历史审计问题整改表生成成功 - 记录数: {}, 处理时间: {}ms", + processedData.size(), (System.currentTimeMillis() - startTime)); + + return buildSuccessResponse(processedData, startTime, "history_audit_rectification"); + + } catch (Exception e) { + log.error("生成历史审计问题整改表失败", e); + return buildErrorResponse("生成历史审计问题整改表失败: " + e.getMessage()); + } + } + + /** + * 检索历史审计问题相关知识 + */ + private Map> retrieveHistoryAuditKnowledge(String kbIds, String libraryKbIds, String projectLibrary) { + Map> knowledgeSources = new HashMap<>(); + knowledgeSources.put("enterprise", new ArrayList<>()); + knowledgeSources.put("auditReports", new ArrayList<>()); + knowledgeSources.put("rectificationReports", new ArrayList<>()); + knowledgeSources.put("regulations", new ArrayList<>()); + + // 构建查询关键词 + List queries = buildHistoryAuditQueries(); + + // 企业单位库检索(历史审计问题) + if (StrUtil.isNotBlank(kbIds)) { + Arrays.stream(kbIds.split(",")) + .map(String::trim) + .filter(StrUtil::isNotBlank) + .forEach(kbId -> knowledgeSources.get("enterprise") + .addAll(queryKnowledgeBase(kbId, queries, 150))); + } + + // 审计报告库检索 + if (StrUtil.isNotBlank(libraryKbIds)) { + Arrays.stream(libraryKbIds.split(",")) + .map(String::trim) + .filter(StrUtil::isNotBlank) + .forEach(libId -> { + knowledgeSources.get("auditReports") + .addAll(queryKnowledgeBase(libId, Arrays.asList("审计报告", "审计发现问题"), 100)); + knowledgeSources.get("rectificationReports") + .addAll(queryKnowledgeBase(libId, Arrays.asList("整改报告", "整改情况", "整改措施"), 80)); + }); + } + + // 法律法规库检索(从项目库) + if (StrUtil.isNotBlank(projectLibrary)) { + knowledgeSources.get("regulations").addAll( + queryKnowledgeBase(projectLibrary, + Arrays.asList("审计制度", "整改机制", "责任追究"), 60)); + } + + // 智能去重和排序 + knowledgeSources.forEach((key, list) -> { + List processed = list.stream() + .distinct() + .sorted(this::historyAuditComparator) + .limit(getLimitBySourceType(key)) + .collect(Collectors.toList()); + knowledgeSources.put(key, processed); + }); + + log.debug("历史审计问题知识检索完成 - 企业: {}条, 审计报告: {}条, 整改报告: {}条, 法规: {}条", + knowledgeSources.get("enterprise").size(), + knowledgeSources.get("auditReports").size(), + knowledgeSources.get("rectificationReports").size(), + knowledgeSources.get("regulations").size()); + + return knowledgeSources; + } + + /** + * 构建历史审计问题查询关键词 + */ + private List buildHistoryAuditQueries() { + return Arrays.asList( + "审计发现问题 整改情况", + "历史审计 遗留问题", + "审计报告 整改报告", + "问题整改 措施 效果", + "审计年度 审计类型" + ); + } + + /** + * 构建完整的知识上下文 + */ + private String buildCompleteKnowledgeContext(Map> knowledgeSources, + String history, String suggestion) { + StringBuilder context = new StringBuilder(); + + // 1. 审计内容11的要求 + context.append("## 审计内容11:历史审计问题整改\n"); + context.append("**审计重点:**\n"); + context.append("1. ").append(AuditContent11HistoryConstants.FOCUS_DESCRIPTIONS.get(AuditContent11HistoryConstants.FOCUS_SYSTEM_MECHANISM)).append("\n"); + context.append("2. ").append(AuditContent11HistoryConstants.FOCUS_DESCRIPTIONS.get(AuditContent11HistoryConstants.FOCUS_HISTORICAL_ISSUES)).append("\n"); + context.append("3. ").append(AuditContent11HistoryConstants.FOCUS_DESCRIPTIONS.get(AuditContent11HistoryConstants.FOCUS_RECTIFICATION_EFFECT)).append("\n"); + context.append("4. ").append(AuditContent11HistoryConstants.FOCUS_DESCRIPTIONS.get(AuditContent11HistoryConstants.FOCUS_SYSTEM_IMPROVEMENT)).append("\n"); + context.append("5. ").append(AuditContent11HistoryConstants.FOCUS_DESCRIPTIONS.get(AuditContent11HistoryConstants.FOCUS_SELF_RECTIFICATION)).append("\n\n"); + + context.append("**审计方法及步骤:**\n"); + context.append("1. ").append(AuditContent11HistoryConstants.METHOD_DESCRIPTIONS.get(AuditContent11HistoryConstants.METHOD_REVIEW_REPORT)).append("\n"); + context.append("2. ").append(AuditContent11HistoryConstants.METHOD_DESCRIPTIONS.get(AuditContent11HistoryConstants.METHOD_REVIEW_RECTIFICATION)).append("\n"); + context.append("3. ").append(AuditContent11HistoryConstants.METHOD_DESCRIPTIONS.get(AuditContent11HistoryConstants.METHOD_VERIFY_RECTIFICATION)).append("\n"); + context.append("4. ").append(AuditContent11HistoryConstants.METHOD_DESCRIPTIONS.get(AuditContent11HistoryConstants.METHOD_INTERVIEW)).append("\n"); + context.append("5. ").append(AuditContent11HistoryConstants.METHOD_DESCRIPTIONS.get(AuditContent11HistoryConstants.METHOD_REVIEW_DOCS)).append("\n\n"); + + // 2. 数据格式要求 + context.append("## 数据格式要求\n"); + context.append("需要生成历史审计问题整改表数据,尽可能生成多个年度、多种类型的审计问题,数量不限:\n\n"); + + context.append("**表格字段说明:**\n"); + context.append("1. **审计年度**:审计报告所属年份,如:2023年\n"); + context.append("2. **审计类型**:内部审计、外部审计、专项审计、经济责任审计等\n"); + context.append("3. **审计发现的问题**:具体审计发现的问题描述,需详细说明\n"); + context.append("4. **整改要求**:对问题的整改要求,包括时间、内容等\n"); + context.append("5. **整改措施**:具体的整改措施和实施情况\n"); + context.append("6. **整改完成情况**:已完成、整改中、未整改、部分整改\n"); + context.append("7. **整改完成时间**:具体完成时间或计划完成时间\n"); + context.append("8. **整改责任人**:负责整改的责任人姓名和职务\n"); + context.append("9. **备注**:其他需要说明的情况\n"); + context.append("10. **工作底稿索引**:相关审计报告、整改报告等文件名称,必须是实际存在的完整文件名\n\n"); + + context.append("**生成要求:**\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"); + context.append("7. 对于制度完善情况,需说明审计后是否建立了相关制度机制\n\n"); + + // 3. 历史内容 + if (StrUtil.isNotBlank(history)) { + context.append("## 历史生成内容\n"); + context.append("以下是之前生成的内容,请基于此进行优化:\n"); + context.append(history).append("\n\n"); + } + + // 4. 用户建议 + if (StrUtil.isNotBlank(suggestion)) { + context.append("## 用户优化建议\n"); + context.append("请根据以下建议对生成内容进行调整:\n"); + context.append(suggestion).append("\n\n"); + } + + // 5. 企业单位知识(审计问题) + if (!knowledgeSources.get("enterprise").isEmpty()) { + context.append("## 企业单位审计问题知识\n"); + knowledgeSources.get("enterprise").forEach(knowledge -> + context.append(knowledge).append("\n")); + context.append("\n"); + } + + // 6. 审计报告知识 + if (!knowledgeSources.get("auditReports").isEmpty()) { + context.append("## 审计报告知识\n"); + knowledgeSources.get("auditReports").forEach(knowledge -> + context.append(knowledge).append("\n")); + context.append("\n"); + } + + // 7. 整改报告知识 + if (!knowledgeSources.get("rectificationReports").isEmpty()) { + context.append("## 整改报告知识\n"); + knowledgeSources.get("rectificationReports").forEach(knowledge -> + context.append(knowledge).append("\n")); + context.append("\n"); + } + + // 8. 法规制度知识 + if (!knowledgeSources.get("regulations").isEmpty()) { + context.append("## 审计整改相关法规制度\n"); + knowledgeSources.get("regulations").forEach(knowledge -> + context.append(knowledge).append("\n")); + } + + return context.toString(); + } + + /** + * 处理表格数据,确保格式正确 + */ + private JSONArray processTableData(JSONArray rawData) { + JSONArray processedData = new JSONArray(); + + for (int i = 0; i < rawData.size(); i++) { + JSONObject item = rawData.getJSONObject(i); + JSONObject processedItem = new JSONObject(); + + // 设置序号 + processedItem.put("index", i + 1); + + // 复制所有字段 + processedItem.putAll(item); + + // 确保必填字段存在 + if (!processedItem.containsKey("auditYear")) { + processedItem.put("auditYear", "2023年"); + } + if (!processedItem.containsKey("auditType")) { + processedItem.put("auditType", AuditContent11HistoryConstants.AUDIT_TYPE_INTERNAL); + } + if (!processedItem.containsKey("rectificationStatus")) { + processedItem.put("rectificationStatus", AuditContent11HistoryConstants.STATUS_IN_PROGRESS); + } + + processedData.add(processedItem); + } + + return processedData; + } + + /** + * 历史审计问题相关性比较器 + */ + private int historyAuditComparator(String reg1, String reg2) { + int score1 = calculateHistoryAuditRelevanceScore(reg1); + int score2 = calculateHistoryAuditRelevanceScore(reg2); + return Integer.compare(score2, score1); + } + + /** + * 计算历史审计问题相关性分数 + */ + private int calculateHistoryAuditRelevanceScore(String content) { + return AuditContent11HistoryConstants.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 150; + case "auditReports": return 100; + case "rectificationReports": return 80; + case "regulations": return 60; + default: return 50; + } + } +} \ No newline at end of file