package com.takai.ai.service.impl; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.github.pagehelper.PageHelper; import com.takai.ai.domain.TakaiSysOss; import com.takai.ai.domain.dto.*; import com.takai.ai.domain.entity.*; import com.takai.ai.mapper.*; import com.takai.ai.service.IMinioConfigService; import com.takai.ai.service.ITakaiAiService; import com.takai.ai.utils.*; import com.takai.common.annotation.DataScope; import com.takai.common.annotation.DataSource; import com.takai.common.config.DeepseekConfig; import com.takai.common.constant.UserConstants; import com.takai.common.core.domain.entity.SysDictData; import com.takai.common.core.domain.entity.SysUser; import com.takai.common.core.domain.model.LoginUser; import com.takai.common.core.redis.RedisCache; import com.takai.common.enums.AppTypeEnum; import com.takai.common.enums.DataSourceType; import com.takai.common.utils.SecurityUtils; import com.takai.common.utils.StringUtils; import com.takai.common.utils.uuid.IdUtils; import com.takai.framework.web.service.SysPermissionService; import com.takai.system.domain.*; import com.takai.system.mapper.*; import com.takai.system.service.ISysUserService; import lombok.extern.slf4j.Slf4j; import okhttp3.*; import okhttp3.sse.EventSource; import okhttp3.sse.EventSourceListener; import okhttp3.sse.EventSources; import org.apache.commons.collections4.MapUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; import javax.validation.constraints.NotNull; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** * 高井 业务层处理 * * @author takai */ @Slf4j @Service @DataSource(DataSourceType.MASTER) public class TakaiAiServiceImpl implements ITakaiAiService { private static final Logger logger = LoggerFactory.getLogger(TakaiAiServiceImpl.class); @Autowired private TakaiDialogMapper takaiDialogMapper; @Autowired private TakaiApplicationMapper takaiApplicationMapper; @Autowired private TakaiQuestionMapper takaiQuestionMapper; @Autowired private TakaiKnowledgeMapper takaiKnowledgeMapper; @Autowired private TakaiDocumentMapper takaiDocumentMapper; @Autowired private TakaiSysOssConfigMapper takaiSysOssConfigMapper; @Autowired private TakaiSysOssMapper takaiSysOssMapper; @Autowired private MinioUtil minioUtil; @Autowired private TakaiDocumentSettingsMapper takaiDocumentSettingsMapper; @Autowired private DeepseekConfig deepseekConfig; @Autowired private TakaiAppInfoMapper takaiAppInfoMapper; @Autowired private TakaiMediaReplacementMapper takaiMediaReplacementMapper; @Autowired private RedisCache redisCache; @Autowired public RedisTemplate redisTemplate; @Autowired private TakaiSliceInfoMapper takaiSliceInfoMapper; @Autowired private DocumentAuditConfigMapper documentAuditConfigMapper; @Autowired private DocumentAuditInfoMapper documentAuditInfoMapper; @Autowired private SysPermissionService permissionService; @Autowired private TypeAppMapper appTypeMapper; @Autowired private TakaiAppCollectMapper appCollectMapper; @Autowired private SysDictDataMapper sysDictDataMapper; @Autowired private SysProjectAppMapper sysProjectAppMapper; @Autowired private TakaiFileInfoMapper fileInfoMapper; @Autowired private Base64DecodeUtil base64DecodeUtil; public static final String START_SIGN = "【"; public static final String END_SIGN = "】"; public static final String SYMBOL = "【示意图序号"; public static final String USER_STR = "user"; public static final String TODAY = "今日"; public static final String BEFOR = "日前"; private final String OSS_URL= "https://minio.jkec.info:9000"; @Autowired private SysProjectMapper sysProjectMapper; @Autowired private ISysUserService userService; @Override public void initDeepseekInfo() { //获取应用列表 // List appList = takaiApplicationMapper.selectApplicationList(null); setRedisCache(null); } private void setRedisCache(String knowledgeId) { //获取知识库列表 List knowledgeList = null; if (StringUtils.isEmpty(knowledgeId)) { knowledgeList = takaiKnowledgeMapper.selectAllKnowledgeList(null); } else { knowledgeList = takaiKnowledgeMapper.selectAllKnowledgeList(TakaiKnowledge.builder().knowledgeId(knowledgeId).build()); } //获取知识列表 if (!knowledgeList.isEmpty()) { for (TakaiKnowledge bmKnowledge : knowledgeList) { TakaiDocument conditon = TakaiDocument.builder().knowledgeId(bmKnowledge.getKnowledgeId()).build(); List documentList = takaiDocumentMapper.selectDocumentList(conditon); if (!documentList.isEmpty()) { for (TakaiDocument bmDocument : documentList) { //获取知识图片列表 TakaiMediaReplacement conditonR = TakaiMediaReplacement.builder().documentId(bmDocument.getDocumentId()).build(); List imageList = takaiMediaReplacementMapper.selectMediaList(conditonR); if (!imageList.isEmpty()) { for (TakaiMediaReplacement image : imageList) { redisCache.setCacheObject(image.getOriginText(), image.getMediaUrl()); } } } } } } } @Override public SseEmitter sseInvoke(TakaiSseInfoParams sseParams) { TakaiApplication appInfo = takaiApplicationMapper.selectTargetApplication(TakaiApplication.builder().appId(sseParams.getAppId()).build()); if (appInfo != null) { List idList = Arrays.stream(appInfo.getKnowledgeIds().split(",")) // 按「逗号+空格」拆分字符串为数组 .filter(str -> str != null && !str.trim().isEmpty()) // 过滤 null 和空字符串(防异常) .collect(Collectors.toList()); TakaiKnowledge knowledgeParam = TakaiKnowledge.builder().knowledgeIds(idList).build(); List knowledgeList = takaiKnowledgeMapper.selectAllKnowledgeList(knowledgeParam); if (knowledgeList != null && !knowledgeList.isEmpty()) { SseEmitter sseEmitter = new SseEmitter(0L); String url = deepseekConfig.getBaseurl() + deepseekConfig.getChat(); TakaiAppInfo info = takaiAppInfoMapper.selectAppInfoByAppId(sseParams.getAppId()); JSONObject json = JSONObject.parseObject(info.getAppInfo()); //重新设置knowledgeIds为数组 json.put("knowledgeIds",idList); String query = null; decodeMessage(sseParams.getMessages()); decodeMessage(sseParams.getPrompt()); if(sseParams.getMessages() != null && !sseParams.getMessages().isEmpty() ) { query = sseParams.getMessages().get(sseParams.getMessages().size() - 1).getContent(); } else { query = sseParams.getPrompt().get(sseParams.getPrompt().size() - 1).getContent(); } log.info("deepseek聊天请求参数:" + query); json.put("query", query); json.put("embeddingId", knowledgeList.get(0).getEmbeddingId()); if(UserConstants.YES.equals(json.getString("isDeepThink"))) { json.put("enable_think", true); } else { json.put("enable_think", false); } RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8"), json.toJSONString()); Request request = buildPostRequest(url, requestBody); // 使用EventSourceListener处理来自服务器的SSE事件 EventSourceListener listener = new EventSourceListener() { private String preData = ""; //图片识别 private String symbolData = ""; @Override public void onOpen(@NotNull EventSource eventSource, @NotNull Response response) { log.info("deepseek Connection opened. Headers: {}", response.headers()); log.info("deepseek Request URL: {}", response.request().url()); } @Override public void onClosed(@NotNull EventSource eventSource) { log.info("deepseek Connection closed."); sseEmitter.complete(); } @Override public void onEvent(@NotNull EventSource eventSource, String id, String type, @NotNull String data) { if (!StringUtils.isEmpty(data)) { String newData = data.substring(preData.length()); logger.info("deepseek聊天返回消息:" + data); preData = data; if (newData.indexOf(START_SIGN) > -1 || symbolData.length() > 0) { symbolData = symbolData + newData; //接收到了完整的图片标识 int endSignPos = symbolData.indexOf(END_SIGN); if (endSignPos > -1) { JSONObject json = new JSONObject(); json.put("id", id); json.put("event", "add"); //是图片 if (symbolData.indexOf(SYMBOL) > -1) { //获取完整Key int startPos = symbolData.indexOf(START_SIGN); int endPos = symbolData.indexOf(END_SIGN) + 1; String key = symbolData.substring(startPos, endPos); String url = redisCache.getCacheObject(key); if (org.springframework.util.StringUtils.hasText(url)) { if(url.contains("https://10.1.28.14:9000")){ //url = url.replace("https://10.1.28.14:9000", "https://minio.jkec.info:9000"); url = url.replace("https://10.1.28.14:9000", OSS_URL); } //匹配markdown图片格式 // symbolData = symbolData.replace(key, "![](" + url + ")"); } else { logger.error("图片标识符"+key+"没有获取到对应的URL{}: " + symbolData); } //检查是否当前token包含其他图片的开始符号”【“ int lastPos = symbolData.lastIndexOf(START_SIGN); if(lastPos > endSignPos){ // 从'【' 开始截取 newData = symbolData.substring(0, lastPos); symbolData = symbolData.substring(lastPos); logger.info("截取结果{}: " + symbolData); } else { newData = symbolData; symbolData = ""; } if(!StringUtils.isEmpty(url)) { newData = newData.replace(key, " ![](" + url + ")"); } } else { newData = symbolData; symbolData = ""; } json.put("data", newData); log.info("获取到图片替换结束符号,返回前端信息:" + json); send(sseEmitter, json); //如果超过长度200还没收到】符号,直接返回。 } else if (symbolData.length() > 200) { JSONObject json = new JSONObject(); json.put("id", id); json.put("event", "add"); json.put("data", symbolData); } } else { JSONObject json = new JSONObject(); json.put("id", id); json.put("event", type); json.put("data", newData); log.info("deepseek返回信息:" + json); send(sseEmitter, json); } } if (com.takai.common.utils.StringUtils.isNotEmpty(type) && "finish".equals(type)) { log.info("deepseek聊天结束"); JSONObject json = new JSONObject(); json.put("id", id); json.put("event", type); json.put("data", data); log.info("deepseek返回信息:" + json); send(sseEmitter, json); } } @Override public void onFailure(@NotNull EventSource eventSource, Throwable t, Response response) { if (response != null) { log.error("deepseek Connection failed. Response code: {}, message: {}, body: {}", response.code(), response.message(), response.body() != null ? response.body().toString() : "null"); } else { log.error("deepseek Connection failed with no response", t); } sseEmitter.completeWithError(t); } private void send(SseEmitter sseEmitter, Object obj) { try { sseEmitter.send(obj); } catch (IOException e) { log.error("deepseek 推送数据失败", e); } } }; OkHttpClient client = buildOkHttpClient(); EventSource.Factory factory = EventSources.createFactory(client); final EventSource eventSources = factory.newEventSource(request, listener); // 客户端主动关闭连接 sseEmitter.onCompletion(() -> { logger.info("deepseek客户端主动关闭连接 -- SSE 连接关闭"); }); // 超时回调 sseEmitter.onTimeout(() -> { logger.info("deepseek客户端连接超时 -- SSE 连接关闭"); if(eventSources != null) { logger.info("deepseek超时回调 -- 成功关闭SSE连接 "); eventSources.cancel(); } }); // 错误回调 sseEmitter.onError(e -> { logger.info("deepseek客户端回调失败 -- SSE 连接关闭"); if(eventSources != null) { logger.info("deepseek错误回调 -- 成功关闭SSE连接 "); eventSources.cancel(); } }); return sseEmitter; } } return null; } private void decodeMessage(List messages) { if(messages == null || messages.isEmpty()) { return; } for (TakaiPromptInfo message : messages) { message.setContent(base64DecodeUtil.decodeIfNeeded(message.getContent())); } } @Override public List asyncCompletions(TakaiCompletionsParams params) { List list = new ArrayList<>(); TakaiApplication vo = takaiApplicationMapper.selectTargetApplication(TakaiApplication.builder().appId(params.getAppId()).build()); if (vo != null) { TakaiPromptInfo info = new TakaiPromptInfo(); info.setContent(deepseekConfig.getPrompt()); info.setRole("user"); decodeMessage(params.getMessages()); params.getMessages().add(info); JSONObject jsonObject = new JSONObject(); jsonObject.put("model", vo.getModel()); jsonObject.put("messages", params.getMessages()); jsonObject.put("chat_id", params.getChat_id()); JSONObject result = getasyncCompletions(jsonObject); if (result != null && result.getInteger("code") == 200) { JSONArray array = result.getJSONArray("data"); if(array != null){ list.addAll(array.toJavaList(String.class)); } } } return list; } private JSONObject getasyncCompletions(JSONObject jsonObject) { String url = deepseekConfig.getBaseurl() + deepseekConfig.getAsyncCompletions(); RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8"), jsonObject.toJSONString()); Request request = buildPostRequest(url, requestBody); OkHttpClient client = buildOkHttpClient(); try { Response response = client.newCall(request).execute(); if (response.isSuccessful()) { String body = response.body().string(); if (isJsonObject(body)) { return JSON.parseObject(body); } } } catch (IOException e) { log.info("deepseek Request URL: {}", e.getMessage()); } return null; } @Override public List getDialogDetail(String dialogId) { List detail = takaiDialogMapper.selectDialogDetail(dialogId); if(detail != null && detail.size() != 0){ for(TakaiDialogRespDTO dto : detail){ if(StringUtils.isNotEmpty(dto.getSliceJson())){ dto.setSliceInfo(JSON.parseObject(dto.getSliceJson(), TakaiSliceInfoDTO.class)); } if("user".equals(dto.getType())){ List fileInfoList = fileInfoMapper.getFileInfoById(null, dto.getDialog_id(), dto.getDid()); if(fileInfoList != null && !fileInfoList.isEmpty()){ List documentDTOS = new ArrayList<>(); for(TakaiFileInfo fileInfo : fileInfoList){ TakaiDocumentDTO documentDTO = new TakaiDocumentDTO(); BeanUtils.copyProperties(fileInfo, documentDTO); documentDTOS.add(documentDTO); } dto.setDocuments(documentDTOS); } } } } return detail; } @Override public void saveDialog(TakaiDialogReqDTO dialogReqDTO) { String dialogId = null; TakaiDialogRespDTO dialogVo = null; if (com.takai.common.utils.StringUtils.isNotEmpty(dialogReqDTO.getId())) { dialogVo = takaiDialogMapper.selectDialogById(dialogReqDTO.getId()); } if (dialogVo == null) { takaiDialogMapper.insertDialog(dialogReqDTO); dialogId = dialogReqDTO.getId(); } else { dialogId = dialogReqDTO.getId(); } for (TakaiDialogDetailReqDTO dto : dialogReqDTO.getMessages()) { dto.setDialogId(dialogId); dto.setContent(base64DecodeUtil.decodeIfNeeded(dto.getContent())); TakaiDialogRespDTO detail = takaiDialogMapper.selectDialogDetailById(dto.getId()); if (detail == null) { if (dto.getSliceInfo() != null) dto.setSliceJson(JSON.toJSONString(dto.getSliceInfo())); takaiDialogMapper.insertDialogDetail(dto); } if(dto.getDocuments() != null && !dto.getDocuments().isEmpty()){ for(TakaiDocumentDTO documentVo : dto.getDocuments()){ if(!"".equals(documentVo.getId())) { List fileInfo = fileInfoMapper.getFileInfoById(documentVo.getId(), null, null); if((fileInfo == null || fileInfo.isEmpty()) && "user".equals(dto.getRole())) { TakaiFileInfo params = new TakaiFileInfo(); params.setId(documentVo.getId()); params.setName(documentVo.getName()); params.setUrl(documentVo.getUrl()); params.setDialogId(dialogId); params.setDialogDid(dto.getId()); fileInfoMapper.insertFileInfo(params); } } } } } } @Override public List getDialogList(String appId, String userId) { List dialogRespDTOS = takaiDialogMapper.selectDialogList(appId, userId); //当前日期 LocalDate today = LocalDate.now(); //根据时间分组降序排序 NavigableMap> groupList = dialogRespDTOS.stream().collect(Collectors.groupingBy(TakaiDialogRespDTO::getCreate_time, TreeMap::new, Collectors.toList())).descendingMap(); List obj = new ArrayList(); if (!groupList.isEmpty()) { for (Map.Entry> entry : groupList.entrySet()) { // 对比两个时间相差多少天 long daysBetween = ChronoUnit.DAYS.between(today, entry.getKey()); Map m = new HashMap(); m.put("key", System.nanoTime()); m.put("type", "group"); if (daysBetween == 0l) { m.put("label", TODAY); m.put("children", setValue(entry.getValue(), appId)); obj.add(m); } else { m.put("label", -daysBetween + BEFOR); m.put("children", setValue(entry.getValue(), appId)); obj.add(m); } } } return obj; } @Override public void DelDialogDetail(String id) { int result = takaiDialogMapper.delDialog(id); if (result > 0) { takaiDialogMapper.delDialogDetail(id); } } @Override public void updateDialog(TakaiDialogReqDTO dialogReqDTO) { takaiDialogMapper.updateDialog(dialogReqDTO); } @Override public List exportExcel(String dialogId) { return takaiDialogMapper.selectDialogExport(dialogId); } @Override public int createKnowledge(TakaiKnowledgeParams knowledge) { SnowflakeDigitGenerator snowflakeDigitGenerator = new SnowflakeDigitGenerator(1, 1); long knowledgeId = snowflakeDigitGenerator.nextId(); String url = deepseekConfig.getBaseurl() + deepseekConfig.getCreateKnowledge(); JSONObject jsonObject = new JSONObject(); jsonObject.put("knowledge_id", "a" + knowledgeId); jsonObject.put("embedding_id", knowledge.getEmbeddingId()); RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8"), jsonObject.toJSONString()); Request request = buildPostRequest(url, requestBody); OkHttpClient client = buildOkHttpClient(); String createdBy = SecurityUtils.getLoginUser() == null ? "":SecurityUtils.getLoginUser().getUserId(); try { Response response = client.newCall(request).execute(); if (response.isSuccessful()) { String body = response.body().string(); JSONObject obj = JSON.parseObject(body); Integer code = obj.getInteger("code"); if (code == 200) { TakaiKnowledge params = TakaiKnowledge.builder() .knowledgeId("a" + knowledgeId) .name(knowledge.getName()) .embeddingId(knowledge.getEmbeddingId()) .description(knowledge.getDescription()) .visible(knowledge.getVisible()) .build(); params.setCreateBy(createdBy); return takaiKnowledgeMapper.insertKnowledge(params); } } else { logger.error("创建知识库调用python接口失败,返回状态码:{}", response.code()); } } catch (IOException e) { logger.error("创建知识库调用python接口失败", e.getMessage()); } return 0; } @Override public int updateKnowledge(TakaiKnowledgeParams knowledge, String knowledgeId) { TakaiKnowledge params = TakaiKnowledge.builder().knowledgeId(knowledgeId) .name(knowledge.getName()) .description(knowledge.getDescription()) .embeddingId(knowledge.getEmbeddingId()) .visible(knowledge.getVisible()) .build(); String updateBy = SecurityUtils.getLoginUser() == null ? "":SecurityUtils.getLoginUser().getUserId(); params.setUpdateBy(updateBy); params.setUpdateTime(new Date()); return takaiKnowledgeMapper.updateKnowledge(params); } @Override public TakaiKnowledge detailKnowledge(String knowledgeId) { TakaiKnowledge vo = TakaiKnowledge.builder().knowledgeId(knowledgeId).build(); return takaiKnowledgeMapper.selectTargetKnowledge(vo); } @Override public int delKnowledge(String knowledgeId) { String url = deepseekConfig.getBaseurl() + deepseekConfig.getDeleteKnowledge() + "/" + knowledgeId; Request request = buildDeleteRequest(url); OkHttpClient client = buildOkHttpClient(); Response response = null; try { response = client.newCall(request).execute(); if (response.isSuccessful()) { String body = response.body().string(); JSONObject obj = JSON.parseObject(body); Integer code = obj.getInteger("code"); if (code == 200) { // TakaiKnowledge info = takaiKnowledgeMapper.selectTargetKnowledge(TakaiKnowledge.builder().knowledgeId(knowledgeId).build()); List list = takaiMediaReplacementMapper.selectMediaList(TakaiMediaReplacement.builder().knowledgeId(knowledgeId).build()); List documentList = takaiDocumentMapper.selectDocumentList(TakaiDocument.builder().knowledgeId(knowledgeId).build()); int knowledgeInt = takaiKnowledgeMapper.delKnowledge(knowledgeId); if (knowledgeInt > 0) { takaiDocumentMapper.delDocumentByKnowledgeId(knowledgeId); takaiDocumentSettingsMapper.deleteDocumentSettingsByKnowledgeId(knowledgeId); if(list != null && list.size() > 0){ try { for(TakaiDocument document: documentList){ logger.info("删除知识库->删除minio文件"); minioUtil.remove("deepseek-doc", "/"+document.getName()); } for (int k = 0; k < list.size(); k++ ) { logger.info("删除知识库->删除minio图片{}", k); String key = "/pdf/"+knowledgeId+"/"+list.get(k).getDocumentId()+"/【示意图序号_"+list.get(k).getDocumentId()+"_"+k+1+"】.jpg"; logger.info("删除知识库->删除minio图片key{}", key); minioUtil.remove("deepseek-doc" , key); } } catch (Exception e) { logger.error("删除知识库->删除minion文件失败", e.getMessage()); throw new RuntimeException(e); } } } return knowledgeInt; } } } catch (IOException e) { logger.error("删除知识库调用python接口失败", e.getMessage()); } return 0; } @Override public int uploadDocument(MultipartFile[] files, String knowledgeId) { List result = null; try { result = minioUtil.uploadMultiple(files); } catch (Exception e) { logger.error("上传文件失败", e.getMessage()); } if (result != null && result.size() > 0) { List params = new ArrayList<>(); for (int i = 0; i 0) { // 保存知识设置信息 SnowflakeDigitGenerator snowflakeDigitGenerator = new SnowflakeDigitGenerator(1, 1); long id = snowflakeDigitGenerator.nextId(); TakaiDocumentSettings dSettings = new TakaiDocumentSettings(); dSettings.setId(String.valueOf(id)); dSettings.setKnowledgeId(knowledgeId); dSettings.setDocumentId(vo.getDocument_id()); dSettings.setSetSlice("0"); // 默认 按标题段落切片 dSettings.setSetAnalyze("1"); // 默认 图片转换成标识符 dSettings.setSetTable("0"); // 默认 ttable转图片 takaiDocumentSettingsMapper.insertDocumentSettings(dSettings); } } } updateKnowledgeSize(knowledgeId); setRedisCache(knowledgeId); return 1; } } return 0; } private void updateKnowledgeSize(String knowledgeId) { TakaiKnowledge info = takaiKnowledgeMapper.selectTargetKnowledge(TakaiKnowledge.builder().knowledgeId(knowledgeId).build()); List documentList = takaiDocumentMapper.selectDocumentList(TakaiDocument.builder().knowledgeId(knowledgeId).build()); int totalLen = documentList.stream() .mapToInt(doc -> doc.getLength() != null ? doc.getLength() : 0) .sum(); int totalWordNum = documentList.stream() .mapToInt(doc -> doc.getWordNum() != null ? doc.getWordNum() : 0) .sum(); int docSize = documentList == null || documentList.size() == 0 ? 0 : documentList.size(); String updateBy = SecurityUtils.getLoginUser() == null ? "":SecurityUtils.getLoginUser().getUserId(); TakaiKnowledge paramInfo = TakaiKnowledge.builder().knowledgeId(knowledgeId) .length(totalLen) // 文件大小 .wordNum(totalWordNum) // 总字符数 .documentSize(docSize) // 文件总数 .build(); paramInfo.setUpdateBy(updateBy); paramInfo.setUpdateTime(new Date()); takaiKnowledgeMapper.updateKnowledge(paramInfo); } private void updateDocumentSize(String knowledgeId,String documentId) { List sliceList = selectByDocumentId(documentId,null); //字符数 int totalLen = sliceList.stream() .mapToInt(slice -> slice.getSliceText() != null ? slice.getSliceText().length() : 0) .sum(); //文件大小 int totalSize = sliceList.stream() .mapToInt(slice -> slice.getSliceText() != null ? slice.getSliceText().getBytes(StandardCharsets.UTF_8).length : 0) .sum(); TakaiDocument doc = TakaiDocument.builder() .documentId(documentId) .length(totalSize) .wordNum(totalLen) .sliceTotal(sliceList.size()) .build(); String updateBy = SecurityUtils.getLoginUser() == null ? "":SecurityUtils.getLoginUser().getUserId(); doc.setUpdateBy(updateBy); doc.setUpdateTime(new Date()); takaiDocumentMapper.updateDocument(doc); updateKnowledgeSize(knowledgeId); } @Override public int updateDocument(TakaiDocumentParams documentParams, String documentId) { int i = takaiDocumentMapper.updateDocument(TakaiDocument.builder() .documentId(documentId) .name(documentParams.getName()) .build()); return i; } @Override public List documentList(TakaiDocumentParams documentParams) { List documentList = takaiDocumentMapper.selectDocumentList(TakaiDocument.builder().knowledgeId(documentParams.getKnowledge_id()).build()); replaceOssUrl(documentList); return documentList; } private void replaceOssUrl(List documentList) { if(documentList == null || documentList.isEmpty()) { return; } for(TakaiDocument document : documentList) { replaceDocUrl(document); } } private void replaceDocUrl(TakaiDocument document) { if(document == null) { return; } String url = document.getUrl(); url = url.replace("https://10.1.28.14:9000", OSS_URL); document.setUrl(url); } @Override public TakaiDocument documentDetail(String documentId) { TakaiDocument doc = takaiDocumentMapper.selectTargetDocument(TakaiDocument.builder().documentId(documentId).build()); replaceDocUrl(doc); return doc; } @Override public int delDocument(String documentId) { TakaiDocument vo = takaiDocumentMapper.selectTargetDocument(TakaiDocument.builder().documentId(documentId).build()); if(vo != null){ String url = deepseekConfig.getBaseurl() + deepseekConfig.getDeleteDoc() + "/" + documentId + "/" + vo.getKnowledgeId(); Request request = buildDeleteRequest(url); OkHttpClient client = buildOkHttpClient(); try { Response response = client.newCall(request).execute(); if (response.isSuccessful()) { String body = response.body().string(); logger.info("删除知识文件调用python接口返回结果:{}", body); JSONObject obj = JSON.parseObject(body); Integer code = obj.getInteger("code"); if (code == 200) { List list = takaiMediaReplacementMapper.selectMediaList(TakaiMediaReplacement.builder().documentId(documentId).build()); // 删除图片 takaiMediaReplacementMapper.deleteMedia(documentId); // 删除document文件 int i = takaiDocumentMapper.delDocument(documentId); if(i > 0){ //更新知识库 updateKnowledgeSize(vo.getKnowledgeId()); // 删除minio文件 try { logger.info("删除minio文件"); minioUtil.remove("deepseek-doc", "/"+vo.getName()); if(list != null && list.size() > 0){ for (int k=1; k<=list.size(); k++ ) { logger.info("删除minio图片{}", k); minioUtil.remove("deepseek-doc" , "/pdf/"+vo.getKnowledgeId()+"/"+documentId+"/【示意图序号_"+documentId+"_"+k+"】.jpg"); } } } catch (Exception e) { logger.error("删除minion文件失败", e.getMessage()); throw new RuntimeException(e); } return i; } } } } catch (IOException e) { logger.error("删除知识文件调用python接口失败", e.getMessage()); } } return 0; } @Override public void uploadUrl(TakaiDocumentObject object) { } @Override public int createApplication(TakaiApplicationParams params, boolean isAdmin) { ApprovalNode vo = getFirstApproverNode(); // 获取第一个审批对象 if(vo != null){ SnowflakeDigitGenerator snowflakeDigitGenerator = new SnowflakeDigitGenerator(1, 1); long appId = snowflakeDigitGenerator.nextId(); TakaiApplication info = TakaiApplication.builder().appId(String.valueOf(appId)) .name(params.getName()) .desc(params.getDesc()) .model(params.getModel()) .knowledgeIds(params.getKnowledge_ids().stream().collect(Collectors.joining(","))) .topP(params.getTop_p()) .temperature(params.getTemperature()) .maxToken(params.getMax_token()) .prompt(base64DecodeUtil.decodeIfNeeded(params.getPrompt())) .knowledgeInfo(params.getKnowledge_info()) .sliceCount(params.getSlice_count()) .typeId(params.getTypeId()) .visible(params.getVisible()) .isDeepThink(params.getIsDeepThink()) .sort(params.getSort()) .build(); //关联项目 if(params.getAppProId() != null){ SysProjectApp sysProjectApp = new SysProjectApp(); sysProjectApp.setProjectId(params.getAppProId()[1]); sysProjectApp.setAppId(info.getAppId()); sysProjectAppMapper.insertSysProjectApp(sysProjectApp); } //管理员,私有,项目级应用不需要审核 if(isAdmin || "1".equals(params.getVisible()) || AppTypeEnum.PROJECT.getCode().equals(String.valueOf(params.getTypeId()))){ // 1 私有 0 公开 info.setStatus("3"); // 有直接创建权限无需审核 }else{ info.setStatus("5"); // 未开始审核状态 info.setApprover(String.valueOf(vo.getApprover())); info.setNodeOrder(String.valueOf(vo.getNodeOrder())); } info.setCreateBy(params.getUserId()); int i = takaiApplicationMapper.insertApplication(info); if (i > 0) { //添加VIP用户 if(params.getVipList() != null && params.getVipList().size() > 0){ for(SysUser sysUser : params.getVipList()){ VipApplication vipApplication = VipApplication.builder() .appId(info.getAppId()) .userId(sysUser.getUserId()) .build(); takaiApplicationMapper.insertVipApp(vipApplication); } } TypeApp appType = new TypeApp(); appType.setTypeId(params.getTypeId() == null ? null : params.getTypeId()); appType.setAppId(String.valueOf(appId)); appTypeMapper.insertAppType(appType); logger.info("create application success, id:{}, name:{}", appId, params.getName()); TakaiAppInfo appInfo = new TakaiAppInfo(); appInfo.setAppId(String.valueOf(appId)); appInfo.setAppInfo(String.valueOf(JSONObject.from(info).toJSONString())); takaiAppInfoMapper.insertAppInfo(appInfo); List list = params.getQuestionList(); if (!list.isEmpty() && list.size() > 0) { for (String str : list) { if (org.apache.commons.lang3.StringUtils.isNotBlank(str)) { String uuid = IdUtils.simpleUUID(); TakaiQuestion question = TakaiQuestion.builder().id(uuid).question(str).appId(String.valueOf(appId)).build(); takaiQuestionMapper.insertQuestion(question); } } } return i; } }else{ // 没有审批人 return 9; } return 0; } @Override public int updateApplication(TakaiApplicationParams params, String appId, boolean isAdmin) { ApprovalNode vo = getFirstApproverNode(); // 获取第一个审批对象 if(vo != null){ TakaiApplication info = TakaiApplication.builder().appId(appId) .name(params.getName()) .desc(params.getDesc()) .model(params.getModel()) .knowledgeIds(params.getKnowledge_ids().stream().collect(Collectors.joining(","))) .topP(params.getTop_p()) .temperature(params.getTemperature()) .maxToken(params.getMax_token()) .prompt(base64DecodeUtil.decodeIfNeeded(params.getPrompt())) .knowledgeInfo(params.getKnowledge_info()) .sliceCount(params.getSlice_count()) .typeId(params.getTypeId()) .isDeepThink(params.getIsDeepThink()) .visible(params.getVisible()) .sort(params.getSort()) .build(); //关联项目 if(params.getAppProId() != null){ SysProjectApp sysProjectApp = sysProjectAppMapper.selectSysProjectAppByAppId(appId); if(sysProjectApp != null){ sysProjectAppMapper.deleteSysProjectAppByAppId(appId); } sysProjectApp = new SysProjectApp(); sysProjectApp.setProjectId(params.getAppProId()[1]); sysProjectApp.setAppId(appId); sysProjectAppMapper.insertSysProjectApp(sysProjectApp); } if(isAdmin || "1".equals(params.getVisible()) || AppTypeEnum.PROJECT.getCode().equals(String.valueOf(params.getTypeId()))){ info.setStatus("3"); // 有直接修改权限无需审核 info.setApprover(null); info.setNodeOrder(null); }else{ info.setStatus("2"); // 未开始审核状态 info.setApprover(String.valueOf(vo.getApprover())); info.setNodeOrder(String.valueOf(vo.getNodeOrder())); } info.setUpdateBy(params.getUserId()); int i = takaiApplicationMapper.updateApplication(info); if (1 > 0) { //添加VIP用户 takaiApplicationMapper.deleteVipByAppId(info.getAppId()); if(params.getVipList() != null && params.getVipList().size() > 0){ for(SysUser sysUser : params.getVipList()){ VipApplication vipApplication = VipApplication.builder() .appId(info.getAppId()) .userId(sysUser.getUserId()) .build(); takaiApplicationMapper.insertVipApp(vipApplication); } } TakaiAppInfo appInfo = new TakaiAppInfo(); appInfo.setAppId(appId); appInfo.setAppInfo(String.valueOf(JSONObject.from(info).toJSONString())); takaiAppInfoMapper.updateAppInfoByAppId(appInfo); logger.info("update application success, id:{}, name:{}", appId, params.getName()); //预设问题写入数据库 takaiQuestionMapper.delQuestionByAppId(appId); List list = params.getQuestionList(); if (!list.isEmpty() && list.size() > 0) { for (String str : list) { if (org.apache.commons.lang3.StringUtils.isNotBlank(str)) { String uuid = IdUtils.simpleUUID(); TakaiQuestion question = TakaiQuestion.builder().id(uuid).question(str).appId(String.valueOf(appId)).build(); takaiQuestionMapper.insertQuestion(question); } } } } return i; } else { return 9; } } @Override @DataScope(deptAlias = "u", userAlias = "u") public List getApplicationList(TakaiApplication params) { //管理员 获取所有项目 Map userParams = getUserParams(); if(userParams != null){ params.getParams().putAll(userParams); } List appList = takaiApplicationMapper.selectApplicationList(params); //添加应用VIP用户 // if(appList != null && appList.size() > 0){ // for (TakaiApplicationResult appResult : appList) { // List vipList = userService.selectAppVipList(appResult.getAppId()); // appResult.setVipList(vipList); // } // } return appList; } @Override public JSONObject selectApplication(String appId) { JSONObject object = new JSONObject(); TakaiApplication application = TakaiApplication.builder().appId(appId).build(); TakaiApplication takaiApplication = takaiApplicationMapper.selectTargetApplication(application); //项目级应用 返回['项目分类','项目id'] if(takaiApplication != null) { //添加应用VIP用户 List vipList = userService.selectAppVipList(appId); takaiApplication.setVipList(vipList); if(AppTypeEnum.PROJECT.getCode().equals(String.valueOf(takaiApplication.getTypeId()))) { SysProjectApp sysProjectApp = sysProjectAppMapper.selectSysProjectAppByAppId(application.getAppId()); if (sysProjectApp != null) { SysProject sysProject = sysProjectMapper.selectSysProjectByProjectId(sysProjectApp.getProjectId()); takaiApplication.setAppProId(Arrays.asList( String.valueOf(sysProject.getSourceFrom()), String.valueOf(sysProject.getProjectId()))); } } List idList = Arrays.stream(takaiApplication.getKnowledgeIds().split(",")) // 按「逗号+空格」拆分字符串为数组 .filter(str -> str != null && !str.trim().isEmpty()) // 过滤 null 和空字符串(防异常) .collect(Collectors.toList()); JSONObject detailObj = JSONObject.from(takaiApplication); // 转为JSON对象 detailObj.put("knowledgeIds", idList); // 用数组替换原字符串 object.put("detail", detailObj); } else { object.put("detail", takaiApplication); } List list = takaiQuestionMapper.getQuestionList(appId); object.put("questionlist", list); return object; } @Override public int delApplication(String appId) { int i = takaiApplicationMapper.delApplication(appId); if (i > 0) { takaiAppInfoMapper.delAppInfoByAppId(appId); takaiQuestionMapper.delQuestionByAppId(appId); takaiApplicationMapper.delApplication(appId); } return i; } @Override public List selectQuestionByAppId(String appId) { List List = takaiQuestionMapper.getQuestionList(appId); return List; } @Override public List queryKnowledgeList() { //管理员 获取所有项目 TakaiKnowledge params = getKnowledgeUserParams(); return takaiKnowledgeMapper.selectKnowledgeList(params); } private TakaiKnowledge getKnowledgeUserParams() { TakaiKnowledge params = null; //管理员 获取所有项目 Map userParams = getUserParams(); if(userParams != null){ params = TakaiKnowledge.builder().build(); params.setParams(userParams); } return params; } private Map getUserParams() { //管理员 获取所有项目 LoginUser user = SecurityUtils.getLoginUser(); Map userParams = null; if(user != null){ userParams = new HashMap<>(); SysUser loginUser = user.getUser(); userParams.put("userType",loginUser.getUserType()); userParams.put("userId",loginUser.getUserId()); if(loginUser.getRoles().stream().anyMatch(role -> role.getRoleId() == 1)) { userParams.put("isAdmin", true); } else { userParams.put("isAdmin", false); } } return userParams; } @Override public List selectDialogListByAppId(String appId, String userId) { List list = takaiDialogMapper.selectDialog(appId, userId); // List result = setDialogList(list); return list; } @Override public TakaiDocumentSettings documentSetting(String documentId) { return takaiDocumentSettingsMapper.selectById(documentId); } @Override public int updateDocumentSetting(TakaiDocumentSettings documentSettings, String documentId) { TakaiDocumentSettings settings = new TakaiDocumentSettings(); TakaiDocumentSettings settingsVo = takaiDocumentSettingsMapper.selectById(documentId); settings.setKnowledgeId(settingsVo.getKnowledgeId()); settings.setSetSlice(documentSettings.getSetSlice()); settings.setSliceValue(documentSettings.getSliceValue()); settings.setSetAnalyze(documentSettings.getSetAnalyze()); settings.setSetTable(documentSettings.getSetTable()); TakaiDocument document = takaiDocumentMapper.selectTargetDocument(TakaiDocument.builder().documentId(documentId).build()); List listParams = new ArrayList<>(); if (document != null) { UploadDocumentParams params = new UploadDocumentParams(); params.setDocument_id(documentId); params.setName(document.getName()); params.setUrl(document.getUrl()); listParams.add(params); } JSONObject jsonObject = analysisFile(listParams, settings, "update"); if (jsonObject != null && jsonObject.containsKey("code") && jsonObject.getInteger("code") == 200) { logger.info("update document setting success, id:{}", documentId); documentSettings.setDocumentId(documentId); return takaiDocumentSettingsMapper.updateDocumentSettings(documentSettings); } return 0; } @Override public JSONObject getSliceList(TakaiSliceParams params) { // String url = deepseekConfig.getBaseurl() + deepseekConfig.getSlicePage(); // JSONObject jsonObject = new JSONObject(); // jsonObject.put("document_id", params.getDocument_id()); // jsonObject.put("knowledge_id", params.getKnowledge_id()); // jsonObject.put("text", params.getText()); // jsonObject.put("pageNum", params.getPageNum()); // jsonObject.put("pageSize", params.getPageSize()); // // RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8"), jsonObject.toJSONString()); // Request request = buildPostRequest(url, requestBody); // // OkHttpClient client = buildOkHttpClient(); // Response response = null; // try { // response = client.newCall(request).execute(); // if (response.isSuccessful()) { // String body = response.body().string(); // JSONObject obj = JSON.parseObject(body); // Integer code = obj.getInteger("code"); // if (code == 200) { // return obj; // } // } else { // logger.info("获取切片列表调用python接口失败,返回状态码:{}", response.code()); // } // } catch (IOException e) { // logger.error("获取切片列表调用python接口失败", e.getMessage()); // } return null; } @Override public int deleteSlice(String sliceId, String knowledgeId, String documentId) { String url = deepseekConfig.getBaseurl() + deepseekConfig.getDeleteSlice() + "/" + sliceId + "/" + knowledgeId + "/" + documentId; Request request = buildDeleteRequest(url); OkHttpClient client = buildOkHttpClient(); Response response = null; try { response = client.newCall(request).execute(); if (response.isSuccessful()) { String body = response.body().string(); JSONObject obj = JSON.parseObject(body); Integer code = obj.getInteger("code"); logger.info("删除切片调用python接口成功,返回结果:{}", body); if (code == 200) { updateDocumentSize(knowledgeId,documentId); return 1; } } } catch (IOException e) { logger.error("删除切片调用python接口失败", e.getMessage()); } return 0; } @Override public JSONObject getSliceDetail(String sliceId, String knowledgeId) { String url = deepseekConfig.getBaseurl() + deepseekConfig.getSliceDetail() + "/" + knowledgeId + "/" + sliceId; Request request = buildGetRequest(url); OkHttpClient client = buildOkHttpClient(); try { Response response = client.newCall(request).execute(); if (response.isSuccessful()) { String body = response.body().string(); log.info("查询切片详情返回:" + body); JSONObject jsonObject = JSON.parseObject(body); JSONObject dataObject = jsonObject.getJSONObject("data"); String docId = dataObject.getString("document_id"); String sliceText = dataObject.getString("slice_text"); TakaiMediaReplacement conditonR = TakaiMediaReplacement.builder().documentId(docId).build(); List imageList = takaiMediaReplacementMapper.selectMediaList(conditonR); //替换【示意图序号_XXXXX】为超链接 List sliceImageList = SchematicNumberParser.extractImageUrlMappings(sliceText,imageList); // String replaceText = SchematicNumberParser.replaceWithImageLinks(sliceText,imageList); // dataObject.put("slice_text",replaceText); dataObject.put("imageList",sliceImageList); return jsonObject; } else { logger.info("获取切片详情调用python接口失败,返回状态码:{}", response.code()); } } catch (IOException e) { log.error("查询切片详情调用python接口失败", e.getMessage()); } return null; } @Override public List uploadSliceImage(MultipartFile[] files, String knowledgeId, String documentId) { List resultList = null; try { resultList = minioUtil.uploadSliceImages(files,knowledgeId,documentId); } catch (Exception e) { logger.error("上传文件失败", e.getMessage()); } //保存图片信息 List originTextList = new ArrayList<>(); for (TakaiSysOss result : resultList) { TakaiMediaReplacement takaiMediaReplacement = TakaiMediaReplacement.builder() .knowledgeId(knowledgeId) .documentId(documentId) .originText(result.getOriginText()) .mediaType("image") .mediaUrl(result.getUrl()) .build(); Date currentDate = new Date(); takaiMediaReplacement.setCreateTime(currentDate); takaiMediaReplacement.setUpdateTime(currentDate); takaiMediaReplacementMapper.insertMedia(takaiMediaReplacement); TakaiSliceImage sliceImage = TakaiSliceImage.builder().name(result.getOriginText()).url(result.getUrl()).build(); originTextList.add(sliceImage); } return originTextList; } @Override public int updateSliceInfo(TakaiSliceUpdateParams params) { String url = deepseekConfig.getBaseurl() + deepseekConfig.getUpdateSlice(); JSONObject object = new JSONObject(); object.put("knowledge_id", params.getKnowledgeId()); object.put("slice_id", params.getSliceId()); object.put("slice_text", base64DecodeUtil.decodeIfNeeded(params.getSliceText())); object.put("document_id", params.getDocumentId()); RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8"), object.toJSONString()); Request request = buildPutRequest(url, requestBody); OkHttpClient client = buildOkHttpClient(); try { Response response = client.newCall(request).execute(); if (response.isSuccessful()) { String body = response.body().string(); JSONObject obj = JSON.parseObject(body); Integer code = obj.getInteger("code"); if (code == 200) { updateDocumentSize(params.getKnowledgeId(),params.getDocumentId()); return 1; } } } catch (Exception e) { logger.error("更新切片信息调用python接口失败", e.getMessage()); } return 0; } @Override public TakaiMediaReplacement getTakaiMediaReplacement() { TakaiMediaReplacement mrParams = TakaiMediaReplacement.builder() .documentId("a2912832435041734656") .originText("【示意图序号_a2912832435041734656_1】") .mediaType("image").build(); TakaiMediaReplacement mrVo = takaiMediaReplacementMapper.selectTargetMedia(mrParams); return mrVo; } @Override public int addSlice(TakaiSliceUpdateParams params) { String url = deepseekConfig.getBaseurl() + deepseekConfig.getAddSlice(); TakaiDocument info = takaiDocumentMapper.selectTargetDocument(TakaiDocument.builder().documentId(params.getDocumentId()).build()); if(info != null){ JSONObject json = new JSONObject(); json.put("knowledge_id", params.getKnowledgeId()); json.put("document_id", params.getDocumentId()); json.put("slice_text", base64DecodeUtil.decodeIfNeeded(params.getSliceText())); json.put("doc_name", info.getName()); RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8"), json.toJSONString()); Request request = buildPostRequest(url, requestBody); OkHttpClient client = buildOkHttpClient(); try { Response response = client.newCall(request).execute(); if (response.isSuccessful()) { String body = response.body().string(); JSONObject obj = JSON.parseObject(body); Integer code = obj.getInteger("code"); if (code == 200) { updateDocumentSize(params.getKnowledgeId(),params.getDocumentId()); return 1; } } }catch (Exception e) { logger.error("新增切片调用python接口失败", e.getMessage()); } } return 0; } @Override public List selectByDocumentId(String documentId,String sliceText) { return takaiSliceInfoMapper.selectByDocumentId(documentId,sliceText); } @Override public TakaiSliceInfo selectBySliceId(String sliceId) { return takaiSliceInfoMapper.selectBySliceId(sliceId); } @Override public List slicePageInfoList(List list) { return takaiSliceInfoMapper.slicePageInfoList(list); } @Override public JSONObject searchSlice(String id) { String url = deepseekConfig.getBaseurl() + deepseekConfig.getSearchSlice() + "/" + id; Request request = buildGetRequest(url); OkHttpClient client = buildOkHttpClient(); try { Response response = client.newCall(request).execute(); if (response.isSuccessful()) { String body = response.body().string(); JSONObject obj = JSON.parseObject(body); Integer code = obj.getInteger("code"); if (code == 200) { return obj; } } }catch (Exception e) { logger.error("切片得分调用python接口失败", e.getMessage()); } return null; } @Override public List searchAppTypeGroupList(List dictDataList, String userId) { List result = new ArrayList(); if (dictDataList!= null && dictDataList.size() > 0) { for (SysDictData dictData : dictDataList){ // PageHelper.startPage(1, 3, "sort is null asc,sort"); PageHelper.orderBy("sort is null asc, sort"); Map map = new HashMap(); TakaiApplication paramsVo = TakaiApplication.builder().approver(userId).flag("0").addOrderBy("0").build(); //项目应用 if(dictData.getDictCode() == 41){ Map l = searchAppProjectGroupList(paramsVo, dictData); if(!MapUtils.isEmpty(l)){ result.add(l); } //其他分类应用 }else{ paramsVo.setTypeId(Long.valueOf(dictData.getDictCode())); List list = takaiApplicationMapper.selectApplicationList(paramsVo); if(list != null && list.size() > 0){ List appInfoList = new ArrayList(); map.put("title", dictData.getDictLabel()); for (TakaiApplicationResult application : list){ Map infoMap = new HashMap(); infoMap.put("title", application.getName()); infoMap.put("appId", application.getAppId()); infoMap.put("showMenu", "false"); infoMap.put("chatMode", "LOCAL"); appInfoList.add(infoMap); } map.put("children", appInfoList); result.add(map); } } } } return result; } private Map searchAppProjectGroupList(TakaiApplication paramsVo, SysDictData dictData) { paramsVo.setTypeId(dictData.getDictCode()); List list = takaiApplicationMapper.selectApplicationList(paramsVo); //项目级应用 Map projectLevelMap = new HashMap(); projectLevelMap.put("title", dictData.getDictLabel()); List projectAppList = new ArrayList(); if (list!= null && list.size() > 0) { // 按项目分组 Map> projectAppMap = list .stream().collect(Collectors.groupingBy(TakaiApplicationResult::getProjectName)); for (Iterator iterator = projectAppMap.keySet().iterator(); iterator.hasNext();) { String projectName = iterator.next(); Map newProjectAppMap = new HashMap(); List appList = projectAppMap.get(projectName); List newAppList = new ArrayList(); for (TakaiApplicationResult application : appList) { Map appMap = new HashMap(); appMap.put("appId", application.getAppId()); appMap.put("showMenu", "false"); appMap.put("chatMode", "LOCAL"); appMap.put("title", application.getName()); newAppList.add(appMap); } newProjectAppMap.put("title", projectName); newProjectAppMap.put("children",newAppList); projectAppList.add(newProjectAppMap); } } projectLevelMap.put("children",projectAppList); return projectLevelMap; }; private Map searchAppTypeGroupList(TakaiApplication paramsVo, SysDictData dictData) { //慧监理 paramsVo.setTypeId(Long.valueOf(42)); List list1 = takaiApplicationMapper.selectApplicationList(paramsVo); //慧项管 paramsVo.setTypeId(Long.valueOf(43)); List list2 = takaiApplicationMapper.selectApplicationList(paramsVo); List list3 = new ArrayList(); list3.addAll(list1); list3.addAll(list2); Map map = new HashMap(); if (list3!= null && list3.size() > 0) { List l = new ArrayList<>(); map.put("title", dictData.getDictLabel()); // 分组 Map> map1 = list3.stream().collect(Collectors.groupingBy(TakaiApplicationResult::getTypeId)); for (Map.Entry> entry : map1.entrySet()) { List mp = entry.getValue(); Map infoProjectMap = new HashMap(); List projectInfoList = new ArrayList(); for (TakaiApplicationResult application : mp){ SysDictData vo = sysDictDataMapper.selectDictDataById(Long.valueOf(application.getTypeId())); infoProjectMap.put("title", vo.getDictLabel()); Map projectMap = new HashMap(); projectMap.put("appId", application.getAppId()); projectMap.put("showMenu", "false"); projectMap.put("chatMode", "LOCAL"); projectMap.put("title", application.getName()); projectInfoList.add(projectMap); } infoProjectMap.put("children", projectInfoList); l.add(infoProjectMap); } map.put("children", l); } return map; } @Override public List applicationListByApprover(TakaiApplicationParams takaiApplicationParams) { TakaiApplication vo = TakaiApplication.builder().approver(takaiApplicationParams.getApprover()) .build(); return takaiApplicationMapper.selectAppListByApprover(vo); } @Override public int startAudit(String appId, String userId) { List list = documentAuditConfigMapper.selectDocumentAuditConfigListByBo(null); if(list != null && list.size() > 0) { ApprovalFlowManager flowManager = new ApprovalFlowManager(); logger.info("开启审核"); for (DocumentAuditConfig config : list) { // 添加审核节点 flowManager.addNode(new ApprovalNode(config.getId(), config.getNodeOrder(), config.getApprover(), config.getChain())); } ApprovalNode vo = flowManager.getFirstApprover(); TakaiApplication appVo = takaiApplicationMapper.selectTargetApplication(TakaiApplication.builder().appId(appId).build()); appVo.setApprover(String.valueOf(vo.getApprover())); appVo.setNodeOrder(String.valueOf(vo.getNodeOrder())); appVo.setStatus("1"); int i = takaiApplicationMapper.updateApplication(appVo); if(i > 0){ DocumentAuditInfo info = new DocumentAuditInfo(); info.setAppId(appId); info.setApprover(userId); info.setStatus("5"); info.setNodeOrder(Integer.valueOf("0")); info.setCreateBy(userId); info.setCreateTime(new Date()); documentAuditInfoMapper.insertDocumentAuditInfo(info); // 审核记录 } return i; }else{ return 9; } } @Override public int updateAuditApplication(TakaiApplicationParams appParams, String appId) { // 获取审核配置信息 (人员,节点) List list = documentAuditConfigMapper.selectDocumentAuditConfigListByBo(null); if(list != null && list.size() > 0){ if(("Y").equals(appParams.getStatus())){ ApprovalFlowManager flowManager = new ApprovalFlowManager(); logger.info("审核通过,开始审批流程"); for (DocumentAuditConfig config: list){ // 添加审核节点 flowManager.addNode(new ApprovalNode(config.getId(), config.getNodeOrder(), config.getApprover(), config.getChain())); } // 根据审核节点获取下一个审核节点 ApprovalNode nextNode = flowManager.getNextApproverByOrder(Integer.valueOf(appParams.getNodeOrder())); if (nextNode == null) { // 审核通过,更新文档状态 logger.info("审核通过,到最后节点"); return saveAuditInfo(appParams, "3", appId); }else{ // 审核通过,下一个节点 TakaiApplication appVo = takaiApplicationMapper.selectTargetApplication(TakaiApplication.builder().appId(appId).build()); appVo.setApprover(String.valueOf(nextNode.getApprover())); appVo.setNodeOrder(String.valueOf(nextNode.getNodeOrder())); appVo.setStatus("2"); appVo.setComment(appParams.getComment()); int successI = takaiApplicationMapper.updateApplication(appVo); if(successI > 0){ DocumentAuditInfo info = new DocumentAuditInfo(); info.setAppId(appId); info.setApprover(appParams.getApprover()); info.setComment(appParams.getComment()); info.setStatus("2"); info.setNodeOrder(Integer.valueOf(appParams.getNodeOrder())); info.setCreateBy(appParams.getApprover()); info.setCreateTime(new Date()); documentAuditInfoMapper.insertDocumentAuditInfo(info); // 审核记录 } return successI; } }else{ // 审核拒绝,更新文档状态 logger.info("审核拒绝,更新状态"); return saveAuditInfo(appParams, "5", appId); } } return 0; } private int saveAuditInfo(TakaiApplicationParams appParams, String status, String appId){ TakaiApplication appVo = takaiApplicationMapper.selectTargetApplication(TakaiApplication.builder().appId(appId).build()); appVo.setApprover(appParams.getApprover()); appVo.setNodeOrder(appParams.getNodeOrder()); appVo.setStatus(status); appVo.setComment(appParams.getComment()); int successI = takaiApplicationMapper.updateApplication(appVo); if(successI > 0){ DocumentAuditInfo info = new DocumentAuditInfo(); info.setAppId(appId); info.setApprover(appParams.getApprover()); info.setComment(appParams.getComment()); if("5".equals(status)){ info.setStatus("4"); }else{ info.setStatus(status); } info.setNodeOrder(Integer.valueOf(appParams.getNodeOrder())); info.setCreateBy(appParams.getApprover()); info.setCreateTime(new Date()); documentAuditInfoMapper.insertDocumentAuditInfo(info); // 审核记录 } return successI; } @Override public List selectAppByUserId(String userId) { return takaiApplicationMapper.selectAppByUserId(userId); } @Override public List selectAppCollectList(String userId) { return appCollectMapper.selectAppCollectList(userId); } @Override public int insertAppCollect(AppCollect appCollect) { AppCollect collect = appCollectMapper.selectAppCollectDetail(appCollect.getAppId(), appCollect.getUserId()); if (collect == null) { return appCollectMapper.insertAppCollect(appCollect); } return 0; } @Override public int deleteAppCollect(String userId, String appId) { return appCollectMapper.delAppCollect(userId, appId); } @Override public List selectRoleApp() { return takaiApplicationMapper.selectRoleApp(); } @Override public List getChatAppList(List params, String userId) { List list = new ArrayList(); for (TakaiApplicationResult app : params) { AppCollect appCollect = appCollectMapper.selectAppCollectDetail(app.getAppId(), userId); SysDictData dictData = null; if(app.getTypeId() != null && !"".equals(app.getTypeId())){ dictData = sysDictDataMapper.selectDictDataById(Long.valueOf(app.getTypeId())); } TakaiApplicationResult appResult = new TakaiApplicationResult(); appResult.setAppId(app.getAppId()); appResult.setName(app.getName()); appResult.setDesc(app.getDesc()); appResult.setTypeId(app.getTypeId()); appResult.setCreateTime(app.getCreateTime()); appResult.setChatMode("LOCAL"); appResult.setIsCollect(appCollect != null ? true : false); appResult.setTypeName(dictData != null ? dictData.getDictLabel() : ""); list.add(appResult); } return list; } private ApprovalNode getFirstApproverNode() { List list = documentAuditConfigMapper.selectDocumentAuditConfigListByBo(null); if(list != null && list.size() > 0) { ApprovalFlowManager flowManager = new ApprovalFlowManager(); logger.info("开启审核"); for (DocumentAuditConfig config : list) { // 添加审核节点 flowManager.addNode(new ApprovalNode(config.getId(), config.getNodeOrder(), config.getApprover(), config.getChain())); } return flowManager.getFirstApprover(); } return null; } private JSONObject analysisFile(List result, TakaiDocumentSettings settings, String flag) { String url = deepseekConfig.getBaseurl() + deepseekConfig.getUploadKnowledge(); JSONObject json = new JSONObject(); json.put("knowledge_id", settings.getKnowledgeId()); json.put("docs", result); if ("upload".equals(flag)) { json.put("set_slice", "0"); json.put("slice_value", null); json.put("set_analyze", "1"); json.put("set_table", "0"); json.put("flag", "upload"); } else { json.put("set_slice", settings.getSetSlice()); json.put("slice_value", settings.getSliceValue()); json.put("set_analyze", settings.getSetAnalyze()); json.put("set_table", settings.getSetTable()); json.put("flag", "update"); } RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), json.toJSONString()); Request request = buildPostRequest(url, requestBody); OkHttpClient client = buildOkHttpClient(); Response response = null; try { response = client.newCall(request).execute(); if (response.isSuccessful()) { String body = response.body().string(); JSONObject obj = JSON.parseObject(body); Integer code = obj.getInteger("code"); if (code == 200) { logger.info("上传文档调用python接口成功,返回内容:{}", body); } else { logger.info("上传文档调用python接口失败,返回内容:{}", body); } return obj; } else { logger.error("上传文档调用python接口失败返回code:{}", response.code()); return null; } } catch (IOException e) { logger.error("上传文档调用python接口失败", e.getMessage()); return null; } } @Override public List setDialogList(List list) { //根据时间分组降序排序 NavigableMap> groupList = list.stream().collect(Collectors.groupingBy(TakaiDialogRespDTO::getCreate_time, TreeMap::new, Collectors.toList())).descendingMap(); List obj = new ArrayList(); if (!groupList.isEmpty()) { for (Map.Entry> entry : groupList.entrySet()) { List aList = entry.getValue(); List detailList = takaiDialogMapper.selectDialogExport(aList.get(0).getId()); Map map = new HashMap(); map.put("dialog_name", aList.get(0).getDialog_name()); map.put("length", detailList.size()); map.put("create_time", aList.get(0).getCreate_time()); map.put("did", aList.get(0).getDid()); map.put("id", aList.get(0).getId()); obj.add(map); } } return obj; } private List> setValue(List list, String appId) { List> l = new ArrayList(); for (TakaiDialogRespDTO vo : list) { Map map = new HashMap(); map.put("key", vo.getId()); map.put("label", vo.getDialog_name()); map.put("appId", appId); map.put("showMenu", "false"); map.put("chatMode", "LOCAL"); l.add(map); } return l; } private OkHttpClient buildOkHttpClient() { return new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .writeTimeout(50, TimeUnit.SECONDS) .readTimeout(20, TimeUnit.MINUTES) .build(); } private Request buildGetRequest(String url) { return new Request.Builder() .addHeader("User-Agent", "insomnia/10.3.1") .url(url).get().build(); } private Request buildPostRequest(String url, RequestBody requestBody) { return new Request.Builder() .addHeader("User-Agent", "insomnia/10.3.1") .addHeader("Content-Type", "application/json") .url(url).post(requestBody).build(); } private Request buildPutRequest(String url, RequestBody requestBody) { return new Request.Builder() .addHeader("User-Agent", "insomnia/10.3.1") .url(url).put(requestBody).build(); } private Request buildDeleteRequest(String url) { return new Request.Builder() .addHeader("Content-Type", "multipart/form-data") .addHeader("User-Agent", "insomnia/10.3.1") .url(url).delete().build(); } private Request buildUploadPostRequest(String url, RequestBody requestBody) { return new Request.Builder() .addHeader("User-Agent", "insomnia/10.3.1") .addHeader("Content-Type", "application/json") .url(url).post(requestBody).build(); } private boolean isJsonObject(String data) { try { JSON.parseObject(data); return true; } catch (Exception e) { return false; } } }