diff --git a/src/main/java/com/gxwebsoft/ai/controller/AiCloudDocController.java b/src/main/java/com/gxwebsoft/ai/controller/AiCloudDocController.java index f243e09..6d114d0 100644 --- a/src/main/java/com/gxwebsoft/ai/controller/AiCloudDocController.java +++ b/src/main/java/com/gxwebsoft/ai/controller/AiCloudDocController.java @@ -2,10 +2,12 @@ package com.gxwebsoft.ai.controller; import com.gxwebsoft.common.core.web.BaseController; import com.gxwebsoft.ai.service.AiCloudDocService; +import com.gxwebsoft.ai.service.AiCloudFileService; import cn.hutool.core.util.StrUtil; import com.gxwebsoft.ai.entity.AiCloudDoc; +import com.gxwebsoft.ai.entity.AiCloudFile; import com.gxwebsoft.ai.param.AiCloudDocParam; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.gxwebsoft.common.core.web.ApiResult; @@ -34,6 +36,8 @@ import java.util.List; public class AiCloudDocController extends BaseController { @Resource private AiCloudDocService aiCloudDocService; + @Resource + private AiCloudFileService aiCloudFileService; //@PreAuthorize("hasAuthority('ai:aiCloudDoc:list')") @Operation(summary = "分页查询AI云文档目录表") @@ -102,6 +106,9 @@ public class AiCloudDocController extends BaseController { @Operation(summary = "删除AI云文档目录表") @DeleteMapping("/{id}") public ApiResult remove(@PathVariable("id") Integer id) { + if(aiCloudFileService.count(new LambdaQueryWrapper().eq(AiCloudFile::getDocId, id))>0) { + return fail("删除失败,当前目录下存在文件"); + } if (aiCloudDocService.removeById(id)) { return success("删除成功"); } diff --git a/src/main/java/com/gxwebsoft/ai/controller/AiCloudFileController.java b/src/main/java/com/gxwebsoft/ai/controller/AiCloudFileController.java index 3df59c0..8197e4d 100644 --- a/src/main/java/com/gxwebsoft/ai/controller/AiCloudFileController.java +++ b/src/main/java/com/gxwebsoft/ai/controller/AiCloudFileController.java @@ -138,6 +138,10 @@ public class AiCloudFileController extends BaseController { if (files == null || files.length == 0) { return fail("请选择要上传的文件"); } + + if (files.length > 10) { + return fail("一次最多只能上传10个文件"); + } User loginUser = getLoginUser(); diff --git a/src/main/java/com/gxwebsoft/ai/service/impl/AiCloudFileServiceImpl.java b/src/main/java/com/gxwebsoft/ai/service/impl/AiCloudFileServiceImpl.java index b1fc80f..0ae1881 100644 --- a/src/main/java/com/gxwebsoft/ai/service/impl/AiCloudFileServiceImpl.java +++ b/src/main/java/com/gxwebsoft/ai/service/impl/AiCloudFileServiceImpl.java @@ -28,6 +28,7 @@ import com.gxwebsoft.oa.service.OaCompanyService; import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.Arrays; +import java.util.Comparator; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -66,6 +67,8 @@ public class AiCloudFileServiceImpl extends ServiceImpl listRel(AiCloudFileParam param) { List list = baseMapper.selectListRel(param); + //文件名排序 + list.sort(Comparator.comparing(AiCloudFile::getFileName)); // 排序 PageParam page = new PageParam<>(); page.setDefaultOrder("sort_number asc, upload_time desc"); diff --git a/src/main/java/com/gxwebsoft/ai/service/impl/AuditContent3TripleServiceImpl.java b/src/main/java/com/gxwebsoft/ai/service/impl/AuditContent3TripleServiceImpl.java index 5fae849..5d8ad51 100644 --- a/src/main/java/com/gxwebsoft/ai/service/impl/AuditContent3TripleServiceImpl.java +++ b/src/main/java/com/gxwebsoft/ai/service/impl/AuditContent3TripleServiceImpl.java @@ -22,9 +22,11 @@ import cn.hutool.http.HttpUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.util.*; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -45,7 +47,11 @@ public class AuditContent3TripleServiceImpl implements AuditContent3TripleServic 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 List CATEGORY_ORDER = Arrays.asList( + "重大决策", "重要人事任免", "重大项目安排", "大额度资金运作", "决策权力主体和程序" + ); + private static final Map TRIPLE_ONE_CATEGORIES = new LinkedHashMap<>(); static { TRIPLE_ONE_CATEGORIES.put("重大决策", "重大决策事项的定义和范围"); @@ -55,6 +61,45 @@ public class AuditContent3TripleServiceImpl implements AuditContent3TripleServic TRIPLE_ONE_CATEGORIES.put("决策权力主体和程序", "决策权力主体和程序的规定"); } + // Excel数据映射 - 从提供的Excel中提取 + private static final Map EXCEL_DATA_MAP = new HashMap<>(); + static { + // 重大决策 + EXCEL_DATA_MAP.put("重大决策", new String[]{ + "1.重大决策事项:是指依照《中华人民共和国公司法》、《中华人民共和国全民所有制工业企业法》、《中华人民共和国企业国有资产法》、《中华人民共和国商业银行法》、《中华人民共和国证券法》、《中华人民共和国保险法》以及其他有关法律法规和党内法规规定的应当由股东大会(股东会)、董事会、未设董事会的经理班子、职工代表大会和党委(党组)决定的事项。主要包括企业贯彻执行党和国家的路线方针政策、法律法规和上级重要决定的重大措施,企业发展战略、破产、改制、兼并重组、资产调整、产权转让、对外投资、利益调配、机构调整等方面的重大决策,企业党的建设和安全稳定的重大决策,以及其他重大决策事项。", + "第四条重大决策的范围(一)集团公司贯彻执行国家法律法规,自治区战略部署及重要决策,以及上级主管部门重要决定等的重大举措;(二)集团公司章程制订和重要修订;集团公司重大基本管理制度,包括“三重一大”决策、投资、担保、资产交易、收入分配、人事、财务理,授权管理以及责任追究等重大管理制度的制订和重大修订;(三)集团公司生产经营方针、发展战略和中长期发展规划,以及重大投融资规划;(四)集团公司及重要子企业主业确定及变更;集团公司投资设立各类二级企业方案;集团公司及二级子公司发生分立、合并、重组,破产、解散及产权变更、增减资本方案;集团公司及所属子公司改制、股份制改造、混合所有制改革等方案;(五)集团公司重大财务管理事项,包括年度财务预算、年度财务决算、利润分配方案、亏损弥补方案;(六)集团公司内部收入分配事项,包括年度工资总额方案、职工工资、奖金、分流安置、劳动保护和劳动保险等事关职工切身利益的重大事项;集团公司所属部门、二级企业负责人年度考核结果及年度薪酬兑现方案;(七)集团公司制订或实施股权激励和员工持股计划;(八)集团公司及所属企业国有股权比例由控股变为非控股或国有股权由参股变为控股的事项;(九)集团公司及所属企业单笔金额为300万元及以上对外重大担保事项,集团公司及所属企业重大关联交易事项、内部借款单笔金额为2000万元及以上事项;(十)集团公司及所属企业产权(资产)对外非公开协议转让、无偿划转及公开进场转让单笔金额为300万元及以上的事项;集团公司内部重组整合进行的产权(资产)非公开协议转让、无偿划转单笔金额为300万元及以上的事项;(十一)集团公司及所属企业重大资产损失、大额不良资产、核销单笔金额为20万元及以上的事项;集团公司及所属企业单笔放弃金额为30万元及以上的重大权益事项;(十二)集团公司内部机构改革方案,内部管理机构设立和调整方案,内部定岗、定编,定员、定责方案;(十三)集团公司党建群团工作的重大事项、方案;(十四)集团公司董事会年度工作报告、经理层年度工作报告、年度依法治企工作报告,年度内部控制体系工作报告等重要报告;(十五)集团公司应对重大法律纠纷、安全稳定,重大突发事件的重大措施及方案;(十六)法律法规和企业章程规定的事项,以及集团公司认为需要集体决策的关系到企业全局性、方向性、战略性的其他重大事项。", + "(一)贯彻执行国家法律法规、自治区战略部署及集团公司的重要决策,以及上级主管部门重要决定等的重大举措;(二)章程制订和重要修订;重大基本管理制度,包括“三重一大”决策、投资、担保、资产交易、收入分配、人事、财务管理、授权管理以及责任追究等重大管理制度的制订和重大修订;(三)生产经营方针、发展战略和中长期发展规划,以及重大投融资规划;(四)公司主业确定及变更;投资设立各类企业方案;发生分立、合并、重组、破产、解散及产权变更、增减资本方案;公司及所属企业改制、股份制改造、混合所有制改革等方案;(五)重大财务管理事项,包括年度财务预算、年度财务决算、利润分配方案、亏损弥补方案;(六)内部收入分配事项,包括年度工资总额方案、职工工资、奖金、分流安置、劳动保护和劳动保险等事关职工切身利益的重大事项;所属部门年度考核结果及年度薪酬兑现方案;(七)制订或实施股权激励和员工持股计划;(八)公司国有股权比例由控股变为非控股或国有股权由参股变为控股的事项;(九)公司对外担保事项,公司重大关联交易事项和内部借款单笔100万元及以上的事项;(十)公司产权(资产)对外非公开协议转让、无偿划转及公开进场转让;公司内部重组整合进行的产权(资产)非公开协议转让、无偿划转的事项;(十一)公司重大资产损失、大额不良资产核销单笔金额为1万元及以上的事项;公司单笔放弃1万元及以上的重大权益事项;(十二)公司内部机构改革方案,内部管理机构设立和调整方案,内部定岗、定编、定员、定责方案;(十三)公司党建群团工作的重大事项、方案;(十四)公司年度工作报告、经理层年度工作报告、年度依法治企工作报告、年度内部控制体系工作报告等重要报告;(十五)公司应对重大法律纠纷、安全稳定、重大突发事件的措施及方案;(十六)法律法规和企业章程规定的事项,以及公司认为需要集体决策的关系到企业全局性、方向性、战略性的其他重大事项。" + }); + + // 重要人事任免 + EXCEL_DATA_MAP.put("重要人事任免", new String[]{ + "2.重要人事任免事项:是指企业直接管理的领导人员以及其他经营管理人员的职务调整事项。主要包括企业中层以上经营管理人员和下属企业、单位领导班子成员的任免、聘用、解除聘用和后备人选的确定,向控股和参股企业委派股东代表,推荐董事会、监事会成员和经理、财务负责人,以及其他重要人事任免事项。", + "第五条重要人事任免的范围(一)对集团公司中层管理人员、二级子公司领导班子成员的任免或聘用、解聘;相当于集团公司中层副职及以上的职业经理人的选聘、解聘;(二)按照企业章程约定,委派、提名、推荐集团公司非全资二级企业董事会、监事会成员和高级经营管理人员;(三)提名或委派集团公司三级企业董事长或执行董事、总经理人选;(四)集团公司中层管理人员后备人选;(五)涉及集团公司总部中层管理人员以及二级子公司班子成员的重要奖惩,对违犯党纪政纪干部职工的处理;(六)重大人事变动及其他人事管理的重要事项。", + "(一)对公司中层管理人员(包括重大项目负责人)的任免或聘用、解除聘用和后备人选的推荐、确定;(二)委派、提名、推荐董事、监事和经理层、财务负责人;(三)干部员工的奖惩;(四)重大人事变动及其他人事管理的重要事项。" + }); + + // 重大项目安排 + EXCEL_DATA_MAP.put("重大项目安排", new String[]{ + "3、重大项目安排事项:是指对企业资产规模、资本结构、盈利能力以及生产装备、技术状况等产生重要影响的项目的设立和安排。主要包括年度投资计划,融资、担保项目,期权、期货等金融衍生业务,重要设备和技术引进,采购大宗物资和购买服务,重大工程建设项目,以及其他重大项目安排事项。", + "(一)集团公司年度投资计划方案;(二)集团公司年度融资计划方案;(三)集团公司及所属企业总投资额为3000万元及以上的投资项目(投资项目范围按集团公司投资管理办法明确的投资项目范围) ;(四)应当向自治区国资委报告的重大投资管理事项;(五)其他需要集体研究决定的重要项目安排事项。", + "(一)企业年度投资计划和投资方案;(二)企业年度融资计划和融资方案,包括银行借贷、上市、发行债券等;(三)企业50万元及以上的投资项目以及非主业投资项目;(四)企业的重大技术改造方案、重要技术设备引进项目;(五)重大、关键性的设备引进和重要物资设备购置等重大招投标管理项目;(六)应当向自治区国资委或广西旅游发展集团有限公司(以下简称“集团公司”)报告的重大投资管理事项;(七)其他需要集体研究决定的重要项目安排事项。" + }); + + // 大额度资金运作 + EXCEL_DATA_MAP.put("大额度资金运作", new String[]{ + "4.大额度资金运作事项:是指超过由企业或者履行国有资产出资人职责的机构所规定的企业领导人员有权调动、使用的资金限额的资金调动和使用。主要包括年度预算内大额度资金调动和使用,超预算的资金调动和使用,对外大额捐赠、赞助,以及其他大额度资金运作事项。", + "(一)除重大决策事项、重大项目安排事项外,涉及单笔7000万元及以上的年度预算内大额度资金使用事项;(二)除重大决策事项、重大项目安排事项外,涉及单笔5000万元及以上的预算外大额度经营性资金的使用事项;(三)预算外非经营性单笔100万元及以上、广西美术馆艺术品收藏单件或单次收藏一批100万元及以上的大额资金使用事项;(四)集团公司及所属企业10万元及以上的对外捐赠、财务资助、公益慈善及用于脱贫攻坚(乡村振兴)等涉及企业政治责任和社会责任方面的重要事项;(五)公司单份工程签证涉及工程造价变更金额为500万元及以上的项目资金支出和其他大额度资金运作事项。", + "(一)除重大决策事项、重大项目安排事项外,涉及单笔500万元及以上的年度预算内大额度资金调动和使用;(二)除重大决策事项、重大项目安排事项外,涉及单笔50万元及以上的预算外大额度资金调动和使用;(三)除重大决策事项、重大项目安排事项外,涉及单笔10万元及以上的非生产性支出;(四)单份工程签证及造价变更额度为10万元及以上的;(五)企业对外捐赠、赞助在1万元及以上的事项;(六)其他大额度资金运作事项。" + }); + + // 决策权力主体和程序 + EXCEL_DATA_MAP.put("决策权力主体和程序", new String[]{ + "", + "第十一条 凡属“三重一大”事项,应按规定程序决策,除遇重大突发事件和紧急情况外,应由领导班子以党委会、董事会或经理层会议形式集体讨论决定,不得以传阅会签或个别征求意见等方式代替集体决策。第十二条 集团公司决策主体权力运行必须坚持落实党组织的法定地位,规范党组织参与“三重一大”决策程序,确保党组织的领导核心和政治核心作用有效发挥。要坚持把党委研究讨论作为董事会、经理层决策重大问题的前置程序,在集团公司董事会决策前,对涉及企业改革发展稳定,重大经营管理和职工切身利益的“三重一大”事项决策事项,集团公司党委应当组织有关人员对决策事项进行调研和论证,提出意见建议,充分体现党组织对决策的定向把关作用,确保决策的合法性科学性、准确性。在董事会决策中,进入董事会的党委班子成员要按照党委的决定在董事会上充分发表意见,保证党委的意图在决策中得到体现。在董事会决策后,党委要建立“三重一大”决策事项跟踪问效制度、定期汇报制度、事后考核制度等,确保党的决策部署在企业贯彻好、执行好、落实好。第十三条 集团公司党委会、董事会,经理层对“三重一大”事项进行决策的具体程序和议题准备、表决、记录等事项严格按照集团公司党委会议事规则、董事会议事规则、总经理办公会议事规则规定的程序和要求执行。第十四条 集团公司研究决定企业改制及经营管理方面的重大问题、涉及职工切身利益的重大事项、制定重要的规章制度,应当听取企业工会的意见,并通过职工代表大会或者其他形式听取职工群众的意见和建议。按照国家有关规定须经职工代表大会或者职工大会审议通过的事项,履行相关程序后董事会或经理层方可批准或者作出决议。涉及重大决策、重大项目、大额度资金的使用,有合同意向的,应将合同的主要条款提交会议讨论。第十五条 “三重一大”事项经集体决策后,企业领导人员应当按照分工和职责组织实施。遇有分工和职责交叉的,应明确牵头落实人员。个人对集体决策有不同意见的,可以保留,但在作出新的决策前,应无条件执行。同时,可按组织程序向上级组织反映意见。第十六条 企业“三重一大”事项经集体决策后,应及时向自治区国资委报告有关决策情况。特别是属于重大报告事项的应按要求及时上报自治区国资委备案。自治区人民政府、自治区国资委另有规定需要报审、报批和备案的,按规定程序办理。", + "第十一条 凡属“三重一大”事项,党支部委员会成员应参加党支部委员会议对议题进行前置研究审议,保证党组织的意图在决策中得到体现。不得以传阅会签或个别征求意见等方式代替集体决策。第十二条 公司决策主体权力运行必须坚持落实党组织的法定地位,规范党组织参与“三重一大”决策程序,确保党组织的领导核心和政治核心作用有效发挥。要坚持把党支部研究讨论作为总经理办公会决策重大问题的前置程序。在总经理办公会会议决策前,对涉及企业改革发展稳定、重大经营管理和职工切身利益的“三重一大”事项决策事项,党支部应当组织有关人员对决策事项进行调研和论证,提出意见建议,充分体现党支部对决策的定向把关作用,确保决策的合法性、科学性、准确性。在总经理办公会的决策中,担任执行董事的党支部领导班子成员要按照党支部的决定在总经理办公会上充分发表意见,保证党支部的意图在决策中得到体现。在总经理办公会决策后,党支部要建立“三重一大”决策事项跟踪问效制度、定期汇报制度、事后考核制度等,确保党的决策部署在企业贯彻好、执行好、落实好。第十三条 公司党支部、经理层对“三重一大”事项进行决策的具体程序和议题准备、表决、记录等事项严格按照公司相关议事规则规定的程序和要求执行。第十四条 公司研究决定企业改制及经营管理方面的重大问题、涉及职工切身利益的重大事项、制定重要的规章制度,应当听取企业工会的意见,并通过职工代表大会或者其他形式听取职工群众的意见和建议。按照国家有关规定须经职工代表大会或者职工大会审议通过的事项,履行相关程序后经理层方可批准或者作出决议。涉及重大决策、重大项目、大额度资金的使用,有合同意向的,应将合同的主要条款提交会议讨论。第十五条 “三重一大”事项经集体决策后,企业领导人员应当按照分工和职责组织实施。遇有分工和职责交叉的,应明确牵头落实人员。个人对集体决策有不同意见的,可以保留,但在作出新的决策前,应无条件执行。同时,可按组织程序向上级组织反映意见。" + }); + } + // 关键词权重 private static final Map KEYWORD_WEIGHTS; static { @@ -84,24 +129,44 @@ public class AuditContent3TripleServiceImpl implements AuditContent3TripleServic long startTime = System.currentTimeMillis(); try { - // 1. 从不同知识库召回相关内容 - Map> knowledgeSources = retrieveTripleOneKnowledge(kbIds, libraryIds, projectLibrary); + // 1. 异步并行处理每个分类 - 按照指定顺序 + Map> futures = new LinkedHashMap<>(); - // 2. 生成三重一大制度对比分析表数据 - JSONArray comparisonTableData = generateComparisonTable(knowledgeSources, userName, history, suggestion); + for (String category : CATEGORY_ORDER) { + CompletableFuture future = generateCategoryDataAsync( + category, kbIds, libraryIds, projectLibrary, userName, history, suggestion + ); + futures.put(category, future); + } - // 3. 数据质量检查 - comparisonTableData = validateAndEnhanceComparisonData(comparisonTableData); + // 2. 等待所有异步任务完成 + CompletableFuture.allOf(futures.values().toArray(new CompletableFuture[0])).join(); - // 4. 构建返回结果 + // 3. 合并所有分类的结果 - 按照指定顺序 + JSONArray allData = new JSONArray(); + for (String category : CATEGORY_ORDER) { + try { + JSONArray categoryData = futures.get(category).get(); + if (categoryData != null && !categoryData.isEmpty()) { + allData.addAll(categoryData); + } + } catch (Exception e) { + log.error("获取分类 {} 数据失败", category, e); + } + } + + // 4. 数据质量检查 + allData = validateAndEnhanceComparisonData(allData); + + // 5. 构建返回结果 result.put("success", true); - result.put("data", comparisonTableData); - result.put("total_records", comparisonTableData.size()); + result.put("data", allData); + result.put("total_records", allData.size()); result.put("generated_time", new Date().toString()); result.put("processing_time", (System.currentTimeMillis() - startTime) + "ms"); log.info("三重一大制度对比分析表生成成功 - 记录数: {}, 处理时间: {}ms", - comparisonTableData.size(), (System.currentTimeMillis() - startTime)); + allData.size(), (System.currentTimeMillis() - startTime)); } catch (Exception e) { log.error("生成三重一大制度对比分析表失败", e); @@ -114,21 +179,57 @@ public class AuditContent3TripleServiceImpl implements AuditContent3TripleServic } /** - * 检索三重一大相关知识 + * 异步生成单个分类的数据 */ - private Map> retrieveTripleOneKnowledge(String kbIds, String libraryIds, String projectLibrary) { + @Async + public CompletableFuture generateCategoryDataAsync(String category, String kbIds, String libraryIds, + String projectLibrary, String userName, + String history, String suggestion) { + return CompletableFuture.supplyAsync(() -> { + try { + log.info("开始生成分类 {} 的数据", category); + + // 1. 为当前分类召回相关知识 + Map> knowledgeSources = retrieveKnowledgeForCategory( + category, kbIds, libraryIds, projectLibrary + ); + + // 2. 生成当前分类的数据 + JSONArray categoryData = generateCategoryTable( + category, knowledgeSources, userName, history, suggestion + ); + + log.info("分类 {} 数据生成完成,生成 {} 条记录", category, categoryData.size()); + return categoryData; + + } catch (Exception e) { + log.error("生成分类 {} 数据失败", category, e); + // 返回空数组而不是抛出异常,避免影响其他分类 + return new JSONArray(); + } + }); + } + + /** + * 为单个分类检索相关知识 + */ + private Map> retrieveKnowledgeForCategory(String category, String kbIds, + String libraryIds, String projectLibrary) { Map> knowledgeSources = new HashMap<>(); - knowledgeSources.put("enterprise", new ArrayList<>()); // 企业单位库 - knowledgeSources.put("regulation", new ArrayList<>()); // 公共法律法规库 - knowledgeSources.put("auditCase", new ArrayList<>()); // 审计案例库 + knowledgeSources.put("enterprise", new ArrayList<>()); + knowledgeSources.put("regulation", new ArrayList<>()); + knowledgeSources.put("auditCase", new ArrayList<>()); - // 企业单位库检索 - 主要来源 + // 构建当前分类的查询词 + List categoryQueries = buildCategoryQueries(category); + + // 企业单位库检索 if (StrUtil.isNotBlank(kbIds)) { Arrays.stream(kbIds.split(",")) .map(String::trim) .filter(StrUtil::isNotBlank) .forEach(kbId -> knowledgeSources.get("enterprise") - .addAll(queryKnowledgeBase(kbId, buildEnterpriseQueries(), 200))); + .addAll(queryKnowledgeBase(kbId, categoryQueries, 100))); } // 公共法律法规库检索 @@ -142,13 +243,13 @@ public class AuditContent3TripleServiceImpl implements AuditContent3TripleServic .map(String::trim) .filter(StrUtil::isNotBlank) .forEach(libId -> knowledgeSources.get("regulation") - .addAll(queryKnowledgeBase(libId, buildRegulationQueries(), 150))); + .addAll(queryKnowledgeBase(libId, categoryQueries, 80))); } // 审计案例库检索 if (StrUtil.isNotBlank(projectLibrary)) { knowledgeSources.get("auditCase").addAll( - queryKnowledgeBase(projectLibrary, buildAuditCaseQueries(), 100)); + queryKnowledgeBase(projectLibrary, categoryQueries, 60)); } // 智能去重和排序 @@ -161,137 +262,152 @@ public class AuditContent3TripleServiceImpl implements AuditContent3TripleServic knowledgeSources.put(key, processed); }); + log.debug("分类 {} 知识检索完成 - 企业: {}条, 法规: {}条, 案例: {}条", + category, + knowledgeSources.get("enterprise").size(), + knowledgeSources.get("regulation").size(), + knowledgeSources.get("auditCase").size()); + return knowledgeSources; } /** - * 构建企业单位库查询 + * 构建分类特定的查询词 */ - private List buildEnterpriseQueries() { - return Arrays.asList( - "三重一大制度 集体决策规定", - "重大决策范围 人事任免范围 项目安排范围 资金运作范围", - "决策程序 权力主体 会议规则", - "集团制度 公司制定 内部规定" - ); - } - - /** - * 构建法律法规库查询 - */ - private List buildRegulationQueries() { - return Arrays.asList( - "三重一大政策 国家法律法规", - "重大决策法规 人事任免法规", - "项目安排规定 资金运作规定", - "决策程序法律要求" - ); - } - - /** - * 构建审计案例库查询 - */ - private List 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 List buildCategoryQueries(String category) { + switch (category) { + case "重大决策": + return Arrays.asList( + "重大决策事项 决策范围 决策程序", + "重大决策制度 集体决策规定", + "党委会 董事会 总经理办公会 决策" + ); + case "重要人事任免": + return Arrays.asList( + "重要人事任免 人事任免范围", + "中层管理人员 领导班子成员 任免", + "人事任免程序 干部管理" + ); + case "重大项目安排": + return Arrays.asList( + "重大项目安排 项目安排范围", + "年度投资计划 融资担保项目", + "重大工程建设项目 重要设备引进" + ); + case "大额度资金运作": + return Arrays.asList( + "大额度资金运作 资金运作范围", + "年度预算 大额度资金使用", + "对外捐赠 赞助 资金调动" + ); + case "决策权力主体和程序": + return Arrays.asList( + "决策权力主体 决策程序", + "集体决策 前置程序", + "党委会前置研究 三重一大决策程序" + ); + default: + return Arrays.asList(category + " 制度规定"); } } /** - * 生成三重一大制度对比分析表 + * 生成单个分类的对比分析表 */ - private JSONArray generateComparisonTable(Map> knowledgeSources, String userName, String history, String suggestion) { - // 构建优化的知识上下文 - String knowledgeContext = buildKnowledgeContext(knowledgeSources, history, suggestion); + private JSONArray generateCategoryTable(String category, Map> knowledgeSources, + String userName, String history, String suggestion) { + // 构建优化的知识上下文 - 包含Excel数据 + String knowledgeContext = buildCategoryKnowledgeContext(category, knowledgeSources, history, suggestion); JSONObject requestBody = buildWorkflowRequest(knowledgeContext, userName); JSONArray rawData = callTripleOneWorkflow(requestBody); // 后处理:数据清洗和格式化 - return postProcessComparisonData(rawData); + return postProcessCategoryData(category, rawData); } /** - * 构建知识上下文 + * 构建分类特定的知识上下文 - 新增Excel数据 */ - private String buildKnowledgeContext(Map> knowledgeSources, String history, String suggestion) { + private String buildCategoryKnowledgeContext(String category, Map> 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"); + context.append("## 三重一大制度对比分析要求 - ").append(category).append("\n"); + context.append("请基于以下知识生成").append(category).append("相关的三重一大制度对比分析表数据:\n\n"); + context.append("1. 仅关注与").append(category).append("直接相关的制度内容,过滤不相关制度\n"); + context.append("2. 对比分析政策内容、集团制度、公司制定的差异\n"); + context.append("3. 重点关注决策范围、金额标准、程序要求的差异\n"); + context.append("4. 识别制度执行中的风险和问题\n"); + context.append("5. 严格判断测试结果,只有证据充分才能判定为通过,证据不足或存在差异必须判定为不通过\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("需要生成").append(category).append("分类的数据,尽可能生成多个实例、多条记录:\n"); + context.append("- ").append(category).append(":").append(TRIPLE_ONE_CATEGORIES.get(category)).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"); + 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"); + context.append("1. 请根据知识库内容尽可能全面地生成所有相关制度规定和检查点\n"); + context.append("2. 公司执行情况分析需包含:查阅了哪些文件、发现了什么内容、与制度的差异点、分析判断过程\n"); + context.append("3. 工作底稿索引必须准确对应实际文件名称,避免使用附表或章节标题\n"); + context.append("4. 测试结果判定需严格,对于制度不一致、执行不到位、证据不充分的情况必须判定为不通过\n\n"); - // 3. 历史内容 + // 3. 参考数据(从Excel中获取) + if (EXCEL_DATA_MAP.containsKey(category)) { + String[] excelData = EXCEL_DATA_MAP.get(category); + context.append("## 参考数据(Excel模板)\n"); + context.append("### 政策内容\n").append(excelData[0]).append("\n\n"); + context.append("### 集团制度\n").append(excelData[1]).append("\n\n"); + context.append("### 公司制定\n").append(excelData[2]).append("\n\n"); + } + + // 4. 历史内容 if (StrUtil.isNotBlank(history)) { context.append("## 历史生成内容\n"); context.append("以下是之前生成的内容,请基于此进行优化:\n"); context.append(history).append("\n\n"); } - // 4. 用户建议 + // 5. 用户建议 if (StrUtil.isNotBlank(suggestion)) { context.append("## 用户优化建议\n"); context.append("请根据以下建议对生成内容进行调整:\n"); context.append(suggestion).append("\n\n"); } - // 5. 企业单位知识 + // 6. 企业单位知识 if (!knowledgeSources.get("enterprise").isEmpty()) { context.append("## 企业单位知识\n"); knowledgeSources.get("enterprise").stream() - .limit(250) + .limit(100) .forEach(knowledge -> context.append("- ").append(knowledge).append("\n")); context.append("\n"); } - // 6. 法律法规知识 + // 7. 法律法规知识 if (!knowledgeSources.get("regulation").isEmpty()) { context.append("## 法律法规知识\n"); knowledgeSources.get("regulation").stream() - .limit(200) + .limit(80) .forEach(knowledge -> context.append("- ").append(knowledge).append("\n")); context.append("\n"); } - // 7. 审计案例知识 + // 8. 审计案例知识 if (!knowledgeSources.get("auditCase").isEmpty()) { context.append("## 审计案例知识\n"); knowledgeSources.get("auditCase").stream() - .limit(150) + .limit(60) .forEach(knowledge -> context.append("- ").append(knowledge).append("\n")); } @@ -299,8 +415,60 @@ public class AuditContent3TripleServiceImpl implements AuditContent3TripleServic } /** - * 数据验证和增强 + * 后处理分类数据 */ + private JSONArray postProcessCategoryData(String category, JSONArray rawData) { + if (rawData == null || rawData.isEmpty()) { + return createDefaultCategoryData(category); + } + + JSONArray processedData = new JSONArray(); + + for (int i = 0; i < rawData.size(); i++) { + JSONObject item = rawData.getJSONObject(i); + if (item != null) { + // 确保分类正确 + item.put("category", category); + + // 确保所有字段都存在 + enhanceComparisonDataItem(item, i); + + processedData.add(item); + } + } + + return processedData; + } + + /** + * 创建默认的分类数据 + */ + private JSONArray createDefaultCategoryData(String category) { + JSONArray defaultData = new JSONArray(); + + 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 int getLimitBySourceType(String sourceType) { + switch (sourceType) { + case "enterprise": return 100; + case "regulation": return 80; + case "auditCase": return 60; + default: return 50; + } + } + private JSONArray validateAndEnhanceComparisonData(JSONArray data) { if (data == null || data.isEmpty()) { return createDefaultComparisonData(); @@ -312,13 +480,11 @@ public class AuditContent3TripleServiceImpl implements AuditContent3TripleServic JSONObject item = data.getJSONObject(i); if (item == null) continue; - // 数据验证 if (!validateComparisonDataItem(item)) { log.warn("数据验证失败,跳过记录: {}", item); continue; } - // 数据增强 enhanceComparisonDataItem(item, i); enhancedData.add(item); } @@ -326,13 +492,10 @@ public class AuditContent3TripleServiceImpl implements AuditContent3TripleServic return enhancedData; } - /** - * 创建默认的对比分析数据 - */ private JSONArray createDefaultComparisonData() { JSONArray defaultData = new JSONArray(); - for (String category : TRIPLE_ONE_CATEGORIES.keySet()) { + for (String category : CATEGORY_ORDER) { JSONObject item = new JSONObject(); item.put("category", category); item.put("policyContent", "待补充相关政策内容"); @@ -347,9 +510,6 @@ public class AuditContent3TripleServiceImpl implements AuditContent3TripleServic return defaultData; } - /** - * 数据项验证 - */ private boolean validateComparisonDataItem(JSONObject item) { return item.containsKey("category") && item.containsKey("policyContent") && @@ -357,19 +517,7 @@ public class AuditContent3TripleServiceImpl implements AuditContent3TripleServic item.containsKey("companyFormulation"); } - /** - * 数据项增强 - */ private void enhanceComparisonDataItem(JSONObject item, int index) { - // 确保分类正确 - if (!item.containsKey("category") || StrUtil.isBlank(item.getString("category"))) { - List 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) { @@ -385,68 +533,12 @@ public class AuditContent3TripleServiceImpl implements AuditContent3TripleServic } } - private JSONArray postProcessComparisonData(JSONArray rawData) { - if (rawData == null || rawData.isEmpty()) { - return createDefaultComparisonData(); - } - - // 使用列表来存储所有条目,避免覆盖 - JSONArray processedData = new JSONArray(); - Map> 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 categoryItems = categoryDataMap.get(category); - if (categoryItems != null && !categoryItems.isEmpty()) { - // 添加该分类下的所有条目 - processedData.addAll(categoryItems); - } - } - - // 处理其他未预定义的分类 - for (Map.Entry> 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())) @@ -454,9 +546,6 @@ public class AuditContent3TripleServiceImpl implements AuditContent3TripleServic .sum(); } - /** - * 查询知识库 - */ private List queryKnowledgeBase(String kbId, List queries, int topK) { Set results = new LinkedHashSet<>(); String workspaceId = config.getWorkspaceId(); @@ -484,9 +573,6 @@ public class AuditContent3TripleServiceImpl implements AuditContent3TripleServic return new ArrayList<>(results); } - /** - * 处理知识库节点 - */ private void processNode(RetrieveResponseBodyDataNodes node, Set results) { try { String text = node.getText(); @@ -503,9 +589,6 @@ public class AuditContent3TripleServiceImpl implements AuditContent3TripleServic } } - /** - * 提取文档名称 - */ private String extractDocumentName(RetrieveResponseBodyDataNodes node) { try { Object metadataObj = node.getMetadata(); @@ -520,16 +603,13 @@ public class AuditContent3TripleServiceImpl implements AuditContent3TripleServic 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) + .timeout(10*60*1000) .execute() .body(); @@ -540,7 +620,6 @@ public class AuditContent3TripleServiceImpl implements AuditContent3TripleServic .path("result") .asText(); - // 使用Jackson解析数组 JsonNode arrayNode = objectMapper.readTree(outputText); return JSONArray.parseArray(arrayNode.toString()); @@ -550,9 +629,6 @@ public class AuditContent3TripleServiceImpl implements AuditContent3TripleServic } } - /** - * 构建工作流请求 - */ private JSONObject buildWorkflowRequest(String knowledge, String userName) { JSONObject requestBody = new JSONObject(); JSONObject inputs = new JSONObject(); diff --git a/src/main/java/com/gxwebsoft/oa/service/impl/OaCompanyServiceImpl.java b/src/main/java/com/gxwebsoft/oa/service/impl/OaCompanyServiceImpl.java index a2b63bf..aa67eb5 100644 --- a/src/main/java/com/gxwebsoft/oa/service/impl/OaCompanyServiceImpl.java +++ b/src/main/java/com/gxwebsoft/oa/service/impl/OaCompanyServiceImpl.java @@ -66,28 +66,49 @@ public class OaCompanyServiceImpl extends ServiceImpl directoryNames = Arrays.asList( - "贯彻决策部署", "单位发展战略执行", "三重一大执行", "目标完成", "财务管理", - "国资管理", "重大投资情况", "治理结构", "人员编制", "廉政情况", "历史审计问题" + "1.基本情况", "2.企业领导人员任职情况", "3.任期内年度总结报告", "4.公司章程及议事规则", + "5.领导班子分工", "6.任期内会议纪要与会议记录", "7.内部控制制度", "8.企业发展规划及战略", + "9.目标责任", "10-11.重大经济事项决策及执行(项目)", "12.固定资产、资产处置资料", + "13.财务数据", "14.以前年度审计" ); List directories = new ArrayList<>(); - for (int i = 0; i < directoryNames.size(); i++) { AiCloudDoc doc = new AiCloudDoc(); doc.setCategoryId(categoryId); doc.setCompanyId(oaCompany.getCompanyId()); - doc.setParentId(0); // 顶级目录 + doc.setParentId(topDirId); // 关键修改:父目录ID设为顶级目录的ID doc.setName(directoryNames.get(i)); doc.setSortNumber(i + 1); doc.setStatus(0); @@ -96,11 +117,10 @@ public class OaCompanyServiceImpl extends ServiceImpl