From 1fcaf3f68a0632d6f33853b9b869e93da83f2b79 Mon Sep 17 00:00:00 2001 From: yuance <182865460@qq.com> Date: Wed, 22 Oct 2025 15:24:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=A1=E8=AE=A1=E5=86=85=E5=AE=B93-=E9=87=8D?= =?UTF-8?q?=E5=A4=A7=E7=BB=8F=E6=B5=8E=E5=86=B3=E7=AD=96=E5=88=9D=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AuditContentController3.java | 46 +++ .../ai/service/AuditContentService3.java | 11 + .../impl/AuditContentServiceImpl3.java | 277 ++++++++++++++++++ 3 files changed, 334 insertions(+) create mode 100644 src/main/java/com/gxwebsoft/ai/controller/AuditContentController3.java create mode 100644 src/main/java/com/gxwebsoft/ai/service/AuditContentService3.java create mode 100644 src/main/java/com/gxwebsoft/ai/service/impl/AuditContentServiceImpl3.java diff --git a/src/main/java/com/gxwebsoft/ai/controller/AuditContentController3.java b/src/main/java/com/gxwebsoft/ai/controller/AuditContentController3.java new file mode 100644 index 0000000..72f841e --- /dev/null +++ b/src/main/java/com/gxwebsoft/ai/controller/AuditContentController3.java @@ -0,0 +1,46 @@ +package com.gxwebsoft.ai.controller; + +import com.alibaba.fastjson.JSONObject; +import com.gxwebsoft.common.core.web.ApiResult; +import com.gxwebsoft.common.core.web.BaseController; +import com.gxwebsoft.common.system.entity.User; +import com.gxwebsoft.ai.service.AuditContentService3; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +/** + * 审计内容3控制器 - 重大经济决策调查表 + */ +@Tag(name = "审计内容3-重大经济决策") +@RestController +@RequestMapping("/api/ai/auditContent3") +public class AuditContentController3 extends BaseController { + + @Autowired + private AuditContentService3 auditContentService3; + + /** + * 生成重大经济决策调查表数据 + */ + @Operation(summary = "生成重大经济决策调查表") + @PostMapping("/generateDecisionTable") + public ApiResult generateDecisionTable( + @RequestParam(value = "kbIds", required = false) String kbIds, + @RequestParam(value = "libraryIds", required = false) String libraryIds, + @RequestParam(value = "projectLibrary", required = false) String projectLibrary) { + + final User loginUser = getLoginUser(); + try { + // 生成重大经济决策调查表数据 + JSONObject result = auditContentService3.generateDecisionTableData(kbIds, libraryIds, projectLibrary, loginUser.getUsername()); + + return success(result); + } catch (Exception e) { + return fail("生成重大经济决策调查表失败: " + e.getMessage()); + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/gxwebsoft/ai/service/AuditContentService3.java b/src/main/java/com/gxwebsoft/ai/service/AuditContentService3.java new file mode 100644 index 0000000..89739d4 --- /dev/null +++ b/src/main/java/com/gxwebsoft/ai/service/AuditContentService3.java @@ -0,0 +1,11 @@ +package com.gxwebsoft.ai.service; + +import com.alibaba.fastjson.JSONObject; + +public interface AuditContentService3 { + + /** + * 生成重大经济决策调查表数据 + */ + JSONObject generateDecisionTableData(String kbIds, String libraryIds, String projectLibrary, String userName); +} \ No newline at end of file diff --git a/src/main/java/com/gxwebsoft/ai/service/impl/AuditContentServiceImpl3.java b/src/main/java/com/gxwebsoft/ai/service/impl/AuditContentServiceImpl3.java new file mode 100644 index 0000000..3b30a1e --- /dev/null +++ b/src/main/java/com/gxwebsoft/ai/service/impl/AuditContentServiceImpl3.java @@ -0,0 +1,277 @@ +package com.gxwebsoft.ai.service.impl; + +import com.aliyun.bailian20231229.Client; +import com.aliyun.bailian20231229.models.RetrieveResponse; +import com.aliyun.bailian20231229.models.RetrieveResponseBody; +import com.aliyun.bailian20231229.models.RetrieveResponseBody.RetrieveResponseBodyData; +import com.aliyun.bailian20231229.models.RetrieveResponseBody.RetrieveResponseBodyDataNodes; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.gxwebsoft.ai.config.KnowledgeBaseConfig; +import com.gxwebsoft.ai.factory.KnowledgeBaseClientFactory; +import com.gxwebsoft.ai.service.AuditContentService3; +import com.gxwebsoft.ai.util.KnowledgeBaseUtil; +import com.gxwebsoft.pwl.entity.PwlProjectLibrary; +import com.gxwebsoft.pwl.service.PwlProjectLibraryService; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpUtil; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +@Service +public class AuditContentServiceImpl3 implements AuditContentService3 { + + @Autowired + private KnowledgeBaseClientFactory clientFactory; + + @Autowired + private KnowledgeBaseConfig config; + + @Autowired + private PwlProjectLibraryService pwlProjectLibraryService; + + // 工作流配置 - 重大经济决策调查表生成 + private static final String DECISION_TABLE_WORKFLOW_URL = "http://1.14.159.185:8180/v1/workflows/run"; + private static final String DECISION_TABLE_TOKEN = "Bearer app-yN7Q8GEN9E7SCMkhI6HaAagW"; + + @Override + public JSONObject generateDecisionTableData(String kbIds, String libraryIds, String projectLibrary, String userName) { + JSONObject result = new JSONObject(); + + try { + // 1. 从知识库召回相关规定和案例 + List regulations = retrieveDecisionRegulations(kbIds, libraryIds, projectLibrary); + + // 2. 生成重大经济决策调查表数据 + JSONArray decisionTableData = generateDecisionTable(regulations, userName); + + // 3. 构建返回结果 + result.put("success", true); + result.put("data", decisionTableData); + result.put("total_records", decisionTableData.size()); + result.put("generated_time", new Date().toString()); + result.put("regulations_count", regulations.size()); + + } catch (Exception e) { + result.put("success", false); + result.put("error", e.getMessage()); + // 返回默认数据避免前端报错 + result.put("data", createDefaultDecisionData()); + } + + return result; + } + + /** + * 从知识库召回重大经济决策相关规定 + */ + private List retrieveDecisionRegulations(String kbIds, String libraryIds, String projectLibrary) { + List regulations = new ArrayList<>(); + String query = buildDecisionQuery(); + + // 主知识库列表 + if (StrUtil.isNotBlank(kbIds)) { + for (String kbId : kbIds.split(",")) { + if (StrUtil.isNotBlank(kbId.trim())) { + regulations.addAll(queryKnowledgeBase(kbId.trim(), query, 100)); + } + } + } + + // 公共库 + if (StrUtil.isNotBlank(libraryIds)) { + List idList = StrUtil.split(libraryIds, ','); + List ret = pwlProjectLibraryService.list(new LambdaQueryWrapper().in(PwlProjectLibrary::getId, idList)); + String libraryKbIds = ret.stream().map(PwlProjectLibrary::getKbId).collect(Collectors.joining(",")); + + for (String libId : libraryKbIds.split(",")) { + if (StrUtil.isNotBlank(libId.trim())) { + regulations.addAll(queryKnowledgeBase(libId.trim(), query, 100)); + } + } + } + + // 案例库 + if (StrUtil.isNotBlank(projectLibrary)) { + regulations.addAll(queryKnowledgeBase(projectLibrary, query, 100)); + } + + return regulations.stream().distinct().collect(Collectors.toList()); + } + + /** + * 生成重大经济决策调查表 + */ + private JSONArray generateDecisionTable(List regulations, String userName) { + // 构建知识上下文 + String knowledgeContext = buildDecisionContext(regulations); + + JSONObject requestBody = buildDecisionTableRequest(knowledgeContext, userName); + + return callDecisionTableWorkflow(requestBody); + } + + /** + * 构建决策查询 + */ + private String buildDecisionQuery() { + String[] keywords = { + "重大经济决策", "三重一大", "集体决策", "重大预算", "重大项目", + "重大采购", "重大投资", "大额资金", "资产处置", "外包业务", + "决策程序", "会议纪要", "决策标准", "审计方法", "时间", "日期" + }; + return String.join(" ", keywords); + } + + /** + * 构建决策上下文 + */ + private String buildDecisionContext(List regulations) { + StringBuilder context = new StringBuilder(); + context.append("重大经济决策审计要求:\n"); + context.append("重点关注\"三重一大\"集体决策制度是否建立健全。重大经济、经营活动必须进行集体决策的标准和必须参加决策的人员是否制定有规定,规定的集体决策的程序(签到表、决策纪要、最终形成的决策、决策人员的签字确认意见等)是否完整,是否有应集体决策而未集体决策的问题,是否有应参加集体决策的人因不合理理由不得参加集体决策的问题,形成的集体决策意见是否符合国家、自治区规定。\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\n"); + + if (!regulations.isEmpty()) { + context.append("相关法规和案例:\n"); + regulations.forEach(reg -> context.append("- ").append(reg).append("\n")); + } + + return context.toString(); + } + + /** + * 调用决策表生成工作流 + */ + private JSONArray callDecisionTableWorkflow(JSONObject requestBody) { + try { + String result = HttpUtil.createPost(DECISION_TABLE_WORKFLOW_URL) + .header("Authorization", DECISION_TABLE_TOKEN) + .header("Content-Type", "application/json") + .body(requestBody.toString()) + .timeout(600000) + .execute() + .body(); + + JSONObject jsonResponse = JSONObject.parseObject(result); + String outputText = jsonResponse.getJSONObject("data") + .getJSONObject("outputs") + .getString("result"); + + // 解析JSON数组 + return JSONArray.parseArray(outputText); + + } catch (Exception e) { + throw new RuntimeException("调用决策表生成工作流失败: " + e.getMessage(), e); + } + } + + /** + * 构建决策表生成请求 + */ + private JSONObject buildDecisionTableRequest(String knowledge, String userName) { + JSONObject requestBody = new JSONObject(); + JSONObject inputs = new JSONObject(); + + inputs.put("knowledge", knowledge); + + requestBody.put("inputs", inputs); + requestBody.put("response_mode", "blocking"); + requestBody.put("user", userName); + + return requestBody; + } + + /** + * 创建默认的决策数据 + */ + private JSONArray createDefaultDecisionData() { + JSONArray defaultData = new JSONArray(); + + // 添加3条默认数据 + for (int i = 1; i <= 3; i++) { + JSONObject item = new JSONObject(); + item.put("index", String.valueOf(i)); + item.put("name", "重大经济决策事项示例 " + i); + item.put("meetingTime", "2024-01-0" + i); + item.put("decisionAmount", (i * 100) + "万元"); + item.put("procedure", "集体决策程序完整"); + item.put("executionStatus", "是"); + + JSONObject effect = new JSONObject(); + effect.put("good", i == 1 ? "是" : "否"); + effect.put("normal", i == 2 ? "是" : "否"); + effect.put("bad", i == 3 ? "是" : "否"); + item.put("executionEffect", effect); + + defaultData.add(item); + } + + return defaultData; + } + + /** + * 查询知识库 + */ + private Set queryKnowledgeBase(String kbId, String query, int topK) { + Set results = new LinkedHashSet<>(); + String workspaceId = config.getWorkspaceId(); + + try { + Client client = clientFactory.createClient(); + RetrieveResponse resp = KnowledgeBaseUtil.retrieveIndex(client, workspaceId, kbId, query); + + // 使用Optional和Stream API简化空值检查和循环 + Optional.ofNullable(resp) + .map(RetrieveResponse::getBody) + .map(RetrieveResponseBody::getData) + .map(RetrieveResponseBodyData::getNodes) + .orElse(Collections.emptyList()) + .stream() + .limit(topK) // 使用limit替代手动break + .forEach(node -> processNode(node, results)); + + } catch (Exception e) { + // 使用printStackTrace打印异常堆栈 + e.printStackTrace(); + throw new RuntimeException("查询知识库失败, kbId: " + kbId + ", query: " + query); + } + + return results; + } + + /** + * 处理单个节点,提取文本信息 + */ + private void processNode(RetrieveResponseBodyDataNodes node, Set results) { + try { + // 安全地将Object类型的metadata转换为Map + Object metadataObj = node.getMetadata(); + if (!(metadataObj instanceof Map)) { +// System.err.println("节点metadata不是Map类型,跳过处理"); + return; + } + + Map metadata = (Map) metadataObj; + Object docNameObj = metadata.get("doc_name"); + String docName = docNameObj != null ? docNameObj.toString() : "未知文档"; + String formattedText = String.format("《%s》%s", docName, node.getText()); + results.add(formattedText); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("处理知识库节点失败: " + e.getMessage()); + } + } +} \ No newline at end of file