diff --git a/src/main/java/com/gxwebsoft/ai/constants/AuditContent5BudgetExecutionConstants.java b/src/main/java/com/gxwebsoft/ai/constants/AuditContent5BudgetExecutionConstants.java new file mode 100644 index 0000000..6723400 --- /dev/null +++ b/src/main/java/com/gxwebsoft/ai/constants/AuditContent5BudgetExecutionConstants.java @@ -0,0 +1,259 @@ +package com.gxwebsoft.ai.constants; + +import java.util.*; + +/** + * 审计内容5-预算执行情况审计常量类 + * 审计目标:检查预算执行的进度、合规性、效果,分析预算执行偏差原因,评估预算执行效益 + */ +public class AuditContent5BudgetExecutionConstants { + + // 分类定义 + public static final String CATEGORY_BUDGET_EXECUTION = "预算执行情况审计"; + + // 审计框架核心 + public static final String AUDIT_FRAMEWORK = + "**审计核心:**\n" + + "预算执行情况审计。包括预算执行进度、执行合规性、执行效果评估、预算执行偏差分析、\n" + + "资金到位情况、项目执行进度、预算执行率、资金使用效益、执行风险预警、整改措施落实等情况。\n\n" + + + "**重点关注:**\n" + + "1. 预算执行率是否达到预期目标,是否存在执行进度滞后问题\n" + + "2. 资金是否按时足额到位,是否存在资金沉淀或短缺问题\n" + + "3. 预算执行是否合规,是否存在超预算、无预算执行问题\n" + + "4. 项目执行进度是否符合计划,是否存在项目延期问题\n" + + "5. 预算调整是否及时报批,是否存在擅自调整预算问题\n" + + "6. 预算执行效益如何,是否达到预期经济效益和社会效益\n" + + "7. 预算执行是否存在偏差,偏差原因是否合理\n" + + "8. 预算执行监控是否到位,是否存在风险预警机制\n" + + "9. 预算执行问题整改是否及时有效,整改措施是否落实\n" + + "10. 预算执行信息公开是否及时准确,透明度如何\n" + + "11. 预算执行考核评价机制是否健全,考核结果是否应用\n" + + "12. 预算执行信息化水平如何,是否实现动态监控\n" + + "13. 预算执行与决算衔接是否顺畅,数据是否一致\n" + + "14. 预算执行对单位履职和事业发展的支撑作用如何\n" + + "15. 预算执行中是否存在挤占挪用、虚列支出等问题\n" + + "16. 预算执行与政府采购、资产管理等是否协调衔接\n\n" + + + "**审计方法及步骤:**\n" + + "1. 预算执行进度审计:\n" + + " (1) 审阅被审计领导干部任职期间的预算执行进度报表、月度/季度/年度执行分析报告\n" + + " (2) 对比预算安排与实际执行数据,计算预算执行率、资金到位率等关键指标\n" + + " (3) 分析执行进度滞后项目的原因,检查是否存在客观障碍或主观问题\n" + + " (4) 检查预算执行台账是否完整,执行记录是否及时准确\n\n" + + + "2. 预算执行合规性审计:\n" + + " (1) 对比预算批复文件与会计账务处理,检查预算执行是否严格按照批复执行\n" + + " (2) 检查是否存在超预算执行、无预算执行、预算科目调剂等违规问题\n" + + " (3) 审查预算调整审批手续是否完备,是否存在擅自调整预算问题\n" + + " (4) 检查资金支付凭证是否合规,支付审批流程是否完整\n\n" + + + "3. 预算执行效果审计:\n" + + " (1) 对照项目可行性研究报告和评审报告,检查项目预期目标实现情况\n" + + " (2) 运用成本效益分析方法,评估预算资金使用效益\n" + + " (3) 实地查看项目实施情况,验证项目实际效果\n" + + " (4) 调查相关受益群体,了解项目社会效益和满意度\n\n" + + + "4. 预算执行偏差分析:\n" + + " (1) 分析预算执行偏差数据,找出偏差较大的项目和科目\n" + + " (2) 通过访谈、座谈等方式了解偏差产生的原因\n" + + " (3) 评估偏差是否合理,是否存在管理问题\n" + + " (4) 检查是否建立偏差分析机制和整改措施\n\n" + + + "5. 预算执行风险管理审计:\n" + + " (1) 检查是否建立预算执行风险预警机制\n" + + " (2) 评估风险预警指标是否科学合理\n" + + " (3) 检查风险预警响应和处置是否及时有效\n" + + " (4) 审查风险防范措施是否落实到位\n\n" + + + "6. 预算执行整改审计:\n" + + " (1) 检查以往审计发现问题的整改情况\n" + + " (2) 评估整改措施的有效性和落实情况\n" + + " (3) 检查是否存在屡审屡犯问题\n" + + " (4) 评估整改长效机制建设情况\n\n" + + + "7. 预算执行信息化审计:\n" + + " (1) 检查预算执行信息系统建设情况\n" + + " (2) 评估系统功能是否满足预算执行监控需求\n" + + " (3) 检查系统数据是否准确完整\n" + + " (4) 评估信息化对预算执行管理的支撑作用"; + + // 审计目标 + public static final String AUDIT_OBJECTIVE = + "全面检查预算执行全过程,包括执行进度、执行合规性、执行效果、执行偏差分析、\n" + + "风险管理、整改落实等,确保预算资金规范高效使用,提高预算执行质量和效益。"; + + // 审计工作原则 + public static final String AUDIT_PRINCIPLES = + "审计工作原则:\n" + + "1. 以《预算法》、《预算法实施条例》及相关财政法规为依据\n" + + "2. 全面覆盖预算执行的所有环节和方面\n" + + "3. 重点关注预算执行率、资金到位率等关键指标\n" + + "4. 检查预算执行合规性和规范性\n" + + "5. 评估预算执行效果和效益\n" + + "6. 分析预算执行偏差原因\n" + + "7. 关注预算执行风险防控\n" + + "8. 检查审计问题整改情况\n" + + "9. 促进预算执行管理完善\n" + + "10. 提高财政资金使用效益"; + + // 关键词权重 + public static final Map KEYWORD_WEIGHTS = new HashMap<>(); + static { + // 预算执行核心概念 + KEYWORD_WEIGHTS.put("预算执行", 10); + KEYWORD_WEIGHTS.put("执行进度", 9); + KEYWORD_WEIGHTS.put("执行率", 10); + KEYWORD_WEIGHTS.put("资金到位", 9); + KEYWORD_WEIGHTS.put("执行合规", 8); + + // 预算执行指标 + KEYWORD_WEIGHTS.put("执行偏差", 8); + KEYWORD_WEIGHTS.put("预算调整", 7); + KEYWORD_WEIGHTS.put("超预算", 8); + KEYWORD_WEIGHTS.put("无预算", 8); + KEYWORD_WEIGHTS.put("科目调剂", 7); + + // 执行效果和效益 + KEYWORD_WEIGHTS.put("执行效果", 8); + KEYWORD_WEIGHTS.put("资金效益", 8); + KEYWORD_WEIGHTS.put("成本效益", 7); + KEYWORD_WEIGHTS.put("社会效益", 7); + KEYWORD_WEIGHTS.put("经济效益", 7); + + // 执行风险管理 + KEYWORD_WEIGHTS.put("风险预警", 7); + KEYWORD_WEIGHTS.put("执行风险", 7); + KEYWORD_WEIGHTS.put("风险防控", 6); + KEYWORD_WEIGHTS.put("预警机制", 6); + + // 执行监控和整改 + KEYWORD_WEIGHTS.put("执行监控", 7); + KEYWORD_WEIGHTS.put("动态监控", 6); + KEYWORD_WEIGHTS.put("整改措施", 7); + KEYWORD_WEIGHTS.put("整改落实", 7); + KEYWORD_WEIGHTS.put("屡审屡犯", 6); + + // 文件类型 + KEYWORD_WEIGHTS.put("执行报表", 8); + KEYWORD_WEIGHTS.put("进度报表", 8); + KEYWORD_WEIGHTS.put("执行分析", 7); + KEYWORD_WEIGHTS.put("执行报告", 7); + KEYWORD_WEIGHTS.put("支付凭证", 7); + KEYWORD_WEIGHTS.put("拨款凭证", 7); + } + + // 审计要点提示 + public static final String AUDIT_KEY_POINTS = + "**审计要点:**\n" + + "1. 检查预算执行率是否达到预期目标,分析执行进度滞后原因\n" + + "2. 核实资金是否按时足额到位,是否存在资金沉淀问题\n" + + "3. 审查预算执行是否合规,是否存在超预算、无预算执行\n" + + "4. 检查项目执行进度是否符合计划,是否存在项目延期\n" + + "5. 评估预算调整审批是否及时合规\n" + + "6. 分析预算执行偏差原因是否合理\n" + + "7. 评估预算执行效益是否达到预期目标\n" + + "8. 检查预算执行风险预警机制是否健全\n" + + "9. 审查审计问题整改是否及时有效\n" + + "10. 评估预算执行信息化水平\n" + + "11. 检查预算执行信息公开情况\n" + + "12. 评估预算执行考核评价机制\n" + + "13. 检查预算执行与决算衔接情况\n" + + "14. 分析预算执行对单位发展的支撑作用\n" + + "15. 检查是否存在挤占挪用、虚列支出问题\n" + + "16. 评估预算执行管理完善程度"; + + // 数据格式要求 + public static final String OUTPUT_FORMAT = + "**输出格式(JSON数组):**\n" + + "[\n" + + " {\n" + + " \"index\": 序号,\n" + + " \"project\": \"项目名称\",\n" + + " \"lastYearCarryOver\": \"上年结转\",\n" + + " \"currentYearBudgetTotal\": \"本年预算小计\",\n" + + " \"initialApprovedBudget\": \"年初批复预算数\",\n" + + " \"additionalBudgetAmount\": \"追加预算数\",\n" + + " \"actualAppropriation\": \"实际拨款数\",\n" + + " \"indicatorBalance\": \"指标结余\",\n" + + " \"workPaperIndex\": [\"实际存在的完整文件名1\", \"实际存在的完整文件名2\", ...]\n" + + " }\n" + + "]\n\n" + + "**重要说明:**\n" + + "1. 每个审计记录对应一个具体的预算项目或执行事项\n" + + "2. 尽可能全面识别所有预算执行项目和环节\n" + + "3. 金额字段应填写具体数值,如\"1,000,000.00\"\n" + + "4. 百分比字段应填写具体百分比,如\"85.50%\"\n" + + "5. workPaperIndex必须填写实际查阅的文件名称\n" + + "6. 对于无数据的字段,可填写\"-\"或留空\n" + + "7. 尽可能多地生成审计记录,覆盖所有预算执行方面\n" + + "8. 重点关注预算执行率低于80%或高于120%的项目\n" + + "9. 深入分析预算执行偏差的根本原因"; + + // 审计证据要求 + public static final String AUDIT_EVIDENCE_REQUIREMENTS = + "**审计证据要求:**\n" + + "1. 预算执行相关文件:预算执行进度报表、月度/季度/年度执行分析报告\n" + + "2. 资金拨付文件:拨款凭证、银行回单、付款审批单\n" + + "3. 预算调整文件:预算调整审批文件、追加预算审批单\n" + + "4. 项目执行文件:项目进度报告、项目验收报告、项目结算资料\n" + + "5. 财务核算文件:会计账簿、会计凭证、银行对账单\n" + + "6. 执行监控文件:预算执行台账、执行监控记录、风险预警记录\n" + + "7. 整改落实文件:审计问题整改报告、整改措施落实证明\n" + + "8. 考核评价文件:预算执行考核方案、考核结果、奖惩记录\n" + + "9. 信息系统文件:预算执行系统截图、数据导出报表\n" + + "10. 现场核实资料:实地查看记录、座谈记录、调查问卷"; + + // 字段映射(用于前端展示) + public static final Map FIELD_DISPLAY_NAMES = new HashMap<>(); + static { + FIELD_DISPLAY_NAMES.put("index", "序号"); + FIELD_DISPLAY_NAMES.put("project", "项目名称"); + FIELD_DISPLAY_NAMES.put("lastYearCarryOver", "上年结转"); + FIELD_DISPLAY_NAMES.put("currentYearBudgetTotal", "本年预算小计"); + FIELD_DISPLAY_NAMES.put("initialApprovedBudget", "年初批复预算数"); + FIELD_DISPLAY_NAMES.put("additionalBudgetAmount", "追加预算数"); + FIELD_DISPLAY_NAMES.put("actualAppropriation", "实际拨款数"); + FIELD_DISPLAY_NAMES.put("indicatorBalance", "指标结余"); + FIELD_DISPLAY_NAMES.put("workPaperIndex", "工作底稿索引"); + } + + // 获取分类的简要审计框架概述 + public static String getBriefAuditFrameworkForCategory(String category) { + if (CATEGORY_BUDGET_EXECUTION.equals(category)) { + return "全面审计预算执行全过程,包括执行进度、合规性、效果、偏差分析、风险管理、整改落实等情况"; + } + return "全面审计预算执行情况"; + } + + // 审计项目类型(常见预算执行项目) + public static final List AUDIT_PROJECT_TYPES = Arrays.asList( + "基本支出-人员经费执行", + "基本支出-公用经费执行", + "项目支出-专项业务费执行", + "项目支出-设备购置费执行", + "项目支出-大型修缮费执行", + "项目支出-信息网络购建费执行", + "项目支出-基础设施建设费执行", + "项目支出-会议费执行", + "项目支出-培训费执行", + "项目支出-差旅费执行", + "项目支出-劳务费执行", + "项目支出-咨询费执行", + "项目支出-委托业务费执行", + "政府采购项目执行", + "科研项目经费执行", + "基建项目资金执行", + "信息化项目执行", + "培训项目执行", + "会议项目执行", + "差旅费执行", + "办公设备购置执行", + "车辆运行维护费执行", + "物业管理费执行", + "租赁费执行", + "维修维护费执行", + "专用材料费执行", + "其他商品和服务支出执行" + ); +} \ No newline at end of file diff --git a/src/main/java/com/gxwebsoft/ai/constants/AuditContent5BudgetManageConstants.java b/src/main/java/com/gxwebsoft/ai/constants/AuditContent5BudgetManageConstants.java new file mode 100644 index 0000000..696d360 --- /dev/null +++ b/src/main/java/com/gxwebsoft/ai/constants/AuditContent5BudgetManageConstants.java @@ -0,0 +1,322 @@ +package com.gxwebsoft.ai.constants; + +import java.util.*; + +/** + * 审计内容5-预算管理审计常量类 + * 审计目标:检查预算编制的完整准确、预算调整审批的合规,以及预算支出的真实合法合规情况 + */ +public class AuditContent5BudgetManageConstants { + + // 分类定义 + public static final String CATEGORY_BUDGET_MANAGEMENT = "预算管理审计"; + + // 审计框架核心(完整基于Excel内容) + public static final String AUDIT_FRAMEWORK = + "**审计核心:**\n" + + "财政财务管理情况。包括预算编制的完整准确、预算调整审批的合规,以及预算支出的真实合法合规情况;\n" + + "财务收支的真实、合法和效益情况;自然资源资产管理和生态环境保护责任的履行情况;\n" + + "境外机构、境外资产和境外经济活动的真实、合法和效益情况。\n\n" + + + "**重点关注:**\n" + + "1. 是否存在应纳入部门预算管理的各项收支未纳入预算编报\n" + + "2. 项目预算编制不细化导致预算执行率低\n" + + "3. 将独立核算的经营收支编入部门预算\n" + + "4. 将预算拨款在不同预算科目之间相互调剂使用\n" + + "5. 年初未安排预算、在年中又追加的预算调整事项是否合理\n" + + "6. 有无未经批复自行调整部门预算的问题\n" + + "7. 部门预算的项目是否全部都是本单位的业务\n" + + "8. 是否有所设立企业的经营收支性质的预算项目\n" + + "9. 预算支出中是否存在以虚假经济业务套取财政资金等问题\n" + + "10. 预算收支的效益性,项目效益、效果等预期目标的实现情况\n" + + "11. 国有资产配置是否按规定实行政府采购\n" + + "12. 国有资产对外投资和收益以及国有资产保值增值的情况\n" + + "13. 政府采购执行情况,是否存在规避政府采购的情况\n" + + "14. 项目实施及管理情况,项目资金安全、实施进度\n" + + "15. 债权债务的情况,债务可控程度,债权形成呆账的比例\n" + + "16. 工会、饭堂财务收支情况,有无将经营收入放进工会、饭堂核算\n\n" + + + "**审计方法及步骤:**\n" + + "1. 部门预算编报及调整情况审计:\n" + + " (1) 审阅被审计领导干部任职期间的部门预算、决算资料,分析预算收入来源渠道和使用方向,将各年度收支预算进行对比,检查收入预算编报的完整性,支出预算编报的真实性、准确性。\n" + + " (2) 审阅项目预算申报文本,对项目的可行性研究报告、评审报告进行审查,通过实地调查或座谈等方法了解项目准备情况和进展情况,检查项目预算申报的规范性,项目预算有无细化到具体执行单位。\n" + + " (3) 审阅预算调整文件,审查申报、审批手续的完整性,重点关注年初未安排预算、在年中又追加的预算调整事项是否合理。有无未经批复自行调整部门预算的问题。\n" + + " (4) 审阅部门预算的项目是否全部都是本单位的业务,检查是否有所设立企业的经营收支性质的预算项目。\n" + + " (5) 将预算下达文件与会计账务处理相对比,检查两者的项目名称一致,是否相互调剂项目预算。\n\n" + + + "2. 预算执行和财政财务收支情况审计:\n" + + " (1) 必须了解被审计单位设置的财务帐套有哪些,核实现金、银行的流水账和会计凭证保存的银行账户对账单是否一致,现金、银行的流动是否正常,有没有转到可疑的、无关的银行账户的现象。\n" + + " (2) 核实财务软件的记录与被审计单位提供及保存的纸质版的账簿是否一致,核实财务帐套设置的明细科目是否与预算批复的明细科目一致。\n" + + " (3) 核实财务帐套的支出数是否与决算报表一致,有无调整财务帐套支出数以达到不超出预算目的的现象,有无不按财务帐套支出数填报决算报表,以达到不超出预算目的的现象。\n" + + " (4) 核实财务帐套上基本支出加项目支出的\"三公\"经费等的支出数,对比预算下达的\"三公经费\"等预算数,检查是否超预算。\n" + + " (5) 审阅被审计领导干部任职期间所在单位各年度预算、决算资料,编制收入和支出情况分析表,将各年度收入和支出规模和结构进行对比,运用分析性复核的方法分析收入和支出的变化趋势,考虑合理的变动因素,审查不合理的变化及差异,检查收入和支出的总体规模、结构是否与单位职责履行、事业发展目标或者所承担重要事项相匹配。\n" + + " (6) 对照收入和支出预算和决算,审查被审计领导干部任职期间部门各年度的会计账簿和凭证,检查预算收入、预算支出的真实性。审阅项目预算申报文本,对照项目预算支出明细,审查会计账簿和凭证,检查是否存在挤占挪用项目资金等问题。实地观察项目执行情况,检查是否存在虚报项目套取财政资金、将所属企业开支纳入预算核算等问题。\n" + + " (7) 结合新执行的预算绩效考核方法,审查被审计领导干部任职期间各年度的会计账簿、凭证和有关业务资料,运用成本效益分析方法,检查预算收支的效益性,对照项目可行性研究报告和评审报告以及年度目标责任制,检查项目效益、效果等预期目标的实现情况,以及对经济社会发展产生的影响。\n\n" + + + "3. 国有资产的管理情况审计:\n" + + " (1) 审阅国有资产采购合同及招投标文件等资料,检查国有资产购置是否按规定实行政府采购。\n" + + " (2) 审阅固定资产登记台账与会计明细账,审查账账是否相符。根据固定资产类别或领用单位等进行抽查盘点,审查账实是否相符,已报废固定资产是否及时予以报废、核销。\n" + + " (3) 审阅国有资产出租、出借、报废核销的上级主管部门和财政部门的批准文件,检查手续是否完整。\n" + + " (4) 审阅国有资产处置收入的评估文件、上级主管部门和财政部门的核准文件,对比市场价格,检查处置收入是否合理,是否具备完整的处置手续。\n" + + " (5) 审阅国有资产处置收入的会计处理凭证及上缴财政国库的会计处理凭证,检查处置收益是否已纳入\"收支两条线\"管理。审计房屋出租是否按照规定上平台招租,可调查周边租金水平,来进行对比。\n" + + " (6) 审阅国有资产对外投资,提供抵押、担保的上级主管部门和财政部门的审计文件,以及提供抵押、担保的合同,检查审批手续是否齐全,是否真实、合法;计算本单位国有资产保值增值率,检查本单位国有资产保值增值的情况;审计被审计单位划拨、借用给设立企业的资产来源是否清晰。\n\n" + + + "4. 政府采购执行情况审计:\n" + + " (1) 审查财务支出凭据,和\"固定资产\"科目,检查是否全部固定资产的采购都是通过具备政府采购手续的。\n" + + " (2) 对照政府采购文件和目录,查阅财务支出,审计是否存在应报政府采购而未报的情况,特别注意成批的易耗品、一般资产也要执行政府采购。审计时,必须将有可能是批量采购而拆解采购的线索联系起来,看采购的时间、品目,是否应当同时购置的,采取分散购置,规避政府采购,发现此类情况的,除追究违反政府采购法的责任外,还要追踪至货物、服务的提供方,检查是否存在关联交易,交易价格是否合理,是否存在利益输送。\n" + + " (3) 将年度内所有已执行政府采购的名单列出,与政府采购预算报表核对,审计是否按照预算采购,有无乱采购、无预算采购。凡是发现无预算采购的,都要关注采购价格和关联方交易、利益输送。\n" + + " (4) 对实施单一采购的,核对政府采购目录,检查是否属于单一采购来源的要求。如果不属于单一采购来源的,也要关注采购价格和关联方交易、利益输送。\n\n" + + + "5. 项目实施及管理情况审计:\n" + + " 关注各单位实施项目的资金安全,实施进度、财务收支以及项目的会计核算及项目管理的相关手续。\n\n" + + + "6. 债权债务的情况审计:\n" + + " (1) 检查审计期末的应收款与应付款借方余额的形成年限,对超过3年未收取的应收款项,询问形成呆账的原因,以及有无采取措施收取。计算3年以上呆账占应收款项的比例,如果占比较高,检查是否建立有坏账的处理机制。\n" + + " (2) 检查审计期末的应付款和应收款的贷方余额,对大额的部分,了解形成的原因、被审计单位的偿还能力。\n\n" + + + "7. 工会、饭堂财务收支情况审计:\n" + + " 重点关注有无将房屋租金、经营收入等放进工会、饭堂核算的现象;工会开支范围和标准是否超过文件规定。"; + + // 审计目标 + public static final String AUDIT_OBJECTIVE = + "全面检查预算管理的各个方面,包括预算编制的完整准确、预算调整审批的合规、预算支出的真实合法合规情况、\n" + + "财务收支的真实合法和效益、国有资产管理、政府采购执行、项目实施管理、债权债务管理、工会饭堂财务等,\n" + + "确保财政资金使用的规范性、有效性和安全性。"; + + // 审计工作原则 + public static final String AUDIT_PRINCIPLES = + "审计工作原则:\n" + + "1. 以《预算法》、《政府采购法》、《国有资产管理办法》及相关财政法规为依据\n" + + "2. 全面覆盖预算管理的所有环节和方面\n" + + "3. 检查预算收入编报的完整性和支出编报的真实性、准确性\n" + + "4. 关注项目预算申报的规范性和细化程度\n" + + "5. 检查预算调整审批手续的合规性\n" + + "6. 核实部门预算项目的相关性\n" + + "7. 检查预算下达与账务处理的一致性\n" + + "8. 审查国有资产管理的合规性和效益性\n" + + "9. 监督政府采购执行的规范性\n" + + "10. 评估项目实施和管理的有效性\n" + + "11. 分析债权债务的风险控制\n" + + "12. 核查工会饭堂财务的合规性"; + + // 关键词权重 + public static final Map KEYWORD_WEIGHTS = new HashMap<>(); + static { + // 预算管理核心概念 + KEYWORD_WEIGHTS.put("部门预算", 10); + KEYWORD_WEIGHTS.put("预算编制", 10); + KEYWORD_WEIGHTS.put("预算调整", 9); + KEYWORD_WEIGHTS.put("预算执行", 9); + KEYWORD_WEIGHTS.put("预算决算", 9); + + // 预算科目和指标 + KEYWORD_WEIGHTS.put("预算科目", 8); + KEYWORD_WEIGHTS.put("指标来源", 8); + KEYWORD_WEIGHTS.put("指标运用", 8); + KEYWORD_WEIGHTS.put("指标结余", 7); + + // 资金类型和用途 + KEYWORD_WEIGHTS.put("财政拨款", 8); + KEYWORD_WEIGHTS.put("工资统发", 7); + KEYWORD_WEIGHTS.put("政府采购", 8); + KEYWORD_WEIGHTS.put("财政管理专户", 6); + KEYWORD_WEIGHTS.put("基本支出", 8); + KEYWORD_WEIGHTS.put("项目支出", 8); + + // 审计要点和方法 + KEYWORD_WEIGHTS.put("项目预算", 8); + KEYWORD_WEIGHTS.put("预算申报", 7); + KEYWORD_WEIGHTS.put("预算审批", 7); + KEYWORD_WEIGHTS.put("预算调剂", 7); + KEYWORD_WEIGHTS.put("国有资产", 8); + KEYWORD_WEIGHTS.put("固定资产", 7); + KEYWORD_WEIGHTS.put("政府采购", 7); + KEYWORD_WEIGHTS.put("债权债务", 6); + KEYWORD_WEIGHTS.put("工会饭堂", 5); + + // 文件类型 + KEYWORD_WEIGHTS.put("预算报表", 7); + KEYWORD_WEIGHTS.put("决算报表", 7); + KEYWORD_WEIGHTS.put("可行性研究", 6); + KEYWORD_WEIGHTS.put("评审报告", 6); + KEYWORD_WEIGHTS.put("会计账簿", 6); + KEYWORD_WEIGHTS.put("会计凭证", 6); + } + + // 审计要点提示 + public static final String AUDIT_KEY_POINTS = + "**审计要点(基于Excel完整内容):**\n" + + "1. 检查应纳入部门预算管理的各项收支是否全部纳入预算编报\n" + + "2. 核实项目预算是否细化到具体执行单位\n" + + "3. 审查预算调整审批手续是否完整合规\n" + + "4. 检查是否存在将经营收支编入部门预算的情况\n" + + "5. 核实预算拨款是否在不同科目间违规调剂使用\n" + + "6. 检查年初未安排预算、年中追加事项的合理性\n" + + "7. 核实部门预算项目是否全部为本单位业务\n" + + "8. 检查是否将设立企业的经营收支纳入部门预算\n" + + "9. 检查预算支出中是否存在以虚假经济业务套取财政资金\n" + + "10. 审查预算收支的效益性,项目效益、效果等预期目标的实现情况\n" + + "11. 检查国有资产配置是否按规定实行政府采购\n" + + "12. 检查国有资产对外投资和收益以及国有资产保值增值情况\n" + + "13. 审计政府采购执行情况,是否存在规避政府采购\n" + + "14. 关注项目实施及管理情况,项目资金安全、实施进度\n" + + "15. 检查债权债务的情况,债务可控程度,债权形成呆账的比例\n" + + "16. 审计工会、饭堂财务收支情况,有无将经营收入放进工会、饭堂核算"; + + // 数据格式要求 + public static final String OUTPUT_FORMAT = + "**输出格式(JSON数组):**\n" + + "[\n" + + " {\n" + + " \"index\": 序号,\n" + + " \"budgetSubject\": \"预算科目名称\",\n" + + " \"indicatorSource\": \"指标来源\",\n" + + " \"indicatorSourceTotal\": \"指标来源合计\",\n" + + " \"indicatorSourceLastYearBalance\": \"上年结余\",\n" + + " \"indicatorSourceInitialBudget\": \"年初部门预算\",\n" + + " \"indicatorSourceAdditionalBudget\": \"追加(减)预算\",\n" + + " \"indicatorUseTotal\": \"指标运用合计\",\n" + + " \"indicatorUseAppropriationSubtotal\": \"拨款小计\",\n" + + " \"indicatorUseAppropriation\": \"拨款\",\n" + + " \"indicatorUseSalaryPayment\": \"工资统发\",\n" + + " \"indicatorUseGovProcurement\": \"政府采购\",\n" + + " \"financeManagementAccount\": \"财政管理专户\",\n" + + " \"budgetUsedForOther\": \"部门预算用于其他\",\n" + + " \"indicatorBalance\": \"指标结余\",\n" + + " \"governmentProcurement\": \"政府采购\",\n" + + " \"payableToUnit\": \"应拨单位款\",\n" + + " \"other\": \"其他(可简要说明审计发现)\",\n" + + " \"workPaperIndex\": [\"实际存在的完整文件名1\", \"实际存在的完整文件名2\", ...]\n" + + " }\n" + + "]\n\n" + + "**重要说明:**\n" + + "1. 每个审计记录对应一项具体的预算科目或审计事项,尽可能全面识别所有预算科目和审计事项\n" + + "2. 预算科目包括但不限于:基本支出(人员经费、公用经费)、项目支出(专项业务费、设备购置费、维修维护费、会议费、培训费、差旅费、劳务费、咨询费、印刷费、邮电费、租赁费、物业管理费、专用材料费、委托业务费、其他商品和服务支出)等\n" + + "3. 审计事项应包括:预算管理、财务收支、国有资产管理、政府采购、项目实施、债权债务、工会饭堂财务等各方面\n" + + "4. 金额字段应填写具体数值,如\"1,000,000.00\",不能填写简单的\"有\"或\"无\"\n" + + "5. workPaperIndex必须填写实际查阅的文件名称,包括各种相关文件\n" + + "6. 对于无数据的字段,可填写\"-\"或留空,但不能填写\"无\"\n" + + "7. 尽可能多地生成审计记录,覆盖所有可能的预算科目和审计事项,不限制数量\n" + + "8. 基于预算编制、调整、执行、决算的全流程进行审计分析\n" + + "9. 多多益善,全面反映审计情况"; + + // 审计证据要求 + public static final String AUDIT_EVIDENCE_REQUIREMENTS = + "**审计证据要求:**\n" + + "1. 预算管理相关文件:部门预算报表、决算报表、项目预算申报文本、可行性研究报告、评审报告\n" + + "2. 预算调整相关文件:预算调整审批文件、预算下达文件、追加预算审批单\n" + + "3. 财务核算相关文件:会计账簿、会计凭证、银行对账单、现金流水账、财务软件记录\n" + + "4. 预算执行相关文件:预算执行进度表、资金拨付记录、拨款凭证、工资发放记录\n" + + "5. 国有资产相关文件:固定资产登记台账、资产盘点表、采购合同、招投标文件、资产处置审批文件、资产评估报告、出租出借合同、投资担保合同\n" + + "6. 政府采购相关文件:政府采购合同、采购发票、采购目录、采购计划、招标文件、投标文件、中标通知书\n" + + "7. 项目实施相关文件:项目合同、项目进度报告、项目验收报告、项目结算资料\n" + + "8. 债权债务相关文件:应收应付款明细账、账龄分析表、坏账核销审批文件、债务偿还计划\n" + + "9. 工会饭堂相关文件:工会账簿、饭堂收支记录、工会经费使用审批单\n" + + "10. 现场核实资料:实地查看记录、座谈记录、业务资料核对记录"; + + // 字段映射(用于前端展示) + public static final Map FIELD_DISPLAY_NAMES = new HashMap<>(); + static { + FIELD_DISPLAY_NAMES.put("index", "序号"); + FIELD_DISPLAY_NAMES.put("budgetSubject", "预算科目名称"); + FIELD_DISPLAY_NAMES.put("indicatorSource", "指标来源"); + FIELD_DISPLAY_NAMES.put("indicatorSourceTotal", "指标来源合计"); + FIELD_DISPLAY_NAMES.put("indicatorSourceLastYearBalance", "上年结余"); + FIELD_DISPLAY_NAMES.put("indicatorSourceInitialBudget", "年初部门预算"); + FIELD_DISPLAY_NAMES.put("indicatorSourceAdditionalBudget", "追加(减)预算"); + FIELD_DISPLAY_NAMES.put("indicatorUseTotal", "指标运用合计"); + FIELD_DISPLAY_NAMES.put("indicatorUseAppropriationSubtotal", "拨款小计"); + FIELD_DISPLAY_NAMES.put("indicatorUseAppropriation", "拨款"); + FIELD_DISPLAY_NAMES.put("indicatorUseSalaryPayment", "工资统发"); + FIELD_DISPLAY_NAMES.put("indicatorUseGovProcurement", "政府采购"); + FIELD_DISPLAY_NAMES.put("financeManagementAccount", "财政管理专户"); + FIELD_DISPLAY_NAMES.put("budgetUsedForOther", "部门预算用于其他"); + FIELD_DISPLAY_NAMES.put("indicatorBalance", "指标结余"); + FIELD_DISPLAY_NAMES.put("governmentProcurement", "政府采购"); + FIELD_DISPLAY_NAMES.put("payableToUnit", "应拨单位款"); + FIELD_DISPLAY_NAMES.put("other", "其他(审计发现)"); + FIELD_DISPLAY_NAMES.put("workPaperIndex", "工作底稿索引"); + } + + // 获取分类的简要审计框架概述 + public static String getBriefAuditFrameworkForCategory(String category) { + if (CATEGORY_BUDGET_MANAGEMENT.equals(category)) { + return "全面审计预算管理的各个方面,包括预算编制、调整、执行、决算的全过程,以及相关的财务收支、国有资产管理、政府采购、项目实施、债权债务、工会饭堂财务等情况"; + } + return "全面审计预算管理情况"; + } + + // 预算科目类型(更全面的列表) + public static final List BUDGET_SUBJECT_TYPES = Arrays.asList( + "基本支出-人员经费-工资福利支出", + "基本支出-人员经费-社会保障缴费", + "基本支出-人员经费-住房公积金", + "基本支出-人员经费-其他人员支出", + "基本支出-公用经费-办公费", + "基本支出-公用经费-印刷费", + "基本支出-公用经费-咨询费", + "基本支出-公用经费-手续费", + "基本支出-公用经费-水费", + "基本支出-公用经费-电费", + "基本支出-公用经费-邮电费", + "基本支出-公用经费-取暖费", + "基本支出-公用经费-物业管理费", + "基本支出-公用经费-差旅费", + "基本支出-公用经费-因公出国(境)费用", + "基本支出-公用经费-维修(护)费", + "基本支出-公用经费-租赁费", + "基本支出-公用经费-会议费", + "基本支出-公用经费-培训费", + "基本支出-公用经费-公务接待费", + "基本支出-公用经费-专用材料费", + "基本支出-公用经费-被装购置费", + "基本支出-公用经费-专用燃料费", + "基本支出-公用经费-劳务费", + "基本支出-公用经费-委托业务费", + "基本支出-公用经费-工会经费", + "基本支出-公用经费-福利费", + "基本支出-公用经费-公务用车运行维护费", + "基本支出-公用经费-其他交通费用", + "基本支出-公用经费-税金及附加费用", + "基本支出-公用经费-其他商品和服务支出", + "项目支出-专项业务费", + "项目支出-设备购置费", + "项目支出-大型修缮费", + "项目支出-信息网络购建费", + "项目支出-基础设施建设费", + "项目支出-物资储备费", + "项目支出-会议费", + "项目支出-培训费", + "项目支出-差旅费", + "项目支出-劳务费", + "项目支出-咨询费", + "项目支出-印刷费", + "项目支出-邮电费", + "项目支出-租赁费", + "项目支出-物业管理费", + "项目支出-专用材料费", + "项目支出-委托业务费", + "项目支出-其他商品和服务支出", + "经营支出-经营成本", + "经营支出-经营费用", + "经营支出-经营税金", + "对个人和家庭的补助-离休费", + "对个人和家庭的补助-退休费", + "对个人和家庭的补助-退职(役)费", + "对个人和家庭的补助-抚恤金", + "对个人和家庭的补助-生活补助", + "对个人和家庭的补助-救济费", + "对个人和家庭的补助-医疗费补助", + "对个人和家庭的补助-助学金", + "对个人和家庭的补助-奖励金", + "对个人和家庭的补助-生产补贴", + "对个人和家庭的补助-住房公积金", + "对个人和家庭的补助-提租补贴", + "对个人和家庭的补助-购房补贴", + "对个人和家庭的补助-其他对个人和家庭的补助", + "债务还本支出-国内债务还本", + "债务还本支出-国外债务还本", + "债务利息支出-国内债务利息", + "债务利息支出-国外债务利息" + ); +} diff --git a/src/main/java/com/gxwebsoft/ai/controller/AuditContent5Controller.java b/src/main/java/com/gxwebsoft/ai/controller/AuditContent5Controller.java new file mode 100644 index 0000000..5ca5ee9 --- /dev/null +++ b/src/main/java/com/gxwebsoft/ai/controller/AuditContent5Controller.java @@ -0,0 +1,352 @@ +package com.gxwebsoft.ai.controller; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.gxwebsoft.ai.dto.AuditContentRequest; +import com.gxwebsoft.ai.dto.export.BudgetManageExportEntity; +import com.gxwebsoft.ai.dto.export.BudgetExecutionExportEntity; +import com.gxwebsoft.ai.entity.AiCloudDoc; +import com.gxwebsoft.ai.entity.AiCloudFile; +import com.gxwebsoft.ai.service.AiHistoryService; +import com.gxwebsoft.ai.utils.ExcelExportTool; +import com.gxwebsoft.common.core.web.ApiResult; +import com.gxwebsoft.common.core.web.BaseController; +import com.gxwebsoft.common.system.entity.User; +import com.gxwebsoft.pwl.entity.PwlProjectLibrary; +import com.gxwebsoft.pwl.service.PwlProjectLibraryService; +import com.gxwebsoft.ai.service.AiCloudDocService; +import com.gxwebsoft.ai.service.AiCloudFileService; +import com.gxwebsoft.ai.service.AuditContent5BudgetManageService; +import com.gxwebsoft.ai.service.AuditContent5BudgetExecutionService; +import com.gxwebsoft.ai.service.KnowledgeBaseService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.digest.DigestUtil; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 审计内容5控制器 - 预算管理审计 + */ +@Slf4j +@Tag(name = "审计内容5-预算管理审计") +@RestController +@RequestMapping("/api/ai/auditContent5") +public class AuditContent5Controller extends BaseController { + + @Autowired + private AuditContent5BudgetManageService auditContent5BudgetManageService; + + @Autowired + private AuditContent5BudgetExecutionService auditContent5BudgetExecutionService; + + @Autowired + private AiCloudDocService aiCloudDocService; + + @Autowired + private AiCloudFileService aiCloudFileService; + + @Autowired + private KnowledgeBaseService knowledgeBaseService; + + @Autowired + private PwlProjectLibraryService pwlProjectLibraryService; + + @Autowired + private AiHistoryService aiHistoryService; + + // 历史记录有效期(分钟) + private static final int HISTORY_EXPIRE_MINUTES = 10; + + /** + * 生成预算管理审计表数据 + */ + @Operation(summary = "生成预算管理审计表") + @PostMapping("/generateBudgetManageTable") + public ApiResult generateBudgetManageTable(@RequestBody AuditContentRequest request, HttpServletRequest servletRequest) { + return generateTableData(request, servletRequest.getRequestURI(), + (params) -> auditContent5BudgetManageService.generateBudgetManageTableData( + params.knowledgeBaseId, params.libraryKbIds, params.projectLibrary, + params.username, params.history, params.suggestion, request.getData() + )); + } + + /** + * 生成预算执行情况审计表数据 + */ + @Operation(summary = "生成预算执行情况审计表") + @PostMapping("/generateBudgetExecutionTable") + public ApiResult generateBudgetExecutionTable(@RequestBody AuditContentRequest request, HttpServletRequest servletRequest) { + return generateTableData(request, servletRequest.getRequestURI(), + (params) -> auditContent5BudgetExecutionService.generateBudgetExecutionTableData( + params.knowledgeBaseId, params.libraryKbIds, params.projectLibrary, + params.username, params.history, params.suggestion, request.getData() + )); + } + + /** + * 通用的表格数据生成方法 + */ + private ApiResult generateTableData(AuditContentRequest request, String interfaceName, Function generateFunction) { + final User loginUser = getLoginUser(); + String requestHistory = request.getHistory(); + request.setHistory(""); + + // 检查历史记录 + String requestHash = generateRequestHash(request, interfaceName); + var history = aiHistoryService.getValidHistory(requestHash, interfaceName, HISTORY_EXPIRE_MINUTES); + if (history != null) { + log.info("返回历史数据,请求哈希: {}", requestHash); + return success(JSONObject.parseObject(history.getResponseData())); + } + request.setHistory(requestHistory); + + String kbIdTmp = ""; + String libraryKbIds = ""; + + try { + // 创建临时知识库(如果需要) + if (hasUploadedFiles(request)) { + kbIdTmp = createTempKnowledgeBase(request); + } + + // 查询项目库信息 + libraryKbIds = getLibraryKbIds(request.getLibraryIds()); + + // 生成数据 + String knowledgeBaseId = getKnowledgeBaseId(kbIdTmp, request.getKbIds()); + GenerateParams params = new GenerateParams(knowledgeBaseId, libraryKbIds, request.getProjectLibrary(), loginUser.getUsername(), request.getHistory(), request.getSuggestion()); + + JSONObject result = generateFunction.apply(params); + + if(result.getBoolean("success")) { + // 保存到历史记录 + saveToHistory(request, interfaceName, requestHash, result, loginUser); + } + + return success(result); + } catch (Exception e) { + log.error("生成表格数据失败,接口: {}", interfaceName, e); + return fail("生成表格数据失败: " + e.getMessage()); + } finally { + cleanupTempKnowledgeBase(kbIdTmp); + } + } + + /** + * 生成请求哈希 + */ + private String generateRequestHash(AuditContentRequest request, String interfaceName) { + String requestJson = JSONObject.toJSONString(request); + return DigestUtil.md5Hex(interfaceName + ":" + requestJson); + } + + /** + * 保存到历史记录 + */ + private void saveToHistory(AuditContentRequest request, String interfaceName, String requestHash, JSONObject result, User loginUser) { + try { + aiHistoryService.saveHistory(requestHash, interfaceName, JSONObject.toJSONString(request), result.toJSONString(), loginUser.getUserId(), loginUser.getUsername(), loginUser.getTenantId()); + } catch (Exception e) { + log.warn("保存历史记录失败", e); + } + } + + /** + * 检查是否有上传的文件 + */ + private boolean hasUploadedFiles(AuditContentRequest request) { + return !request.getDocList().isEmpty() || !request.getFileList().isEmpty(); + } + + /** + * 获取知识库ID + */ + private String getKnowledgeBaseId(String tempKbId, String requestKbIds) { + return StrUtil.isNotBlank(tempKbId) ? tempKbId : requestKbIds; + } + + /** + * 获取项目库KB IDs + */ + private String getLibraryKbIds(String libraryIds) { + if (StrUtil.isBlank(libraryIds)) { + return ""; + } + List idList = StrUtil.split(libraryIds, ','); + List ret = pwlProjectLibraryService.list(new LambdaQueryWrapper().in(PwlProjectLibrary::getId, idList)); + return ret.stream().map(PwlProjectLibrary::getKbId).filter(StrUtil::isNotBlank).collect(Collectors.joining(",")); + } + + /** + * 创建临时知识库并提交文档 + */ + private String createTempKnowledgeBase(AuditContentRequest request) { + String kbIdTmp = knowledgeBaseService.createKnowledgeBaseTemp(); + // 收集文档ID + Set docIds = request.getDocList().stream().flatMap(docId -> aiCloudDocService.getSelfAndChildren(docId).stream()).map(AiCloudDoc::getId).collect(Collectors.toSet()); + // 查询相关文件 + List fileList = getRelatedFiles(docIds, request.getFileList()); + // 提取文件ID并提交到知识库 + Set kbFileIds = fileList.stream().map(AiCloudFile::getFileId).collect(Collectors.toSet()); + if (!kbFileIds.isEmpty()) { + knowledgeBaseService.submitDocuments(kbIdTmp, new ArrayList<>(kbFileIds)); + } + return kbIdTmp; + } + + /** + * 获取相关文件列表 + */ + private List getRelatedFiles(Set docIds, List fileList) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() + .in(!docIds.isEmpty(), AiCloudFile::getDocId, docIds) + .or(!fileList.isEmpty()) + .in(!fileList.isEmpty(), AiCloudFile::getId, fileList); + return aiCloudFileService.list(queryWrapper); + } + + /** + * 清理临时知识库 + */ + private void cleanupTempKnowledgeBase(String kbId) { + if (StrUtil.isNotBlank(kbId)) { + try { + knowledgeBaseService.deleteIndex(kbId); + } catch (Exception e) { + log.warn("删除临时知识库失败: {}", kbId, e); + } + } + } + + /** + * 导出预算管理审计表到Excel + */ + @Operation(summary = "导出预算管理审计表到Excel") + @PostMapping("/exportBudgetManageTable") + public void exportBudgetManageTable(@RequestBody Map request, HttpServletResponse response) { + exportToExcel(request, response, "预算管理审计表", + this::convertToBudgetManageEntityList, BudgetManageExportEntity.class); + } + + /** + * 导出预算执行情况审计表到Excel + */ + @Operation(summary = "导出预算执行情况审计表到Excel") + @PostMapping("/exportBudgetExecutionTable") + public void exportBudgetExecutionTable(@RequestBody Map request, HttpServletResponse response) { + exportToExcel(request, response, "预算执行情况审计表", + this::convertToBudgetExecutionEntityList, BudgetExecutionExportEntity.class); + } + + /** + * 通用的Excel导出方法 + */ + private void exportToExcel(Map request, HttpServletResponse response, + String sheetName, Function>, List> converter, + Class entityClass) { + List> dataList = (List>) request.get("data"); + String companyName = (String) request.get("companyName"); + + List exportData = converter.apply(dataList); + + String fileName = sheetName + "_" + (companyName != null ? companyName : "未知公司"); + String title = companyName != null ? companyName + " - " + sheetName : sheetName; + + ExcelExportTool.exportExcel(exportData, entityClass, fileName, sheetName, title, response); + } + + /** + * 参数包装类 + */ + private static class GenerateParams { + final String knowledgeBaseId; + final String libraryKbIds; + final String projectLibrary; + final String username; + final String history; + final String suggestion; + + GenerateParams(String knowledgeBaseId, String libraryKbIds, String projectLibrary, String username, String history, String suggestion) { + this.knowledgeBaseId = knowledgeBaseId; + this.libraryKbIds = libraryKbIds; + this.projectLibrary = projectLibrary; + this.username = username; + this.history = history; + this.suggestion = suggestion; + } + } + + // ========== 数据转换方法 ========== + + private List convertToBudgetManageEntityList(List> originalData) { + return originalData.stream().map(this::convertToBudgetManageEntity).collect(Collectors.toList()); + } + + private List convertToBudgetExecutionEntityList(List> originalData) { + return originalData.stream().map(this::convertToBudgetExecutionEntity).collect(Collectors.toList()); + } + + private BudgetManageExportEntity convertToBudgetManageEntity(Map item) { + BudgetManageExportEntity entity = new BudgetManageExportEntity(); + entity.setBudgetSubject(getStringValue(item, "budgetSubject")); + entity.setIndicatorSourceTotal(getStringValue(item, "indicatorSourceTotal")); + entity.setIndicatorSourceLastYearBalance(getStringValue(item, "indicatorSourceLastYearBalance")); + entity.setIndicatorSourceInitialBudget(getStringValue(item, "indicatorSourceInitialBudget")); + entity.setIndicatorSourceAdditionalBudget(getStringValue(item, "indicatorSourceAdditionalBudget")); + entity.setIndicatorUseTotal(getStringValue(item, "indicatorUseTotal")); + entity.setIndicatorUseAppropriationSubtotal(getStringValue(item, "indicatorUseAppropriationSubtotal")); + entity.setIndicatorUseAppropriation(getStringValue(item, "indicatorUseAppropriation")); + entity.setIndicatorUseSalaryPayment(getStringValue(item, "indicatorUseSalaryPayment")); + entity.setIndicatorUseGovProcurement(getStringValue(item, "indicatorUseGovProcurement")); + entity.setFinanceManagementAccount(getStringValue(item, "financeManagementAccount")); + entity.setBudgetUsedForOther(getStringValue(item, "budgetUsedForOther")); + entity.setIndicatorBalance(getStringValue(item, "indicatorBalance")); + entity.setGovernmentProcurement(getStringValue(item, "governmentProcurement")); + entity.setPayableToUnit(getStringValue(item, "payableToUnit")); + entity.setOther(getStringValue(item, "other")); + entity.setWorkPaperIndex(formatWorkPaperIndex(item.get("workPaperIndex"))); + return entity; + } + + private BudgetExecutionExportEntity convertToBudgetExecutionEntity(Map item) { + BudgetExecutionExportEntity entity = new BudgetExecutionExportEntity(); + entity.setProject(getStringValue(item, "project")); + entity.setLastYearCarryOver(getStringValue(item, "lastYearCarryOver")); + entity.setCurrentYearBudgetTotal(getStringValue(item, "currentYearBudgetTotal")); + entity.setInitialApprovedBudget(getStringValue(item, "initialApprovedBudget")); + entity.setAdditionalBudgetAmount(getStringValue(item, "additionalBudgetAmount")); + entity.setActualAppropriation(getStringValue(item, "actualAppropriation")); + entity.setIndicatorBalance(getStringValue(item, "indicatorBalance")); + entity.setWorkPaperIndex(formatWorkPaperIndex(item.get("workPaperIndex"))); + return entity; + } + + private String getStringValue(Map map, String key) { + Object value = map.get(key); + return value != null ? value.toString() : ""; + } + + private String formatWorkPaperIndex(Object workPaperIndex) { + if (workPaperIndex == null) { + return ""; + } + + if (workPaperIndex instanceof List) { + List list = (List) workPaperIndex; + return String.join(", ", list.stream() + .map(Object::toString) + .collect(Collectors.toList())); + } + + return workPaperIndex.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/com/gxwebsoft/ai/dto/export/BudgetExecutionExportEntity.java b/src/main/java/com/gxwebsoft/ai/dto/export/BudgetExecutionExportEntity.java new file mode 100644 index 0000000..a4bbc7d --- /dev/null +++ b/src/main/java/com/gxwebsoft/ai/dto/export/BudgetExecutionExportEntity.java @@ -0,0 +1,37 @@ +package com.gxwebsoft.ai.dto.export; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import cn.afterturn.easypoi.excel.annotation.ExcelTarget; +import lombok.Data; + +/** + * 预算执行情况审计表导出实体 + */ +@Data +@ExcelTarget("BudgetExecutionExportEntity") +public class BudgetExecutionExportEntity { + + @Excel(name = "项目", orderNum = "1", width = 30) + private String project; + + @Excel(name = "上年结转", orderNum = "2", width = 15) + private String lastYearCarryOver; + + @Excel(name = "本年预算小计", orderNum = "3", width = 15) + private String currentYearBudgetTotal; + + @Excel(name = "年初批复预算数", orderNum = "4", width = 15) + private String initialApprovedBudget; + + @Excel(name = "追加预算数", orderNum = "5", width = 15) + private String additionalBudgetAmount; + + @Excel(name = "实际拨款数", orderNum = "6", width = 15) + private String actualAppropriation; + + @Excel(name = "指标结余", orderNum = "7", width = 15) + private String indicatorBalance; + + @Excel(name = "工作底稿索引", orderNum = "8", width = 20) + private String workPaperIndex; +} \ No newline at end of file diff --git a/src/main/java/com/gxwebsoft/ai/dto/export/BudgetManageExportEntity.java b/src/main/java/com/gxwebsoft/ai/dto/export/BudgetManageExportEntity.java new file mode 100644 index 0000000..e9e78e1 --- /dev/null +++ b/src/main/java/com/gxwebsoft/ai/dto/export/BudgetManageExportEntity.java @@ -0,0 +1,64 @@ +package com.gxwebsoft.ai.dto.export; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import cn.afterturn.easypoi.excel.annotation.ExcelTarget; +import lombok.Data; + +/** + * 预算管理审计表导出实体 + */ +@Data +@ExcelTarget("BudgetManageExportEntity") +public class BudgetManageExportEntity { + + @Excel(name = "预算科目名称", orderNum = "1", width = 25) + private String budgetSubject; + + @Excel(name = "指标来源-合计", orderNum = "2", width = 15) + private String indicatorSourceTotal; + + @Excel(name = "指标来源-上年结余", orderNum = "3", width = 15) + private String indicatorSourceLastYearBalance; + + @Excel(name = "指标来源-年初部门预算", orderNum = "4", width = 15) + private String indicatorSourceInitialBudget; + + @Excel(name = "指标来源-追加(减)预算", orderNum = "5", width = 15) + private String indicatorSourceAdditionalBudget; + + @Excel(name = "指标运用-合计", orderNum = "6", width = 15) + private String indicatorUseTotal; + + @Excel(name = "指标运用-拨款小计", orderNum = "7", width = 15) + private String indicatorUseAppropriationSubtotal; + + @Excel(name = "指标运用-拨款", orderNum = "8", width = 15) + private String indicatorUseAppropriation; + + @Excel(name = "指标运用-工资统发", orderNum = "9", width = 15) + private String indicatorUseSalaryPayment; + + @Excel(name = "指标运用-政府采购", orderNum = "10", width = 15) + private String indicatorUseGovProcurement; + + @Excel(name = "财政管理专户", orderNum = "11", width = 15) + private String financeManagementAccount; + + @Excel(name = "部门预算用于其他", orderNum = "12", width = 15) + private String budgetUsedForOther; + + @Excel(name = "指标结余", orderNum = "13", width = 15) + private String indicatorBalance; + + @Excel(name = "政府采购", orderNum = "14", width = 15) + private String governmentProcurement; + + @Excel(name = "应拨单位款", orderNum = "15", width = 15) + private String payableToUnit; + + @Excel(name = "其他", orderNum = "16", width = 15) + private String other; + + @Excel(name = "工作底稿索引", orderNum = "17", width = 20) + private String workPaperIndex; +} \ No newline at end of file diff --git a/src/main/java/com/gxwebsoft/ai/service/AuditContent5BudgetExecutionService.java b/src/main/java/com/gxwebsoft/ai/service/AuditContent5BudgetExecutionService.java new file mode 100644 index 0000000..055e5d0 --- /dev/null +++ b/src/main/java/com/gxwebsoft/ai/service/AuditContent5BudgetExecutionService.java @@ -0,0 +1,23 @@ +package com.gxwebsoft.ai.service; + +import com.alibaba.fastjson.JSONObject; + +/** + * 审计内容5-预算执行情况审计服务接口 + */ +public interface AuditContent5BudgetExecutionService { + + /** + * 生成预算执行情况审计表数据 + * @param kbIds 知识库ID + * @param libraryKbIds 项目库知识库ID + * @param projectLibrary 项目库 + * @param userName 用户名 + * @param history 历史记录 + * @param suggestion 用户建议 + * @param data 前端传入的预算管理审计数据(可选) + * @return JSON格式的审计表数据 + */ + JSONObject generateBudgetExecutionTableData(String kbIds, String libraryKbIds, String projectLibrary, + String userName, String history, String suggestion, Object data); +} \ No newline at end of file diff --git a/src/main/java/com/gxwebsoft/ai/service/AuditContent5BudgetManageService.java b/src/main/java/com/gxwebsoft/ai/service/AuditContent5BudgetManageService.java new file mode 100644 index 0000000..062e897 --- /dev/null +++ b/src/main/java/com/gxwebsoft/ai/service/AuditContent5BudgetManageService.java @@ -0,0 +1,22 @@ +package com.gxwebsoft.ai.service; + +import com.alibaba.fastjson.JSONObject; + +/** + * 审计内容5-预算管理审计服务接口 + */ +public interface AuditContent5BudgetManageService { + + /** + * 生成预算管理审计表数据 + * @param kbIds 知识库ID + * @param libraryKbIds 项目库知识库ID + * @param projectLibrary 项目库 + * @param userName 用户名 + * @param history 历史记录 + * @param suggestion 用户建议 + * @return JSON格式的审计表数据 + */ + JSONObject generateBudgetManageTableData(String kbIds, String libraryKbIds, String projectLibrary, + String userName, String history, String suggestion, Object data); +} \ No newline at end of file diff --git a/src/main/java/com/gxwebsoft/ai/service/impl/AuditContent5BudgetExecutionServiceImpl.java b/src/main/java/com/gxwebsoft/ai/service/impl/AuditContent5BudgetExecutionServiceImpl.java new file mode 100644 index 0000000..0c30ad5 --- /dev/null +++ b/src/main/java/com/gxwebsoft/ai/service/impl/AuditContent5BudgetExecutionServiceImpl.java @@ -0,0 +1,313 @@ +package com.gxwebsoft.ai.service.impl; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.gxwebsoft.ai.constants.AuditContent5BudgetExecutionConstants; +import com.gxwebsoft.ai.service.AuditContent5BudgetExecutionService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; + +import java.util.*; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class AuditContent5BudgetExecutionServiceImpl extends AbstractAuditContentService implements AuditContent5BudgetExecutionService { + + // 工作流配置 + private static final String DIFY_WORKFLOW_TOKEN = "Bearer app-40NwSJCFSFKkOwRdGe8nqVsA"; + + @Override + public JSONObject generateBudgetExecutionTableData(String kbIds, String libraryKbIds, String projectLibrary, + String userName, String history, String suggestion, Object data) { + log.info("开始生成预算执行情况审计表数据 - 用户: {}, kbIds: {}, libraryIds: {}, projectLibrary: {}", + userName, kbIds, libraryKbIds, projectLibrary); + + long startTime = System.currentTimeMillis(); + + try { + if (ObjectUtil.isEmpty(data)) { + JSONObject result = new JSONObject(); + log.warn("未传入预算管理审计数据,无法生成预算执行情况审计表"); + result.put("success", false); + result.put("error", "需要预算管理审计数据作为生成依据"); + return result; + } + + // 1. 检索相关知识 + Map> knowledgeSources = retrieveKnowledgeForBudgetExecution( + kbIds, libraryKbIds, projectLibrary + ); + + // 2. 构建完整的知识上下文(包含预算管理数据) + String knowledgeContext = buildCompleteKnowledgeContext(knowledgeSources, history, suggestion, data.toString()); + + // 3. 调用工作流生成数据 + JSONObject requestBody = buildWorkflowRequest(knowledgeContext, userName); + JSONArray auditData = callWorkflow(DIFY_WORKFLOW_URL, DIFY_WORKFLOW_TOKEN, requestBody, "预算执行情况审计"); + + log.info("预算执行情况审计表生成成功 - 记录数: {}, 处理时间: {}ms", + auditData.size(), (System.currentTimeMillis() - startTime)); + + return buildSuccessResponse(auditData, startTime, "budget_execution_audit"); + + } catch (Exception e) { + log.error("生成预算执行情况审计表失败", e); + return buildErrorResponse("生成预算执行情况审计表失败: " + e.getMessage()); + } + } + + /** + * 检索预算执行情况相关知识 + */ + private Map> retrieveKnowledgeForBudgetExecution(String kbIds, String libraryKbIds, String projectLibrary) { + Map> knowledgeSources = new HashMap<>(); + knowledgeSources.put("enterprise", new ArrayList<>()); + knowledgeSources.put("regulation", new ArrayList<>()); + knowledgeSources.put("auditCase", new ArrayList<>()); + knowledgeSources.put("financial", new ArrayList<>()); + + // 构建查询词 - 具体化,提高识别率 + List queries = buildBudgetExecutionQueries(); + + // 企业单位库检索 - 增加查询深度 + if (StrUtil.isNotBlank(kbIds)) { + Arrays.stream(kbIds.split(",")) + .map(String::trim) + .filter(StrUtil::isNotBlank) + .forEach(kbId -> knowledgeSources.get("enterprise") + .addAll(queryKnowledgeBase(kbId, queries, 100))); + } + + // 公共法律法规库检索 + if (StrUtil.isNotBlank(libraryKbIds)) { + Arrays.stream(libraryKbIds.split(",")) + .map(String::trim) + .filter(StrUtil::isNotBlank) + .forEach(libId -> knowledgeSources.get("regulation") + .addAll(queryKnowledgeBase(libId, queries, 100))); + } + + // 审计案例库检索 + if (StrUtil.isNotBlank(projectLibrary)) { + knowledgeSources.get("auditCase").addAll( + queryKnowledgeBase(projectLibrary, queries, 80)); + } + + // 财务知识库检索(预算执行相关) + if (StrUtil.isNotBlank(kbIds)) { + knowledgeSources.get("financial").addAll( + queryKnowledgeBase(kbIds.split(",")[0], buildFinancialExecutionQueries(), 120)); + } + + // 智能去重和排序 + knowledgeSources.forEach((key, list) -> { + List processed = list.stream() + .map(String::trim) // 去除首尾空格 + .filter(str -> !StrUtil.isBlank(str)) // 过滤空字符串 + .distinct() + .sorted(this::budgetExecutionComparator) + .limit(getLimitBySourceType(key)) + .collect(Collectors.toList()); + knowledgeSources.put(key, processed); + }); + + log.debug("预算执行情况知识检索完成 - 企业: {}条, 法规: {}条, 案例: {}条, 财务: {}条", + knowledgeSources.get("enterprise").size(), + knowledgeSources.get("regulation").size(), + knowledgeSources.get("auditCase").size(), + knowledgeSources.get("financial").size()); + + return knowledgeSources; + } + + /** + * 构建预算执行情况查询词 - 具体化 + */ + private List buildBudgetExecutionQueries() { + return Arrays.asList( + "预算执行率 执行进度 进度报表", + "实际拨款 拨款到位 资金拨付", + "预算调整 追加预算 调整审批", + "预算执行分析 执行情况分析 执行报告", + "项目执行 项目实施 项目进度", + "资金使用 资金拨付 资金到位", + "指标结余 预算结余 结转结余", + "预算执行偏差 执行差异 差异分析", + "月度执行 季度执行 年度执行", + "预算执行监督 执行检查 执行审计", + "预算执行效果 执行效益 执行成果", + "预算执行合规 执行规范 执行合法", + "预算执行台账 执行记录 执行日志", + "拨款凭证 付款凭证 资金支付", + "预算执行预警 执行风险 风险预警", + "预算执行考核 执行评价 绩效考核", + "预算执行整改 执行问题 整改措施", + "预算执行信息化 执行系统 电子台账", + "预算执行报告 执行汇报 执行总结", + "预算执行公开 执行透明 信息公开" + ); + } + + /** + * 构建财务执行相关查询词 + */ + private List buildFinancialExecutionQueries() { + return Arrays.asList( + "财务报表 财务报告 会计报表", + "资金流水 银行流水 现金流水", + "支付凭证 付款记录 银行回单", + "预算执行表 执行进度表 执行明细", + "决算报表 决算报告 决算分析", + "费用报销 报销凭证 报销记录", + "项目支出 项目付款 项目结算", + "资金监管 资金监控 资金跟踪", + "财务分析 执行分析 差异分析", + "审计报告 审计意见 审计整改" + ); + } + + /** + * 构建完整的知识上下文 + */ + private String buildCompleteKnowledgeContext(Map> knowledgeSources, + String history, String suggestion, String data) { + StringBuilder context = new StringBuilder(); + + // 1. 核心审计任务 + context.append("## 核心审计任务\n"); + context.append("审计分类:").append(AuditContent5BudgetExecutionConstants.CATEGORY_BUDGET_EXECUTION).append("\n"); + context.append("审计描述:检查预算执行的进度、合规性、效果,分析预算执行偏差原因,评估预算执行效益\n\n"); + + // 2. 审计框架(审计规则) + context.append("## 审计框架(审计规则)\n"); + context.append("以下审计框架定义了审计范围和要点,请基于此框架开展工作:\n"); + context.append(AuditContent5BudgetExecutionConstants.AUDIT_FRAMEWORK).append("\n\n"); + + // 3. 审计目标 + context.append("## 审计目标\n"); + context.append(AuditContent5BudgetExecutionConstants.AUDIT_OBJECTIVE).append("\n\n"); + + // 4. 审计工作原则 + context.append("## 审计工作原则\n"); + context.append(AuditContent5BudgetExecutionConstants.AUDIT_PRINCIPLES).append("\n\n"); + + // 4.5. 预算管理审计数据(作为上下文) + if (ObjectUtil.isNotEmpty(data)) { + context.append("## 预算管理审计数据(作为参考上下文)\n"); + context.append(data).append("\n\n"); + } + + // 5. 企业单位知识(主要考察内容) + if (!knowledgeSources.get("enterprise").isEmpty()) { + context.append("## 企业单位知识(具体考察内容)\n"); + context.append("以下是企业单位的实际预算执行资料,请基于审计框架,结合这些具体内容生成审计记录:\n\n"); + knowledgeSources.get("enterprise").forEach(knowledge -> + context.append("• ").append(knowledge).append("\n")); + context.append("\n"); + } + + // 6. 财务知识(预算执行相关) + if (!knowledgeSources.get("financial").isEmpty()) { + context.append("## 财务知识(预算执行相关)\n"); + context.append("以下是财务相关预算执行资料,包括预算执行进度、资金拨付等信息:\n\n"); + knowledgeSources.get("financial").forEach(knowledge -> + context.append("• ").append(knowledge).append("\n")); + context.append("\n"); + } + + // 7. 审计要点提示 + context.append("## 审计要点提示\n"); + context.append(AuditContent5BudgetExecutionConstants.AUDIT_KEY_POINTS).append("\n\n"); + + // 8. 数据格式要求 + context.append("## 数据格式要求\n"); + context.append("请生成JSON数组格式的审计表数据,每个审计条目包含以下字段:\n"); + context.append(AuditContent5BudgetExecutionConstants.OUTPUT_FORMAT).append("\n\n"); + + // 9. 审计证据要求 + context.append("## 审计证据要求\n"); + context.append(AuditContent5BudgetExecutionConstants.AUDIT_EVIDENCE_REQUIREMENTS).append("\n\n"); + + // 10. 特别提醒 - 强调全面识别 + context.append("## 特别提醒\n"); + context.append("1. 必须全面分析预算执行全过程,包括执行进度、执行效果、执行合规性\n"); + context.append("2. 重点关注预算执行率、资金到位率、预算执行偏差等关键指标\n"); + context.append("3. 金额字段应填写具体数值,如\"1,000,000.00\",不能填写简单的\"有\"或\"无\"\n"); + context.append("4. workPaperIndex必须填写实际存在的完整文件名\n"); + context.append("5. 对于无数据的字段,可填写\"-\"或留空,但不能填写\"无\"\n"); + context.append("6. 基于预算执行全流程进行审计分析,包括月度、季度、年度执行情况\n"); + context.append("7. 重点关注预算执行偏差原因分析和整改措施\n"); + context.append("8. 尽可能多地生成审计记录,覆盖所有预算项目和执行环节\n\n"); + + // 11. 审计项目参考 + context.append("## 审计项目参考(常见类型)\n"); + AuditContent5BudgetExecutionConstants.AUDIT_PROJECT_TYPES.forEach(project -> + context.append("• ").append(project).append("\n")); + context.append("\n"); + + // 12. 法规和案例参考 + if (!knowledgeSources.get("regulation").isEmpty()) { + context.append("## 法律法规参考\n"); + knowledgeSources.get("regulation").forEach(knowledge -> + context.append("• ").append(knowledge).append("\n")); + context.append("\n"); + } + + if (!knowledgeSources.get("auditCase").isEmpty()) { + context.append("## 审计案例参考\n"); + knowledgeSources.get("auditCase").forEach(knowledge -> + context.append("• ").append(knowledge).append("\n")); + context.append("\n"); + } + + // 13. 历史内容(如果有) + if (StrUtil.isNotBlank(history)) { + context.append("## 历史生成内容\n"); + context.append(history).append("\n\n"); + } + + // 14. 用户建议(如果有) + if (StrUtil.isNotBlank(suggestion)) { + context.append("## 用户建议\n"); + context.append(suggestion).append("\n\n"); + } + + log.debug("预算执行情况审计知识上下文长度: {} 字符", context.length()); + + return context.toString(); + } + + /** + * 预算执行情况审计相关性比较器 + */ + private int budgetExecutionComparator(String reg1, String reg2) { + int score1 = calculateBudgetExecutionRelevanceScore(reg1); + int score2 = calculateBudgetExecutionRelevanceScore(reg2); + return Integer.compare(score2, score1); // 降序排序 + } + + /** + * 计算预算执行情况审计相关性分数 + */ + private int calculateBudgetExecutionRelevanceScore(String content) { + return AuditContent5BudgetExecutionConstants.KEYWORD_WEIGHTS.entrySet().stream() + .filter(entry -> content.contains(entry.getKey())) + .mapToInt(Map.Entry::getValue) + .sum(); + } + + private int getLimitBySourceType(String sourceType) { + switch (sourceType) { + case "enterprise": return 250; + case "financial": return 150; + case "regulation": return 60; + case "auditCase": return 40; + default: return 50; + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/gxwebsoft/ai/service/impl/AuditContent5BudgetManageServiceImpl.java b/src/main/java/com/gxwebsoft/ai/service/impl/AuditContent5BudgetManageServiceImpl.java new file mode 100644 index 0000000..12b46e3 --- /dev/null +++ b/src/main/java/com/gxwebsoft/ai/service/impl/AuditContent5BudgetManageServiceImpl.java @@ -0,0 +1,312 @@ +package com.gxwebsoft.ai.service.impl; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.gxwebsoft.ai.constants.AuditContent5BudgetManageConstants; +import com.gxwebsoft.ai.service.AuditContent5BudgetManageService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; + +import java.util.*; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class AuditContent5BudgetManageServiceImpl extends AbstractAuditContentService implements AuditContent5BudgetManageService { + + // 工作流配置 + private static final String DIFY_WORKFLOW_TOKEN = "Bearer app-ZGILK3nfQ9A0jHot1r4Tta0r"; + + @Override + public JSONObject generateBudgetManageTableData(String kbIds, String libraryKbIds, String projectLibrary, + String userName, String history, String suggestion, Object data) { + log.info("开始生成预算管理审计表数据 - 用户: {}, kbIds: {}, libraryIds: {}, projectLibrary: {}", + userName, kbIds, libraryKbIds, projectLibrary); + + long startTime = System.currentTimeMillis(); + + try { + if (ObjectUtil.isEmpty(data)) { + JSONObject result = new JSONObject(); + log.warn("未传入审计内容6大数据,无法生成预算管理审计表"); + result.put("success", false); + result.put("error", "需要审计内容6数据作为生成依据"); + return result; + } + + // 1. 检索相关知识 + Map> knowledgeSources = retrieveKnowledgeForBudgetManagement( + kbIds, libraryKbIds, projectLibrary + ); + + // 2. 构建完整的知识上下文 + String knowledgeContext = buildCompleteKnowledgeContext(knowledgeSources, history, suggestion, data.toString()); + + // 3. 调用工作流生成数据 + JSONObject requestBody = buildWorkflowRequest(knowledgeContext, userName); + JSONArray auditData = callWorkflow(DIFY_WORKFLOW_URL, DIFY_WORKFLOW_TOKEN, requestBody, "预算管理审计"); + + log.info("预算管理审计表生成成功 - 记录数: {}, 处理时间: {}ms", + auditData.size(), (System.currentTimeMillis() - startTime)); + + return buildSuccessResponse(auditData, startTime, "budget_manage_audit"); + + } catch (Exception e) { + log.error("生成预算管理审计表失败", e); + return buildErrorResponse("生成预算管理审计表失败: " + e.getMessage()); + } + } + + /** + * 检索预算管理相关知识 + */ + private Map> retrieveKnowledgeForBudgetManagement(String kbIds, String libraryKbIds, String projectLibrary) { + Map> knowledgeSources = new HashMap<>(); + knowledgeSources.put("enterprise", new ArrayList<>()); + knowledgeSources.put("regulation", new ArrayList<>()); + knowledgeSources.put("auditCase", new ArrayList<>()); + knowledgeSources.put("financial", new ArrayList<>()); + + // 构建查询词 - 具体化,提高识别率 + List queries = buildBudgetManagementQueries(); + + // 企业单位库检索 - 增加查询深度 + if (StrUtil.isNotBlank(kbIds)) { + Arrays.stream(kbIds.split(",")) + .map(String::trim) + .filter(StrUtil::isNotBlank) + .forEach(kbId -> knowledgeSources.get("enterprise") + .addAll(queryKnowledgeBase(kbId, queries, 100))); + } + + // 公共法律法规库检索 + if (StrUtil.isNotBlank(libraryKbIds)) { + Arrays.stream(libraryKbIds.split(",")) + .map(String::trim) + .filter(StrUtil::isNotBlank) + .forEach(libId -> knowledgeSources.get("regulation") + .addAll(queryKnowledgeBase(libId, queries, 100))); + } + + // 审计案例库检索 + if (StrUtil.isNotBlank(projectLibrary)) { + knowledgeSources.get("auditCase").addAll( + queryKnowledgeBase(projectLibrary, queries, 80)); + } + + // 财务知识库检索(预算相关) + if (StrUtil.isNotBlank(kbIds)) { + knowledgeSources.get("financial").addAll( + queryKnowledgeBase(kbIds.split(",")[0], buildFinancialQueries(), 120)); + } + + // 智能去重和排序 + knowledgeSources.forEach((key, list) -> { + List processed = list.stream() + .map(String::trim) // 去除首尾空格 + .filter(str -> !StrUtil.isBlank(str)) // 过滤空字符串 + .distinct() + .sorted(this::budgetManagementComparator) + .limit(getLimitBySourceType(key)) + .collect(Collectors.toList()); + knowledgeSources.put(key, processed); + }); + + log.debug("预算管理知识检索完成 - 企业: {}条, 法规: {}条, 案例: {}条, 财务: {}条", + knowledgeSources.get("enterprise").size(), + knowledgeSources.get("regulation").size(), + knowledgeSources.get("auditCase").size(), + knowledgeSources.get("financial").size()); + + return knowledgeSources; + } + + /** + * 构建预算管理查询词 - 具体化 + */ + private List buildBudgetManagementQueries() { + return Arrays.asList( + "部门预算 预算编制 预算报表", + "预算调整 追加预算 预算调剂", + "预算执行 预算决算 决算报表", + "指标来源 指标运用 指标结余", + "财政拨款 资金拨付 经费拨款", + "工资统发 人员经费 工资发放", + "政府采购 采购预算 采购资金", + "财政管理专户 专户管理 资金专户", + "项目预算 项目申报 项目资金", + "预算科目 科目设置 会计科目", + "上年结余 结余资金 结转资金", + "年初预算 年度预算 预算安排", + "追加预算 预算追加 调整预算", + "预算审批 审批手续 审批流程", + "预算下达 预算批复 批复文件", + "会计处理 账务处理 财务处理", + "预算调剂 科目调剂 资金调剂", + "经营收支 经营预算 企业预算", + "可行性研究 项目评审 评审报告", + "执行单位 实施单位 承办单位" + ); + } + + /** + * 构建财务相关查询词 + */ + private List buildFinancialQueries() { + return Arrays.asList( + "财务报表 财务报告 会计报表", + "会计凭证 记账凭证 原始凭证", + "会计账簿 总账 明细账", + "资金流水 银行流水 现金流水", + "收支明细 收入支出 收付实现", + "经费支出 费用报销 报销凭证", + "工资表 工资发放表 人员工资", + "采购发票 采购合同 付款凭证", + "预算执行表 执行进度 进度报表", + "决算报告 决算分析 决算说明" + ); + } + + /** + * 构建完整的知识上下文 + */ + private String buildCompleteKnowledgeContext(Map> knowledgeSources, + String history, String suggestion, String data) { + StringBuilder context = new StringBuilder(); + + // 1. 核心审计任务 + context.append("## 核心审计任务\n"); + context.append("审计分类:").append(AuditContent5BudgetManageConstants.CATEGORY_BUDGET_MANAGEMENT).append("\n"); + context.append("审计描述:检查预算编制的完整准确、预算调整审批的合规,以及预算支出的真实合法合规情况\n\n"); + + // 2. 审计框架(审计规则) + context.append("## 审计框架(审计规则)\n"); + context.append("以下审计框架定义了审计范围和要点,请基于此框架开展工作:\n"); + context.append(AuditContent5BudgetManageConstants.AUDIT_FRAMEWORK).append("\n\n"); + + // 3. 审计目标 + context.append("## 审计目标\n"); + context.append(AuditContent5BudgetManageConstants.AUDIT_OBJECTIVE).append("\n\n"); + + // 4. 审计工作原则 + context.append("## 审计工作原则\n"); + context.append(AuditContent5BudgetManageConstants.AUDIT_PRINCIPLES).append("\n\n"); + + // 4.5. 国有资产的管理情况、政府采购执行情况,审计内容6数据(作为上下文) + if (StrUtil.isNotBlank(data)) { + context.append("## 国有资产的管理情况、政府采购执行情况,审计内容6分析数据(作为参考上下文)\n"); + context.append(data).append("\n\n"); + } + + // 5. 企业单位知识(主要考察内容) + if (!knowledgeSources.get("enterprise").isEmpty()) { + context.append("## 企业单位知识(具体考察内容)\n"); + context.append("以下是企业单位的实际资料,请基于审计框架,结合这些具体内容生成审计记录:\n\n"); + knowledgeSources.get("enterprise").forEach(knowledge -> + context.append("• ").append(knowledge).append("\n")); + context.append("\n"); + } + + // 6. 财务知识(预算相关) + if (!knowledgeSources.get("financial").isEmpty()) { + context.append("## 财务知识(预算相关)\n"); + context.append("以下是财务相关资料,包括预算编制、执行、调整等信息:\n\n"); + knowledgeSources.get("financial").forEach(knowledge -> + context.append("• ").append(knowledge).append("\n")); + context.append("\n"); + } + + // 7. 审计要点提示 + context.append("## 审计要点提示\n"); + context.append(AuditContent5BudgetManageConstants.AUDIT_KEY_POINTS).append("\n\n"); + + // 8. 数据格式要求 + context.append("## 数据格式要求\n"); + context.append("请生成JSON数组格式的审计表数据,每个审计条目包含以下字段:\n"); + context.append(AuditContent5BudgetManageConstants.OUTPUT_FORMAT).append("\n\n"); + + // 9. 审计证据要求 + context.append("## 审计证据要求\n"); + context.append(AuditContent5BudgetManageConstants.AUDIT_EVIDENCE_REQUIREMENTS).append("\n\n"); + + // 10. 特别提醒 - 强调全面识别 + context.append("## 特别提醒\n"); + context.append("1. 必须全面识别知识库中所有预算科目,包括:基本支出、项目支出、人员经费、公用经费等\n"); + context.append("2. 每个独立的预算科目都要生成独立的审计记录,不限制数量,尽可能多地生成\n"); + context.append("3. 金额字段应填写具体数值,如\"1,000,000.00\",不能填写简单的\"有\"或\"无\"\n"); + context.append("4. workPaperIndex必须填写实际存在的完整文件名\n"); + context.append("5. 对于无数据的字段,可填写\"-\"或留空,但不能填写\"无\"\n"); + context.append("6. 基于预算编制、调整、执行的全流程进行审计分析\n"); + context.append("7. 重点关注预算调整的合规性和预算执行的真实性\n\n"); + + // 11. 预算科目参考 + context.append("## 预算科目参考(常见类型)\n"); + AuditContent5BudgetManageConstants.BUDGET_SUBJECT_TYPES.forEach(subject -> + context.append("• ").append(subject).append("\n")); + context.append("\n"); + + // 12. 法规和案例参考 + if (!knowledgeSources.get("regulation").isEmpty()) { + context.append("## 法律法规参考\n"); + knowledgeSources.get("regulation").forEach(knowledge -> + context.append("• ").append(knowledge).append("\n")); + context.append("\n"); + } + + if (!knowledgeSources.get("auditCase").isEmpty()) { + context.append("## 审计案例参考\n"); + knowledgeSources.get("auditCase").forEach(knowledge -> + context.append("• ").append(knowledge).append("\n")); + context.append("\n"); + } + + // 13. 历史内容(如果有) + if (StrUtil.isNotBlank(history)) { + context.append("## 历史生成内容\n"); + context.append(history).append("\n\n"); + } + + // 14. 用户建议(如果有) + if (StrUtil.isNotBlank(suggestion)) { + context.append("## 用户建议\n"); + context.append(suggestion).append("\n\n"); + } + + log.debug("预算管理审计知识上下文长度: {} 字符", context.length()); + + return context.toString(); + } + + /** + * 预算管理审计相关性比较器 + */ + private int budgetManagementComparator(String reg1, String reg2) { + int score1 = calculateBudgetManagementRelevanceScore(reg1); + int score2 = calculateBudgetManagementRelevanceScore(reg2); + return Integer.compare(score2, score1); // 降序排序 + } + + /** + * 计算预算管理审计相关性分数 + */ + private int calculateBudgetManagementRelevanceScore(String content) { + return AuditContent5BudgetManageConstants.KEYWORD_WEIGHTS.entrySet().stream() + .filter(entry -> content.contains(entry.getKey())) + .mapToInt(Map.Entry::getValue) + .sum(); + } + + private int getLimitBySourceType(String sourceType) { + switch (sourceType) { + case "enterprise": return 250; + case "financial": return 150; + case "regulation": return 60; + case "auditCase": return 40; + default: return 50; + } + } + +} \ No newline at end of file