三重一大生成接口优化
This commit is contained in:
@@ -1,21 +1,36 @@
|
|||||||
package com.gxwebsoft.ai.controller;
|
package com.gxwebsoft.ai.controller;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.gxwebsoft.ai.dto.AuditContentRequest;
|
import com.gxwebsoft.ai.dto.AuditContentRequest;
|
||||||
|
import com.gxwebsoft.ai.entity.AiCloudDoc;
|
||||||
|
import com.gxwebsoft.ai.entity.AiCloudFile;
|
||||||
import com.gxwebsoft.common.core.web.ApiResult;
|
import com.gxwebsoft.common.core.web.ApiResult;
|
||||||
import com.gxwebsoft.common.core.web.BaseController;
|
import com.gxwebsoft.common.core.web.BaseController;
|
||||||
import com.gxwebsoft.common.system.entity.User;
|
import com.gxwebsoft.common.system.entity.User;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import com.gxwebsoft.ai.service.AiCloudDocService;
|
||||||
|
import com.gxwebsoft.ai.service.AiCloudFileService;
|
||||||
import com.gxwebsoft.ai.service.AuditContentService3;
|
import com.gxwebsoft.ai.service.AuditContentService3;
|
||||||
|
import com.gxwebsoft.ai.service.KnowledgeBaseService;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 审计内容3控制器 - 重大经济决策调查表
|
* 审计内容3控制器 - 三重一大制度对比分析
|
||||||
*/
|
*/
|
||||||
@Tag(name = "审计内容3-重大经济决策")
|
@Slf4j
|
||||||
|
@Tag(name = "审计内容3-三重一大制度对比")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/ai/auditContent3")
|
@RequestMapping("/api/ai/auditContent3")
|
||||||
public class AuditContentController3 extends BaseController {
|
public class AuditContentController3 extends BaseController {
|
||||||
@@ -23,18 +38,34 @@ public class AuditContentController3 extends BaseController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private AuditContentService3 auditContentService3;
|
private AuditContentService3 auditContentService3;
|
||||||
|
|
||||||
/**
|
@Autowired
|
||||||
* 生成重大经济决策调查表数据
|
private AiCloudDocService aiCloudDocService;
|
||||||
*/
|
|
||||||
@Operation(summary = "生成重大经济决策调查表")
|
|
||||||
@PostMapping("/generateDecisionTable")
|
|
||||||
public ApiResult<?> generateDecisionTable(@RequestBody AuditContentRequest request) {
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AiCloudFileService aiCloudFileService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private KnowledgeBaseService knowledgeBaseService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成三重一大制度对比分析表数据
|
||||||
|
*/
|
||||||
|
@Operation(summary = "生成三重一大制度对比分析表")
|
||||||
|
@PostMapping("/generateTripleOneTable")
|
||||||
|
public ApiResult<?> generateTripleOneTable(@RequestBody AuditContentRequest request) {
|
||||||
final User loginUser = getLoginUser();
|
final User loginUser = getLoginUser();
|
||||||
|
String kbIdTmp = "";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 生成重大经济决策调查表数据
|
// 创建临时知识库(如果需要)
|
||||||
JSONObject result = auditContentService3.generateDecisionTableData(
|
if (!request.getDocList().isEmpty() || !request.getFileList().isEmpty()) {
|
||||||
request.getKbIds(),
|
kbIdTmp = createTempKnowledgeBase(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成三重一大制度对比分析表数据
|
||||||
|
String knowledgeBaseId = StrUtil.isNotBlank(kbIdTmp) ? kbIdTmp : request.getKbIds();
|
||||||
|
JSONObject result = auditContentService3.generateTripleOneTableData(
|
||||||
|
knowledgeBaseId,
|
||||||
request.getLibraryIds(),
|
request.getLibraryIds(),
|
||||||
request.getProjectLibrary(),
|
request.getProjectLibrary(),
|
||||||
loginUser.getUsername(),
|
loginUser.getUsername(),
|
||||||
@@ -44,8 +75,55 @@ public class AuditContentController3 extends BaseController {
|
|||||||
|
|
||||||
return success(result);
|
return success(result);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return fail("生成重大经济决策调查表失败: " + e.getMessage());
|
log.error("生成三重一大制度对比分析表失败", e);
|
||||||
|
return fail("生成三重一大制度对比分析表失败: " + e.getMessage());
|
||||||
|
} finally {
|
||||||
|
cleanupTempKnowledgeBase(kbIdTmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建临时知识库并提交文档
|
||||||
|
*/
|
||||||
|
private String createTempKnowledgeBase(AuditContentRequest request) {
|
||||||
|
String kbIdTmp = knowledgeBaseService.createKnowledgeBaseTemp();
|
||||||
|
|
||||||
|
// 收集文档ID
|
||||||
|
Set<Integer> docIds = request.getDocList().stream()
|
||||||
|
.flatMap(docId -> aiCloudDocService.getSelfAndChildren(docId).stream())
|
||||||
|
.map(AiCloudDoc::getId)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
// 查询相关文件
|
||||||
|
LambdaQueryWrapper<AiCloudFile> queryWrapper = new LambdaQueryWrapper<AiCloudFile>()
|
||||||
|
.in(!docIds.isEmpty(), AiCloudFile::getDocId, docIds)
|
||||||
|
.or(!request.getFileList().isEmpty())
|
||||||
|
.in(!request.getFileList().isEmpty(), AiCloudFile::getId, request.getFileList());
|
||||||
|
|
||||||
|
List<AiCloudFile> fileList = aiCloudFileService.list(queryWrapper);
|
||||||
|
|
||||||
|
// 提取文件ID并提交到知识库
|
||||||
|
Set<String> kbFileIds = fileList.stream()
|
||||||
|
.map(AiCloudFile::getFileId)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
if (!kbFileIds.isEmpty()) {
|
||||||
|
knowledgeBaseService.submitDocuments(kbIdTmp, new ArrayList<>(kbFileIds));
|
||||||
|
}
|
||||||
|
|
||||||
|
return kbIdTmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理临时知识库
|
||||||
|
*/
|
||||||
|
private void cleanupTempKnowledgeBase(String kbId) {
|
||||||
|
if (StrUtil.isNotBlank(kbId)) {
|
||||||
|
try {
|
||||||
|
knowledgeBaseService.deleteIndex(kbId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("删除临时知识库失败: {}", kbId, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.gxwebsoft.ai.dto;
|
package com.gxwebsoft.ai.dto;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,4 +34,14 @@ public class AuditContentRequest {
|
|||||||
* 优化建议
|
* 优化建议
|
||||||
*/
|
*/
|
||||||
private String suggestion;
|
private String suggestion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 目录列表
|
||||||
|
*/
|
||||||
|
private List<Integer> docList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件列表
|
||||||
|
*/
|
||||||
|
private List<Integer> fileList;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import com.alibaba.fastjson.JSONObject;
|
|||||||
public interface AuditContentService3 {
|
public interface AuditContentService3 {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成重大经济决策调查表数据
|
* 生成三重一大制度对比分析表数据
|
||||||
*/
|
*/
|
||||||
JSONObject generateDecisionTableData(String kbIds, String libraryIds, String projectLibrary, String userName, String history, String suggestion);
|
JSONObject generateTripleOneTableData(String kbIds, String libraryIds, String projectLibrary,
|
||||||
|
String userName, String history, String suggestion);
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ package com.gxwebsoft.ai.service;
|
|||||||
|
|
||||||
import com.gxwebsoft.ai.dto.KnowledgeBaseRequest;
|
import com.gxwebsoft.ai.dto.KnowledgeBaseRequest;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@@ -24,6 +25,11 @@ public interface KnowledgeBaseService {
|
|||||||
*/
|
*/
|
||||||
String createKnowledgeBase(String companyName, String companyCode);
|
String createKnowledgeBase(String companyName, String companyCode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建临时知识库
|
||||||
|
*/
|
||||||
|
String createKnowledgeBaseTemp();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查知识库是否存
|
* 检查知识库是否存
|
||||||
*/
|
*/
|
||||||
@@ -39,6 +45,11 @@ public interface KnowledgeBaseService {
|
|||||||
*/
|
*/
|
||||||
Map<String,Object> listDocuments(String kbId, Integer pageSize, Integer pageNumber);
|
Map<String,Object> listDocuments(String kbId, Integer pageSize, Integer pageNumber);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除知识库
|
||||||
|
*/
|
||||||
|
boolean deleteIndex(String kbId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除知识库下的文档
|
* 删除知识库下的文档
|
||||||
*/
|
*/
|
||||||
@@ -53,4 +64,9 @@ public interface KnowledgeBaseService {
|
|||||||
* 知识库追加导入已解析的文档
|
* 知识库追加导入已解析的文档
|
||||||
*/
|
*/
|
||||||
void submitDocuments(String kbId, String fileId);
|
void submitDocuments(String kbId, String fileId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 知识库追加导入已解析的文档
|
||||||
|
*/
|
||||||
|
void submitDocuments(String kbId, List<String> fileIds);
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,8 @@ import com.aliyun.bailian20231229.models.RetrieveResponseBody;
|
|||||||
import com.aliyun.bailian20231229.models.RetrieveResponseBody.RetrieveResponseBodyData;
|
import com.aliyun.bailian20231229.models.RetrieveResponseBody.RetrieveResponseBodyData;
|
||||||
import com.aliyun.bailian20231229.models.RetrieveResponseBody.RetrieveResponseBodyDataNodes;
|
import com.aliyun.bailian20231229.models.RetrieveResponseBody.RetrieveResponseBodyDataNodes;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
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.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.gxwebsoft.ai.config.KnowledgeBaseConfig;
|
import com.gxwebsoft.ai.config.KnowledgeBaseConfig;
|
||||||
@@ -40,103 +42,96 @@ public class AuditContentServiceImpl3 implements AuditContentService3 {
|
|||||||
private PwlProjectLibraryService pwlProjectLibraryService;
|
private PwlProjectLibraryService pwlProjectLibraryService;
|
||||||
|
|
||||||
// 工作流配置
|
// 工作流配置
|
||||||
private static final String DECISION_TABLE_WORKFLOW_URL = "http://1.14.159.185:8180/v1/workflows/run";
|
private static final String TRIPLE_ONE_WORKFLOW_URL = "http://1.14.159.185:8180/v1/workflows/run";
|
||||||
private static final String DECISION_TABLE_TOKEN = "Bearer app-yN7Q8GEN9E7SCMkhI6HaAagW";
|
private static final String TRIPLE_ONE_TOKEN = "Bearer app-tjXbmHDE6daMbYOT4O13ev2X";
|
||||||
|
|
||||||
// 缓存
|
// 三重一大分类定义
|
||||||
private final Map<String, Set<String>> knowledgeCache = new ConcurrentHashMap<>();
|
private static final Map<String, String> TRIPLE_ONE_CATEGORIES = new LinkedHashMap<>();
|
||||||
private static final long CACHE_EXPIRE_TIME = 5 * 60 * 1000;
|
|
||||||
private final Map<String, Long> cacheTimestamps = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
// 决策程序类型
|
|
||||||
private static final Map<String, String> DECISION_PROCEDURES = new HashMap<>();
|
|
||||||
static {
|
static {
|
||||||
DECISION_PROCEDURES.put("会议决策", "通过召开专题会议进行集体决策,会议纪要完整");
|
TRIPLE_ONE_CATEGORIES.put("重大决策", "重大决策事项的定义和范围");
|
||||||
DECISION_PROCEDURES.put("会签决策", "通过会签方式进行决策,相关人员签字确认");
|
TRIPLE_ONE_CATEGORIES.put("重要人事任免", "重要人事任免事项的定义和范围");
|
||||||
DECISION_PROCEDURES.put("书面决策", "通过书面请示报告方式进行决策");
|
TRIPLE_ONE_CATEGORIES.put("重大项目安排", "重大项目安排事项的定义和范围");
|
||||||
DECISION_PROCEDURES.put("授权决策", "在授权范围内由负责人直接决策");
|
TRIPLE_ONE_CATEGORIES.put("大额度资金运作", "大额度资金运作事项的定义和范围");
|
||||||
|
TRIPLE_ONE_CATEGORIES.put("决策权力主体和程序", "决策权力主体和程序的规定");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 关键词权重
|
||||||
private static final Map<String, Integer> KEYWORD_WEIGHTS;
|
private static final Map<String, Integer> KEYWORD_WEIGHTS;
|
||||||
static {
|
static {
|
||||||
Map<String, Integer> map = new HashMap<>();
|
Map<String, Integer> map = new HashMap<>();
|
||||||
map.put("三重一大", 10);
|
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("集体决策", 8);
|
||||||
map.put("重大经济决策", 9);
|
map.put("会议纪要", 6);
|
||||||
map.put("会议纪要", 7);
|
map.put("金额标准", 6);
|
||||||
map.put("决策程序", 7);
|
|
||||||
map.put("决策标准", 6);
|
|
||||||
map.put("审计方法", 6);
|
|
||||||
map.put("重大预算", 5);
|
|
||||||
map.put("重大项目", 5);
|
|
||||||
map.put("重大采购", 5);
|
|
||||||
map.put("重大投资", 5);
|
|
||||||
KEYWORD_WEIGHTS = Collections.unmodifiableMap(map);
|
KEYWORD_WEIGHTS = Collections.unmodifiableMap(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JSONObject generateDecisionTableData(String kbIds, String libraryIds, String projectLibrary, String userName, String history, String suggestion) {
|
public JSONObject generateTripleOneTableData(String kbIds, String libraryIds, String projectLibrary,
|
||||||
log.info("开始生成重大经济决策调查表数据 - 用户: {}, kbIds: {}, libraryIds: {}, projectLibrary: {}", userName, kbIds, libraryIds, projectLibrary);
|
String userName, String history, String suggestion) {
|
||||||
|
log.info("开始生成三重一大制度对比分析表数据 - 用户: {}, kbIds: {}, libraryIds: {}, projectLibrary: {}",
|
||||||
|
userName, kbIds, libraryIds, projectLibrary);
|
||||||
|
|
||||||
JSONObject result = new JSONObject();
|
JSONObject result = new JSONObject();
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 1. 从不同知识库召回相关内容
|
// 1. 从不同知识库召回相关内容
|
||||||
Map<String, List<String>> knowledgeSources = retrieveDecisionKnowledgeSeparated(kbIds, libraryIds, projectLibrary);
|
Map<String, List<String>> knowledgeSources = retrieveTripleOneKnowledge(kbIds, libraryIds, projectLibrary);
|
||||||
|
|
||||||
// 2. 生成重大经济决策调查表数据
|
// 2. 生成三重一大制度对比分析表数据
|
||||||
JSONArray decisionTableData = generateDecisionTable(knowledgeSources, userName, history, suggestion);
|
JSONArray comparisonTableData = generateComparisonTable(knowledgeSources, userName, history, suggestion);
|
||||||
|
|
||||||
// 3. 数据质量检查
|
// 3. 数据质量检查
|
||||||
decisionTableData = validateAndEnhanceData(decisionTableData);
|
comparisonTableData = validateAndEnhanceComparisonData(comparisonTableData);
|
||||||
|
|
||||||
// 4. 构建返回结果
|
// 4. 构建返回结果
|
||||||
result.put("success", true);
|
result.put("success", true);
|
||||||
result.put("data", decisionTableData);
|
result.put("data", comparisonTableData);
|
||||||
result.put("total_records", decisionTableData.size());
|
result.put("total_records", comparisonTableData.size());
|
||||||
result.put("generated_time", new Date().toString());
|
result.put("generated_time", new Date().toString());
|
||||||
result.put("core_knowledge_count", knowledgeSources.get("core").size());
|
|
||||||
result.put("case_knowledge_count", knowledgeSources.get("case").size());
|
|
||||||
result.put("regulation_knowledge_count", knowledgeSources.get("regulation").size());
|
|
||||||
result.put("processing_time", (System.currentTimeMillis() - startTime) + "ms");
|
result.put("processing_time", (System.currentTimeMillis() - startTime) + "ms");
|
||||||
|
|
||||||
log.info("重大经济决策调查表生成成功 - 记录数: {}, 处理时间: {}ms",
|
log.info("三重一大制度对比分析表生成成功 - 记录数: {}, 处理时间: {}ms",
|
||||||
decisionTableData.size(), (System.currentTimeMillis() - startTime));
|
comparisonTableData.size(), (System.currentTimeMillis() - startTime));
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("生成重大经济决策调查表失败", e);
|
log.error("生成三重一大制度对比分析表失败", e);
|
||||||
// 直接抛出异常,不返回默认数据
|
result.put("success", false);
|
||||||
throw new RuntimeException("生成重大经济决策调查表失败: " + e.getMessage(), e);
|
result.put("error", e.getMessage());
|
||||||
|
throw new RuntimeException("生成三重一大制度对比分析表失败: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分离不同知识库的检索策略
|
* 检索三重一大相关知识
|
||||||
*/
|
*/
|
||||||
private Map<String, List<String>> retrieveDecisionKnowledgeSeparated(String kbIds, String libraryIds, String projectLibrary) {
|
private Map<String, List<String>> retrieveTripleOneKnowledge(String kbIds, String libraryIds, String projectLibrary) {
|
||||||
Map<String, List<String>> knowledgeSources = new HashMap<>();
|
Map<String, List<String>> knowledgeSources = new HashMap<>();
|
||||||
knowledgeSources.put("core", new ArrayList<>());
|
knowledgeSources.put("enterprise", new ArrayList<>()); // 企业单位库
|
||||||
knowledgeSources.put("case", new ArrayList<>());
|
knowledgeSources.put("regulation", new ArrayList<>()); // 公共法律法规库
|
||||||
knowledgeSources.put("regulation", new ArrayList<>());
|
knowledgeSources.put("auditCase", new ArrayList<>()); // 审计案例库
|
||||||
|
|
||||||
// 核心审计库 - 主要来源
|
// 企业单位库检索 - 主要来源
|
||||||
if (StrUtil.isNotBlank(kbIds)) {
|
if (StrUtil.isNotBlank(kbIds)) {
|
||||||
Arrays.stream(kbIds.split(","))
|
Arrays.stream(kbIds.split(","))
|
||||||
.map(String::trim)
|
.map(String::trim)
|
||||||
.filter(StrUtil::isNotBlank)
|
.filter(StrUtil::isNotBlank)
|
||||||
.forEach(kbId -> knowledgeSources.get("core")
|
.forEach(kbId -> knowledgeSources.get("enterprise")
|
||||||
.addAll(queryKnowledgeBaseWithCache(kbId, buildCoreQueries(), 150)));
|
.addAll(queryKnowledgeBase(kbId, buildEnterpriseQueries(), 200)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 案例库 - 辅助参考
|
// 公共法律法规库检索
|
||||||
if (StrUtil.isNotBlank(projectLibrary)) {
|
|
||||||
knowledgeSources.get("case").addAll(queryKnowledgeBaseWithCache(projectLibrary, buildCaseQueries(), 100));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 法规库 - 制度校验
|
|
||||||
if (StrUtil.isNotBlank(libraryIds)) {
|
if (StrUtil.isNotBlank(libraryIds)) {
|
||||||
List<String> idList = StrUtil.split(libraryIds, ',');
|
List<String> idList = StrUtil.split(libraryIds, ',');
|
||||||
List<PwlProjectLibrary> ret = pwlProjectLibraryService.list(
|
List<PwlProjectLibrary> ret = pwlProjectLibraryService.list(
|
||||||
@@ -147,14 +142,20 @@ public class AuditContentServiceImpl3 implements AuditContentService3 {
|
|||||||
.map(String::trim)
|
.map(String::trim)
|
||||||
.filter(StrUtil::isNotBlank)
|
.filter(StrUtil::isNotBlank)
|
||||||
.forEach(libId -> knowledgeSources.get("regulation")
|
.forEach(libId -> knowledgeSources.get("regulation")
|
||||||
.addAll(queryKnowledgeBaseWithCache(libId, buildRegulationQueries(), 80)));
|
.addAll(queryKnowledgeBase(libId, buildRegulationQueries(), 150)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分别进行智能去重和排序
|
// 审计案例库检索
|
||||||
|
if (StrUtil.isNotBlank(projectLibrary)) {
|
||||||
|
knowledgeSources.get("auditCase").addAll(
|
||||||
|
queryKnowledgeBase(projectLibrary, buildAuditCaseQueries(), 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 智能去重和排序
|
||||||
knowledgeSources.forEach((key, list) -> {
|
knowledgeSources.forEach((key, list) -> {
|
||||||
List<String> processed = list.stream()
|
List<String> processed = list.stream()
|
||||||
.distinct()
|
.distinct()
|
||||||
.sorted(this::regulationsComparator)
|
.sorted(this::tripleOneComparator)
|
||||||
.limit(getLimitBySourceType(key))
|
.limit(getLimitBySourceType(key))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
knowledgeSources.put(key, processed);
|
knowledgeSources.put(key, processed);
|
||||||
@@ -164,34 +165,37 @@ public class AuditContentServiceImpl3 implements AuditContentService3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建核心审计库查询
|
* 构建企业单位库查询
|
||||||
*/
|
*/
|
||||||
private List<String> buildCoreQueries() {
|
private List<String> buildEnterpriseQueries() {
|
||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
"三重一大 集体决策 会议纪要 决策程序",
|
"三重一大制度 集体决策规定",
|
||||||
"重大经济决策 资本性支出 费用性支出",
|
"重大决策范围 人事任免范围 项目安排范围 资金运作范围",
|
||||||
"重大项目 重大投资 重大采购"
|
"决策程序 权力主体 会议规则",
|
||||||
|
"集团制度 公司制定 内部规定"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建案例库查询
|
* 构建法律法规库查询
|
||||||
*/
|
|
||||||
private List<String> buildCaseQueries() {
|
|
||||||
return Arrays.asList(
|
|
||||||
"类似案例 参考案例 最佳实践",
|
|
||||||
"决策效果 执行结果 经验教训"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建法规库查询
|
|
||||||
*/
|
*/
|
||||||
private List<String> buildRegulationQueries() {
|
private List<String> buildRegulationQueries() {
|
||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
"三重一大制度 集体决策规定",
|
"三重一大政策 国家法律法规",
|
||||||
"重大经济决策程序 审批权限",
|
"重大决策法规 人事任免法规",
|
||||||
"审计法规 审计标准"
|
"项目安排规定 资金运作规定",
|
||||||
|
"决策程序法律要求"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建审计案例库查询
|
||||||
|
*/
|
||||||
|
private List<String> buildAuditCaseQueries() {
|
||||||
|
return Arrays.asList(
|
||||||
|
"三重一大审计案例 检查证据",
|
||||||
|
"决策程序测试 执行效果",
|
||||||
|
"工作底稿 审计测试结果"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,111 +204,94 @@ public class AuditContentServiceImpl3 implements AuditContentService3 {
|
|||||||
*/
|
*/
|
||||||
private int getLimitBySourceType(String sourceType) {
|
private int getLimitBySourceType(String sourceType) {
|
||||||
switch (sourceType) {
|
switch (sourceType) {
|
||||||
case "core": return 300;
|
case "enterprise": return 300;
|
||||||
case "case": return 150;
|
case "regulation": return 200;
|
||||||
case "regulation": return 100;
|
case "auditCase": return 150;
|
||||||
default: return 100;
|
default: return 100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 带缓存的知识库查询
|
* 生成三重一大制度对比分析表
|
||||||
*/
|
*/
|
||||||
private Set<String> queryKnowledgeBaseWithCache(String kbId, List<String> queries, int topK) {
|
private JSONArray generateComparisonTable(Map<String, List<String>> knowledgeSources, String userName, String history, String suggestion) {
|
||||||
Set<String> allResults = new LinkedHashSet<>();
|
|
||||||
|
|
||||||
queries.forEach(query -> {
|
|
||||||
String cacheKey = kbId + ":" + query;
|
|
||||||
long currentTime = System.currentTimeMillis();
|
|
||||||
|
|
||||||
if (knowledgeCache.containsKey(cacheKey) &&
|
|
||||||
cacheTimestamps.containsKey(cacheKey) &&
|
|
||||||
(currentTime - cacheTimestamps.get(cacheKey)) < CACHE_EXPIRE_TIME) {
|
|
||||||
allResults.addAll(knowledgeCache.get(cacheKey));
|
|
||||||
} else {
|
|
||||||
Set<String> results = queryKnowledgeBase(kbId, query, topK);
|
|
||||||
knowledgeCache.put(cacheKey, new LinkedHashSet<>(results));
|
|
||||||
cacheTimestamps.put(cacheKey, currentTime);
|
|
||||||
allResults.addAll(results);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return allResults;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成重大经济决策调查表
|
|
||||||
*/
|
|
||||||
private JSONArray generateDecisionTable(Map<String, List<String>> knowledgeSources,
|
|
||||||
String userName, String history, String suggestion) {
|
|
||||||
// 构建优化的知识上下文
|
// 构建优化的知识上下文
|
||||||
String knowledgeContext = buildOptimizedKnowledgeContext(knowledgeSources, history, suggestion);
|
String knowledgeContext = buildKnowledgeContext(knowledgeSources, history, suggestion);
|
||||||
|
|
||||||
JSONObject requestBody = buildDecisionTableRequest(knowledgeContext, userName);
|
JSONObject requestBody = buildWorkflowRequest(knowledgeContext, userName);
|
||||||
|
|
||||||
JSONArray rawData = callDecisionTableWorkflow(requestBody);
|
JSONArray rawData = callTripleOneWorkflow(requestBody);
|
||||||
|
|
||||||
// 后处理:数据清洗和格式化
|
// 后处理:数据清洗和格式化
|
||||||
return postProcessTableData(rawData);
|
return postProcessComparisonData(rawData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建优化的知识上下文
|
* 构建知识上下文
|
||||||
*/
|
*/
|
||||||
private String buildOptimizedKnowledgeContext(Map<String, List<String>> knowledgeSources,
|
private String buildKnowledgeContext(Map<String, List<String>> knowledgeSources, String history, String suggestion) {
|
||||||
String history, String suggestion) {
|
|
||||||
StringBuilder context = new StringBuilder();
|
StringBuilder context = new StringBuilder();
|
||||||
|
|
||||||
// 1. 核心审计要求
|
// 1. 分析要求
|
||||||
context.append("## 核心审计要求\n");
|
context.append("## 三重一大制度对比分析要求\n");
|
||||||
context.append("请基于以下审计要求生成重大经济决策调查表数据:\n\n");
|
context.append("请基于以下知识生成三重一大制度对比分析表数据:\n\n");
|
||||||
context.append("1. 检查\"三重一大\"集体决策制度建立和执行情况\n");
|
context.append("1. 对比分析政策内容、集团制度、公司制定的差异\n");
|
||||||
context.append("2. 验证重大经济事项集体决策的程序完整性\n");
|
context.append("2. 重点关注决策范围、金额标准、程序要求的差异\n");
|
||||||
context.append("3. 确认决策内容符合相关规定\n");
|
context.append("3. 识别制度执行中的风险和问题\n\n");
|
||||||
context.append("4. 评估决策执行情况和效果\n\n");
|
|
||||||
|
|
||||||
// 2. 数据格式要求
|
// 2. 数据格式要求
|
||||||
context.append("## 数据格式要求\n");
|
context.append("## 数据格式要求\n");
|
||||||
context.append("每条记录应包含:序号、事项名称、会议时间、决策金额、程序、执行情况、执行效果\n");
|
context.append("需要生成5个分类的数据,每个分类尽可能多的生成多个实例、多条记录,尽可能三重一大的五个方面都包含:\n");
|
||||||
context.append("- 程序字段:描述具体的决策程序,如:会议决策(党委会/董事会/总经理办公会)、会签决策等\n");
|
TRIPLE_ONE_CATEGORIES.forEach((category, desc) ->
|
||||||
context.append("- 决策金额:根据实际情况使用正确单位(元/万元/亿元)\n");
|
context.append("- ").append(category).append(":").append(desc).append("\n"));
|
||||||
context.append("- 执行效果需在'好、一般、差'中选择一项标记为'是'\n\n");
|
context.append("\n");
|
||||||
|
|
||||||
// 3. 历史内容(用于优化调整)
|
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)) {
|
if (StrUtil.isNotBlank(history)) {
|
||||||
context.append("## 历史生成内容\n");
|
context.append("## 历史生成内容\n");
|
||||||
context.append("以下是之前生成的内容,请基于此进行优化:\n");
|
context.append("以下是之前生成的内容,请基于此进行优化:\n");
|
||||||
context.append(history).append("\n\n");
|
context.append(history).append("\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 用户建议(用于定向优化)
|
// 4. 用户建议
|
||||||
if (StrUtil.isNotBlank(suggestion)) {
|
if (StrUtil.isNotBlank(suggestion)) {
|
||||||
context.append("## 用户优化建议\n");
|
context.append("## 用户优化建议\n");
|
||||||
context.append("请根据以下建议对生成内容进行调整:\n");
|
context.append("请根据以下建议对生成内容进行调整:\n");
|
||||||
context.append(suggestion).append("\n\n");
|
context.append(suggestion).append("\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. 核心审计知识
|
// 5. 企业单位知识
|
||||||
if (!knowledgeSources.get("core").isEmpty()) {
|
if (!knowledgeSources.get("enterprise").isEmpty()) {
|
||||||
context.append("## 核心审计知识\n");
|
context.append("## 企业单位知识\n");
|
||||||
knowledgeSources.get("core").stream()
|
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)
|
.limit(200)
|
||||||
.forEach(knowledge -> context.append("- ").append(knowledge).append("\n"));
|
.forEach(knowledge -> context.append("- ").append(knowledge).append("\n"));
|
||||||
|
context.append("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. 参考案例
|
// 7. 审计案例知识
|
||||||
if (!knowledgeSources.get("case").isEmpty()) {
|
if (!knowledgeSources.get("auditCase").isEmpty()) {
|
||||||
context.append("## 参考案例\n");
|
context.append("## 审计案例知识\n");
|
||||||
knowledgeSources.get("case").stream()
|
knowledgeSources.get("auditCase").stream()
|
||||||
.limit(100)
|
.limit(150)
|
||||||
.forEach(knowledge -> context.append("- ").append(knowledge).append("\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 7. 法规要求
|
|
||||||
if (!knowledgeSources.get("regulation").isEmpty()) {
|
|
||||||
context.append("## 法规要求\n");
|
|
||||||
knowledgeSources.get("regulation").stream()
|
|
||||||
.limit(80)
|
|
||||||
.forEach(knowledge -> context.append("- ").append(knowledge).append("\n"));
|
.forEach(knowledge -> context.append("- ").append(knowledge).append("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,9 +301,9 @@ public class AuditContentServiceImpl3 implements AuditContentService3 {
|
|||||||
/**
|
/**
|
||||||
* 数据验证和增强
|
* 数据验证和增强
|
||||||
*/
|
*/
|
||||||
private JSONArray validateAndEnhanceData(JSONArray data) {
|
private JSONArray validateAndEnhanceComparisonData(JSONArray data) {
|
||||||
if (data == null || data.isEmpty()) {
|
if (data == null || data.isEmpty()) {
|
||||||
return new JSONArray(); // 返回空数组,不提供默认数据
|
return createDefaultComparisonData();
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONArray enhancedData = new JSONArray();
|
JSONArray enhancedData = new JSONArray();
|
||||||
@@ -326,126 +313,143 @@ public class AuditContentServiceImpl3 implements AuditContentService3 {
|
|||||||
if (item == null) continue;
|
if (item == null) continue;
|
||||||
|
|
||||||
// 数据验证
|
// 数据验证
|
||||||
if (!validateDataItem(item)) {
|
if (!validateComparisonDataItem(item)) {
|
||||||
log.warn("数据验证失败,跳过记录: {}", item);
|
log.warn("数据验证失败,跳过记录: {}", item);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 数据增强
|
// 数据增强
|
||||||
enhanceDataItem(item, i);
|
enhanceComparisonDataItem(item, i);
|
||||||
enhancedData.add(item);
|
enhancedData.add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
return enhancedData;
|
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 validateDataItem(JSONObject item) {
|
private boolean validateComparisonDataItem(JSONObject item) {
|
||||||
return item.containsKey("name") &&
|
return item.containsKey("category") &&
|
||||||
item.containsKey("meetingTime") &&
|
item.containsKey("policyContent") &&
|
||||||
item.containsKey("decisionAmount") &&
|
item.containsKey("groupSystem") &&
|
||||||
item.containsKey("procedure") &&
|
item.containsKey("companyFormulation");
|
||||||
item.containsKey("executionStatus");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据项增强
|
* 数据项增强
|
||||||
*/
|
*/
|
||||||
private void enhanceDataItem(JSONObject item, int index) {
|
private void enhanceComparisonDataItem(JSONObject item, int index) {
|
||||||
// 确保序号正确
|
// 确保分类正确
|
||||||
item.put("index", String.valueOf(index + 1));
|
if (!item.containsKey("category") || StrUtil.isBlank(item.getString("category"))) {
|
||||||
|
List<String> categories = new ArrayList<>(TRIPLE_ONE_CATEGORIES.keySet());
|
||||||
// 增强程序描述
|
if (index < categories.size()) {
|
||||||
String procedure = item.getString("procedure");
|
item.put("category", categories.get(index));
|
||||||
if (StrUtil.isBlank(procedure) || procedure.length() < 10) {
|
|
||||||
item.put("procedure", generateProcedureDescription());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 增强执行效果结构
|
|
||||||
if (!item.containsKey("executionEffect")) {
|
|
||||||
JSONObject effect = new JSONObject();
|
|
||||||
effect.put("good", "否");
|
|
||||||
effect.put("normal", "是");
|
|
||||||
effect.put("bad", "否");
|
|
||||||
item.put("executionEffect", effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 标准化金额格式
|
|
||||||
String amount = item.getString("decisionAmount");
|
|
||||||
if (amount != null) {
|
|
||||||
item.put("decisionAmount", normalizeAmount(amount));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// 确保所有字段都存在
|
||||||
* 生成程序描述
|
String[] requiredFields = {"policyContent", "groupSystem", "companyFormulation",
|
||||||
*/
|
"checkEvidence", "testResult", "workPaperIndex"};
|
||||||
private String generateProcedureDescription() {
|
for (String field : requiredFields) {
|
||||||
Random random = new Random();
|
if (!item.containsKey(field) || item.get(field) == null) {
|
||||||
List<String> procedures = new ArrayList<>(DECISION_PROCEDURES.keySet());
|
if ("workPaperIndex".equals(field)) {
|
||||||
String procedureType = procedures.get(random.nextInt(procedures.size()));
|
item.put(field, Collections.singletonList("待关联工作底稿"));
|
||||||
return DECISION_PROCEDURES.get(procedureType);
|
} else if ("testResult".equals(field)) {
|
||||||
}
|
item.put(field, "待检查");
|
||||||
|
|
||||||
/**
|
|
||||||
* 标准化金额格式
|
|
||||||
*/
|
|
||||||
private String normalizeAmount(String amount) {
|
|
||||||
if (amount == null) return "0元";
|
|
||||||
|
|
||||||
// 如果已经包含单位,直接返回
|
|
||||||
if (amount.contains("万元") || amount.contains("元") || amount.contains("亿")) {
|
|
||||||
return amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 尝试解析数字
|
|
||||||
try {
|
|
||||||
String cleanAmount = amount.replaceAll("[^\\d.]", "");
|
|
||||||
if (StrUtil.isNotBlank(cleanAmount)) {
|
|
||||||
double value = Double.parseDouble(cleanAmount);
|
|
||||||
if (value >= 100000000) {
|
|
||||||
return String.format("%.2f亿元", value / 100000000);
|
|
||||||
} else if (value >= 10000) {
|
|
||||||
return String.format("%.2f万元", value / 10000);
|
|
||||||
} else {
|
} else {
|
||||||
return String.format("%.0f元", value);
|
item.put(field, "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
log.debug("金额解析失败: {}", amount);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return amount + "元";
|
private JSONArray postProcessComparisonData(JSONArray rawData) {
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 后处理表格数据
|
|
||||||
*/
|
|
||||||
private JSONArray postProcessTableData(JSONArray rawData) {
|
|
||||||
if (rawData == null || rawData.isEmpty()) {
|
if (rawData == null || rawData.isEmpty()) {
|
||||||
return new JSONArray();
|
return createDefaultComparisonData();
|
||||||
}
|
}
|
||||||
|
|
||||||
return rawData; // 简化处理,直接返回原始数据
|
// 使用列表来存储所有条目,避免覆盖
|
||||||
|
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 regulationsComparator(String reg1, String reg2) {
|
private int tripleOneComparator(String reg1, String reg2) {
|
||||||
int score1 = calculateRelevanceScore(reg1);
|
int score1 = calculateTripleOneRelevanceScore(reg1);
|
||||||
int score2 = calculateRelevanceScore(reg2);
|
int score2 = calculateTripleOneRelevanceScore(reg2);
|
||||||
return Integer.compare(score2, score1);
|
return Integer.compare(score2, score1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算相关性分数
|
* 计算三重一大相关性分数
|
||||||
*/
|
*/
|
||||||
private int calculateRelevanceScore(String regulation) {
|
private int calculateTripleOneRelevanceScore(String content) {
|
||||||
return KEYWORD_WEIGHTS.entrySet().stream()
|
return KEYWORD_WEIGHTS.entrySet().stream()
|
||||||
.filter(entry -> regulation.contains(entry.getKey()))
|
.filter(entry -> content.contains(entry.getKey()))
|
||||||
.mapToInt(Map.Entry::getValue)
|
.mapToInt(Map.Entry::getValue)
|
||||||
.sum();
|
.sum();
|
||||||
}
|
}
|
||||||
@@ -453,12 +457,14 @@ public class AuditContentServiceImpl3 implements AuditContentService3 {
|
|||||||
/**
|
/**
|
||||||
* 查询知识库
|
* 查询知识库
|
||||||
*/
|
*/
|
||||||
private Set<String> queryKnowledgeBase(String kbId, String query, int topK) {
|
private List<String> queryKnowledgeBase(String kbId, List<String> queries, int topK) {
|
||||||
Set<String> results = new LinkedHashSet<>();
|
Set<String> results = new LinkedHashSet<>();
|
||||||
String workspaceId = config.getWorkspaceId();
|
String workspaceId = config.getWorkspaceId();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Client client = clientFactory.createClient();
|
Client client = clientFactory.createClient();
|
||||||
|
|
||||||
|
for (String query : queries) {
|
||||||
RetrieveResponse resp = KnowledgeBaseUtil.retrieveIndex(client, workspaceId, kbId, query);
|
RetrieveResponse resp = KnowledgeBaseUtil.retrieveIndex(client, workspaceId, kbId, query);
|
||||||
|
|
||||||
Optional.ofNullable(resp)
|
Optional.ofNullable(resp)
|
||||||
@@ -469,12 +475,13 @@ public class AuditContentServiceImpl3 implements AuditContentService3 {
|
|||||||
.stream()
|
.stream()
|
||||||
.limit(topK)
|
.limit(topK)
|
||||||
.forEach(node -> processNode(node, results));
|
.forEach(node -> processNode(node, results));
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("查询知识库失败 - kbId: {}, query: {}", kbId, query, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
} catch (Exception e) {
|
||||||
|
log.error("查询知识库失败 - kbId: {}, queries: {}", kbId, queries, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ArrayList<>(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -514,35 +521,39 @@ public class AuditContentServiceImpl3 implements AuditContentService3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 调用决策表生成工作流
|
* 调用三重一大工作流
|
||||||
*/
|
*/
|
||||||
private JSONArray callDecisionTableWorkflow(JSONObject requestBody) {
|
private JSONArray callTripleOneWorkflow(JSONObject requestBody) {
|
||||||
try {
|
try {
|
||||||
String result = HttpUtil.createPost(DECISION_TABLE_WORKFLOW_URL)
|
String result = HttpUtil.createPost(TRIPLE_ONE_WORKFLOW_URL)
|
||||||
.header("Authorization", DECISION_TABLE_TOKEN)
|
.header("Authorization", TRIPLE_ONE_TOKEN)
|
||||||
.header("Content-Type", "application/json")
|
.header("Content-Type", "application/json")
|
||||||
.body(requestBody.toString())
|
.body(requestBody.toString())
|
||||||
.timeout(120000)
|
.timeout(5*60*1000)
|
||||||
.execute()
|
.execute()
|
||||||
.body();
|
.body();
|
||||||
|
|
||||||
JSONObject jsonResponse = JSONObject.parseObject(result);
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
String outputText = jsonResponse.getJSONObject("data")
|
JsonNode rootNode = objectMapper.readTree(result);
|
||||||
.getJSONObject("outputs")
|
String outputText = rootNode.path("data")
|
||||||
.getString("result");
|
.path("outputs")
|
||||||
|
.path("result")
|
||||||
|
.asText();
|
||||||
|
|
||||||
return JSONArray.parseArray(outputText);
|
// 使用Jackson解析数组
|
||||||
|
JsonNode arrayNode = objectMapper.readTree(outputText);
|
||||||
|
return JSONArray.parseArray(arrayNode.toString());
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("调用决策表生成工作流失败", e);
|
log.error("调用三重一大工作流失败", e);
|
||||||
throw new RuntimeException("调用决策表生成工作流失败: " + e.getMessage(), e);
|
throw new RuntimeException("调用三重一大工作流失败: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建决策表生成请求
|
* 构建工作流请求
|
||||||
*/
|
*/
|
||||||
private JSONObject buildDecisionTableRequest(String knowledge, String userName) {
|
private JSONObject buildWorkflowRequest(String knowledge, String userName) {
|
||||||
JSONObject requestBody = new JSONObject();
|
JSONObject requestBody = new JSONObject();
|
||||||
JSONObject inputs = new JSONObject();
|
JSONObject inputs = new JSONObject();
|
||||||
|
|
||||||
@@ -554,15 +565,4 @@ public class AuditContentServiceImpl3 implements AuditContentService3 {
|
|||||||
|
|
||||||
return requestBody;
|
return requestBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 清理缓存
|
|
||||||
*/
|
|
||||||
public void clearExpiredCache() {
|
|
||||||
long currentTime = System.currentTimeMillis();
|
|
||||||
cacheTimestamps.entrySet().removeIf(entry ->
|
|
||||||
(currentTime - entry.getValue()) >= CACHE_EXPIRE_TIME
|
|
||||||
);
|
|
||||||
knowledgeCache.keySet().removeIf(key -> !cacheTimestamps.containsKey(key));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@ package com.gxwebsoft.ai.service.impl;
|
|||||||
import com.aliyun.bailian20231229.Client;
|
import com.aliyun.bailian20231229.Client;
|
||||||
import com.aliyun.bailian20231229.models.CreateIndexResponse;
|
import com.aliyun.bailian20231229.models.CreateIndexResponse;
|
||||||
import com.aliyun.bailian20231229.models.DeleteIndexDocumentResponse;
|
import com.aliyun.bailian20231229.models.DeleteIndexDocumentResponse;
|
||||||
|
import com.aliyun.bailian20231229.models.DeleteIndexResponse;
|
||||||
import com.aliyun.bailian20231229.models.ListIndexDocumentsResponse;
|
import com.aliyun.bailian20231229.models.ListIndexDocumentsResponse;
|
||||||
import com.aliyun.bailian20231229.models.ListIndicesResponse;
|
import com.aliyun.bailian20231229.models.ListIndicesResponse;
|
||||||
import com.aliyun.bailian20231229.models.RetrieveResponse;
|
import com.aliyun.bailian20231229.models.RetrieveResponse;
|
||||||
@@ -21,6 +22,8 @@ import org.springframework.scheduling.annotation.Async;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
@@ -83,6 +86,12 @@ public class KnowledgeBaseServiceImpl implements KnowledgeBaseService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String createKnowledgeBaseTemp() {
|
||||||
|
String code = "Temp_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("MMddHHmmssSSS"));
|
||||||
|
return createKnowledgeBase(code, code);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean existsKnowledgeBase(String companyCode) {
|
public boolean existsKnowledgeBase(String companyCode) {
|
||||||
String workspaceId = config.getWorkspaceId();
|
String workspaceId = config.getWorkspaceId();
|
||||||
@@ -129,6 +138,18 @@ public class KnowledgeBaseServiceImpl implements KnowledgeBaseService {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteIndex(String kbId) {
|
||||||
|
String workspaceId = config.getWorkspaceId();
|
||||||
|
try {
|
||||||
|
Client client = clientFactory.createClient();
|
||||||
|
DeleteIndexResponse indexDocumentResponse = KnowledgeBaseUtil.deleteIndex(client, workspaceId, kbId);
|
||||||
|
return indexDocumentResponse.getBody().getSuccess();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("删除知识库失败: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean deleteIndexDocument(String kbId, String fileIds) {
|
public boolean deleteIndexDocument(String kbId, String fileIds) {
|
||||||
String workspaceId = config.getWorkspaceId();
|
String workspaceId = config.getWorkspaceId();
|
||||||
@@ -171,5 +192,16 @@ public class KnowledgeBaseServiceImpl implements KnowledgeBaseService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void submitDocuments(String kbId, List<String> fileIds) {
|
||||||
|
String workspaceId = config.getWorkspaceId();
|
||||||
|
try {
|
||||||
|
Client client = clientFactory.createClient();
|
||||||
|
AiCloudKnowledgeBaseUtil.submitIndexAddDocumentsJob(client, workspaceId, kbId, fileIds);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("添加文档到知识库失败: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -156,4 +156,24 @@ public class AiCloudKnowledgeBaseUtil {
|
|||||||
RuntimeOptions runtime = new RuntimeOptions();
|
RuntimeOptions runtime = new RuntimeOptions();
|
||||||
return client.submitIndexAddDocumentsJobWithOptions(workspaceId, submitIndexAddDocumentsJobRequest, headers, runtime);
|
return client.submitIndexAddDocumentsJobWithOptions(workspaceId, submitIndexAddDocumentsJobRequest, headers, runtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向一个非结构化知识库追加导入已解析的文档
|
||||||
|
*
|
||||||
|
* @param client 客户端(Client)
|
||||||
|
* @param workspaceId 业务空间ID
|
||||||
|
* @param indexId 知识库ID
|
||||||
|
* @param fileId 文档ID
|
||||||
|
* @param sourceType 数据类型
|
||||||
|
* @return 阿里云百炼服务的响应
|
||||||
|
*/
|
||||||
|
public static SubmitIndexAddDocumentsJobResponse submitIndexAddDocumentsJob(com.aliyun.bailian20231229.Client client, String workspaceId, String indexId, List<String> fileIds) throws Exception {
|
||||||
|
Map<String, String> headers = new HashMap<>();
|
||||||
|
SubmitIndexAddDocumentsJobRequest submitIndexAddDocumentsJobRequest = new SubmitIndexAddDocumentsJobRequest();
|
||||||
|
submitIndexAddDocumentsJobRequest.setIndexId(indexId);
|
||||||
|
submitIndexAddDocumentsJobRequest.setDocumentIds(fileIds);
|
||||||
|
submitIndexAddDocumentsJobRequest.setSourceType("DATA_CENTER_FILE");
|
||||||
|
RuntimeOptions runtime = new RuntimeOptions();
|
||||||
|
return client.submitIndexAddDocumentsJobWithOptions(workspaceId, submitIndexAddDocumentsJobRequest, headers, runtime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,9 @@ public class PwlProject implements Serializable {
|
|||||||
@TableId(value = "id", type = IdType.AUTO)
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
private Integer id;
|
private Integer id;
|
||||||
|
|
||||||
|
@Schema(description = "公司id")
|
||||||
|
private Integer companyId;
|
||||||
|
|
||||||
@Schema(description = "项目名称")
|
@Schema(description = "项目名称")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,9 @@
|
|||||||
<if test="param.id != null">
|
<if test="param.id != null">
|
||||||
AND a.id = #{param.id}
|
AND a.id = #{param.id}
|
||||||
</if>
|
</if>
|
||||||
|
<if test="param.companyId != null">
|
||||||
|
AND a.company_id = #{param.companyId}
|
||||||
|
</if>
|
||||||
<if test="param.name != null">
|
<if test="param.name != null">
|
||||||
AND a.name LIKE CONCAT('%', #{param.name}, '%')
|
AND a.name LIKE CONCAT('%', #{param.name}, '%')
|
||||||
</if>
|
</if>
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ public class PwlProjectParam extends BaseParam {
|
|||||||
@QueryField(type = QueryType.EQ)
|
@QueryField(type = QueryType.EQ)
|
||||||
private Integer id;
|
private Integer id;
|
||||||
|
|
||||||
|
@Schema(description = "公司id")
|
||||||
|
private Integer companyId;
|
||||||
|
|
||||||
@Schema(description = "项目名称")
|
@Schema(description = "项目名称")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user