新增审计内容11-历史审计问题整改接口
This commit is contained in:
@@ -0,0 +1,90 @@
|
|||||||
|
package com.gxwebsoft.ai.constants;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 审计内容11-历史审计问题整改常量类
|
||||||
|
*/
|
||||||
|
public class AuditContent11HistoryConstants {
|
||||||
|
|
||||||
|
// 审计类型分类
|
||||||
|
public static final String AUDIT_TYPE_INTERNAL = "内部审计";
|
||||||
|
public static final String AUDIT_TYPE_EXTERNAL = "外部审计";
|
||||||
|
public static final String AUDIT_TYPE_SPECIAL = "专项审计";
|
||||||
|
public static final String AUDIT_TYPE_ECONOMIC = "经济责任审计";
|
||||||
|
|
||||||
|
// 整改状态
|
||||||
|
public static final String STATUS_COMPLETED = "已完成";
|
||||||
|
public static final String STATUS_IN_PROGRESS = "整改中";
|
||||||
|
public static final String STATUS_NOT_STARTED = "未整改";
|
||||||
|
public static final String STATUS_PARTIAL = "部分整改";
|
||||||
|
|
||||||
|
// 审计重点分类
|
||||||
|
public static final String FOCUS_SYSTEM_MECHANISM = "制度机制建立情况";
|
||||||
|
public static final String FOCUS_HISTORICAL_ISSUES = "历史遗留问题处理";
|
||||||
|
public static final String FOCUS_RECTIFICATION_EFFECT = "整改数量及效果";
|
||||||
|
public static final String FOCUS_SYSTEM_IMPROVEMENT = "制度完善情况";
|
||||||
|
public static final String FOCUS_SELF_RECTIFICATION = "自行发现整改情况";
|
||||||
|
|
||||||
|
// 审计方法关键词
|
||||||
|
public static final String METHOD_REVIEW_REPORT = "审阅审计报告";
|
||||||
|
public static final String METHOD_REVIEW_RECTIFICATION = "审阅整改报告";
|
||||||
|
public static final String METHOD_VERIFY_RECTIFICATION = "核实整改情况";
|
||||||
|
public static final String METHOD_INTERVIEW = "个别访谈";
|
||||||
|
public static final String METHOD_REVIEW_DOCS = "查阅相关资料";
|
||||||
|
|
||||||
|
// 分类描述
|
||||||
|
public static final Map<String, String> FOCUS_DESCRIPTIONS = new HashMap<>();
|
||||||
|
static {
|
||||||
|
FOCUS_DESCRIPTIONS.put(FOCUS_SYSTEM_MECHANISM, "是否有处理历史遗留问题的制度机制");
|
||||||
|
FOCUS_DESCRIPTIONS.put(FOCUS_HISTORICAL_ISSUES, "任期内是否有处理非任期的历史遗留问题");
|
||||||
|
FOCUS_DESCRIPTIONS.put(FOCUS_RECTIFICATION_EFFECT, "对历次审计检查发现的问题整改的数量及效果");
|
||||||
|
FOCUS_DESCRIPTIONS.put(FOCUS_SYSTEM_IMPROVEMENT, "历次审计检查发现问题后是否有完善相关制度");
|
||||||
|
FOCUS_DESCRIPTIONS.put(FOCUS_SELF_RECTIFICATION, "历次审计没有发现的问题是否自行发现并整改完善");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 审计方法描述
|
||||||
|
public static final Map<String, String> METHOD_DESCRIPTIONS = new HashMap<>();
|
||||||
|
static {
|
||||||
|
METHOD_DESCRIPTIONS.put(METHOD_REVIEW_REPORT, "审阅任职期间审计报告");
|
||||||
|
METHOD_DESCRIPTIONS.put(METHOD_REVIEW_RECTIFICATION, "审阅整改情况报告");
|
||||||
|
METHOD_DESCRIPTIONS.put(METHOD_VERIFY_RECTIFICATION, "对提出问题整改情况逐一进行核实");
|
||||||
|
METHOD_DESCRIPTIONS.put(METHOD_INTERVIEW, "通过个别访谈了解情况");
|
||||||
|
METHOD_DESCRIPTIONS.put(METHOD_REVIEW_DOCS, "查阅相关资料了解单位存在的历年遗留问题和处理情况");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关键词权重(用于知识检索排序)
|
||||||
|
public static final Map<String, Integer> KEYWORD_WEIGHTS = new HashMap<>();
|
||||||
|
static {
|
||||||
|
KEYWORD_WEIGHTS.put("审计发现问题", 10);
|
||||||
|
KEYWORD_WEIGHTS.put("问题整改", 9);
|
||||||
|
KEYWORD_WEIGHTS.put("整改情况", 9);
|
||||||
|
KEYWORD_WEIGHTS.put("整改报告", 8);
|
||||||
|
KEYWORD_WEIGHTS.put("审计报告", 8);
|
||||||
|
KEYWORD_WEIGHTS.put("历史遗留问题", 9);
|
||||||
|
KEYWORD_WEIGHTS.put("制度机制", 7);
|
||||||
|
KEYWORD_WEIGHTS.put("整改措施", 7);
|
||||||
|
KEYWORD_WEIGHTS.put("整改责任人", 6);
|
||||||
|
KEYWORD_WEIGHTS.put("整改完成", 6);
|
||||||
|
KEYWORD_WEIGHTS.put("审计年度", 5);
|
||||||
|
KEYWORD_WEIGHTS.put("审计类型", 5);
|
||||||
|
KEYWORD_WEIGHTS.put("经济责任审计", 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 整改要求常见关键词
|
||||||
|
public static final String[] RECTIFICATION_REQUIREMENT_KEYWORDS = {
|
||||||
|
"限期整改", "建立机制", "完善制度", "责任追究", "资金追回",
|
||||||
|
"规范管理", "加强内控", "落实责任", "建立台账", "跟踪检查"
|
||||||
|
};
|
||||||
|
|
||||||
|
// 整改措施常见关键词
|
||||||
|
public static final String[] RECTIFICATION_MEASURES_KEYWORDS = {
|
||||||
|
"修订制度", "完善流程", "加强培训", "调整人员", "资金归还",
|
||||||
|
"建立台账", "完善手续", "强化监督", "责任追究", "定期检查"
|
||||||
|
};
|
||||||
|
|
||||||
|
private AuditContent11HistoryConstants() {
|
||||||
|
// 防止实例化
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,297 @@
|
|||||||
|
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.HistoryTableExportEntity;
|
||||||
|
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.AuditContent11HistoryService;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 审计内容11控制器 - 历史审计问题整改表
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Tag(name = "审计内容11-历史审计问题整改")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/ai/auditContent11")
|
||||||
|
public class AuditContent11Controller extends BaseController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AuditContent11HistoryService auditContent11HistoryService;
|
||||||
|
|
||||||
|
@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("/generateHistoryTable")
|
||||||
|
public ApiResult<?> generateHistoryTable(@RequestBody AuditContentRequest request, HttpServletRequest servletRequest) {
|
||||||
|
return generateTableData(request, servletRequest.getRequestURI(),
|
||||||
|
(params) -> auditContent11HistoryService.generateHistoryTableData(
|
||||||
|
params.knowledgeBaseId, params.libraryKbIds, params.projectLibrary,
|
||||||
|
params.username, params.history, params.suggestion
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出历史审计问题整改表到Excel
|
||||||
|
*/
|
||||||
|
@Operation(summary = "导出历史审计问题整改表到Excel")
|
||||||
|
@PostMapping("/exportHistoryTable")
|
||||||
|
public void exportHistoryTable(@RequestBody Map<String, Object> request, HttpServletResponse response) {
|
||||||
|
List<Map<String, Object>> dataList = (List<Map<String, Object>>) request.get("data");
|
||||||
|
String companyName = (String) request.get("companyName");
|
||||||
|
String auditTime = (String) request.get("auditTime");
|
||||||
|
|
||||||
|
List<HistoryTableExportEntity> exportData = convertToHistoryTableEntityList(dataList);
|
||||||
|
|
||||||
|
String fileName = "历史审计问题整改表_" + (companyName != null ? companyName : "未知公司");
|
||||||
|
String sheetName = "历史审计问题整改表";
|
||||||
|
String title = companyName != null ?
|
||||||
|
companyName + " - 历史审计问题整改表" + (auditTime != null ? "(" + auditTime + ")" : "") :
|
||||||
|
"历史审计问题整改表";
|
||||||
|
|
||||||
|
ExcelExportTool.exportExcel(exportData, HistoryTableExportEntity.class, fileName, sheetName, title, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用的表格数据生成方法
|
||||||
|
*/
|
||||||
|
private ApiResult<?> generateTableData(AuditContentRequest request, String interfaceName, Function<GenerateParams, JSONObject> 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("生成历史审计问题整改表数据失败", 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<String> idList = StrUtil.split(libraryIds, ',');
|
||||||
|
List<PwlProjectLibrary> ret = pwlProjectLibraryService.list(new LambdaQueryWrapper<PwlProjectLibrary>().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<Integer> docIds = request.getDocList().stream().flatMap(docId -> aiCloudDocService.getSelfAndChildren(docId).stream()).map(AiCloudDoc::getId).collect(Collectors.toSet());
|
||||||
|
// 查询相关文件
|
||||||
|
List<AiCloudFile> fileList = getRelatedFiles(docIds, request.getFileList());
|
||||||
|
// 提取文件ID并提交到知识库
|
||||||
|
Set<String> kbFileIds = fileList.stream().map(AiCloudFile::getFileId).collect(Collectors.toSet());
|
||||||
|
if (!kbFileIds.isEmpty()) {
|
||||||
|
knowledgeBaseService.submitDocuments(kbIdTmp, new ArrayList<>(kbFileIds));
|
||||||
|
}
|
||||||
|
return kbIdTmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取相关文件列表
|
||||||
|
*/
|
||||||
|
private List<AiCloudFile> getRelatedFiles(Set<Integer> docIds, List<Integer> fileList) {
|
||||||
|
LambdaQueryWrapper<AiCloudFile> queryWrapper = new LambdaQueryWrapper<AiCloudFile>()
|
||||||
|
.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 数据转换方法 ==========
|
||||||
|
|
||||||
|
private List<HistoryTableExportEntity> convertToHistoryTableEntityList(List<Map<String, Object>> originalData) {
|
||||||
|
return originalData.stream()
|
||||||
|
.map(this::convertToHistoryTableEntity)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private HistoryTableExportEntity convertToHistoryTableEntity(Map<String, Object> item) {
|
||||||
|
HistoryTableExportEntity entity = new HistoryTableExportEntity();
|
||||||
|
entity.setIndex(getStringValue(item, "index"));
|
||||||
|
entity.setAuditYear(getStringValue(item, "auditYear"));
|
||||||
|
entity.setAuditType(getStringValue(item, "auditType"));
|
||||||
|
entity.setProblemFound(getStringValue(item, "problemFound"));
|
||||||
|
entity.setRectificationRequirement(getStringValue(item, "rectificationRequirement"));
|
||||||
|
entity.setRectificationMeasures(getStringValue(item, "rectificationMeasures"));
|
||||||
|
entity.setRectificationStatus(getStringValue(item, "rectificationStatus"));
|
||||||
|
entity.setCompletionDate(getStringValue(item, "completionDate"));
|
||||||
|
entity.setResponsiblePerson(getStringValue(item, "responsiblePerson"));
|
||||||
|
entity.setRemark(getStringValue(item, "remark"));
|
||||||
|
entity.setWorkPaperIndex(formatWorkPaperIndex(item.get("workPaperIndex")));
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getStringValue(Map<String, Object> 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参数包装类
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
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("HistoryTableExportEntity")
|
||||||
|
public class HistoryTableExportEntity {
|
||||||
|
|
||||||
|
@Excel(name = "序号", orderNum = "1", width = 8)
|
||||||
|
private String index;
|
||||||
|
|
||||||
|
@Excel(name = "审计年度", orderNum = "2", width = 12)
|
||||||
|
private String auditYear;
|
||||||
|
|
||||||
|
@Excel(name = "审计类型", orderNum = "3", width = 15)
|
||||||
|
private String auditType;
|
||||||
|
|
||||||
|
@Excel(name = "审计发现的问题", orderNum = "4", width = 40, needMerge = true)
|
||||||
|
private String problemFound;
|
||||||
|
|
||||||
|
@Excel(name = "整改要求", orderNum = "5", width = 30, needMerge = true)
|
||||||
|
private String rectificationRequirement;
|
||||||
|
|
||||||
|
@Excel(name = "整改措施", orderNum = "6", width = 30, needMerge = true)
|
||||||
|
private String rectificationMeasures;
|
||||||
|
|
||||||
|
@Excel(name = "整改完成情况", orderNum = "7", width = 15)
|
||||||
|
private String rectificationStatus;
|
||||||
|
|
||||||
|
@Excel(name = "整改完成时间", orderNum = "8", width = 15)
|
||||||
|
private String completionDate;
|
||||||
|
|
||||||
|
@Excel(name = "整改责任人", orderNum = "9", width = 15)
|
||||||
|
private String responsiblePerson;
|
||||||
|
|
||||||
|
@Excel(name = "备注", orderNum = "10", width = 20, needMerge = true)
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
@Excel(name = "工作底稿索引", orderNum = "11", width = 25, needMerge = true)
|
||||||
|
private String workPaperIndex;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.gxwebsoft.ai.service;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 审计内容11-历史审计问题整改服务接口
|
||||||
|
*/
|
||||||
|
public interface AuditContent11HistoryService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成历史审计问题整改表数据
|
||||||
|
*
|
||||||
|
* @param kbIds 知识库ID
|
||||||
|
* @param libraryKbIds 项目库知识库ID
|
||||||
|
* @param projectLibrary 项目库
|
||||||
|
* @param userName 用户名
|
||||||
|
* @param history 历史内容
|
||||||
|
* @param suggestion 用户建议
|
||||||
|
* @return JSON结果
|
||||||
|
*/
|
||||||
|
JSONObject generateHistoryTableData(String kbIds, String libraryKbIds, String projectLibrary,
|
||||||
|
String userName, String history, String suggestion);
|
||||||
|
}
|
||||||
@@ -0,0 +1,291 @@
|
|||||||
|
package com.gxwebsoft.ai.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.gxwebsoft.ai.constants.AuditContent11HistoryConstants;
|
||||||
|
import com.gxwebsoft.ai.service.AuditContent11HistoryService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class AuditContent11HistoryServiceImpl extends AbstractAuditContentService implements AuditContent11HistoryService {
|
||||||
|
|
||||||
|
// 工作流配置
|
||||||
|
private static final String DIFY_WORKFLOW_TOKEN = "Bearer app-tMty75ly5NmqQXvBGZMxOKdk";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject generateHistoryTableData(String kbIds, String libraryKbIds, String projectLibrary,
|
||||||
|
String userName, String history, String suggestion) {
|
||||||
|
log.info("开始生成历史审计问题整改表数据 - 用户: {}, kbIds: {}, libraryIds: {}, projectLibrary: {}",
|
||||||
|
userName, kbIds, libraryKbIds, projectLibrary);
|
||||||
|
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 检索相关知识
|
||||||
|
Map<String, List<String>> knowledgeSources = retrieveHistoryAuditKnowledge(
|
||||||
|
kbIds, libraryKbIds, projectLibrary
|
||||||
|
);
|
||||||
|
|
||||||
|
// 2. 构建完整的知识上下文
|
||||||
|
String knowledgeContext = buildCompleteKnowledgeContext(
|
||||||
|
knowledgeSources, history, suggestion
|
||||||
|
);
|
||||||
|
|
||||||
|
// 3. 调用工作流生成数据
|
||||||
|
JSONObject requestBody = buildWorkflowRequest(knowledgeContext, userName);
|
||||||
|
JSONArray tableData = callWorkflow(DIFY_WORKFLOW_URL, DIFY_WORKFLOW_TOKEN, requestBody, "历史审计问题整改");
|
||||||
|
|
||||||
|
// 4. 处理返回数据,确保格式正确
|
||||||
|
JSONArray processedData = processTableData(tableData);
|
||||||
|
|
||||||
|
log.info("历史审计问题整改表生成成功 - 记录数: {}, 处理时间: {}ms",
|
||||||
|
processedData.size(), (System.currentTimeMillis() - startTime));
|
||||||
|
|
||||||
|
return buildSuccessResponse(processedData, startTime, "history_audit_rectification");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("生成历史审计问题整改表失败", e);
|
||||||
|
return buildErrorResponse("生成历史审计问题整改表失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检索历史审计问题相关知识
|
||||||
|
*/
|
||||||
|
private Map<String, List<String>> retrieveHistoryAuditKnowledge(String kbIds, String libraryKbIds, String projectLibrary) {
|
||||||
|
Map<String, List<String>> knowledgeSources = new HashMap<>();
|
||||||
|
knowledgeSources.put("enterprise", new ArrayList<>());
|
||||||
|
knowledgeSources.put("auditReports", new ArrayList<>());
|
||||||
|
knowledgeSources.put("rectificationReports", new ArrayList<>());
|
||||||
|
knowledgeSources.put("regulations", new ArrayList<>());
|
||||||
|
|
||||||
|
// 构建查询关键词
|
||||||
|
List<String> queries = buildHistoryAuditQueries();
|
||||||
|
|
||||||
|
// 企业单位库检索(历史审计问题)
|
||||||
|
if (StrUtil.isNotBlank(kbIds)) {
|
||||||
|
Arrays.stream(kbIds.split(","))
|
||||||
|
.map(String::trim)
|
||||||
|
.filter(StrUtil::isNotBlank)
|
||||||
|
.forEach(kbId -> knowledgeSources.get("enterprise")
|
||||||
|
.addAll(queryKnowledgeBase(kbId, queries, 150)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 审计报告库检索
|
||||||
|
if (StrUtil.isNotBlank(libraryKbIds)) {
|
||||||
|
Arrays.stream(libraryKbIds.split(","))
|
||||||
|
.map(String::trim)
|
||||||
|
.filter(StrUtil::isNotBlank)
|
||||||
|
.forEach(libId -> {
|
||||||
|
knowledgeSources.get("auditReports")
|
||||||
|
.addAll(queryKnowledgeBase(libId, Arrays.asList("审计报告", "审计发现问题"), 100));
|
||||||
|
knowledgeSources.get("rectificationReports")
|
||||||
|
.addAll(queryKnowledgeBase(libId, Arrays.asList("整改报告", "整改情况", "整改措施"), 80));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 法律法规库检索(从项目库)
|
||||||
|
if (StrUtil.isNotBlank(projectLibrary)) {
|
||||||
|
knowledgeSources.get("regulations").addAll(
|
||||||
|
queryKnowledgeBase(projectLibrary,
|
||||||
|
Arrays.asList("审计制度", "整改机制", "责任追究"), 60));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 智能去重和排序
|
||||||
|
knowledgeSources.forEach((key, list) -> {
|
||||||
|
List<String> processed = list.stream()
|
||||||
|
.distinct()
|
||||||
|
.sorted(this::historyAuditComparator)
|
||||||
|
.limit(getLimitBySourceType(key))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
knowledgeSources.put(key, processed);
|
||||||
|
});
|
||||||
|
|
||||||
|
log.debug("历史审计问题知识检索完成 - 企业: {}条, 审计报告: {}条, 整改报告: {}条, 法规: {}条",
|
||||||
|
knowledgeSources.get("enterprise").size(),
|
||||||
|
knowledgeSources.get("auditReports").size(),
|
||||||
|
knowledgeSources.get("rectificationReports").size(),
|
||||||
|
knowledgeSources.get("regulations").size());
|
||||||
|
|
||||||
|
return knowledgeSources;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建历史审计问题查询关键词
|
||||||
|
*/
|
||||||
|
private List<String> buildHistoryAuditQueries() {
|
||||||
|
return Arrays.asList(
|
||||||
|
"审计发现问题 整改情况",
|
||||||
|
"历史审计 遗留问题",
|
||||||
|
"审计报告 整改报告",
|
||||||
|
"问题整改 措施 效果",
|
||||||
|
"审计年度 审计类型"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建完整的知识上下文
|
||||||
|
*/
|
||||||
|
private String buildCompleteKnowledgeContext(Map<String, List<String>> knowledgeSources,
|
||||||
|
String history, String suggestion) {
|
||||||
|
StringBuilder context = new StringBuilder();
|
||||||
|
|
||||||
|
// 1. 审计内容11的要求
|
||||||
|
context.append("## 审计内容11:历史审计问题整改\n");
|
||||||
|
context.append("**审计重点:**\n");
|
||||||
|
context.append("1. ").append(AuditContent11HistoryConstants.FOCUS_DESCRIPTIONS.get(AuditContent11HistoryConstants.FOCUS_SYSTEM_MECHANISM)).append("\n");
|
||||||
|
context.append("2. ").append(AuditContent11HistoryConstants.FOCUS_DESCRIPTIONS.get(AuditContent11HistoryConstants.FOCUS_HISTORICAL_ISSUES)).append("\n");
|
||||||
|
context.append("3. ").append(AuditContent11HistoryConstants.FOCUS_DESCRIPTIONS.get(AuditContent11HistoryConstants.FOCUS_RECTIFICATION_EFFECT)).append("\n");
|
||||||
|
context.append("4. ").append(AuditContent11HistoryConstants.FOCUS_DESCRIPTIONS.get(AuditContent11HistoryConstants.FOCUS_SYSTEM_IMPROVEMENT)).append("\n");
|
||||||
|
context.append("5. ").append(AuditContent11HistoryConstants.FOCUS_DESCRIPTIONS.get(AuditContent11HistoryConstants.FOCUS_SELF_RECTIFICATION)).append("\n\n");
|
||||||
|
|
||||||
|
context.append("**审计方法及步骤:**\n");
|
||||||
|
context.append("1. ").append(AuditContent11HistoryConstants.METHOD_DESCRIPTIONS.get(AuditContent11HistoryConstants.METHOD_REVIEW_REPORT)).append("\n");
|
||||||
|
context.append("2. ").append(AuditContent11HistoryConstants.METHOD_DESCRIPTIONS.get(AuditContent11HistoryConstants.METHOD_REVIEW_RECTIFICATION)).append("\n");
|
||||||
|
context.append("3. ").append(AuditContent11HistoryConstants.METHOD_DESCRIPTIONS.get(AuditContent11HistoryConstants.METHOD_VERIFY_RECTIFICATION)).append("\n");
|
||||||
|
context.append("4. ").append(AuditContent11HistoryConstants.METHOD_DESCRIPTIONS.get(AuditContent11HistoryConstants.METHOD_INTERVIEW)).append("\n");
|
||||||
|
context.append("5. ").append(AuditContent11HistoryConstants.METHOD_DESCRIPTIONS.get(AuditContent11HistoryConstants.METHOD_REVIEW_DOCS)).append("\n\n");
|
||||||
|
|
||||||
|
// 2. 数据格式要求
|
||||||
|
context.append("## 数据格式要求\n");
|
||||||
|
context.append("需要生成历史审计问题整改表数据,尽可能生成多个年度、多种类型的审计问题,数量不限:\n\n");
|
||||||
|
|
||||||
|
context.append("**表格字段说明:**\n");
|
||||||
|
context.append("1. **审计年度**:审计报告所属年份,如:2023年\n");
|
||||||
|
context.append("2. **审计类型**:内部审计、外部审计、专项审计、经济责任审计等\n");
|
||||||
|
context.append("3. **审计发现的问题**:具体审计发现的问题描述,需详细说明\n");
|
||||||
|
context.append("4. **整改要求**:对问题的整改要求,包括时间、内容等\n");
|
||||||
|
context.append("5. **整改措施**:具体的整改措施和实施情况\n");
|
||||||
|
context.append("6. **整改完成情况**:已完成、整改中、未整改、部分整改\n");
|
||||||
|
context.append("7. **整改完成时间**:具体完成时间或计划完成时间\n");
|
||||||
|
context.append("8. **整改责任人**:负责整改的责任人姓名和职务\n");
|
||||||
|
context.append("9. **备注**:其他需要说明的情况\n");
|
||||||
|
context.append("10. **工作底稿索引**:相关审计报告、整改报告等文件名称,必须是实际存在的完整文件名\n\n");
|
||||||
|
|
||||||
|
context.append("**生成要求:**\n");
|
||||||
|
context.append("1. 基于知识库内容,尽可能全面地生成历次审计发现的问题和整改情况\n");
|
||||||
|
context.append("2. 每个问题应包含完整的审计年度、类型、问题描述、整改要求、措施、完成情况等\n");
|
||||||
|
context.append("3. 重点关注整改措施的落实情况和实际效果\n");
|
||||||
|
context.append("4. 工作底稿索引必须准确对应实际文件名称,确保能在文件夹中搜索到\n");
|
||||||
|
context.append("5. 整改完成情况需根据实际情况判断,证据充分的才能判定为'已完成'\n");
|
||||||
|
context.append("6. 对于历史遗留问题,需特别注明是否为非任期问题\n");
|
||||||
|
context.append("7. 对于制度完善情况,需说明审计后是否建立了相关制度机制\n\n");
|
||||||
|
|
||||||
|
// 3. 历史内容
|
||||||
|
if (StrUtil.isNotBlank(history)) {
|
||||||
|
context.append("## 历史生成内容\n");
|
||||||
|
context.append("以下是之前生成的内容,请基于此进行优化:\n");
|
||||||
|
context.append(history).append("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 用户建议
|
||||||
|
if (StrUtil.isNotBlank(suggestion)) {
|
||||||
|
context.append("## 用户优化建议\n");
|
||||||
|
context.append("请根据以下建议对生成内容进行调整:\n");
|
||||||
|
context.append(suggestion).append("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 企业单位知识(审计问题)
|
||||||
|
if (!knowledgeSources.get("enterprise").isEmpty()) {
|
||||||
|
context.append("## 企业单位审计问题知识\n");
|
||||||
|
knowledgeSources.get("enterprise").forEach(knowledge ->
|
||||||
|
context.append(knowledge).append("\n"));
|
||||||
|
context.append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 审计报告知识
|
||||||
|
if (!knowledgeSources.get("auditReports").isEmpty()) {
|
||||||
|
context.append("## 审计报告知识\n");
|
||||||
|
knowledgeSources.get("auditReports").forEach(knowledge ->
|
||||||
|
context.append(knowledge).append("\n"));
|
||||||
|
context.append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. 整改报告知识
|
||||||
|
if (!knowledgeSources.get("rectificationReports").isEmpty()) {
|
||||||
|
context.append("## 整改报告知识\n");
|
||||||
|
knowledgeSources.get("rectificationReports").forEach(knowledge ->
|
||||||
|
context.append(knowledge).append("\n"));
|
||||||
|
context.append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8. 法规制度知识
|
||||||
|
if (!knowledgeSources.get("regulations").isEmpty()) {
|
||||||
|
context.append("## 审计整改相关法规制度\n");
|
||||||
|
knowledgeSources.get("regulations").forEach(knowledge ->
|
||||||
|
context.append(knowledge).append("\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return context.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理表格数据,确保格式正确
|
||||||
|
*/
|
||||||
|
private JSONArray processTableData(JSONArray rawData) {
|
||||||
|
JSONArray processedData = new JSONArray();
|
||||||
|
|
||||||
|
for (int i = 0; i < rawData.size(); i++) {
|
||||||
|
JSONObject item = rawData.getJSONObject(i);
|
||||||
|
JSONObject processedItem = new JSONObject();
|
||||||
|
|
||||||
|
// 设置序号
|
||||||
|
processedItem.put("index", i + 1);
|
||||||
|
|
||||||
|
// 复制所有字段
|
||||||
|
processedItem.putAll(item);
|
||||||
|
|
||||||
|
// 确保必填字段存在
|
||||||
|
if (!processedItem.containsKey("auditYear")) {
|
||||||
|
processedItem.put("auditYear", "2023年");
|
||||||
|
}
|
||||||
|
if (!processedItem.containsKey("auditType")) {
|
||||||
|
processedItem.put("auditType", AuditContent11HistoryConstants.AUDIT_TYPE_INTERNAL);
|
||||||
|
}
|
||||||
|
if (!processedItem.containsKey("rectificationStatus")) {
|
||||||
|
processedItem.put("rectificationStatus", AuditContent11HistoryConstants.STATUS_IN_PROGRESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
processedData.add(processedItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
return processedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 历史审计问题相关性比较器
|
||||||
|
*/
|
||||||
|
private int historyAuditComparator(String reg1, String reg2) {
|
||||||
|
int score1 = calculateHistoryAuditRelevanceScore(reg1);
|
||||||
|
int score2 = calculateHistoryAuditRelevanceScore(reg2);
|
||||||
|
return Integer.compare(score2, score1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算历史审计问题相关性分数
|
||||||
|
*/
|
||||||
|
private int calculateHistoryAuditRelevanceScore(String content) {
|
||||||
|
return AuditContent11HistoryConstants.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 150;
|
||||||
|
case "auditReports": return 100;
|
||||||
|
case "rectificationReports": return 80;
|
||||||
|
case "regulations": return 60;
|
||||||
|
default: return 50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user