优化重大经济决策调查表生成逻辑
This commit is contained in:
@@ -44,6 +44,16 @@ public class AuditContent3DecisionServiceImpl implements AuditContent3DecisionSe
|
||||
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";
|
||||
|
||||
// Excel Sheet1 中的条件信息
|
||||
private static final String EXCEL_SHEET1_CONDITIONS =
|
||||
"## 重大经济决策调查表审计重点\n" +
|
||||
"重大经济事项的决策、执行和效果情况,具体包括重大预算管理、重大项目实施、重大采购项目、重大投资项目、重大外包业务、重大资产处置、大额资金使用的决策和执行情况等。\n\n" +
|
||||
"## 重点关注\n" +
|
||||
"\"三重一大\"集体决策制度是否建立健全。重大经济、经营活动必须进行集体决策的标准和必须参加决策的人员是否制定有规定,规定的集体决策的程序(签到表、决策纪要、最终形成的决策、决策人员的签字确认意见等)是否完整,是否有应集体决策而未集体决策的问题,是否有应参加集体决策的人因不合理理由不得参加集体决策的问题,形成的集体决策意见是否符合国家、自治区规定。\n\n" +
|
||||
"## 审计方法及步骤\n" +
|
||||
"1. 查阅单位制度,检查议事制度是否建立,查看重大事项进行集体决策的规定,查阅相关会议记录资料,检查会议签到表、会议纪要、会议决定内容及决策参与人员签字确认意见,以确认会议集体决策程序的完整性;对照重大决策内容,检查相关对应资料,确认集体决策内容是否符合国家、自治区规定。\n" +
|
||||
"2. 抽查一些重大经济决策事项,比如重大建设项目、维修、大宗物资采购、企业投资运营等,审查其决策的背景、决策的过程、决策的执行和落实情况,决策的效果情况,以此来确定是否符合国家、自治区相关规定,执行是否有效。";
|
||||
|
||||
@Override
|
||||
public JSONObject generateDecisionTableData(String kbIds, String libraryIds, String projectLibrary,
|
||||
String userName, String history, String suggestion, Object data) {
|
||||
@@ -54,14 +64,24 @@ public class AuditContent3DecisionServiceImpl implements AuditContent3DecisionSe
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
try {
|
||||
// 1. 从不同知识库召回相关内容
|
||||
Map<String, List<String>> knowledgeSources = retrieveDecisionKnowledge(kbIds, libraryIds, projectLibrary);
|
||||
// 1. 解析三重一大数据
|
||||
JSONArray tripleOneData = parseTripleOneData(data);
|
||||
|
||||
// 2. 分析三重一大数据,确定审计重点
|
||||
Map<String, List<JSONObject>> auditFocusAreas = analyzeTripleOneData(data);
|
||||
if (tripleOneData == null || tripleOneData.isEmpty()) {
|
||||
log.warn("未传入三重一大数据,无法生成重大经济决策调查表");
|
||||
result.put("success", false);
|
||||
result.put("error", "需要三重一大数据作为生成依据");
|
||||
return result;
|
||||
}
|
||||
|
||||
// 3. 生成重大经济决策调查表数据
|
||||
JSONArray decisionTableData = generateDecisionTable(knowledgeSources, auditFocusAreas, userName, history, suggestion);
|
||||
// 2. 基于三重一大数据同步检索相关知识库内容
|
||||
Map<String, List<String>> knowledgeSources = retrieveKnowledgeForTripleOne(kbIds, libraryIds, projectLibrary, tripleOneData);
|
||||
|
||||
// 3. 构建完整的上下文并调用工作流
|
||||
String knowledgeContext = buildCompleteContext(tripleOneData, knowledgeSources, history, suggestion);
|
||||
|
||||
JSONObject requestBody = buildWorkflowRequest(knowledgeContext, userName);
|
||||
JSONArray decisionTableData = callDecisionWorkflow(requestBody);
|
||||
|
||||
// 4. 构建返回结果
|
||||
result.put("success", true);
|
||||
@@ -69,6 +89,7 @@ public class AuditContent3DecisionServiceImpl implements AuditContent3DecisionSe
|
||||
result.put("total_records", decisionTableData.size());
|
||||
result.put("generated_time", new Date().toString());
|
||||
result.put("processing_time", (System.currentTimeMillis() - startTime) + "ms");
|
||||
result.put("data_source", "triple_one_primary");
|
||||
|
||||
log.info("重大经济决策调查表生成成功 - 记录数: {}, 处理时间: {}ms",
|
||||
decisionTableData.size(), (System.currentTimeMillis() - startTime));
|
||||
@@ -84,76 +105,93 @@ public class AuditContent3DecisionServiceImpl implements AuditContent3DecisionSe
|
||||
}
|
||||
|
||||
/**
|
||||
* 分析三重一大数据,确定审计重点领域
|
||||
* 为三重一大数据同步检索相关知识
|
||||
*/
|
||||
private Map<String, List<JSONObject>> analyzeTripleOneData(Object data) {
|
||||
Map<String, List<JSONObject>> auditFocus = new HashMap<>();
|
||||
private Map<String, List<String>> retrieveKnowledgeForTripleOne(String kbIds, String libraryIds,
|
||||
String projectLibrary, JSONArray tripleOneData) {
|
||||
Map<String, List<String>> knowledgeSources = new HashMap<>();
|
||||
knowledgeSources.put("enterprise", new ArrayList<>());
|
||||
knowledgeSources.put("regulation", new ArrayList<>());
|
||||
knowledgeSources.put("auditCase", new ArrayList<>());
|
||||
|
||||
if (data == null) {
|
||||
log.info("未传入三重一大数据");
|
||||
return auditFocus;
|
||||
// 企业单位知识:每个三重一大数据项同步检索前10条
|
||||
for (int i = 0; i < tripleOneData.size(); i++) {
|
||||
JSONObject tripleItem = tripleOneData.getJSONObject(i);
|
||||
if (tripleItem != null) {
|
||||
List<String> enterpriseKnowledge = retrieveEnterpriseKnowledgeForItem(tripleItem, kbIds);
|
||||
knowledgeSources.get("enterprise").addAll(enterpriseKnowledge);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// 解析三重一大数据
|
||||
JSONArray tripleData;
|
||||
if (data instanceof JSONArray) {
|
||||
tripleData = (JSONArray) data;
|
||||
} else if (data instanceof List) {
|
||||
tripleData = JSONArray.parseArray(JSONObject.toJSONString(data));
|
||||
} else {
|
||||
// 尝试从JSONObject中提取data字段
|
||||
JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(data));
|
||||
if (jsonObject.containsKey("data") && jsonObject.get("data") instanceof JSONArray) {
|
||||
tripleData = jsonObject.getJSONArray("data");
|
||||
} else {
|
||||
log.warn("无法解析三重一大数据结构: {}", data.getClass().getSimpleName());
|
||||
return auditFocus;
|
||||
}
|
||||
}
|
||||
|
||||
// 按分类分组不通过的测试结果
|
||||
for (int i = 0; i < tripleData.size(); i++) {
|
||||
JSONObject item = tripleData.getJSONObject(i);
|
||||
if (item != null && "不通过".equals(item.getString("testResult"))) {
|
||||
String category = item.getString("category");
|
||||
if (category != null) {
|
||||
auditFocus.computeIfAbsent(category, k -> new ArrayList<>()).add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.info("三重一大分析完成 - 发现 {} 个分类存在不通过项", auditFocus.size());
|
||||
auditFocus.forEach((category, items) ->
|
||||
log.info("分类 {}: {} 个不通过项", category, items.size()));
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("分析三重一大数据失败", e);
|
||||
// 法律法规知识:全局检索100条,所有tripleItem共享
|
||||
if (StrUtil.isNotBlank(libraryIds)) {
|
||||
List<String> regulationKnowledge = retrieveGlobalRegulationKnowledge(libraryIds, tripleOneData);
|
||||
knowledgeSources.get("regulation").addAll(regulationKnowledge);
|
||||
}
|
||||
|
||||
return auditFocus;
|
||||
// 审计案例知识:全局检索50条,所有tripleItem共享
|
||||
if (StrUtil.isNotBlank(projectLibrary)) {
|
||||
List<String> auditCaseKnowledge = retrieveGlobalAuditCaseKnowledge(projectLibrary, tripleOneData);
|
||||
knowledgeSources.get("auditCase").addAll(auditCaseKnowledge);
|
||||
}
|
||||
|
||||
// 去重和限制数量
|
||||
knowledgeSources.put("enterprise", knowledgeSources.get("enterprise").stream()
|
||||
.distinct()
|
||||
.limit(200)
|
||||
.collect(Collectors.toList()));
|
||||
knowledgeSources.put("regulation", knowledgeSources.get("regulation").stream()
|
||||
.distinct()
|
||||
.limit(100)
|
||||
.collect(Collectors.toList()));
|
||||
knowledgeSources.put("auditCase", knowledgeSources.get("auditCase").stream()
|
||||
.distinct()
|
||||
.limit(50)
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
log.info("知识库检索完成 - 企业单位: {}条, 法律法规: {}条, 审计案例: {}条",
|
||||
knowledgeSources.get("enterprise").size(),
|
||||
knowledgeSources.get("regulation").size(),
|
||||
knowledgeSources.get("auditCase").size());
|
||||
|
||||
return knowledgeSources;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检索重大经济决策相关知识
|
||||
* 为单个三重一大项检索企业单位知识(限制10条)
|
||||
*/
|
||||
private Map<String, List<String>> retrieveDecisionKnowledge(String kbIds, String libraryIds, String projectLibrary) {
|
||||
Map<String, List<String>> knowledgeSources = new HashMap<>();
|
||||
knowledgeSources.put("enterprise", new ArrayList<>()); // 企业单位库
|
||||
knowledgeSources.put("regulation", new ArrayList<>()); // 公共法律法规库
|
||||
knowledgeSources.put("auditCase", new ArrayList<>()); // 审计案例库
|
||||
private List<String> retrieveEnterpriseKnowledgeForItem(JSONObject tripleItem, String kbIds) {
|
||||
List<String> enterpriseKnowledge = new ArrayList<>();
|
||||
|
||||
// 企业单位库检索 - 主要来源
|
||||
if (StrUtil.isNotBlank(kbIds)) {
|
||||
Arrays.stream(kbIds.split(","))
|
||||
.map(String::trim)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.forEach(kbId -> knowledgeSources.get("enterprise")
|
||||
.addAll(queryKnowledgeBase(kbId, buildEnterpriseQueries(), 200)));
|
||||
try {
|
||||
List<String> queries = buildQueriesForTripleOneItem(tripleItem);
|
||||
|
||||
if (StrUtil.isNotBlank(kbIds)) {
|
||||
Arrays.stream(kbIds.split(","))
|
||||
.map(String::trim)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.forEach(kbId -> enterpriseKnowledge
|
||||
.addAll(queryKnowledgeBaseForItem(kbId, queries, tripleItem, 10)));
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("检索企业单位知识失败", e);
|
||||
}
|
||||
|
||||
// 公共法律法规库检索
|
||||
if (StrUtil.isNotBlank(libraryIds)) {
|
||||
return enterpriseKnowledge.stream()
|
||||
.distinct()
|
||||
.limit(10)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局检索法律法规知识(100条)
|
||||
*/
|
||||
private List<String> retrieveGlobalRegulationKnowledge(String libraryIds, JSONArray tripleOneData) {
|
||||
List<String> regulationKnowledge = new ArrayList<>();
|
||||
|
||||
try {
|
||||
List<String> globalQueries = buildGlobalRegulationQueries(tripleOneData);
|
||||
List<String> idList = StrUtil.split(libraryIds, ',');
|
||||
List<PwlProjectLibrary> ret = pwlProjectLibraryService.list(
|
||||
new LambdaQueryWrapper<PwlProjectLibrary>().in(PwlProjectLibrary::getId, idList));
|
||||
@@ -162,217 +200,126 @@ public class AuditContent3DecisionServiceImpl implements AuditContent3DecisionSe
|
||||
Arrays.stream(libraryKbIds.split(","))
|
||||
.map(String::trim)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.forEach(libId -> knowledgeSources.get("regulation")
|
||||
.addAll(queryKnowledgeBase(libId, buildRegulationQueries(), 150)));
|
||||
.forEach(libId -> regulationKnowledge
|
||||
.addAll(queryKnowledgeBaseForGlobal(libId, globalQueries, 100)));
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("全局检索法律法规知识失败", e);
|
||||
}
|
||||
|
||||
// 审计案例库检索
|
||||
if (StrUtil.isNotBlank(projectLibrary)) {
|
||||
knowledgeSources.get("auditCase").addAll(
|
||||
queryKnowledgeBase(projectLibrary, buildAuditCaseQueries(), 100));
|
||||
}
|
||||
|
||||
// 智能去重和排序
|
||||
knowledgeSources.forEach((key, list) -> {
|
||||
List<String> processed = list.stream()
|
||||
.distinct()
|
||||
.limit(getLimitBySourceType(key))
|
||||
.collect(Collectors.toList());
|
||||
knowledgeSources.put(key, processed);
|
||||
});
|
||||
|
||||
return knowledgeSources;
|
||||
return regulationKnowledge;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建企业单位库查询
|
||||
* 全局检索审计案例知识(50条)
|
||||
*/
|
||||
private List<String> buildEnterpriseQueries() {
|
||||
return Arrays.asList(
|
||||
"重大经济决策事项 会议记录 会议纪要",
|
||||
"决策程序 集体决策 会议纪要 签到表",
|
||||
"重大投资项目 采购项目 资产处置 预算管理",
|
||||
"资金使用 外包业务 经济决策",
|
||||
"总经理办公会 董事会 党委会 决策会议"
|
||||
);
|
||||
private List<String> retrieveGlobalAuditCaseKnowledge(String projectLibrary, JSONArray tripleOneData) {
|
||||
List<String> auditCaseKnowledge = new ArrayList<>();
|
||||
|
||||
try {
|
||||
List<String> globalQueries = buildGlobalAuditCaseQueries(tripleOneData);
|
||||
auditCaseKnowledge.addAll(
|
||||
queryKnowledgeBaseForGlobal(projectLibrary, globalQueries, 50));
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("全局检索审计案例知识失败", e);
|
||||
}
|
||||
|
||||
return auditCaseKnowledge;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建法律法规库查询
|
||||
* 构建全局法律法规查询
|
||||
*/
|
||||
private List<String> buildRegulationQueries() {
|
||||
return Arrays.asList(
|
||||
"重大经济决策 集体决策规定",
|
||||
"决策程序 法律法规要求",
|
||||
"三重一大 经济决策 程序要求"
|
||||
);
|
||||
}
|
||||
private List<String> buildGlobalRegulationQueries(JSONArray tripleOneData) {
|
||||
List<String> queries = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 构建审计案例库查询
|
||||
*/
|
||||
private List<String> buildAuditCaseQueries() {
|
||||
return Arrays.asList(
|
||||
"重大经济决策审计案例 检查方法",
|
||||
"决策程序检查 执行效果评估",
|
||||
"经济决策测试 审计步骤"
|
||||
);
|
||||
}
|
||||
// 从所有tripleItem中提取共性关键词
|
||||
Set<String> categories = new HashSet<>();
|
||||
Set<String> policyKeywords = new HashSet<>();
|
||||
|
||||
/**
|
||||
* 根据知识库类型获取限制数量
|
||||
*/
|
||||
private int getLimitBySourceType(String sourceType) {
|
||||
switch (sourceType) {
|
||||
case "enterprise": return 300;
|
||||
case "regulation": return 200;
|
||||
case "auditCase": return 150;
|
||||
default: return 100;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成重大经济决策调查表
|
||||
*/
|
||||
private JSONArray generateDecisionTable(Map<String, List<String>> knowledgeSources,
|
||||
Map<String, List<JSONObject>> auditFocusAreas,
|
||||
String userName, String history, String suggestion) {
|
||||
// 构建优化的知识上下文
|
||||
String knowledgeContext = buildKnowledgeContext(knowledgeSources, auditFocusAreas, history, suggestion);
|
||||
|
||||
JSONObject requestBody = buildWorkflowRequest(knowledgeContext, userName);
|
||||
|
||||
JSONArray rawData = callDecisionWorkflow(requestBody);
|
||||
|
||||
// 后处理:数据清洗和格式化
|
||||
return postProcessDecisionData(rawData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建知识上下文
|
||||
*/
|
||||
private String buildKnowledgeContext(Map<String, List<String>> knowledgeSources,
|
||||
Map<String, List<JSONObject>> auditFocusAreas,
|
||||
String history, String suggestion) {
|
||||
StringBuilder context = new StringBuilder();
|
||||
|
||||
// 1. 分析要求
|
||||
context.append("## 重大经济决策调查表生成要求\n");
|
||||
context.append("请基于以下知识生成重大经济决策调查表数据:\n\n");
|
||||
context.append("1. 重点关注重大预算管理、重大项目实施、重大采购项目、重大投资项目、重大外包业务、重大资产处置、大额资金使用的决策和执行情况\n");
|
||||
context.append("2. 检查决策程序的完整性(签到表、决策纪要、决策人员签字确认等)\n");
|
||||
context.append("3. 评估决策执行情况和效果\n");
|
||||
context.append("4. 程序字段要详细描述具体的决策程序,包括会议类型、参与人员、决策依据文件等\n\n");
|
||||
|
||||
// 2. 数据格式要求
|
||||
context.append("## 数据格式要求\n");
|
||||
context.append("需要生成JSON数组格式的数据,每条记录包含以下字段:\n");
|
||||
context.append("[\n");
|
||||
context.append(" {\n");
|
||||
context.append(" \"decisionItem\": \"重大经济决策事项名称(具体描述)\",\n");
|
||||
context.append(" \"meetingTime\": \"会议时间(YYYY-MM-DD格式)\",\n");
|
||||
context.append(" \"decisionAmount\": \"决策事项金额(包含单位)\",\n");
|
||||
context.append(" \"procedure\": \"详细的决策程序描述,包括会议类型、参会人员、决策依据文件等\",\n");
|
||||
context.append(" \"executionStatus\": \"执行情况(是/否)\",\n");
|
||||
context.append(" \"executionEffect\": {\n");
|
||||
context.append(" \"good\": \"好(是/否)\",\n");
|
||||
context.append(" \"normal\": \"一般(是/否)\",\n");
|
||||
context.append(" \"bad\": \"差(是/否)\"\n");
|
||||
context.append(" }\n");
|
||||
context.append(" }\n");
|
||||
context.append("]\n\n");
|
||||
|
||||
// 3. 三重一大分析结果 - 审计重点
|
||||
if (!auditFocusAreas.isEmpty()) {
|
||||
context.append("## 三重一大制度分析结果 - 审计重点领域\n");
|
||||
context.append("基于三重一大制度对比分析,发现以下问题领域,请重点关注这些领域的决策事项:\n\n");
|
||||
|
||||
auditFocusAreas.forEach((category, items) -> {
|
||||
context.append("### ").append(category).append("领域\n");
|
||||
context.append("发现").append(items.size()).append("个不通过项:\n");
|
||||
|
||||
for (int i = 0; i < items.size() && i < 3; i++) { // 限制显示数量
|
||||
JSONObject item = items.get(i);
|
||||
context.append(i + 1).append(". ")
|
||||
.append(item.getString("checkEvidence")).append("\n");
|
||||
context.append(" 公司制度问题: ").append(item.getString("companyFormulation")).append("\n");
|
||||
context.append(" 政策要求: ").append(item.getString("policyContent")).append("\n\n");
|
||||
}
|
||||
});
|
||||
context.append("\n");
|
||||
} else {
|
||||
context.append("## 三重一大分析\n");
|
||||
context.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");
|
||||
context.append("以下是从企业单位库检索到的相关知识:\n");
|
||||
knowledgeSources.get("enterprise").stream()
|
||||
.limit(200)
|
||||
.forEach(knowledge -> context.append("- ").append(knowledge).append("\n"));
|
||||
context.append("\n");
|
||||
}
|
||||
|
||||
// 7. 法律法规知识
|
||||
if (!knowledgeSources.get("regulation").isEmpty()) {
|
||||
context.append("## 法律法规知识\n");
|
||||
context.append("以下是从公共法律法规库检索到的相关知识:\n");
|
||||
knowledgeSources.get("regulation").stream()
|
||||
.limit(150)
|
||||
.forEach(knowledge -> context.append("- ").append(knowledge).append("\n"));
|
||||
context.append("\n");
|
||||
}
|
||||
|
||||
// 8. 审计案例知识
|
||||
if (!knowledgeSources.get("auditCase").isEmpty()) {
|
||||
context.append("## 审计案例知识\n");
|
||||
context.append("以下是从审计案例库检索到的相关知识:\n");
|
||||
knowledgeSources.get("auditCase").stream()
|
||||
.limit(100)
|
||||
.forEach(knowledge -> context.append("- ").append(knowledge).append("\n"));
|
||||
}
|
||||
|
||||
log.debug("构建的知识上下文长度: {}", context.length());
|
||||
return context.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 后处理决策数据
|
||||
*/
|
||||
private JSONArray postProcessDecisionData(JSONArray rawData) {
|
||||
JSONArray processedData = new JSONArray();
|
||||
|
||||
for (int i = 0; i < rawData.size(); i++) {
|
||||
JSONObject item = rawData.getJSONObject(i);
|
||||
for (int i = 0; i < tripleOneData.size(); i++) {
|
||||
JSONObject item = tripleOneData.getJSONObject(i);
|
||||
if (item != null) {
|
||||
processedData.add(item);
|
||||
String category = item.getString("category");
|
||||
String policyContent = item.getString("policyContent");
|
||||
|
||||
if (StrUtil.isNotBlank(category)) {
|
||||
categories.add(category);
|
||||
}
|
||||
if (StrUtil.isNotBlank(policyContent)) {
|
||||
if (policyContent.contains("公司法")) policyKeywords.add("公司法");
|
||||
if (policyContent.contains("国有资产")) policyKeywords.add("国有资产法");
|
||||
if (policyContent.contains("党组织")) policyKeywords.add("党组织");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.info("后处理完成 - 输入数据条数: {}, 输出数据条数: {}", rawData.size(), processedData.size());
|
||||
return processedData;
|
||||
// 构建通用查询
|
||||
queries.add("重大经济决策 法律法规");
|
||||
queries.add("三重一大 政策规定");
|
||||
queries.add("集体决策 制度规定");
|
||||
|
||||
// 添加分类相关查询
|
||||
for (String category : categories) {
|
||||
queries.add(category + " 法律法规");
|
||||
}
|
||||
|
||||
// 添加政策关键词相关查询
|
||||
for (String keyword : policyKeywords) {
|
||||
queries.add(keyword + " 决策规定");
|
||||
}
|
||||
|
||||
return queries;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询知识库
|
||||
* 构建全局审计案例查询
|
||||
*/
|
||||
private List<String> queryKnowledgeBase(String kbId, List<String> queries, int topK) {
|
||||
private List<String> buildGlobalAuditCaseQueries(JSONArray tripleOneData) {
|
||||
List<String> queries = new ArrayList<>();
|
||||
|
||||
// 从所有tripleItem中提取共性信息
|
||||
Set<String> categories = new HashSet<>();
|
||||
boolean hasFailedCases = false;
|
||||
|
||||
for (int i = 0; i < tripleOneData.size(); i++) {
|
||||
JSONObject item = tripleOneData.getJSONObject(i);
|
||||
if (item != null) {
|
||||
String category = item.getString("category");
|
||||
String testResult = item.getString("testResult");
|
||||
|
||||
if (StrUtil.isNotBlank(category)) {
|
||||
categories.add(category);
|
||||
}
|
||||
if ("不通过".equals(testResult)) {
|
||||
hasFailedCases = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 构建通用查询
|
||||
queries.add("重大经济决策 审计案例");
|
||||
queries.add("三重一大 检查方法");
|
||||
|
||||
// 添加分类相关查询
|
||||
for (String category : categories) {
|
||||
queries.add(category + " 审计案例");
|
||||
}
|
||||
|
||||
// 如果有不通过的案例,添加相关查询
|
||||
if (hasFailedCases) {
|
||||
queries.add("决策程序缺陷 案例");
|
||||
queries.add("集体决策问题 审计");
|
||||
}
|
||||
|
||||
return queries;
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局知识库查询(不关联特定tripleItem)
|
||||
*/
|
||||
private List<String> queryKnowledgeBaseForGlobal(String kbId, List<String> queries, int topK) {
|
||||
Set<String> results = new LinkedHashSet<>();
|
||||
String workspaceId = config.getWorkspaceId();
|
||||
|
||||
@@ -390,7 +337,245 @@ public class AuditContent3DecisionServiceImpl implements AuditContent3DecisionSe
|
||||
.orElse(Collections.emptyList())
|
||||
.stream()
|
||||
.limit(topK)
|
||||
.forEach(node -> processNode(node, results));
|
||||
.forEach(node -> processNodeForGlobal(node, results));
|
||||
|
||||
} catch (Exception e) {
|
||||
log.warn("全局查询知识库失败 - kbId: {}, query: {}", kbId, query, e);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("创建知识库客户端失败", e);
|
||||
}
|
||||
|
||||
return new ArrayList<>(results);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理全局知识库节点
|
||||
*/
|
||||
private void processNodeForGlobal(RetrieveResponseBodyDataNodes node, Set<String> results) {
|
||||
try {
|
||||
String text = node.getText();
|
||||
if (StrUtil.isBlank(text) || text.length() < 10) {
|
||||
return;
|
||||
}
|
||||
|
||||
String docName = extractDocumentName(node);
|
||||
String formattedText = String.format("《%s》%s", docName, text);
|
||||
results.add(formattedText);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.warn("处理全局知识库节点失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析三重一大数据
|
||||
*/
|
||||
private JSONArray parseTripleOneData(Object data) {
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
JSONArray tripleData;
|
||||
if (data instanceof JSONArray) {
|
||||
tripleData = (JSONArray) data;
|
||||
} else if (data instanceof List) {
|
||||
tripleData = JSONArray.parseArray(JSONObject.toJSONString(data));
|
||||
} else {
|
||||
JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(data));
|
||||
if (jsonObject.containsKey("data") && jsonObject.get("data") instanceof JSONArray) {
|
||||
tripleData = jsonObject.getJSONArray("data");
|
||||
} else {
|
||||
tripleData = new JSONArray();
|
||||
tripleData.add(jsonObject);
|
||||
}
|
||||
}
|
||||
|
||||
log.info("解析三重一大数据成功,条数: {}", tripleData.size());
|
||||
return tripleData;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("解析三重一大数据失败", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 为单个三重一大项构建查询
|
||||
*/
|
||||
private List<String> buildQueriesForTripleOneItem(JSONObject tripleItem) {
|
||||
List<String> queries = new ArrayList<>();
|
||||
|
||||
String category = tripleItem.getString("category");
|
||||
String policyContent = tripleItem.getString("policyContent");
|
||||
String checkEvidence = tripleItem.getString("checkEvidence");
|
||||
String companyFormulation = tripleItem.getString("companyFormulation");
|
||||
|
||||
// 基于分类构建查询
|
||||
if (category != null) {
|
||||
queries.add(category + " 会议记录 决策事项");
|
||||
queries.add(category + " 经济决策 程序");
|
||||
}
|
||||
|
||||
// 从政策内容提取关键词
|
||||
if (policyContent != null) {
|
||||
if (policyContent.contains("投资")) queries.add("投资项目 决策");
|
||||
if (policyContent.contains("采购")) queries.add("采购项目 决策");
|
||||
if (policyContent.contains("资产")) queries.add("资产处置 决策");
|
||||
if (policyContent.contains("预算")) queries.add("预算管理 决策");
|
||||
if (policyContent.contains("人事")) queries.add("人事任免 决策");
|
||||
}
|
||||
|
||||
// 从检查证据提取具体事项
|
||||
if (checkEvidence != null) {
|
||||
String[] evidenceKeywords = extractKeywordsFromEvidence(checkEvidence);
|
||||
for (String keyword : evidenceKeywords) {
|
||||
if (keyword.length() > 2) {
|
||||
queries.add(keyword + " 会议纪要");
|
||||
queries.add(keyword + " 决策程序");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 从公司制度问题提取关键词
|
||||
if (companyFormulation != null) {
|
||||
if (companyFormulation.contains("权限")) queries.add("决策权限 授权");
|
||||
if (companyFormulation.contains("程序")) queries.add("决策程序 流程");
|
||||
if (companyFormulation.contains("审批")) queries.add("审批流程 决策");
|
||||
}
|
||||
|
||||
return queries;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从检查证据中提取关键词
|
||||
*/
|
||||
private String[] extractKeywordsFromEvidence(String checkEvidence) {
|
||||
if (checkEvidence == null) return new String[0];
|
||||
|
||||
List<String> keywords = new ArrayList<>();
|
||||
|
||||
// 提取可能的项目名称(包含《》的文件名)
|
||||
if (checkEvidence.contains("《") && checkEvidence.contains("》")) {
|
||||
int start = checkEvidence.indexOf("《");
|
||||
int end = checkEvidence.indexOf("》");
|
||||
if (start < end) {
|
||||
String fileName = checkEvidence.substring(start + 1, end);
|
||||
keywords.add(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
// 提取可能的金额数字
|
||||
if (checkEvidence.matches(".*\\d+(\\.\\d+)?万.*")) {
|
||||
keywords.add("金额");
|
||||
}
|
||||
|
||||
// 提取常见项目类型
|
||||
String[] projectTypes = {"项目", "投资", "采购", "建设", "改造", "扩建", "维修"};
|
||||
for (String type : projectTypes) {
|
||||
if (checkEvidence.contains(type)) {
|
||||
keywords.add(type);
|
||||
}
|
||||
}
|
||||
|
||||
return keywords.toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建完整的上下文
|
||||
*/
|
||||
private String buildCompleteContext(JSONArray tripleOneData, Map<String, List<String>> knowledgeSources,
|
||||
String history, String suggestion) {
|
||||
StringBuilder context = new StringBuilder();
|
||||
|
||||
// 1. 核心指令
|
||||
context.append("## 核心生成指令\n");
|
||||
context.append("请基于以下三重一大制度对比分析数据为主要依据,结合相关知识库内容,生成重大经济决策调查表。\n\n");
|
||||
context.append("**数据优先级**: 三重一大数据 > 知识库内容 > 通用审计规则\n\n");
|
||||
|
||||
// 2. Excel Sheet1 条件信息
|
||||
context.append(EXCEL_SHEET1_CONDITIONS).append("\n\n");
|
||||
|
||||
// 3. 三重一大数据(主要依据)
|
||||
context.append("## 三重一大制度对比分析数据(主要依据)\n");
|
||||
context.append("请基于以下三重一大数据生成对应的重大经济决策调查记录,每条三重一大数据都应生成对应的调查表记录:\n\n");
|
||||
|
||||
for (int i = 0; i < tripleOneData.size(); i++) {
|
||||
JSONObject item = tripleOneData.getJSONObject(i);
|
||||
if (item != null) {
|
||||
context.append("### 三重一大事项 ").append(i + 1).append("\n");
|
||||
context.append("```json\n");
|
||||
context.append(JSONObject.toJSONString(item, true));
|
||||
context.append("\n```\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 知识库内容(辅助信息)
|
||||
context.append("## 相关知识库内容(辅助信息)\n");
|
||||
context.append("以下是从知识库中检索到的相关信息,用于补充决策事项的细节:\n\n");
|
||||
|
||||
if (!knowledgeSources.get("enterprise").isEmpty()) {
|
||||
context.append("### 企业单位知识\n");
|
||||
knowledgeSources.get("enterprise").forEach(knowledge ->
|
||||
context.append("- ").append(knowledge).append("\n"));
|
||||
context.append("\n");
|
||||
}
|
||||
|
||||
if (!knowledgeSources.get("regulation").isEmpty()) {
|
||||
context.append("### 法律法规知识\n");
|
||||
knowledgeSources.get("regulation").forEach(knowledge ->
|
||||
context.append("- ").append(knowledge).append("\n"));
|
||||
context.append("\n");
|
||||
}
|
||||
|
||||
if (!knowledgeSources.get("auditCase").isEmpty()) {
|
||||
context.append("### 审计案例知识\n");
|
||||
knowledgeSources.get("auditCase").forEach(knowledge ->
|
||||
context.append("- ").append(knowledge).append("\n"));
|
||||
context.append("\n");
|
||||
}
|
||||
|
||||
// 5. 历史内容和用户建议
|
||||
if (StrUtil.isNotBlank(history)) {
|
||||
context.append("## 历史生成内容\n");
|
||||
context.append(history).append("\n\n");
|
||||
}
|
||||
|
||||
if (StrUtil.isNotBlank(suggestion)) {
|
||||
context.append("## 用户优化建议\n");
|
||||
context.append(suggestion).append("\n\n");
|
||||
}
|
||||
|
||||
log.debug("完整上下文长度: {}", context.length());
|
||||
return context.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 为单个项查询知识库
|
||||
*/
|
||||
private List<String> queryKnowledgeBaseForItem(String kbId, List<String> queries, JSONObject tripleItem, int topK) {
|
||||
Set<String> results = new LinkedHashSet<>();
|
||||
String workspaceId = config.getWorkspaceId();
|
||||
|
||||
try {
|
||||
Client client = clientFactory.createClient();
|
||||
|
||||
for (String query : queries) {
|
||||
try {
|
||||
RetrieveResponse resp = KnowledgeBaseUtil.retrieveIndex(client, workspaceId, kbId, query);
|
||||
|
||||
Optional.ofNullable(resp)
|
||||
.map(RetrieveResponse::getBody)
|
||||
.map(RetrieveResponseBody::getData)
|
||||
.map(RetrieveResponseBodyData::getNodes)
|
||||
.orElse(Collections.emptyList())
|
||||
.stream()
|
||||
.limit(topK)
|
||||
.forEach(node -> processNodeForItem(node, results, tripleItem));
|
||||
|
||||
} catch (Exception e) {
|
||||
log.warn("查询知识库失败 - kbId: {}, query: {}", kbId, query, e);
|
||||
}
|
||||
@@ -404,29 +589,61 @@ public class AuditContent3DecisionServiceImpl implements AuditContent3DecisionSe
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理知识库节点
|
||||
* 处理知识库节点(针对特定三重一项)
|
||||
*/
|
||||
private void processNode(RetrieveResponseBodyDataNodes node, Set<String> results) {
|
||||
private void processNodeForItem(RetrieveResponseBodyDataNodes node, Set<String> results, JSONObject tripleItem) {
|
||||
try {
|
||||
String text = node.getText();
|
||||
if (StrUtil.isBlank(text) || text.length() < 10) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 限制文本长度,避免上下文过长
|
||||
if (text.length() > 500) {
|
||||
text = text.substring(0, 500) + "...";
|
||||
// 检查文本是否与当前三重一项相关
|
||||
if (isTextRelevantToItem(text, tripleItem)) {
|
||||
String docName = extractDocumentName(node);
|
||||
String formattedText = String.format("《%s》%s", docName, text);
|
||||
results.add(formattedText);
|
||||
}
|
||||
|
||||
String docName = extractDocumentName(node);
|
||||
String formattedText = String.format("《%s》%s", docName, text);
|
||||
results.add(formattedText);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.warn("处理知识库节点失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查文本是否与三重一项相关
|
||||
*/
|
||||
private boolean isTextRelevantToItem(String text, JSONObject tripleItem) {
|
||||
String category = tripleItem.getString("category");
|
||||
String checkEvidence = tripleItem.getString("checkEvidence");
|
||||
String policyContent = tripleItem.getString("policyContent");
|
||||
|
||||
// 基于分类检查相关性
|
||||
if (category != null && text.contains(category)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 基于检查证据中的关键词检查相关性
|
||||
if (checkEvidence != null) {
|
||||
String[] keywords = extractKeywordsFromEvidence(checkEvidence);
|
||||
for (String keyword : keywords) {
|
||||
if (keyword.length() > 2 && text.contains(keyword)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 基于政策内容中的关键词检查相关性
|
||||
if (policyContent != null) {
|
||||
if (policyContent.contains("投资") && text.contains("投资")) return true;
|
||||
if (policyContent.contains("采购") && text.contains("采购")) return true;
|
||||
if (policyContent.contains("资产") && text.contains("资产")) return true;
|
||||
if (policyContent.contains("预算") && text.contains("预算")) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取文档名称
|
||||
*/
|
||||
@@ -437,8 +654,7 @@ public class AuditContent3DecisionServiceImpl implements AuditContent3DecisionSe
|
||||
Map<?, ?> metadata = (Map<?, ?>) metadataObj;
|
||||
Object docNameObj = metadata.get("doc_name");
|
||||
if (docNameObj != null) {
|
||||
String docName = docNameObj.toString();
|
||||
return docName.length() > 50 ? docName.substring(0, 50) + "..." : docName;
|
||||
return docNameObj.toString();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@@ -447,9 +663,6 @@ public class AuditContent3DecisionServiceImpl implements AuditContent3DecisionSe
|
||||
return "相关文档";
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用重大经济决策工作流
|
||||
*/
|
||||
private JSONArray callDecisionWorkflow(JSONObject requestBody) {
|
||||
try {
|
||||
log.info("调用重大经济决策工作流,请求体长度: {}", requestBody.toString().length());
|
||||
@@ -458,7 +671,7 @@ public class AuditContent3DecisionServiceImpl implements AuditContent3DecisionSe
|
||||
.header("Authorization", DECISION_TABLE_TOKEN)
|
||||
.header("Content-Type", "application/json")
|
||||
.body(requestBody.toString())
|
||||
.timeout(10 * 60 * 1000) // 10分钟超时
|
||||
.timeout(10 * 60 * 1000)
|
||||
.execute()
|
||||
.body();
|
||||
|
||||
@@ -467,7 +680,6 @@ public class AuditContent3DecisionServiceImpl implements AuditContent3DecisionSe
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
JsonNode rootNode = objectMapper.readTree(result);
|
||||
|
||||
// 简化的返回结构处理 - 参考 AuditContentServiceImpl3 的写法
|
||||
String outputText = rootNode.path("data")
|
||||
.path("outputs")
|
||||
.path("result")
|
||||
@@ -478,7 +690,6 @@ public class AuditContent3DecisionServiceImpl implements AuditContent3DecisionSe
|
||||
return new JSONArray();
|
||||
}
|
||||
|
||||
// 使用Jackson解析数组
|
||||
JsonNode arrayNode = objectMapper.readTree(outputText);
|
||||
JSONArray jsonArray = JSONArray.parseArray(arrayNode.toString());
|
||||
|
||||
@@ -491,9 +702,6 @@ public class AuditContent3DecisionServiceImpl implements AuditContent3DecisionSe
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建工作流请求
|
||||
*/
|
||||
private JSONObject buildWorkflowRequest(String knowledge, String userName) {
|
||||
JSONObject requestBody = new JSONObject();
|
||||
JSONObject inputs = new JSONObject();
|
||||
@@ -503,7 +711,7 @@ public class AuditContent3DecisionServiceImpl implements AuditContent3DecisionSe
|
||||
requestBody.put("inputs", inputs);
|
||||
requestBody.put("response_mode", "blocking");
|
||||
requestBody.put("user", userName);
|
||||
requestBody.put("timeout", 600); // 10分钟超时
|
||||
requestBody.put("timeout", 600);
|
||||
|
||||
return requestBody;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user