277 lines
11 KiB
Java
277 lines
11 KiB
Java
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<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("生成表格数据失败,接口: {}", 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<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(","));
|
||
}
|
||
|
||
/**
|
||
* 创建临时知识库并提交文档
|
||
*/
|
||
protected 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;
|
||
}
|
||
|
||
/**
|
||
* 获取相关文件列表
|
||
*/
|
||
protected 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);
|
||
}
|
||
|
||
/**
|
||
* 清理临时知识库
|
||
*/
|
||
protected void cleanupTempKnowledgeBase(String kbId) {
|
||
if (StrUtil.isNotBlank(kbId)) {
|
||
try {
|
||
knowledgeBaseService.deleteIndex(kbId);
|
||
} catch (Exception e) {
|
||
log.warn("删除临时知识库失败: {}", kbId, e);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 通用的Excel导出方法
|
||
*/
|
||
protected <T> void exportToExcel(Map<String, Object> request, HttpServletResponse response,
|
||
String sheetName, Function<List<Map<String, Object>>, List<T>> converter,
|
||
Class<T> entityClass) {
|
||
List<Map<String, Object>> dataList = (List<Map<String, Object>>) request.get("data");
|
||
String companyName = (String) request.get("companyName");
|
||
|
||
List<T> 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 <T> void exportToExcelWithAuditTime(Map<String, Object> request, HttpServletResponse response,
|
||
String sheetName, Function<List<Map<String, Object>>, List<T>> converter,
|
||
Class<T> entityClass) {
|
||
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<T> 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<String, Object> 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();
|
||
}
|
||
} |