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.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.KnowledgeBaseService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.ResponseBody; 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; /** * 审计内容基础控制器 */ @Slf4j public abstract class BaseAuditContentController extends BaseController { @Autowired protected AiCloudDocService aiCloudDocService; @Autowired protected AiCloudFileService aiCloudFileService; @Autowired protected KnowledgeBaseService knowledgeBaseService; @Autowired protected PwlProjectLibraryService pwlProjectLibraryService; @Autowired protected AiHistoryService aiHistoryService; // 历史记录有效期(分钟) protected static final int HISTORY_EXPIRE_MINUTES = 10; /** * 通用的表格数据生成方法 */ protected 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); } } /** * 生成请求哈希 */ protected String generateRequestHash(AuditContentRequest request, String interfaceName) { String requestJson = JSONObject.toJSONString(request); return DigestUtil.md5Hex(interfaceName + ":" + requestJson); } /** * 保存到历史记录 */ protected void saveToHistory(AuditContentRequest request, String interfaceName, String requestHash, JSONObject result, User loginUser) { try { aiHistoryService.saveHistory(request.getProjectId(), requestHash, interfaceName, JSONObject.toJSONString(request), result.toJSONString(), loginUser.getUserId(), loginUser.getUsername(), loginUser.getTenantId()); } catch (Exception e) { log.warn("保存历史记录失败", e); } } /** * 检查是否有上传的文件 */ protected boolean hasUploadedFiles(AuditContentRequest request) { return !request.getDocList().isEmpty() || !request.getFileList().isEmpty(); } /** * 获取知识库ID */ protected String getKnowledgeBaseId(String tempKbId, String requestKbIds) { return StrUtil.isNotBlank(tempKbId) ? tempKbId : requestKbIds; } /** * 获取项目库KB IDs */ protected 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(",")); } /** * 创建临时知识库并提交文档 */ protected 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; } /** * 获取相关文件列表 */ protected 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); } /** * 清理临时知识库 */ protected void cleanupTempKnowledgeBase(String kbId) { if (StrUtil.isNotBlank(kbId)) { try { knowledgeBaseService.deleteIndex(kbId); } catch (Exception e) { log.warn("删除临时知识库失败: {}", kbId, e); } } } /** * 通用的Excel导出方法 */ protected 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); } /** * 带审计时间的Excel导出方法 */ protected void exportToExcelWithAuditTime(Map request, HttpServletResponse response, String sheetName, Function>, List> converter, Class entityClass) { List> dataList = (List>) request.get("data"); String companyName = (String) request.get("companyName"); String auditTime = (String) request.get("auditTime"); List exportData = converter.apply(dataList); String fileName = sheetName + "_" + (companyName != null ? companyName : "未知公司"); String title = companyName != null ? companyName + " - " + sheetName : sheetName; if (auditTime != null) { title += "(审计时间:" + auditTime + ")"; } ExcelExportTool.exportExcel(exportData, entityClass, fileName, sheetName, title, response); } /** * 参数包装类 */ protected static class GenerateParams { public final String knowledgeBaseId; public final String libraryKbIds; public final String projectLibrary; public final String username; public final String history; public final String suggestion; public 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; } } // ========== 通用的工具方法 ========== /** * 获取字符串值 */ protected String getStringValue(Map map, String key) { Object value = map.get(key); return value != null ? value.toString() : ""; } /** * 格式化底稿索引 */ protected 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(); } }