diff --git a/src/main/java/com/gxwebsoft/ai/controller/AuditEvidenceController.java b/src/main/java/com/gxwebsoft/ai/controller/AuditEvidenceController.java index 59dafc6..8ac50f9 100644 --- a/src/main/java/com/gxwebsoft/ai/controller/AuditEvidenceController.java +++ b/src/main/java/com/gxwebsoft/ai/controller/AuditEvidenceController.java @@ -1,6 +1,7 @@ package com.gxwebsoft.ai.controller; import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.gxwebsoft.ai.dto.AuditEvidenceRequest; import com.gxwebsoft.ai.entity.AuditEvidence; import com.gxwebsoft.ai.param.AuditEvidenceParam; @@ -126,6 +127,26 @@ public class AuditEvidenceController extends BaseController { return fail("保存审计取证单异常:" + e.getMessage(), null); } } + + /** + * 保存审计取证单到数据库 + */ + @Operation(summary = "批量查询取证单接口") + @PostMapping("/batchQuery") + public ApiResult> batchQueryEvidence(@RequestBody Map> request) { + List evidenceIds = request.get("evidenceIds"); + + if (evidenceIds == null || evidenceIds.isEmpty()) { + return success(new ArrayList<>()); + } + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.in(AuditEvidence::getId, evidenceIds) + .eq(AuditEvidence::getDeleted, 0); + + List evidences = auditEvidenceService.list(wrapper); + return success(evidences); + } /** * 下载审计取证单Word文档 diff --git a/src/main/java/com/gxwebsoft/ai/controller/AuditReportController.java b/src/main/java/com/gxwebsoft/ai/controller/AuditReportController.java index e6dba4b..681c3ee 100644 --- a/src/main/java/com/gxwebsoft/ai/controller/AuditReportController.java +++ b/src/main/java/com/gxwebsoft/ai/controller/AuditReportController.java @@ -1,7 +1,6 @@ package com.gxwebsoft.ai.controller; import java.io.IOException; -import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import java.util.ArrayList; @@ -17,16 +16,20 @@ import javax.servlet.http.HttpServletResponse; import cn.hutool.crypto.digest.DigestUtil; import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.gxwebsoft.ai.entity.AuditEvidence; import com.gxwebsoft.ai.mapper.AuditEvidenceMapper; +import com.gxwebsoft.ai.service.AiCloudDocService; +import com.gxwebsoft.ai.service.AiCloudFileService; +import com.gxwebsoft.ai.service.AuditEvidenceService; import com.gxwebsoft.pwl.entity.PwlProject; import com.gxwebsoft.pwl.service.PwlProjectService; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.poi.openxml4j.util.ZipSecureFile; import org.apache.poi.xwpf.usermodel.BreakType; import org.apache.poi.xwpf.usermodel.ParagraphAlignment; -import org.apache.poi.xwpf.usermodel.UnderlinePatterns; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.xwpf.usermodel.XWPFRun; @@ -37,7 +40,6 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSpacing; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -74,30 +76,28 @@ import io.swagger.v3.oas.annotations.tags.Tag; @Tag(name = "审计报告") @RestController @RequestMapping("/api/ai/auditReport") +@RequiredArgsConstructor @Slf4j public class AuditReportController extends BaseController { - @Autowired - private TemplateConfig templateConfig; - - @Autowired - private KnowledgeBaseService knowledgeBaseService; - - @Autowired - private AuditReportService auditReportService; + private final TemplateConfig templateConfig; + + private final KnowledgeBaseService knowledgeBaseService; + + private final AuditReportService auditReportService; + + private final PwlProjectService pwlProjectService; + + private final AuditEvidenceMapper auditEvidenceMapper; + + private final AuditEvidenceService auditEvidenceService; + + private final AiHistoryService aiHistoryService; + + private final AiCloudFileService aiCloudFileService; + + private final AiCloudDocService aiCloudDocService; - @Autowired - private PwlProjectService pwlProjectService; - - @Autowired - private AuditEvidenceMapper auditEvidenceMapper; - -// @Autowired -// private AuditEvidenceService auditEvidenceService; - - @Autowired - private AiHistoryService aiHistoryService; - private String invok(String query, String knowledge, String history, String suggestion, String title, String userName) { // 构建请求体 JSONObject requestBody = new JSONObject(); @@ -1286,24 +1286,7 @@ public class AuditReportController extends BaseController { document.createParagraph(); document.createParagraph(); } - - /** - * 添加主标题 - */ - private void addMainTitle(XWPFDocument document, String title) throws IOException { - XWPFParagraph titlePara = document.createParagraph(); - titlePara.setAlignment(ParagraphAlignment.CENTER); - XWPFRun titleRun = titlePara.createRun(); - titleRun.setText(title); - titleRun.setBold(true); - titleRun.setFontSize(16); // 三号 - titleRun.setFontFamily("仿宋_GB2312"); - - // 添加 2 个空行 - document.createParagraph(); - document.createParagraph(); - } - + /** * 添加文号(右对齐,蓝色) */ @@ -1384,91 +1367,6 @@ public class AuditReportController extends BaseController { document.createParagraph(); document.createParagraph(); } - - /** - * 添加标题 - */ - private void addTitle(XWPFDocument document, String title) throws IOException { - XWPFParagraph titlePara = document.createParagraph(); - titlePara.setAlignment(ParagraphAlignment.CENTER); - XWPFRun titleRun = titlePara.createRun(); - titleRun.setText(title); - titleRun.setBold(true); - titleRun.setFontSize(16); // 三号 - titleRun.setFontFamily("仿宋_GB2312"); - - // 添加空行 - document.createParagraph(); - } - - /** - * 添加章节 - */ - private void addSection(XWPFDocument document, String sectionTitle, List subSections) throws IOException { - // 一级标题(仿宋_GB2312,三号,加粗) - XWPFParagraph sectionPara = document.createParagraph(); - sectionPara.setAlignment(ParagraphAlignment.LEFT); - XWPFRun sectionRun = sectionPara.createRun(); - sectionRun.setText(sectionTitle); - sectionRun.setBold(true); - sectionRun.setFontSize(16); // 三号 - sectionRun.setFontFamily("仿宋_GB2312"); - - // 添加子章节 - if (subSections != null && !subSections.isEmpty()) { - for (String subSection : subSections) { - if (subSection != null && !subSection.trim().isEmpty()) { - // 按换行符分割内容 - String[] lines = subSection.split("\\n"); - for (String line : lines) { - if (!line.trim().isEmpty()) { - XWPFParagraph contentPara = document.createParagraph(); - contentPara.setAlignment(ParagraphAlignment.LEFT); - XWPFRun contentRun = contentPara.createRun(); - contentRun.setText(line.trim()); - contentRun.setFontSize(12); // 小四 - contentRun.setFontFamily("仿宋_GB2312"); - - // 设置首行缩进 1 个中文字符 - contentPara.setIndentationFirstLine(480); - } - } - } - } - } - - // 添加空行 - document.createParagraph(); - } - - /** - * 添加章节内容(只显示内容,不显示标题) - */ - private void addSectionContent(XWPFDocument document, String content) throws IOException { - if (content == null || content.trim().isEmpty()) { - return; - } - - // 按换行符分割内容 - String[] lines = content.split("\\n"); - for (String line : lines) { - if (!line.trim().isEmpty()) { - XWPFParagraph contentPara = document.createParagraph(); - contentPara.setAlignment(ParagraphAlignment.LEFT); - XWPFRun contentRun = contentPara.createRun(); - contentRun.setText(line.trim()); - contentRun.setFontSize(12); // 小四 - contentRun.setFontFamily("仿宋_GB2312"); - - // 设置首行缩进 2 个中文字符 - contentPara.setIndentationFirstLine(480); - } - } - - // 添加空行 - document.createParagraph(); - } - /** * 添加章节(带标题和前缀,支持子章节) */ @@ -1533,20 +1431,20 @@ public class AuditReportController extends BaseController { * 根据 formCommit 获取子章节标题 */ private String getSubsectionTitle(Integer formCommit, PwlProject project) { - switch (formCommit) { - case 10: return "(一)审计依据"; - case 41: return String.format("(二)%s概况", project.getName()); - case 42: return String.format("(三)%s任职及分工情况", project.getPersonName()); - case 43: return "(四)实施审计的基本情况"; - case 51: return "(一)贯彻执行党和国家经济方针政策、决策部署情况"; - case 52: return "(二)企业发展战略规划的制定、执行和效果情况"; - case 53: return "(三)重大经济事项的决策、执行和效果情况"; - case 54: return "(四)企业法人治理结构的建立、健全和运行情况,内部控制制度的制定和执行情况"; - case 55: return "(五)企业财务的真实合法效益情况,风险管控情况,境外资产管理情况,生态环境保护情况"; - case 56: return "(六)在经济活动中落实有关党风廉政建设责任和遵守廉洁从业规定情况"; - case 57: return "(七)以往审计发现问题的整改情况"; - default: return ""; - } + return switch (formCommit) { + case 10 -> "(一)审计依据"; + case 41 -> String.format("(二)%s概况", project.getName()); + case 42 -> String.format("(三)%s任职及分工情况", project.getPersonName()); + case 43 -> "(四)实施审计的基本情况"; + case 51 -> "(一)贯彻执行党和国家经济方针政策、决策部署情况"; + case 52 -> "(二)企业发展战略规划的制定、执行和效果情况"; + case 53 -> "(三)重大经济事项的决策、执行和效果情况"; + case 54 -> "(四)企业法人治理结构的建立、健全和运行情况,内部控制制度的制定和执行情况"; + case 55 -> "(五)企业财务的真实合法效益情况,风险管控情况,境外资产管理情况,生态环境保护情况"; + case 56 -> "(六)在经济活动中落实有关党风廉政建设责任和遵守廉洁从业规定情况"; + case 57 -> "(七)以往审计发现问题的整改情况"; + default -> ""; + }; } /** @@ -1715,7 +1613,7 @@ public class AuditReportController extends BaseController { } String companyName = project.getName(); String personName = project.getPersonName(); - String prompt; + String prompt = ""; if (request.getFormCommit() == 20) { // 二、总体评价的特殊提示词模板 // 查询该项目的所有取证单,判断是否有发现问题 @@ -1762,7 +1660,7 @@ public class AuditReportController extends BaseController { StringBuilder promptBuilder = new StringBuilder(); // 只传递取证单 ID 列表,让 AI 自行从数据库读取 - if (evidenceIds != null && !evidenceIds.isEmpty()) { + if (!evidenceIds.isEmpty()) { // 将 ID 列表转换为逗号分隔的字符串 String evidenceIdsStr = evidenceIds.stream() .map(String::valueOf) @@ -1778,15 +1676,22 @@ public class AuditReportController extends BaseController { promptBuilder.append("2. 原因分析\n"); promptBuilder.append("3. 责任界定\n"); promptBuilder.append("\n注意:输出内容中不要显示取证单编号,直接生成正式的审计报告内容。\n"); - + prompt = promptBuilder.toString(); } - else { - // 其他章节使用通用 prompt - 查询审计相关法规 - prompt = String.format("请查询与'%s'相关的所有审计法规、制度和政策文件。要求:1.列出完整的法规名称;2.注明颁布单位;3.注明发文字号(如有);4.列出相关条款;5.按重要性排序;6.使用规范的格式。", title); - } + + // 其他章节使用通用 prompt - 查询审计相关法规 + // 注意:AI工作流限制query不能超过512字符,因此提示词必须精简 + // 详细信息通过evidenceIds参数和知识库检索获取 + + StringBuilder promptBuilder = new StringBuilder(); + promptBuilder.append(String.format("请为审计报告章节'%s'生成内容。\n", title)); + promptBuilder.append("数据源:1)取证单(已通过evidenceIds传入) 2)阿里云资料库(自动检索)\n"); + promptBuilder.append("要求:优先用取证单事实,结合资料库制度,不足时生成框架内容,勿编造数据。\n"); + + prompt = promptBuilder.toString(); - prompt += "\n(重要提示:数据源必须严格来自页面上选择的取证单数据,不能从其他地方获取数据。)"; +// prompt += "\n(重要提示:数据源必须严格来自传入接口的取证单数据,或者在本项目配置的阿里云资料库中的文件,必须保存在ai_cloud_doc和ai_cloud_file表中(根据pwl_project.company_id),不能凭空捏造或者从互联网上获取数据。)"; log.info("生成审计报告标题:{},AI 提示词:{}", request.getChapterTitle(), prompt); // 调用 AI 接口,同时传递取证单 ID 列表 @@ -1882,11 +1787,15 @@ public class AuditReportController extends BaseController { // 如果有取证单 ID,加入到请求中 if (evidenceIds != null && !evidenceIds.isEmpty()) { inputs.put("evidenceIds", evidenceIds); + List evidences = auditEvidenceService.listByIds(evidenceIds); + inputs.put("evidences", evidences); } requestBody.put("inputs", inputs); requestBody.put("response_mode", "blocking"); requestBody.put("user", userName); + + log.info("生成审计报告AI请求参数:{}", JSON.toJSONString(requestBody)); try { // 发送 POST 请求 diff --git a/src/main/java/com/gxwebsoft/ai/service/AuditEvidenceService.java b/src/main/java/com/gxwebsoft/ai/service/AuditEvidenceService.java index 5fe2c5a..900b8a2 100644 --- a/src/main/java/com/gxwebsoft/ai/service/AuditEvidenceService.java +++ b/src/main/java/com/gxwebsoft/ai/service/AuditEvidenceService.java @@ -1,6 +1,6 @@ package com.gxwebsoft.ai.service; -import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.extension.service.IService; import com.gxwebsoft.ai.dto.AuditEvidenceRequest; import com.gxwebsoft.ai.entity.AuditEvidence; import com.gxwebsoft.ai.param.AuditEvidenceParam; @@ -8,7 +8,7 @@ import com.gxwebsoft.common.core.web.ApiResult; import com.gxwebsoft.common.core.web.PageParam; import com.gxwebsoft.common.core.web.PageResult; -public interface AuditEvidenceService { +public interface AuditEvidenceService extends IService { /** * 生成审计取证单 */