三重一大、重大经济决策调查表数据生成优化

This commit is contained in:
2025-10-31 17:43:15 +08:00
parent 8b841767e2
commit cb93f4e566
6 changed files with 582 additions and 9 deletions

View File

@@ -0,0 +1,568 @@
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.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
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.AuditContent3TripleService;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
@Slf4j
@Service
public class AuditContent3TripleServiceImpl implements AuditContent3TripleService {
@Autowired
private KnowledgeBaseClientFactory clientFactory;
@Autowired
private KnowledgeBaseConfig config;
@Autowired
private PwlProjectLibraryService pwlProjectLibraryService;
// 工作流配置
private static final String TRIPLE_ONE_WORKFLOW_URL = "http://1.14.159.185:8180/v1/workflows/run";
private static final String TRIPLE_ONE_TOKEN = "Bearer app-tjXbmHDE6daMbYOT4O13ev2X";
// 三重一大分类定义
private static final Map<String, String> TRIPLE_ONE_CATEGORIES = new LinkedHashMap<>();
static {
TRIPLE_ONE_CATEGORIES.put("重大决策", "重大决策事项的定义和范围");
TRIPLE_ONE_CATEGORIES.put("重要人事任免", "重要人事任免事项的定义和范围");
TRIPLE_ONE_CATEGORIES.put("重大项目安排", "重大项目安排事项的定义和范围");
TRIPLE_ONE_CATEGORIES.put("大额度资金运作", "大额度资金运作事项的定义和范围");
TRIPLE_ONE_CATEGORIES.put("决策权力主体和程序", "决策权力主体和程序的规定");
}
// 关键词权重
private static final Map<String, Integer> KEYWORD_WEIGHTS;
static {
Map<String, Integer> map = new HashMap<>();
map.put("三重一大", 10);
map.put("重大决策", 9);
map.put("重要人事任免", 9);
map.put("重大项目安排", 9);
map.put("大额度资金运作", 9);
map.put("决策程序", 8);
map.put("党委会", 7);
map.put("董事会", 7);
map.put("总经理办公会", 7);
map.put("集体决策", 8);
map.put("会议纪要", 6);
map.put("金额标准", 6);
KEYWORD_WEIGHTS = Collections.unmodifiableMap(map);
}
@Override
public JSONObject generateTripleOneTableData(String kbIds, String libraryIds, String projectLibrary,
String userName, String history, String suggestion) {
log.info("开始生成三重一大制度对比分析表数据 - 用户: {}, kbIds: {}, libraryIds: {}, projectLibrary: {}",
userName, kbIds, libraryIds, projectLibrary);
JSONObject result = new JSONObject();
long startTime = System.currentTimeMillis();
try {
// 1. 从不同知识库召回相关内容
Map<String, List<String>> knowledgeSources = retrieveTripleOneKnowledge(kbIds, libraryIds, projectLibrary);
// 2. 生成三重一大制度对比分析表数据
JSONArray comparisonTableData = generateComparisonTable(knowledgeSources, userName, history, suggestion);
// 3. 数据质量检查
comparisonTableData = validateAndEnhanceComparisonData(comparisonTableData);
// 4. 构建返回结果
result.put("success", true);
result.put("data", comparisonTableData);
result.put("total_records", comparisonTableData.size());
result.put("generated_time", new Date().toString());
result.put("processing_time", (System.currentTimeMillis() - startTime) + "ms");
log.info("三重一大制度对比分析表生成成功 - 记录数: {}, 处理时间: {}ms",
comparisonTableData.size(), (System.currentTimeMillis() - startTime));
} catch (Exception e) {
log.error("生成三重一大制度对比分析表失败", e);
result.put("success", false);
result.put("error", e.getMessage());
throw new RuntimeException("生成三重一大制度对比分析表失败: " + e.getMessage(), e);
}
return result;
}
/**
* 检索三重一大相关知识
*/
private Map<String, List<String>> retrieveTripleOneKnowledge(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<>()); // 审计案例库
// 企业单位库检索 - 主要来源
if (StrUtil.isNotBlank(kbIds)) {
Arrays.stream(kbIds.split(","))
.map(String::trim)
.filter(StrUtil::isNotBlank)
.forEach(kbId -> knowledgeSources.get("enterprise")
.addAll(queryKnowledgeBase(kbId, buildEnterpriseQueries(), 200)));
}
// 公共法律法规库检索
if (StrUtil.isNotBlank(libraryIds)) {
List<String> idList = StrUtil.split(libraryIds, ',');
List<PwlProjectLibrary> ret = pwlProjectLibraryService.list(
new LambdaQueryWrapper<PwlProjectLibrary>().in(PwlProjectLibrary::getId, idList));
String libraryKbIds = ret.stream().map(PwlProjectLibrary::getKbId).collect(Collectors.joining(","));
Arrays.stream(libraryKbIds.split(","))
.map(String::trim)
.filter(StrUtil::isNotBlank)
.forEach(libId -> knowledgeSources.get("regulation")
.addAll(queryKnowledgeBase(libId, buildRegulationQueries(), 150)));
}
// 审计案例库检索
if (StrUtil.isNotBlank(projectLibrary)) {
knowledgeSources.get("auditCase").addAll(
queryKnowledgeBase(projectLibrary, buildAuditCaseQueries(), 100));
}
// 智能去重和排序
knowledgeSources.forEach((key, list) -> {
List<String> processed = list.stream()
.distinct()
.sorted(this::tripleOneComparator)
.limit(getLimitBySourceType(key))
.collect(Collectors.toList());
knowledgeSources.put(key, processed);
});
return knowledgeSources;
}
/**
* 构建企业单位库查询
*/
private List<String> buildEnterpriseQueries() {
return Arrays.asList(
"三重一大制度 集体决策规定",
"重大决策范围 人事任免范围 项目安排范围 资金运作范围",
"决策程序 权力主体 会议规则",
"集团制度 公司制定 内部规定"
);
}
/**
* 构建法律法规库查询
*/
private List<String> buildRegulationQueries() {
return Arrays.asList(
"三重一大政策 国家法律法规",
"重大决策法规 人事任免法规",
"项目安排规定 资金运作规定",
"决策程序法律要求"
);
}
/**
* 构建审计案例库查询
*/
private List<String> buildAuditCaseQueries() {
return Arrays.asList(
"三重一大审计案例 检查证据",
"决策程序测试 执行效果",
"工作底稿 审计测试结果"
);
}
/**
* 根据知识库类型获取限制数量
*/
private int getLimitBySourceType(String sourceType) {
switch (sourceType) {
case "enterprise": return 300;
case "regulation": return 200;
case "auditCase": return 150;
default: return 100;
}
}
/**
* 生成三重一大制度对比分析表
*/
private JSONArray generateComparisonTable(Map<String, List<String>> knowledgeSources, String userName, String history, String suggestion) {
// 构建优化的知识上下文
String knowledgeContext = buildKnowledgeContext(knowledgeSources, history, suggestion);
JSONObject requestBody = buildWorkflowRequest(knowledgeContext, userName);
JSONArray rawData = callTripleOneWorkflow(requestBody);
// 后处理:数据清洗和格式化
return postProcessComparisonData(rawData);
}
/**
* 构建知识上下文
*/
private String buildKnowledgeContext(Map<String, List<String>> knowledgeSources, 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\n");
// 2. 数据格式要求
context.append("## 数据格式要求\n");
context.append("需要生成5个分类的数据每个分类尽可能多的生成多个实例、多条记录尽可能三重一大的五个方面都包含\n");
TRIPLE_ONE_CATEGORIES.forEach((category, desc) ->
context.append("- ").append(category).append("").append(desc).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相关《参考文件名》以及工作底稿的索引编号\n");
context.append("\n注意每个分类下可以有多个条目请根据知识库内容尽可能全面地生成所有相关制度规定和检查点。\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").stream()
.limit(250)
.forEach(knowledge -> context.append("- ").append(knowledge).append("\n"));
context.append("\n");
}
// 6. 法律法规知识
if (!knowledgeSources.get("regulation").isEmpty()) {
context.append("## 法律法规知识\n");
knowledgeSources.get("regulation").stream()
.limit(200)
.forEach(knowledge -> context.append("- ").append(knowledge).append("\n"));
context.append("\n");
}
// 7. 审计案例知识
if (!knowledgeSources.get("auditCase").isEmpty()) {
context.append("## 审计案例知识\n");
knowledgeSources.get("auditCase").stream()
.limit(150)
.forEach(knowledge -> context.append("- ").append(knowledge).append("\n"));
}
return context.toString();
}
/**
* 数据验证和增强
*/
private JSONArray validateAndEnhanceComparisonData(JSONArray data) {
if (data == null || data.isEmpty()) {
return createDefaultComparisonData();
}
JSONArray enhancedData = new JSONArray();
for (int i = 0; i < data.size(); i++) {
JSONObject item = data.getJSONObject(i);
if (item == null) continue;
// 数据验证
if (!validateComparisonDataItem(item)) {
log.warn("数据验证失败,跳过记录: {}", item);
continue;
}
// 数据增强
enhanceComparisonDataItem(item, i);
enhancedData.add(item);
}
return enhancedData;
}
/**
* 创建默认的对比分析数据
*/
private JSONArray createDefaultComparisonData() {
JSONArray defaultData = new JSONArray();
for (String category : TRIPLE_ONE_CATEGORIES.keySet()) {
JSONObject item = new JSONObject();
item.put("category", category);
item.put("policyContent", "待补充相关政策内容");
item.put("groupSystem", "待补充集团制度规定");
item.put("companyFormulation", "待补充公司制定内容");
item.put("checkEvidence", "待补充检查证据");
item.put("testResult", "待检查");
item.put("workPaperIndex", Collections.singletonList("待关联工作底稿"));
defaultData.add(item);
}
return defaultData;
}
/**
* 数据项验证
*/
private boolean validateComparisonDataItem(JSONObject item) {
return item.containsKey("category") &&
item.containsKey("policyContent") &&
item.containsKey("groupSystem") &&
item.containsKey("companyFormulation");
}
/**
* 数据项增强
*/
private void enhanceComparisonDataItem(JSONObject item, int index) {
// 确保分类正确
if (!item.containsKey("category") || StrUtil.isBlank(item.getString("category"))) {
List<String> categories = new ArrayList<>(TRIPLE_ONE_CATEGORIES.keySet());
if (index < categories.size()) {
item.put("category", categories.get(index));
}
}
// 确保所有字段都存在
String[] requiredFields = {"policyContent", "groupSystem", "companyFormulation",
"checkEvidence", "testResult", "workPaperIndex"};
for (String field : requiredFields) {
if (!item.containsKey(field) || item.get(field) == null) {
if ("workPaperIndex".equals(field)) {
item.put(field, Collections.singletonList("待关联工作底稿"));
} else if ("testResult".equals(field)) {
item.put(field, "待检查");
} else {
item.put(field, "");
}
}
}
}
private JSONArray postProcessComparisonData(JSONArray rawData) {
if (rawData == null || rawData.isEmpty()) {
return createDefaultComparisonData();
}
// 使用列表来存储所有条目,避免覆盖
JSONArray processedData = new JSONArray();
Map<String, List<JSONObject>> categoryDataMap = new LinkedHashMap<>();
// 初始化分类映射
for (String category : TRIPLE_ONE_CATEGORIES.keySet()) {
categoryDataMap.put(category, new ArrayList<>());
}
// 按分类分组所有条目
for (int i = 0; i < rawData.size(); i++) {
JSONObject item = rawData.getJSONObject(i);
if (item != null && item.containsKey("category")) {
String category = item.getString("category");
if (categoryDataMap.containsKey(category)) {
categoryDataMap.get(category).add(item);
} else {
// 如果分类不在预定义列表中,添加到其他分类
log.warn("发现未预定义的分类: {}", category);
categoryDataMap.computeIfAbsent(category, k -> new ArrayList<>()).add(item);
}
}
}
// 按照固定顺序输出所有条目
for (String category : TRIPLE_ONE_CATEGORIES.keySet()) {
List<JSONObject> categoryItems = categoryDataMap.get(category);
if (categoryItems != null && !categoryItems.isEmpty()) {
// 添加该分类下的所有条目
processedData.addAll(categoryItems);
}
}
// 处理其他未预定义的分类
for (Map.Entry<String, List<JSONObject>> entry : categoryDataMap.entrySet()) {
String category = entry.getKey();
if (!TRIPLE_ONE_CATEGORIES.containsKey(category)) {
processedData.addAll(entry.getValue());
}
}
log.info("后处理完成 - 输入数据条数: {}, 输出数据条数: {}", rawData.size(), processedData.size());
return processedData;
}
/**
* 三重一大内容比较器
*/
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 KEYWORD_WEIGHTS.entrySet().stream()
.filter(entry -> content.contains(entry.getKey()))
.mapToInt(Map.Entry::getValue)
.sum();
}
/**
* 查询知识库
*/
private List<String> queryKnowledgeBase(String kbId, List<String> queries, int topK) {
Set<String> results = new LinkedHashSet<>();
String workspaceId = config.getWorkspaceId();
try {
Client client = clientFactory.createClient();
for (String query : queries) {
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 -> processNode(node, results));
}
} catch (Exception e) {
log.error("查询知识库失败 - kbId: {}, queries: {}", kbId, queries, e);
}
return new ArrayList<>(results);
}
/**
* 处理知识库节点
*/
private void processNode(RetrieveResponseBodyDataNodes node, Set<String> results) {
try {
String text = node.getText();
if (StrUtil.isBlank(text) || text.length() < 10 || text.length() > 1000) {
return;
}
String docName = extractDocumentName(node);
String formattedText = String.format("《%s》%s", docName, text);
results.add(formattedText);
} catch (Exception e) {
log.warn("处理知识库节点失败", e);
}
}
/**
* 提取文档名称
*/
private String extractDocumentName(RetrieveResponseBodyDataNodes node) {
try {
Object metadataObj = node.getMetadata();
if (metadataObj instanceof Map) {
Map<?, ?> metadata = (Map<?, ?>) metadataObj;
Object docNameObj = metadata.get("doc_name");
return docNameObj != null ? docNameObj.toString() : "相关文档";
}
} catch (Exception e) {
log.debug("提取文档名称失败", e);
}
return "相关文档";
}
/**
* 调用三重一大工作流
*/
private JSONArray callTripleOneWorkflow(JSONObject requestBody) {
try {
String result = HttpUtil.createPost(TRIPLE_ONE_WORKFLOW_URL)
.header("Authorization", TRIPLE_ONE_TOKEN)
.header("Content-Type", "application/json")
.body(requestBody.toString())
.timeout(5*60*1000)
.execute()
.body();
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(result);
String outputText = rootNode.path("data")
.path("outputs")
.path("result")
.asText();
// 使用Jackson解析数组
JsonNode arrayNode = objectMapper.readTree(outputText);
return JSONArray.parseArray(arrayNode.toString());
} catch (Exception e) {
log.error("调用三重一大工作流失败", e);
throw new RuntimeException("调用三重一大工作流失败: " + e.getMessage(), e);
}
}
/**
* 构建工作流请求
*/
private JSONObject buildWorkflowRequest(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;
}
}