TakaiAiServiceImpl.java 84 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840
  1. package com.takai.ai.service.impl;
  2. import com.alibaba.fastjson2.JSON;
  3. import com.alibaba.fastjson2.JSONArray;
  4. import com.alibaba.fastjson2.JSONObject;
  5. import com.github.pagehelper.PageHelper;
  6. import com.takai.ai.domain.TakaiSysOss;
  7. import com.takai.ai.domain.dto.*;
  8. import com.takai.ai.domain.entity.*;
  9. import com.takai.ai.mapper.*;
  10. import com.takai.ai.service.IMinioConfigService;
  11. import com.takai.ai.service.ITakaiAiService;
  12. import com.takai.ai.utils.*;
  13. import com.takai.common.annotation.DataSource;
  14. import com.takai.common.config.DeepseekConfig;
  15. import com.takai.common.constant.UserConstants;
  16. import com.takai.common.core.domain.entity.SysDictData;
  17. import com.takai.common.core.domain.entity.SysUser;
  18. import com.takai.common.core.domain.model.LoginUser;
  19. import com.takai.common.core.redis.RedisCache;
  20. import com.takai.common.enums.AppTypeEnum;
  21. import com.takai.common.enums.DataSourceType;
  22. import com.takai.common.utils.SecurityUtils;
  23. import com.takai.common.utils.StringUtils;
  24. import com.takai.common.utils.uuid.IdUtils;
  25. import com.takai.framework.web.service.SysPermissionService;
  26. import com.takai.system.domain.*;
  27. import com.takai.system.mapper.*;
  28. import com.takai.system.service.ISysUserService;
  29. import lombok.extern.slf4j.Slf4j;
  30. import okhttp3.*;
  31. import okhttp3.sse.EventSource;
  32. import okhttp3.sse.EventSourceListener;
  33. import okhttp3.sse.EventSources;
  34. import org.apache.commons.collections4.MapUtils;
  35. import org.slf4j.Logger;
  36. import org.slf4j.LoggerFactory;
  37. import org.springframework.beans.BeanUtils;
  38. import org.springframework.beans.factory.annotation.Autowired;
  39. import org.springframework.data.redis.core.RedisTemplate;
  40. import org.springframework.stereotype.Service;
  41. import org.springframework.web.multipart.MultipartFile;
  42. import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
  43. import javax.validation.constraints.NotNull;
  44. import java.io.IOException;
  45. import java.nio.charset.StandardCharsets;
  46. import java.time.LocalDate;
  47. import java.time.LocalDateTime;
  48. import java.time.temporal.ChronoUnit;
  49. import java.util.*;
  50. import java.util.concurrent.TimeUnit;
  51. import java.util.stream.Collectors;
  52. /**
  53. * 高井 业务层处理
  54. *
  55. * @author takai
  56. */
  57. @Slf4j
  58. @Service
  59. @DataSource(DataSourceType.MASTER)
  60. public class TakaiAiServiceImpl implements ITakaiAiService {
  61. private static final Logger logger = LoggerFactory.getLogger(TakaiAiServiceImpl.class);
  62. @Autowired
  63. private TakaiDialogMapper takaiDialogMapper;
  64. @Autowired
  65. private TakaiApplicationMapper takaiApplicationMapper;
  66. @Autowired
  67. private TakaiQuestionMapper takaiQuestionMapper;
  68. @Autowired
  69. private TakaiKnowledgeMapper takaiKnowledgeMapper;
  70. @Autowired
  71. private TakaiDocumentMapper takaiDocumentMapper;
  72. @Autowired
  73. private TakaiSysOssConfigMapper takaiSysOssConfigMapper;
  74. @Autowired
  75. private TakaiSysOssMapper takaiSysOssMapper;
  76. @Autowired
  77. private MinioUtil minioUtil;
  78. @Autowired
  79. private TakaiDocumentSettingsMapper takaiDocumentSettingsMapper;
  80. @Autowired
  81. private DeepseekConfig deepseekConfig;
  82. @Autowired
  83. private TakaiAppInfoMapper takaiAppInfoMapper;
  84. @Autowired
  85. private TakaiMediaReplacementMapper takaiMediaReplacementMapper;
  86. @Autowired
  87. private RedisCache redisCache;
  88. @Autowired
  89. public RedisTemplate redisTemplate;
  90. @Autowired
  91. private TakaiSliceInfoMapper takaiSliceInfoMapper;
  92. @Autowired
  93. private DocumentAuditConfigMapper documentAuditConfigMapper;
  94. @Autowired
  95. private DocumentAuditInfoMapper documentAuditInfoMapper;
  96. @Autowired
  97. private SysPermissionService permissionService;
  98. @Autowired
  99. private TypeAppMapper appTypeMapper;
  100. @Autowired
  101. private TakaiAppCollectMapper appCollectMapper;
  102. @Autowired
  103. private SysDictDataMapper sysDictDataMapper;
  104. @Autowired
  105. private SysProjectAppMapper sysProjectAppMapper;
  106. @Autowired
  107. private TakaiFileInfoMapper fileInfoMapper;
  108. @Autowired
  109. private Base64DecodeUtil base64DecodeUtil;
  110. public static final String START_SIGN = "【";
  111. public static final String END_SIGN = "】";
  112. public static final String SYMBOL = "【示意图序号";
  113. public static final String USER_STR = "user";
  114. public static final String TODAY = "今日";
  115. public static final String BEFOR = "日前";
  116. private final String OSS_URL= "https://minio.jkec.info:9000";
  117. @Autowired
  118. private SysProjectMapper sysProjectMapper;
  119. @Autowired
  120. private ISysUserService userService;
  121. @Override
  122. public void initDeepseekInfo() {
  123. //获取应用列表
  124. // List<TakaiApplication> appList = takaiApplicationMapper.selectApplicationList(null);
  125. setRedisCache(null);
  126. }
  127. private void setRedisCache(String knowledgeId) {
  128. //获取知识库列表
  129. List<TakaiKnowledge> knowledgeList = null;
  130. if (StringUtils.isEmpty(knowledgeId)) {
  131. knowledgeList = takaiKnowledgeMapper.selectAllKnowledgeList(null);
  132. } else {
  133. knowledgeList = takaiKnowledgeMapper.selectAllKnowledgeList(TakaiKnowledge.builder().knowledgeId(knowledgeId).build());
  134. }
  135. //获取知识列表
  136. if (!knowledgeList.isEmpty()) {
  137. for (TakaiKnowledge bmKnowledge : knowledgeList) {
  138. TakaiDocument conditon = TakaiDocument.builder().knowledgeId(bmKnowledge.getKnowledgeId()).build();
  139. List<TakaiDocument> documentList = takaiDocumentMapper.selectDocumentList(conditon);
  140. if (!documentList.isEmpty()) {
  141. for (TakaiDocument bmDocument : documentList) {
  142. //获取知识图片列表
  143. TakaiMediaReplacement conditonR = TakaiMediaReplacement.builder().documentId(bmDocument.getDocumentId()).build();
  144. List<TakaiMediaReplacement> imageList = takaiMediaReplacementMapper.selectMediaList(conditonR);
  145. if (!imageList.isEmpty()) {
  146. for (TakaiMediaReplacement image : imageList) {
  147. redisCache.setCacheObject(image.getOriginText(), image.getMediaUrl());
  148. }
  149. }
  150. }
  151. }
  152. }
  153. }
  154. }
  155. @Override
  156. public SseEmitter sseInvoke(TakaiSseInfoParams sseParams) {
  157. TakaiApplication appInfo = takaiApplicationMapper.selectTargetApplication(TakaiApplication.builder().appId(sseParams.getAppId()).build());
  158. if (appInfo != null) {
  159. List<String> idList = Arrays.stream(appInfo.getKnowledgeIds().split(",")) // 按「逗号+空格」拆分字符串为数组
  160. .filter(str -> str != null && !str.trim().isEmpty()) // 过滤 null 和空字符串(防异常)
  161. .collect(Collectors.toList());
  162. TakaiKnowledge knowledgeParam = TakaiKnowledge.builder().knowledgeIds(idList).build();
  163. List<TakaiKnowledge> knowledgeList = takaiKnowledgeMapper.selectAllKnowledgeList(knowledgeParam);
  164. if (knowledgeList != null && !knowledgeList.isEmpty()) {
  165. SseEmitter sseEmitter = new SseEmitter(0L);
  166. String url = deepseekConfig.getBaseurl() + deepseekConfig.getChat();
  167. TakaiAppInfo info = takaiAppInfoMapper.selectAppInfoByAppId(sseParams.getAppId());
  168. JSONObject json = JSONObject.parseObject(info.getAppInfo());
  169. //重新设置knowledgeIds为数组
  170. json.put("knowledgeIds",idList);
  171. String query = null;
  172. decodeMessage(sseParams.getMessages());
  173. decodeMessage(sseParams.getPrompt());
  174. if(sseParams.getMessages() != null && !sseParams.getMessages().isEmpty() ) {
  175. query = sseParams.getMessages().get(sseParams.getMessages().size() - 1).getContent();
  176. } else {
  177. query = sseParams.getPrompt().get(sseParams.getPrompt().size() - 1).getContent();
  178. }
  179. log.info("deepseek聊天请求参数:" + query);
  180. json.put("query", query);
  181. json.put("embeddingId", knowledgeList.get(0).getEmbeddingId());
  182. if(UserConstants.YES.equals(json.getString("isDeepThink"))) {
  183. json.put("enable_think", true);
  184. } else {
  185. json.put("enable_think", false);
  186. }
  187. RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8"), json.toJSONString());
  188. Request request = buildPostRequest(url, requestBody);
  189. // 使用EventSourceListener处理来自服务器的SSE事件
  190. EventSourceListener listener = new EventSourceListener() {
  191. private String preData = "";
  192. //图片识别
  193. private String symbolData = "";
  194. @Override
  195. public void onOpen(@NotNull EventSource eventSource, @NotNull Response response) {
  196. log.info("deepseek Connection opened. Headers: {}", response.headers());
  197. log.info("deepseek Request URL: {}", response.request().url());
  198. }
  199. @Override
  200. public void onClosed(@NotNull EventSource eventSource) {
  201. log.info("deepseek Connection closed.");
  202. sseEmitter.complete();
  203. }
  204. @Override
  205. public void onEvent(@NotNull EventSource eventSource, String id, String type, @NotNull String data) {
  206. if (!StringUtils.isEmpty(data)) {
  207. String newData = data.substring(preData.length());
  208. logger.info("deepseek聊天返回消息:" + data);
  209. preData = data;
  210. if (newData.indexOf(START_SIGN) > -1 || symbolData.length() > 0) {
  211. symbolData = symbolData + newData;
  212. //接收到了完整的图片标识
  213. int endSignPos = symbolData.indexOf(END_SIGN);
  214. if (endSignPos > -1) {
  215. JSONObject json = new JSONObject();
  216. json.put("id", id);
  217. json.put("event", "add");
  218. //是图片
  219. if (symbolData.indexOf(SYMBOL) > -1) {
  220. //获取完整Key
  221. int startPos = symbolData.indexOf(START_SIGN);
  222. int endPos = symbolData.indexOf(END_SIGN) + 1;
  223. String key = symbolData.substring(startPos, endPos);
  224. String url = redisCache.getCacheObject(key);
  225. if (org.springframework.util.StringUtils.hasText(url)) {
  226. if(url.contains("https://10.1.28.14:9000")){
  227. //url = url.replace("https://10.1.28.14:9000", "https://minio.jkec.info:9000");
  228. url = url.replace("https://10.1.28.14:9000", OSS_URL);
  229. }
  230. //匹配markdown图片格式
  231. // symbolData = symbolData.replace(key, "![](" + url + ")");
  232. } else {
  233. logger.error("图片标识符"+key+"没有获取到对应的URL{}: " + symbolData);
  234. }
  235. //检查是否当前token包含其他图片的开始符号”【“
  236. int lastPos = symbolData.lastIndexOf(START_SIGN);
  237. if(lastPos > endSignPos){
  238. // 从'【' 开始截取
  239. newData = symbolData.substring(0, lastPos);
  240. symbolData = symbolData.substring(lastPos);
  241. logger.info("截取结果{}: " + symbolData);
  242. } else {
  243. newData = symbolData;
  244. symbolData = "";
  245. }
  246. if(!StringUtils.isEmpty(url)) {
  247. newData = newData.replace(key, " ![](" + url + ")");
  248. }
  249. } else {
  250. newData = symbolData;
  251. symbolData = "";
  252. }
  253. json.put("data", newData);
  254. log.info("获取到图片替换结束符号,返回前端信息:" + json);
  255. send(sseEmitter, json);
  256. //如果超过长度200还没收到】符号,直接返回。
  257. } else if (symbolData.length() > 200) {
  258. JSONObject json = new JSONObject();
  259. json.put("id", id);
  260. json.put("event", "add");
  261. json.put("data", symbolData);
  262. }
  263. } else {
  264. JSONObject json = new JSONObject();
  265. json.put("id", id);
  266. json.put("event", type);
  267. json.put("data", newData);
  268. log.info("deepseek返回信息:" + json);
  269. send(sseEmitter, json);
  270. }
  271. }
  272. if (com.takai.common.utils.StringUtils.isNotEmpty(type) && "finish".equals(type)) {
  273. log.info("deepseek聊天结束");
  274. JSONObject json = new JSONObject();
  275. json.put("id", id);
  276. json.put("event", type);
  277. json.put("data", data);
  278. log.info("deepseek返回信息:" + json);
  279. send(sseEmitter, json);
  280. }
  281. }
  282. @Override
  283. public void onFailure(@NotNull EventSource eventSource, Throwable t, Response response) {
  284. if (response != null) {
  285. log.error("deepseek Connection failed. Response code: {}, message: {}, body: {}",
  286. response.code(), response.message(), response.body() != null ? response.body().toString() : "null");
  287. } else {
  288. log.error("deepseek Connection failed with no response", t);
  289. }
  290. sseEmitter.completeWithError(t);
  291. }
  292. private void send(SseEmitter sseEmitter, Object obj) {
  293. try {
  294. sseEmitter.send(obj);
  295. } catch (IOException e) {
  296. log.error("deepseek 推送数据失败", e);
  297. }
  298. }
  299. };
  300. OkHttpClient client = buildOkHttpClient();
  301. EventSource.Factory factory = EventSources.createFactory(client);
  302. final EventSource eventSources = factory.newEventSource(request, listener);
  303. // 客户端主动关闭连接
  304. sseEmitter.onCompletion(() -> {
  305. logger.info("deepseek客户端主动关闭连接 -- SSE 连接关闭");
  306. });
  307. // 超时回调
  308. sseEmitter.onTimeout(() -> {
  309. logger.info("deepseek客户端连接超时 -- SSE 连接关闭");
  310. if(eventSources != null) {
  311. logger.info("deepseek超时回调 -- 成功关闭SSE连接 ");
  312. eventSources.cancel();
  313. }
  314. });
  315. // 错误回调
  316. sseEmitter.onError(e -> {
  317. logger.info("deepseek客户端回调失败 -- SSE 连接关闭");
  318. if(eventSources != null) {
  319. logger.info("deepseek错误回调 -- 成功关闭SSE连接 ");
  320. eventSources.cancel();
  321. }
  322. });
  323. return sseEmitter;
  324. }
  325. }
  326. return null;
  327. }
  328. private void decodeMessage(List<TakaiPromptInfo> messages) {
  329. if(messages == null || messages.isEmpty()) {
  330. return;
  331. }
  332. for (TakaiPromptInfo message : messages) {
  333. message.setContent(base64DecodeUtil.decodeIfNeeded(message.getContent()));
  334. }
  335. }
  336. @Override
  337. public List<String> asyncCompletions(TakaiCompletionsParams params) {
  338. List<String> list = new ArrayList<>();
  339. TakaiApplication vo = takaiApplicationMapper.selectTargetApplication(TakaiApplication.builder().appId(params.getAppId()).build());
  340. if (vo != null) {
  341. TakaiPromptInfo info = new TakaiPromptInfo();
  342. info.setContent(deepseekConfig.getPrompt());
  343. info.setRole("user");
  344. decodeMessage(params.getMessages());
  345. params.getMessages().add(info);
  346. JSONObject jsonObject = new JSONObject();
  347. jsonObject.put("model", vo.getModel());
  348. jsonObject.put("messages", params.getMessages());
  349. jsonObject.put("chat_id", params.getChat_id());
  350. JSONObject result = getasyncCompletions(jsonObject);
  351. if (result != null && result.getInteger("code") == 200) {
  352. JSONArray array = result.getJSONArray("data");
  353. if(array != null){
  354. list.addAll(array.toJavaList(String.class));
  355. }
  356. }
  357. }
  358. return list;
  359. }
  360. private JSONObject getasyncCompletions(JSONObject jsonObject) {
  361. String url = deepseekConfig.getBaseurl() + deepseekConfig.getAsyncCompletions();
  362. RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8"), jsonObject.toJSONString());
  363. Request request = buildPostRequest(url, requestBody);
  364. OkHttpClient client = buildOkHttpClient();
  365. try {
  366. Response response = client.newCall(request).execute();
  367. if (response.isSuccessful()) {
  368. String body = response.body().string();
  369. if (isJsonObject(body)) {
  370. return JSON.parseObject(body);
  371. }
  372. }
  373. } catch (IOException e) {
  374. log.info("deepseek Request URL: {}", e.getMessage());
  375. }
  376. return null;
  377. }
  378. @Override
  379. public List<TakaiDialogRespDTO> getDialogDetail(String dialogId) {
  380. List<TakaiDialogRespDTO> detail = takaiDialogMapper.selectDialogDetail(dialogId);
  381. if(detail != null && detail.size() != 0){
  382. for(TakaiDialogRespDTO dto : detail){
  383. if(StringUtils.isNotEmpty(dto.getSliceJson())){
  384. dto.setSliceInfo(JSON.parseObject(dto.getSliceJson(), TakaiSliceInfoDTO.class));
  385. }
  386. if("user".equals(dto.getType())){
  387. List<TakaiFileInfo> fileInfoList = fileInfoMapper.getFileInfoById(null, dto.getDialog_id(), dto.getDid());
  388. if(fileInfoList != null && !fileInfoList.isEmpty()){
  389. List<TakaiDocumentDTO> documentDTOS = new ArrayList<>();
  390. for(TakaiFileInfo fileInfo : fileInfoList){
  391. TakaiDocumentDTO documentDTO = new TakaiDocumentDTO();
  392. BeanUtils.copyProperties(fileInfo, documentDTO);
  393. documentDTOS.add(documentDTO);
  394. }
  395. dto.setDocuments(documentDTOS);
  396. }
  397. }
  398. }
  399. }
  400. return detail;
  401. }
  402. @Override
  403. public void saveDialog(TakaiDialogReqDTO dialogReqDTO) {
  404. String dialogId = null;
  405. TakaiDialogRespDTO dialogVo = null;
  406. if (com.takai.common.utils.StringUtils.isNotEmpty(dialogReqDTO.getId())) {
  407. dialogVo = takaiDialogMapper.selectDialogById(dialogReqDTO.getId());
  408. }
  409. if (dialogVo == null) {
  410. takaiDialogMapper.insertDialog(dialogReqDTO);
  411. dialogId = dialogReqDTO.getId();
  412. } else {
  413. dialogId = dialogReqDTO.getId();
  414. }
  415. for (TakaiDialogDetailReqDTO dto : dialogReqDTO.getMessages()) {
  416. dto.setDialogId(dialogId);
  417. dto.setContent(base64DecodeUtil.decodeIfNeeded(dto.getContent()));
  418. TakaiDialogRespDTO detail = takaiDialogMapper.selectDialogDetailById(dto.getId());
  419. if (detail == null) {
  420. if (dto.getSliceInfo() != null) dto.setSliceJson(JSON.toJSONString(dto.getSliceInfo()));
  421. takaiDialogMapper.insertDialogDetail(dto);
  422. }
  423. if(dto.getDocuments() != null && !dto.getDocuments().isEmpty()){
  424. for(TakaiDocumentDTO documentVo : dto.getDocuments()){
  425. if(!"".equals(documentVo.getId())) {
  426. List<TakaiFileInfo> fileInfo = fileInfoMapper.getFileInfoById(documentVo.getId(), null, null);
  427. if((fileInfo == null || fileInfo.isEmpty()) && "user".equals(dto.getRole())) {
  428. TakaiFileInfo params = new TakaiFileInfo();
  429. params.setId(documentVo.getId());
  430. params.setName(documentVo.getName());
  431. params.setUrl(documentVo.getUrl());
  432. params.setDialogId(dialogId);
  433. params.setDialogDid(dto.getId());
  434. fileInfoMapper.insertFileInfo(params);
  435. }
  436. }
  437. }
  438. }
  439. }
  440. }
  441. @Override
  442. public List<Object> getDialogList(String appId, String userId) {
  443. List<TakaiDialogRespDTO> dialogRespDTOS = takaiDialogMapper.selectDialogList(appId, userId);
  444. //当前日期
  445. LocalDate today = LocalDate.now();
  446. //根据时间分组降序排序
  447. NavigableMap<LocalDateTime, List<TakaiDialogRespDTO>> groupList = dialogRespDTOS.stream().collect(Collectors.groupingBy(TakaiDialogRespDTO::getCreate_time, TreeMap::new, Collectors.toList())).descendingMap();
  448. List<Object> obj = new ArrayList();
  449. if (!groupList.isEmpty()) {
  450. for (Map.Entry<LocalDateTime, List<TakaiDialogRespDTO>> entry : groupList.entrySet()) {
  451. // 对比两个时间相差多少天
  452. long daysBetween = ChronoUnit.DAYS.between(today, entry.getKey());
  453. Map<String, Object> m = new HashMap();
  454. m.put("key", System.nanoTime());
  455. m.put("type", "group");
  456. if (daysBetween == 0l) {
  457. m.put("label", TODAY);
  458. m.put("children", setValue(entry.getValue(), appId));
  459. obj.add(m);
  460. } else {
  461. m.put("label", -daysBetween + BEFOR);
  462. m.put("children", setValue(entry.getValue(), appId));
  463. obj.add(m);
  464. }
  465. }
  466. }
  467. return obj;
  468. }
  469. @Override
  470. public void DelDialogDetail(String id) {
  471. int result = takaiDialogMapper.delDialog(id);
  472. if (result > 0) {
  473. takaiDialogMapper.delDialogDetail(id);
  474. }
  475. }
  476. @Override
  477. public void updateDialog(TakaiDialogReqDTO dialogReqDTO) {
  478. takaiDialogMapper.updateDialog(dialogReqDTO);
  479. }
  480. @Override
  481. public List<TakaiDialogRespDTO> exportExcel(String dialogId) {
  482. return takaiDialogMapper.selectDialogExport(dialogId);
  483. }
  484. @Override
  485. public int createKnowledge(TakaiKnowledgeParams knowledge) {
  486. SnowflakeDigitGenerator snowflakeDigitGenerator = new SnowflakeDigitGenerator(1, 1);
  487. long knowledgeId = snowflakeDigitGenerator.nextId();
  488. String url = deepseekConfig.getBaseurl() + deepseekConfig.getCreateKnowledge();
  489. JSONObject jsonObject = new JSONObject();
  490. jsonObject.put("knowledge_id", "a" + knowledgeId);
  491. jsonObject.put("embedding_id", knowledge.getEmbeddingId());
  492. RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8"), jsonObject.toJSONString());
  493. Request request = buildPostRequest(url, requestBody);
  494. OkHttpClient client = buildOkHttpClient();
  495. String createdBy = SecurityUtils.getLoginUser() == null ? "":SecurityUtils.getLoginUser().getUserId();
  496. try {
  497. Response response = client.newCall(request).execute();
  498. if (response.isSuccessful()) {
  499. String body = response.body().string();
  500. JSONObject obj = JSON.parseObject(body);
  501. Integer code = obj.getInteger("code");
  502. if (code == 200) {
  503. TakaiKnowledge params = TakaiKnowledge.builder()
  504. .knowledgeId("a" + knowledgeId)
  505. .name(knowledge.getName())
  506. .embeddingId(knowledge.getEmbeddingId())
  507. .description(knowledge.getDescription())
  508. .visible(knowledge.getVisible())
  509. .build();
  510. params.setCreateBy(createdBy);
  511. return takaiKnowledgeMapper.insertKnowledge(params);
  512. }
  513. } else {
  514. logger.error("创建知识库调用python接口失败,返回状态码:{}", response.code());
  515. }
  516. } catch (IOException e) {
  517. logger.error("创建知识库调用python接口失败", e.getMessage());
  518. }
  519. return 0;
  520. }
  521. @Override
  522. public int updateKnowledge(TakaiKnowledgeParams knowledge, String knowledgeId) {
  523. TakaiKnowledge params = TakaiKnowledge.builder().knowledgeId(knowledgeId)
  524. .name(knowledge.getName())
  525. .description(knowledge.getDescription())
  526. .embeddingId(knowledge.getEmbeddingId())
  527. .visible(knowledge.getVisible())
  528. .build();
  529. String updateBy = SecurityUtils.getLoginUser() == null ? "":SecurityUtils.getLoginUser().getUserId();
  530. params.setUpdateBy(updateBy);
  531. params.setUpdateTime(new Date());
  532. return takaiKnowledgeMapper.updateKnowledge(params);
  533. }
  534. @Override
  535. public TakaiKnowledge detailKnowledge(String knowledgeId) {
  536. TakaiKnowledge vo = TakaiKnowledge.builder().knowledgeId(knowledgeId).build();
  537. return takaiKnowledgeMapper.selectTargetKnowledge(vo);
  538. }
  539. @Override
  540. public int delKnowledge(String knowledgeId) {
  541. String url = deepseekConfig.getBaseurl() + deepseekConfig.getDeleteKnowledge() + "/" + knowledgeId;
  542. Request request = buildDeleteRequest(url);
  543. OkHttpClient client = buildOkHttpClient();
  544. Response response = null;
  545. try {
  546. response = client.newCall(request).execute();
  547. if (response.isSuccessful()) {
  548. String body = response.body().string();
  549. JSONObject obj = JSON.parseObject(body);
  550. Integer code = obj.getInteger("code");
  551. if (code == 200) {
  552. // TakaiKnowledge info = takaiKnowledgeMapper.selectTargetKnowledge(TakaiKnowledge.builder().knowledgeId(knowledgeId).build());
  553. List<TakaiMediaReplacement> list = takaiMediaReplacementMapper.selectMediaList(TakaiMediaReplacement.builder().knowledgeId(knowledgeId).build());
  554. List<TakaiDocument> documentList = takaiDocumentMapper.selectDocumentList(TakaiDocument.builder().knowledgeId(knowledgeId).build());
  555. int knowledgeInt = takaiKnowledgeMapper.delKnowledge(knowledgeId);
  556. if (knowledgeInt > 0) {
  557. takaiDocumentMapper.delDocumentByKnowledgeId(knowledgeId);
  558. takaiDocumentSettingsMapper.deleteDocumentSettingsByKnowledgeId(knowledgeId);
  559. if(list != null && list.size() > 0){
  560. try {
  561. for(TakaiDocument document: documentList){
  562. logger.info("删除知识库->删除minio文件");
  563. minioUtil.remove("deepseek-doc", "/"+document.getName());
  564. }
  565. for (int k = 0; k < list.size(); k++ ) {
  566. logger.info("删除知识库->删除minio图片{}", k);
  567. String key = "/pdf/"+knowledgeId+"/"+list.get(k).getDocumentId()+"/【示意图序号_"+list.get(k).getDocumentId()+"_"+k+1+"】.jpg";
  568. logger.info("删除知识库->删除minio图片key{}", key);
  569. minioUtil.remove("deepseek-doc" , key);
  570. }
  571. } catch (Exception e) {
  572. logger.error("删除知识库->删除minion文件失败", e.getMessage());
  573. throw new RuntimeException(e);
  574. }
  575. }
  576. }
  577. return knowledgeInt;
  578. }
  579. }
  580. } catch (IOException e) {
  581. logger.error("删除知识库调用python接口失败", e.getMessage());
  582. }
  583. return 0;
  584. }
  585. @Override
  586. public int uploadDocument(MultipartFile[] files, String knowledgeId) {
  587. List<TakaiSysOss> result = null;
  588. try {
  589. result = minioUtil.uploadMultiple(files);
  590. } catch (Exception e) {
  591. logger.error("上传文件失败", e.getMessage());
  592. }
  593. if (result != null && result.size() > 0) {
  594. List<UploadDocumentParams> params = new ArrayList<>();
  595. for (int i = 0; i<result.size(); i++) {
  596. SnowflakeDigitGenerator documentIdGenerator = new SnowflakeDigitGenerator(i, i);
  597. long documentId = documentIdGenerator.nextId();
  598. UploadDocumentParams param = new UploadDocumentParams();
  599. param.setDocument_id("a" + documentId);
  600. param.setName(result.get(i).getOriginalName());
  601. param.setUrl(result.get(i).getUrl());
  602. params.add(param);
  603. }
  604. TakaiDocumentSettings settings = new TakaiDocumentSettings();
  605. settings.setKnowledgeId(knowledgeId);
  606. JSONObject jsonObject = analysisFile(params, settings, "upload");
  607. String updateBy = SecurityUtils.getLoginUser() == null ? "":SecurityUtils.getLoginUser().getUserId();
  608. if (jsonObject != null && jsonObject.containsKey("code") && jsonObject.getInteger("code") == 200) {
  609. for (UploadDocumentParams vo : params) {
  610. // 更新知识库文件大小,总字符数, 文件总数
  611. JSONObject docInfo = jsonObject.getJSONObject("doc_info");
  612. if(docInfo != null){
  613. Integer fileLen = docInfo.getInteger("file_size");
  614. Integer wordNum = docInfo.getInteger("total_char_len");
  615. Integer sliceTotal = docInfo.getInteger("slice_num");
  616. for (TakaiSysOss oss : result) {
  617. // oss保存到数据库
  618. takaiSysOssMapper.insertSysOss(oss);
  619. }
  620. // 保存知识信息
  621. TakaiDocument document = TakaiDocument.builder()
  622. .documentId(vo.getDocument_id())
  623. .knowledgeId(knowledgeId)
  624. .customSeparator(String.format("[\"%s\"", "\\n") + "]")
  625. .sentenceSize("300")
  626. .name(vo.getName())
  627. .url(vo.getUrl())
  628. .sliceTotal(sliceTotal)
  629. .length(fileLen)
  630. .wordNum(wordNum)
  631. .build();
  632. document.setCreateBy(updateBy);
  633. int documentIdInsert = takaiDocumentMapper.insertDocument(document);
  634. if (documentIdInsert > 0) {
  635. // 保存知识设置信息
  636. SnowflakeDigitGenerator snowflakeDigitGenerator = new SnowflakeDigitGenerator(1, 1);
  637. long id = snowflakeDigitGenerator.nextId();
  638. TakaiDocumentSettings dSettings = new TakaiDocumentSettings();
  639. dSettings.setId(String.valueOf(id));
  640. dSettings.setKnowledgeId(knowledgeId);
  641. dSettings.setDocumentId(vo.getDocument_id());
  642. dSettings.setSetSlice("0"); // 默认 按标题段落切片
  643. dSettings.setSetAnalyze("1"); // 默认 图片转换成标识符
  644. dSettings.setSetTable("0"); // 默认 ttable转图片
  645. takaiDocumentSettingsMapper.insertDocumentSettings(dSettings);
  646. }
  647. }
  648. }
  649. updateKnowledgeSize(knowledgeId);
  650. setRedisCache(knowledgeId);
  651. return 1;
  652. }
  653. }
  654. return 0;
  655. }
  656. private void updateKnowledgeSize(String knowledgeId) {
  657. TakaiKnowledge info = takaiKnowledgeMapper.selectTargetKnowledge(TakaiKnowledge.builder().knowledgeId(knowledgeId).build());
  658. List<TakaiDocument> documentList = takaiDocumentMapper.selectDocumentList(TakaiDocument.builder().knowledgeId(knowledgeId).build());
  659. int totalLen = documentList.stream()
  660. .mapToInt(doc -> doc.getLength() != null ? doc.getLength() : 0)
  661. .sum();
  662. int totalWordNum = documentList.stream()
  663. .mapToInt(doc -> doc.getWordNum() != null ? doc.getWordNum() : 0)
  664. .sum();
  665. int docSize = documentList == null || documentList.size() == 0 ? 0 : documentList.size();
  666. String updateBy = SecurityUtils.getLoginUser() == null ? "":SecurityUtils.getLoginUser().getUserId();
  667. TakaiKnowledge paramInfo = TakaiKnowledge.builder().knowledgeId(knowledgeId)
  668. .length(totalLen) // 文件大小
  669. .wordNum(totalWordNum) // 总字符数
  670. .documentSize(docSize) // 文件总数
  671. .build();
  672. paramInfo.setUpdateBy(updateBy);
  673. paramInfo.setUpdateTime(new Date());
  674. takaiKnowledgeMapper.updateKnowledge(paramInfo);
  675. }
  676. private void updateDocumentSize(String knowledgeId,String documentId) {
  677. List<TakaiSliceInfo> sliceList = selectByDocumentId(documentId,null);
  678. //字符数
  679. int totalLen = sliceList.stream()
  680. .mapToInt(slice -> slice.getSliceText() != null ? slice.getSliceText().length() : 0)
  681. .sum();
  682. //文件大小
  683. int totalSize = sliceList.stream()
  684. .mapToInt(slice -> slice.getSliceText() != null ? slice.getSliceText().getBytes(StandardCharsets.UTF_8).length : 0)
  685. .sum();
  686. TakaiDocument doc = TakaiDocument.builder()
  687. .documentId(documentId)
  688. .length(totalSize)
  689. .wordNum(totalLen)
  690. .sliceTotal(sliceList.size())
  691. .build();
  692. String updateBy = SecurityUtils.getLoginUser() == null ? "":SecurityUtils.getLoginUser().getUserId();
  693. doc.setUpdateBy(updateBy);
  694. doc.setUpdateTime(new Date());
  695. takaiDocumentMapper.updateDocument(doc);
  696. updateKnowledgeSize(knowledgeId);
  697. }
  698. @Override
  699. public int updateDocument(TakaiDocumentParams documentParams, String documentId) {
  700. int i = takaiDocumentMapper.updateDocument(TakaiDocument.builder()
  701. .documentId(documentId)
  702. .name(documentParams.getName())
  703. .build());
  704. return i;
  705. }
  706. @Override
  707. public List<TakaiDocument> documentList(TakaiDocumentParams documentParams) {
  708. List<TakaiDocument> documentList = takaiDocumentMapper.selectDocumentList(TakaiDocument.builder().knowledgeId(documentParams.getKnowledge_id()).build());
  709. replaceOssUrl(documentList);
  710. return documentList;
  711. }
  712. private void replaceOssUrl(List<TakaiDocument> documentList) {
  713. if(documentList == null || documentList.isEmpty()) {
  714. return;
  715. }
  716. for(TakaiDocument document : documentList) {
  717. replaceDocUrl(document);
  718. }
  719. }
  720. private void replaceDocUrl(TakaiDocument document) {
  721. if(document == null) {
  722. return;
  723. }
  724. String url = document.getUrl();
  725. url = url.replace("https://10.1.28.14:9000", OSS_URL);
  726. document.setUrl(url);
  727. }
  728. @Override
  729. public TakaiDocument documentDetail(String documentId) {
  730. TakaiDocument doc = takaiDocumentMapper.selectTargetDocument(TakaiDocument.builder().documentId(documentId).build());
  731. replaceDocUrl(doc);
  732. return doc;
  733. }
  734. @Override
  735. public int delDocument(String documentId) {
  736. TakaiDocument vo = takaiDocumentMapper.selectTargetDocument(TakaiDocument.builder().documentId(documentId).build());
  737. if(vo != null){
  738. String url = deepseekConfig.getBaseurl() + deepseekConfig.getDeleteDoc() + "/" + documentId + "/" + vo.getKnowledgeId();
  739. Request request = buildDeleteRequest(url);
  740. OkHttpClient client = buildOkHttpClient();
  741. try {
  742. Response response = client.newCall(request).execute();
  743. if (response.isSuccessful()) {
  744. String body = response.body().string();
  745. logger.info("删除知识文件调用python接口返回结果:{}", body);
  746. JSONObject obj = JSON.parseObject(body);
  747. Integer code = obj.getInteger("code");
  748. if (code == 200) {
  749. List<TakaiMediaReplacement> list = takaiMediaReplacementMapper.selectMediaList(TakaiMediaReplacement.builder().documentId(documentId).build());
  750. // 删除图片
  751. takaiMediaReplacementMapper.deleteMedia(documentId);
  752. // 删除document文件
  753. int i = takaiDocumentMapper.delDocument(documentId);
  754. if(i > 0){
  755. //更新知识库
  756. updateKnowledgeSize(vo.getKnowledgeId());
  757. // 删除minio文件
  758. try {
  759. logger.info("删除minio文件");
  760. minioUtil.remove("deepseek-doc", "/"+vo.getName());
  761. if(list != null && list.size() > 0){
  762. for (int k=1; k<=list.size(); k++ ) {
  763. logger.info("删除minio图片{}", k);
  764. minioUtil.remove("deepseek-doc" , "/pdf/"+vo.getKnowledgeId()+"/"+documentId+"/【示意图序号_"+documentId+"_"+k+"】.jpg");
  765. }
  766. }
  767. } catch (Exception e) {
  768. logger.error("删除minion文件失败", e.getMessage());
  769. throw new RuntimeException(e);
  770. }
  771. return i;
  772. }
  773. }
  774. }
  775. } catch (IOException e) {
  776. logger.error("删除知识文件调用python接口失败", e.getMessage());
  777. }
  778. }
  779. return 0;
  780. }
  781. @Override
  782. public void uploadUrl(TakaiDocumentObject object) {
  783. }
  784. @Override
  785. public int createApplication(TakaiApplicationParams params, boolean isAdmin) {
  786. ApprovalNode vo = getFirstApproverNode(); // 获取第一个审批对象
  787. if(vo != null){
  788. SnowflakeDigitGenerator snowflakeDigitGenerator = new SnowflakeDigitGenerator(1, 1);
  789. long appId = snowflakeDigitGenerator.nextId();
  790. TakaiApplication info = TakaiApplication.builder().appId(String.valueOf(appId))
  791. .name(params.getName())
  792. .desc(params.getDesc())
  793. .model(params.getModel())
  794. .knowledgeIds(params.getKnowledge_ids().stream().collect(Collectors.joining(",")))
  795. .topP(params.getTop_p())
  796. .temperature(params.getTemperature())
  797. .maxToken(params.getMax_token())
  798. .prompt(params.getPrompt())
  799. .knowledgeInfo(params.getKnowledge_info())
  800. .sliceCount(params.getSlice_count())
  801. .typeId(params.getTypeId())
  802. .visible(params.getVisible())
  803. .isDeepThink(params.getIsDeepThink())
  804. .sort(params.getSort())
  805. .build();
  806. //关联项目
  807. if(params.getAppProId() != null){
  808. SysProjectApp sysProjectApp = new SysProjectApp();
  809. sysProjectApp.setProjectId(params.getAppProId()[1]);
  810. sysProjectApp.setAppId(info.getAppId());
  811. sysProjectAppMapper.insertSysProjectApp(sysProjectApp);
  812. }
  813. //管理员,私有,项目级应用不需要审核
  814. if(isAdmin
  815. || "1".equals(params.getVisible())
  816. || AppTypeEnum.PROJECT.getCode().equals(String.valueOf(params.getTypeId()))){ // 1 私有 0 公开
  817. info.setStatus("3"); // 有直接创建权限无需审核
  818. }else{
  819. info.setStatus("5"); // 未开始审核状态
  820. info.setApprover(String.valueOf(vo.getApprover()));
  821. info.setNodeOrder(String.valueOf(vo.getNodeOrder()));
  822. }
  823. info.setCreateBy(params.getUserId());
  824. int i = takaiApplicationMapper.insertApplication(info);
  825. if (i > 0) {
  826. //添加VIP用户
  827. if(params.getVipList() != null && params.getVipList().size() > 0){
  828. for(SysUser sysUser : params.getVipList()){
  829. VipApplication vipApplication =
  830. VipApplication.builder()
  831. .appId(info.getAppId())
  832. .userId(sysUser.getUserId())
  833. .build();
  834. takaiApplicationMapper.insertVipApp(vipApplication);
  835. }
  836. }
  837. TypeApp appType = new TypeApp();
  838. appType.setTypeId(params.getTypeId() == null ? null : params.getTypeId());
  839. appType.setAppId(String.valueOf(appId));
  840. appTypeMapper.insertAppType(appType);
  841. logger.info("create application success, id:{}, name:{}", appId, params.getName());
  842. TakaiAppInfo appInfo = new TakaiAppInfo();
  843. appInfo.setAppId(String.valueOf(appId));
  844. appInfo.setAppInfo(String.valueOf(JSONObject.from(info).toJSONString()));
  845. takaiAppInfoMapper.insertAppInfo(appInfo);
  846. List<String> list = params.getQuestionList();
  847. if (!list.isEmpty() && list.size() > 0) {
  848. for (String str : list) {
  849. if (org.apache.commons.lang3.StringUtils.isNotBlank(str)) {
  850. String uuid = IdUtils.simpleUUID();
  851. TakaiQuestion question = TakaiQuestion.builder().id(uuid).question(str).appId(String.valueOf(appId)).build();
  852. takaiQuestionMapper.insertQuestion(question);
  853. }
  854. }
  855. }
  856. return i;
  857. }
  858. }else{
  859. // 没有审批人
  860. return 9;
  861. }
  862. return 0;
  863. }
  864. @Override
  865. public int updateApplication(TakaiApplicationParams params, String appId, boolean isAdmin) {
  866. ApprovalNode vo = getFirstApproverNode(); // 获取第一个审批对象
  867. if(vo != null){
  868. TakaiApplication info = TakaiApplication.builder().appId(appId)
  869. .name(params.getName())
  870. .desc(params.getDesc())
  871. .model(params.getModel())
  872. .knowledgeIds(params.getKnowledge_ids().stream().collect(Collectors.joining(",")))
  873. .topP(params.getTop_p())
  874. .temperature(params.getTemperature())
  875. .maxToken(params.getMax_token())
  876. .prompt(params.getPrompt())
  877. .knowledgeInfo(params.getKnowledge_info())
  878. .sliceCount(params.getSlice_count())
  879. .typeId(params.getTypeId())
  880. .isDeepThink(params.getIsDeepThink())
  881. .visible(params.getVisible())
  882. .sort(params.getSort())
  883. .build();
  884. //关联项目
  885. if(params.getAppProId() != null){
  886. SysProjectApp sysProjectApp = sysProjectAppMapper.selectSysProjectAppByAppId(appId);
  887. if(sysProjectApp != null){
  888. sysProjectAppMapper.deleteSysProjectAppByAppId(appId);
  889. }
  890. sysProjectApp = new SysProjectApp();
  891. sysProjectApp.setProjectId(params.getAppProId()[1]);
  892. sysProjectApp.setAppId(appId);
  893. sysProjectAppMapper.insertSysProjectApp(sysProjectApp);
  894. }
  895. if(isAdmin || "1".equals(params.getVisible())){
  896. info.setStatus("3"); // 有直接修改权限无需审核
  897. info.setApprover(null);
  898. info.setNodeOrder(null);
  899. }else{
  900. info.setStatus("2"); // 未开始审核状态
  901. info.setApprover(String.valueOf(vo.getApprover()));
  902. info.setNodeOrder(String.valueOf(vo.getNodeOrder()));
  903. }
  904. info.setUpdateBy(params.getUserId());
  905. int i = takaiApplicationMapper.updateApplication(info);
  906. if (1 > 0) {
  907. //添加VIP用户
  908. takaiApplicationMapper.deleteVipByAppId(info.getAppId());
  909. if(params.getVipList() != null && params.getVipList().size() > 0){
  910. for(SysUser sysUser : params.getVipList()){
  911. VipApplication vipApplication =
  912. VipApplication.builder()
  913. .appId(info.getAppId())
  914. .userId(sysUser.getUserId())
  915. .build();
  916. takaiApplicationMapper.insertVipApp(vipApplication);
  917. }
  918. }
  919. TakaiAppInfo appInfo = new TakaiAppInfo();
  920. appInfo.setAppId(appId);
  921. appInfo.setAppInfo(String.valueOf(JSONObject.from(info).toJSONString()));
  922. takaiAppInfoMapper.updateAppInfoByAppId(appInfo);
  923. logger.info("update application success, id:{}, name:{}", appId, params.getName());
  924. //预设问题写入数据库
  925. takaiQuestionMapper.delQuestionByAppId(appId);
  926. List<String> list = params.getQuestionList();
  927. if (!list.isEmpty() && list.size() > 0) {
  928. for (String str : list) {
  929. if (org.apache.commons.lang3.StringUtils.isNotBlank(str)) {
  930. String uuid = IdUtils.simpleUUID();
  931. TakaiQuestion question = TakaiQuestion.builder().id(uuid).question(str).appId(String.valueOf(appId)).build();
  932. takaiQuestionMapper.insertQuestion(question);
  933. }
  934. }
  935. }
  936. }
  937. return i;
  938. } else {
  939. return 9;
  940. }
  941. }
  942. @Override
  943. public List<TakaiApplicationResult> getApplicationList(TakaiApplication params) {
  944. //管理员 获取所有项目
  945. Map<String,Object> userParams = getUserParams();
  946. if(userParams != null){
  947. params.setParams(userParams);
  948. }
  949. List<TakaiApplicationResult> appList = takaiApplicationMapper.selectApplicationList(params);
  950. //添加应用VIP用户
  951. // if(appList != null && appList.size() > 0){
  952. // for (TakaiApplicationResult appResult : appList) {
  953. // List<SysUser> vipList = userService.selectAppVipList(appResult.getAppId());
  954. // appResult.setVipList(vipList);
  955. // }
  956. // }
  957. return appList;
  958. }
  959. @Override
  960. public JSONObject selectApplication(String appId) {
  961. JSONObject object = new JSONObject();
  962. TakaiApplication application = TakaiApplication.builder().appId(appId).build();
  963. TakaiApplication takaiApplication = takaiApplicationMapper.selectTargetApplication(application);
  964. //项目级应用 返回['项目分类','项目id']
  965. if(takaiApplication != null) {
  966. //添加应用VIP用户
  967. List<SysUser> vipList = userService.selectAppVipList(appId);
  968. takaiApplication.setVipList(vipList);
  969. if(AppTypeEnum.PROJECT.getCode().equals(String.valueOf(takaiApplication.getTypeId()))) {
  970. SysProjectApp sysProjectApp = sysProjectAppMapper.selectSysProjectAppByAppId(application.getAppId());
  971. if (sysProjectApp != null) {
  972. SysProject sysProject = sysProjectMapper.selectSysProjectByProjectId(sysProjectApp.getProjectId());
  973. takaiApplication.setAppProId(Arrays.asList(
  974. String.valueOf(sysProject.getSourceFrom()),
  975. String.valueOf(sysProject.getProjectId())));
  976. }
  977. }
  978. List<String> idList = Arrays.stream(takaiApplication.getKnowledgeIds().split(",")) // 按「逗号+空格」拆分字符串为数组
  979. .filter(str -> str != null && !str.trim().isEmpty()) // 过滤 null 和空字符串(防异常)
  980. .collect(Collectors.toList());
  981. JSONObject detailObj = JSONObject.from(takaiApplication); // 转为JSON对象
  982. detailObj.put("knowledgeIds", idList); // 用数组替换原字符串
  983. object.put("detail", detailObj);
  984. } else {
  985. object.put("detail", takaiApplication);
  986. }
  987. List<TakaiQuestionDTO> list = takaiQuestionMapper.getQuestionList(appId);
  988. object.put("questionlist", list);
  989. return object;
  990. }
  991. @Override
  992. public int delApplication(String appId) {
  993. int i = takaiApplicationMapper.delApplication(appId);
  994. if (i > 0) {
  995. takaiAppInfoMapper.delAppInfoByAppId(appId);
  996. takaiQuestionMapper.delQuestionByAppId(appId);
  997. takaiApplicationMapper.delApplication(appId);
  998. }
  999. return i;
  1000. }
  1001. @Override
  1002. public List<TakaiQuestionDTO> selectQuestionByAppId(String appId) {
  1003. List<TakaiQuestionDTO> List = takaiQuestionMapper.getQuestionList(appId);
  1004. return List;
  1005. }
  1006. @Override
  1007. public List<TakaiKnowledge> queryKnowledgeList() {
  1008. //管理员 获取所有项目
  1009. TakaiKnowledge params = getKnowledgeUserParams();
  1010. return takaiKnowledgeMapper.selectKnowledgeList(params);
  1011. }
  1012. private TakaiKnowledge getKnowledgeUserParams() {
  1013. TakaiKnowledge params = null;
  1014. //管理员 获取所有项目
  1015. Map<String,Object> userParams = getUserParams();
  1016. if(userParams != null){
  1017. params = TakaiKnowledge.builder().build();
  1018. params.setParams(userParams);
  1019. }
  1020. return params;
  1021. }
  1022. private Map<String,Object> getUserParams() {
  1023. //管理员 获取所有项目
  1024. LoginUser user = SecurityUtils.getLoginUser();
  1025. Map<String,Object> userParams = null;
  1026. if(user != null){
  1027. userParams = new HashMap<>();
  1028. SysUser loginUser = user.getUser();
  1029. userParams.put("userType",loginUser.getUserType());
  1030. userParams.put("userId",loginUser.getUserId());
  1031. if(loginUser.getRoles().stream().anyMatch(role -> role.getRoleId() == 1)) {
  1032. userParams.put("isAdmin", true);
  1033. } else {
  1034. userParams.put("isAdmin", false);
  1035. }
  1036. }
  1037. return userParams;
  1038. }
  1039. @Override
  1040. public List<TakaiDialogRespDTO> selectDialogListByAppId(String appId, String userId) {
  1041. List<TakaiDialogRespDTO> list = takaiDialogMapper.selectDialog(appId, userId);
  1042. // List<Object> result = setDialogList(list);
  1043. return list;
  1044. }
  1045. @Override
  1046. public TakaiDocumentSettings documentSetting(String documentId) {
  1047. return takaiDocumentSettingsMapper.selectById(documentId);
  1048. }
  1049. @Override
  1050. public int updateDocumentSetting(TakaiDocumentSettings documentSettings, String documentId) {
  1051. TakaiDocumentSettings settings = new TakaiDocumentSettings();
  1052. TakaiDocumentSettings settingsVo = takaiDocumentSettingsMapper.selectById(documentId);
  1053. settings.setKnowledgeId(settingsVo.getKnowledgeId());
  1054. settings.setSetSlice(documentSettings.getSetSlice());
  1055. settings.setSliceValue(documentSettings.getSliceValue());
  1056. settings.setSetAnalyze(documentSettings.getSetAnalyze());
  1057. settings.setSetTable(documentSettings.getSetTable());
  1058. TakaiDocument document = takaiDocumentMapper.selectTargetDocument(TakaiDocument.builder().documentId(documentId).build());
  1059. List<UploadDocumentParams> listParams = new ArrayList<>();
  1060. if (document != null) {
  1061. UploadDocumentParams params = new UploadDocumentParams();
  1062. params.setDocument_id(documentId);
  1063. params.setName(document.getName());
  1064. params.setUrl(document.getUrl());
  1065. listParams.add(params);
  1066. }
  1067. JSONObject jsonObject = analysisFile(listParams, settings, "update");
  1068. if (jsonObject != null && jsonObject.containsKey("code") && jsonObject.getInteger("code") == 200) {
  1069. logger.info("update document setting success, id:{}", documentId);
  1070. documentSettings.setDocumentId(documentId);
  1071. return takaiDocumentSettingsMapper.updateDocumentSettings(documentSettings);
  1072. }
  1073. return 0;
  1074. }
  1075. @Override
  1076. public JSONObject getSliceList(TakaiSliceParams params) {
  1077. // String url = deepseekConfig.getBaseurl() + deepseekConfig.getSlicePage();
  1078. // JSONObject jsonObject = new JSONObject();
  1079. // jsonObject.put("document_id", params.getDocument_id());
  1080. // jsonObject.put("knowledge_id", params.getKnowledge_id());
  1081. // jsonObject.put("text", params.getText());
  1082. // jsonObject.put("pageNum", params.getPageNum());
  1083. // jsonObject.put("pageSize", params.getPageSize());
  1084. //
  1085. // RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8"), jsonObject.toJSONString());
  1086. // Request request = buildPostRequest(url, requestBody);
  1087. //
  1088. // OkHttpClient client = buildOkHttpClient();
  1089. // Response response = null;
  1090. // try {
  1091. // response = client.newCall(request).execute();
  1092. // if (response.isSuccessful()) {
  1093. // String body = response.body().string();
  1094. // JSONObject obj = JSON.parseObject(body);
  1095. // Integer code = obj.getInteger("code");
  1096. // if (code == 200) {
  1097. // return obj;
  1098. // }
  1099. // } else {
  1100. // logger.info("获取切片列表调用python接口失败,返回状态码:{}", response.code());
  1101. // }
  1102. // } catch (IOException e) {
  1103. // logger.error("获取切片列表调用python接口失败", e.getMessage());
  1104. // }
  1105. return null;
  1106. }
  1107. @Override
  1108. public int deleteSlice(String sliceId, String knowledgeId, String documentId) {
  1109. String url = deepseekConfig.getBaseurl() + deepseekConfig.getDeleteSlice() + "/" + sliceId + "/" + knowledgeId + "/" + documentId;
  1110. Request request = buildDeleteRequest(url);
  1111. OkHttpClient client = buildOkHttpClient();
  1112. Response response = null;
  1113. try {
  1114. response = client.newCall(request).execute();
  1115. if (response.isSuccessful()) {
  1116. String body = response.body().string();
  1117. JSONObject obj = JSON.parseObject(body);
  1118. Integer code = obj.getInteger("code");
  1119. logger.info("删除切片调用python接口成功,返回结果:{}", body);
  1120. if (code == 200) {
  1121. updateDocumentSize(knowledgeId,documentId);
  1122. return 1;
  1123. }
  1124. }
  1125. } catch (IOException e) {
  1126. logger.error("删除切片调用python接口失败", e.getMessage());
  1127. }
  1128. return 0;
  1129. }
  1130. @Override
  1131. public JSONObject getSliceDetail(String sliceId, String knowledgeId) {
  1132. String url = deepseekConfig.getBaseurl() + deepseekConfig.getSliceDetail() + "/" + knowledgeId + "/" + sliceId;
  1133. Request request = buildGetRequest(url);
  1134. OkHttpClient client = buildOkHttpClient();
  1135. try {
  1136. Response response = client.newCall(request).execute();
  1137. if (response.isSuccessful()) {
  1138. String body = response.body().string();
  1139. log.info("查询切片详情返回:" + body);
  1140. JSONObject jsonObject = JSON.parseObject(body);
  1141. JSONObject dataObject = jsonObject.getJSONObject("data");
  1142. String docId = dataObject.getString("document_id");
  1143. String sliceText = dataObject.getString("slice_text");
  1144. TakaiMediaReplacement conditonR = TakaiMediaReplacement.builder().documentId(docId).build();
  1145. List<TakaiMediaReplacement> imageList = takaiMediaReplacementMapper.selectMediaList(conditonR);
  1146. //替换【示意图序号_XXXXX】为超链接
  1147. List<TakaiSliceImage> sliceImageList = SchematicNumberParser.extractImageUrlMappings(sliceText,imageList);
  1148. // String replaceText = SchematicNumberParser.replaceWithImageLinks(sliceText,imageList);
  1149. // dataObject.put("slice_text",replaceText);
  1150. dataObject.put("imageList",sliceImageList);
  1151. return jsonObject;
  1152. } else {
  1153. logger.info("获取切片详情调用python接口失败,返回状态码:{}", response.code());
  1154. }
  1155. } catch (IOException e) {
  1156. log.error("查询切片详情调用python接口失败", e.getMessage());
  1157. }
  1158. return null;
  1159. }
  1160. @Override
  1161. public List<TakaiSliceImage> uploadSliceImage(MultipartFile[] files, String knowledgeId, String documentId) {
  1162. List<TakaiSysOss> resultList = null;
  1163. try {
  1164. resultList = minioUtil.uploadSliceImages(files,knowledgeId,documentId);
  1165. } catch (Exception e) {
  1166. logger.error("上传文件失败", e.getMessage());
  1167. }
  1168. //保存图片信息
  1169. List<TakaiSliceImage> originTextList = new ArrayList<>();
  1170. for (TakaiSysOss result : resultList) {
  1171. TakaiMediaReplacement takaiMediaReplacement =
  1172. TakaiMediaReplacement.builder()
  1173. .knowledgeId(knowledgeId)
  1174. .documentId(documentId)
  1175. .originText(result.getOriginText())
  1176. .mediaType("image")
  1177. .mediaUrl(result.getUrl())
  1178. .build();
  1179. Date currentDate = new Date();
  1180. takaiMediaReplacement.setCreateTime(currentDate);
  1181. takaiMediaReplacement.setUpdateTime(currentDate);
  1182. takaiMediaReplacementMapper.insertMedia(takaiMediaReplacement);
  1183. TakaiSliceImage sliceImage = TakaiSliceImage.builder().name(result.getOriginText()).url(result.getUrl()).build();
  1184. originTextList.add(sliceImage);
  1185. }
  1186. return originTextList;
  1187. }
  1188. @Override
  1189. public int updateSliceInfo(TakaiSliceUpdateParams params) {
  1190. String url = deepseekConfig.getBaseurl() + deepseekConfig.getUpdateSlice();
  1191. JSONObject object = new JSONObject();
  1192. object.put("knowledge_id", params.getKnowledgeId());
  1193. object.put("slice_id", params.getSliceId());
  1194. object.put("slice_text", params.getSliceText());
  1195. object.put("document_id", params.getDocumentId());
  1196. RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8"), object.toJSONString());
  1197. Request request = buildPutRequest(url, requestBody);
  1198. OkHttpClient client = buildOkHttpClient();
  1199. try {
  1200. Response response = client.newCall(request).execute();
  1201. if (response.isSuccessful()) {
  1202. String body = response.body().string();
  1203. JSONObject obj = JSON.parseObject(body);
  1204. Integer code = obj.getInteger("code");
  1205. if (code == 200) {
  1206. updateDocumentSize(params.getKnowledgeId(),params.getDocumentId());
  1207. return 1;
  1208. }
  1209. }
  1210. } catch (Exception e) {
  1211. logger.error("更新切片信息调用python接口失败", e.getMessage());
  1212. }
  1213. return 0;
  1214. }
  1215. @Override
  1216. public TakaiMediaReplacement getTakaiMediaReplacement() {
  1217. TakaiMediaReplacement mrParams = TakaiMediaReplacement.builder()
  1218. .documentId("a2912832435041734656")
  1219. .originText("【示意图序号_a2912832435041734656_1】")
  1220. .mediaType("image").build();
  1221. TakaiMediaReplacement mrVo = takaiMediaReplacementMapper.selectTargetMedia(mrParams);
  1222. return mrVo;
  1223. }
  1224. @Override
  1225. public int addSlice(TakaiSliceUpdateParams params) {
  1226. String url = deepseekConfig.getBaseurl() + deepseekConfig.getAddSlice();
  1227. TakaiDocument info = takaiDocumentMapper.selectTargetDocument(TakaiDocument.builder().documentId(params.getDocumentId()).build());
  1228. if(info != null){
  1229. JSONObject json = new JSONObject();
  1230. json.put("knowledge_id", params.getKnowledgeId());
  1231. json.put("document_id", params.getDocumentId());
  1232. json.put("slice_text", params.getSliceText());
  1233. json.put("doc_name", info.getName());
  1234. RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8"), json.toJSONString());
  1235. Request request = buildPostRequest(url, requestBody);
  1236. OkHttpClient client = buildOkHttpClient();
  1237. try {
  1238. Response response = client.newCall(request).execute();
  1239. if (response.isSuccessful()) {
  1240. String body = response.body().string();
  1241. JSONObject obj = JSON.parseObject(body);
  1242. Integer code = obj.getInteger("code");
  1243. if (code == 200) {
  1244. updateDocumentSize(params.getKnowledgeId(),params.getDocumentId());
  1245. return 1;
  1246. }
  1247. }
  1248. }catch (Exception e) {
  1249. logger.error("新增切片调用python接口失败", e.getMessage());
  1250. }
  1251. }
  1252. return 0;
  1253. }
  1254. @Override
  1255. public List<TakaiSliceInfo> selectByDocumentId(String documentId,String sliceText) {
  1256. return takaiSliceInfoMapper.selectByDocumentId(documentId,sliceText);
  1257. }
  1258. @Override
  1259. public TakaiSliceInfo selectBySliceId(String sliceId) {
  1260. return takaiSliceInfoMapper.selectBySliceId(sliceId);
  1261. }
  1262. @Override
  1263. public List<SliceInfo> slicePageInfoList(List<String> list) {
  1264. return takaiSliceInfoMapper.slicePageInfoList(list);
  1265. }
  1266. @Override
  1267. public JSONObject searchSlice(String id) {
  1268. String url = deepseekConfig.getBaseurl() + deepseekConfig.getSearchSlice() + "/" + id;
  1269. Request request = buildGetRequest(url);
  1270. OkHttpClient client = buildOkHttpClient();
  1271. try {
  1272. Response response = client.newCall(request).execute();
  1273. if (response.isSuccessful()) {
  1274. String body = response.body().string();
  1275. JSONObject obj = JSON.parseObject(body);
  1276. Integer code = obj.getInteger("code");
  1277. if (code == 200) {
  1278. return obj;
  1279. }
  1280. }
  1281. }catch (Exception e) {
  1282. logger.error("切片得分调用python接口失败", e.getMessage());
  1283. }
  1284. return null;
  1285. }
  1286. @Override
  1287. public List<Object> searchAppTypeGroupList(List<SysDictData> dictDataList, String userId) {
  1288. List<Object> result = new ArrayList();
  1289. if (dictDataList!= null && dictDataList.size() > 0) {
  1290. for (SysDictData dictData : dictDataList){
  1291. // PageHelper.startPage(1, 3, "sort is null asc,sort");
  1292. PageHelper.orderBy("sort is null asc, sort");
  1293. Map<String, Object> map = new HashMap();
  1294. TakaiApplication paramsVo = TakaiApplication.builder().approver(userId).flag("0").addOrderBy("0").build();
  1295. //项目应用
  1296. if(dictData.getDictCode() == 41){
  1297. Map<String, Object> l = searchAppProjectGroupList(paramsVo, dictData);
  1298. if(!MapUtils.isEmpty(l)){
  1299. result.add(l);
  1300. }
  1301. //其他分类应用
  1302. }else{
  1303. paramsVo.setTypeId(Long.valueOf(dictData.getDictCode()));
  1304. List<TakaiApplicationResult> list = takaiApplicationMapper.selectApplicationList(paramsVo);
  1305. if(list != null && list.size() > 0){
  1306. List<Object> appInfoList = new ArrayList();
  1307. map.put("title", dictData.getDictLabel());
  1308. for (TakaiApplicationResult application : list){
  1309. Map<String, Object> infoMap = new HashMap();
  1310. infoMap.put("title", application.getName());
  1311. infoMap.put("appId", application.getAppId());
  1312. infoMap.put("showMenu", "false");
  1313. infoMap.put("chatMode", "LOCAL");
  1314. appInfoList.add(infoMap);
  1315. }
  1316. map.put("children", appInfoList);
  1317. result.add(map);
  1318. }
  1319. }
  1320. }
  1321. }
  1322. return result;
  1323. }
  1324. private Map<String, Object> searchAppProjectGroupList(TakaiApplication paramsVo, SysDictData dictData) {
  1325. paramsVo.setTypeId(dictData.getDictCode());
  1326. List<TakaiApplicationResult> list = takaiApplicationMapper.selectApplicationList(paramsVo);
  1327. //项目级应用
  1328. Map<String, Object> projectLevelMap = new HashMap();
  1329. projectLevelMap.put("title", dictData.getDictLabel());
  1330. List<Object> projectAppList = new ArrayList();
  1331. if (list!= null && list.size() > 0) {
  1332. // 按项目分组
  1333. Map<String, List<TakaiApplicationResult>> projectAppMap = list
  1334. .stream().collect(Collectors.groupingBy(TakaiApplicationResult::getProjectName));
  1335. for (Iterator<String> iterator = projectAppMap.keySet().iterator(); iterator.hasNext();) {
  1336. String projectName = iterator.next();
  1337. Map<String,Object> newProjectAppMap = new HashMap();
  1338. List<TakaiApplicationResult> appList = projectAppMap.get(projectName);
  1339. List<Object> newAppList = new ArrayList();
  1340. for (TakaiApplicationResult application : appList) {
  1341. Map<String, Object> appMap = new HashMap();
  1342. appMap.put("appId", application.getAppId());
  1343. appMap.put("showMenu", "false");
  1344. appMap.put("chatMode", "LOCAL");
  1345. appMap.put("title", application.getName());
  1346. newAppList.add(appMap);
  1347. }
  1348. newProjectAppMap.put("title", projectName);
  1349. newProjectAppMap.put("children",newAppList);
  1350. projectAppList.add(newProjectAppMap);
  1351. }
  1352. }
  1353. projectLevelMap.put("children",projectAppList);
  1354. return projectLevelMap;
  1355. };
  1356. private Map<String, Object> searchAppTypeGroupList(TakaiApplication paramsVo, SysDictData dictData) {
  1357. //慧监理
  1358. paramsVo.setTypeId(Long.valueOf(42));
  1359. List<TakaiApplicationResult> list1 = takaiApplicationMapper.selectApplicationList(paramsVo);
  1360. //慧项管
  1361. paramsVo.setTypeId(Long.valueOf(43));
  1362. List<TakaiApplicationResult> list2 = takaiApplicationMapper.selectApplicationList(paramsVo);
  1363. List<TakaiApplicationResult> list3 = new ArrayList();
  1364. list3.addAll(list1);
  1365. list3.addAll(list2);
  1366. Map<String, Object> map = new HashMap();
  1367. if (list3!= null && list3.size() > 0) {
  1368. List<Object> l = new ArrayList<>();
  1369. map.put("title", dictData.getDictLabel());
  1370. // 分组
  1371. Map<String, List<TakaiApplicationResult>> map1 = list3.stream().collect(Collectors.groupingBy(TakaiApplicationResult::getTypeId));
  1372. for (Map.Entry<String, List<TakaiApplicationResult>> entry : map1.entrySet()) {
  1373. List<TakaiApplicationResult> mp = entry.getValue();
  1374. Map<String, Object> infoProjectMap = new HashMap();
  1375. List<Object> projectInfoList = new ArrayList();
  1376. for (TakaiApplicationResult application : mp){
  1377. SysDictData vo = sysDictDataMapper.selectDictDataById(Long.valueOf(application.getTypeId()));
  1378. infoProjectMap.put("title", vo.getDictLabel());
  1379. Map<String, Object> projectMap = new HashMap();
  1380. projectMap.put("appId", application.getAppId());
  1381. projectMap.put("showMenu", "false");
  1382. projectMap.put("chatMode", "LOCAL");
  1383. projectMap.put("title", application.getName());
  1384. projectInfoList.add(projectMap);
  1385. }
  1386. infoProjectMap.put("children", projectInfoList);
  1387. l.add(infoProjectMap);
  1388. }
  1389. map.put("children", l);
  1390. }
  1391. return map;
  1392. }
  1393. @Override
  1394. public List<TakaiApplication> applicationListByApprover(TakaiApplicationParams takaiApplicationParams) {
  1395. TakaiApplication vo = TakaiApplication.builder().approver(takaiApplicationParams.getApprover())
  1396. .build();
  1397. return takaiApplicationMapper.selectAppListByApprover(vo);
  1398. }
  1399. @Override
  1400. public int startAudit(String appId, String userId) {
  1401. List<DocumentAuditConfig> list = documentAuditConfigMapper.selectDocumentAuditConfigListByBo(null);
  1402. if(list != null && list.size() > 0) {
  1403. ApprovalFlowManager flowManager = new ApprovalFlowManager();
  1404. logger.info("开启审核");
  1405. for (DocumentAuditConfig config : list) {
  1406. // 添加审核节点
  1407. flowManager.addNode(new ApprovalNode(config.getId(), config.getNodeOrder(), config.getApprover(), config.getChain()));
  1408. }
  1409. ApprovalNode vo = flowManager.getFirstApprover();
  1410. TakaiApplication appVo = takaiApplicationMapper.selectTargetApplication(TakaiApplication.builder().appId(appId).build());
  1411. appVo.setApprover(String.valueOf(vo.getApprover()));
  1412. appVo.setNodeOrder(String.valueOf(vo.getNodeOrder()));
  1413. appVo.setStatus("1");
  1414. int i = takaiApplicationMapper.updateApplication(appVo);
  1415. if(i > 0){
  1416. DocumentAuditInfo info = new DocumentAuditInfo();
  1417. info.setAppId(appId);
  1418. info.setApprover(userId);
  1419. info.setStatus("5");
  1420. info.setNodeOrder(Integer.valueOf("0"));
  1421. info.setCreateBy(userId);
  1422. info.setCreateTime(new Date());
  1423. documentAuditInfoMapper.insertDocumentAuditInfo(info); // 审核记录
  1424. }
  1425. return i;
  1426. }else{
  1427. return 9;
  1428. }
  1429. }
  1430. @Override
  1431. public int updateAuditApplication(TakaiApplicationParams appParams, String appId) {
  1432. // 获取审核配置信息 (人员,节点)
  1433. List<DocumentAuditConfig> list = documentAuditConfigMapper.selectDocumentAuditConfigListByBo(null);
  1434. if(list != null && list.size() > 0){
  1435. if(("Y").equals(appParams.getStatus())){
  1436. ApprovalFlowManager flowManager = new ApprovalFlowManager();
  1437. logger.info("审核通过,开始审批流程");
  1438. for (DocumentAuditConfig config: list){
  1439. // 添加审核节点
  1440. flowManager.addNode(new ApprovalNode(config.getId(), config.getNodeOrder(), config.getApprover(), config.getChain()));
  1441. }
  1442. // 根据审核节点获取下一个审核节点
  1443. ApprovalNode nextNode = flowManager.getNextApproverByOrder(Integer.valueOf(appParams.getNodeOrder()));
  1444. if (nextNode == null) {
  1445. // 审核通过,更新文档状态
  1446. logger.info("审核通过,到最后节点");
  1447. return saveAuditInfo(appParams, "3", appId);
  1448. }else{
  1449. // 审核通过,下一个节点
  1450. TakaiApplication appVo = takaiApplicationMapper.selectTargetApplication(TakaiApplication.builder().appId(appId).build());
  1451. appVo.setApprover(String.valueOf(nextNode.getApprover()));
  1452. appVo.setNodeOrder(String.valueOf(nextNode.getNodeOrder()));
  1453. appVo.setStatus("2");
  1454. appVo.setComment(appParams.getComment());
  1455. int successI = takaiApplicationMapper.updateApplication(appVo);
  1456. if(successI > 0){
  1457. DocumentAuditInfo info = new DocumentAuditInfo();
  1458. info.setAppId(appId);
  1459. info.setApprover(appParams.getApprover());
  1460. info.setComment(appParams.getComment());
  1461. info.setStatus("2");
  1462. info.setNodeOrder(Integer.valueOf(appParams.getNodeOrder()));
  1463. info.setCreateBy(appParams.getApprover());
  1464. info.setCreateTime(new Date());
  1465. documentAuditInfoMapper.insertDocumentAuditInfo(info); // 审核记录
  1466. }
  1467. return successI;
  1468. }
  1469. }else{
  1470. // 审核拒绝,更新文档状态
  1471. logger.info("审核拒绝,更新状态");
  1472. return saveAuditInfo(appParams, "5", appId);
  1473. }
  1474. }
  1475. return 0;
  1476. }
  1477. private int saveAuditInfo(TakaiApplicationParams appParams, String status, String appId){
  1478. TakaiApplication appVo = takaiApplicationMapper.selectTargetApplication(TakaiApplication.builder().appId(appId).build());
  1479. appVo.setApprover(appParams.getApprover());
  1480. appVo.setNodeOrder(appParams.getNodeOrder());
  1481. appVo.setStatus(status);
  1482. appVo.setComment(appParams.getComment());
  1483. int successI = takaiApplicationMapper.updateApplication(appVo);
  1484. if(successI > 0){
  1485. DocumentAuditInfo info = new DocumentAuditInfo();
  1486. info.setAppId(appId);
  1487. info.setApprover(appParams.getApprover());
  1488. info.setComment(appParams.getComment());
  1489. if("5".equals(status)){
  1490. info.setStatus("4");
  1491. }else{
  1492. info.setStatus(status);
  1493. }
  1494. info.setNodeOrder(Integer.valueOf(appParams.getNodeOrder()));
  1495. info.setCreateBy(appParams.getApprover());
  1496. info.setCreateTime(new Date());
  1497. documentAuditInfoMapper.insertDocumentAuditInfo(info); // 审核记录
  1498. }
  1499. return successI;
  1500. }
  1501. @Override
  1502. public List<TakaiApplicationResult> selectAppByUserId(String userId) {
  1503. return takaiApplicationMapper.selectAppByUserId(userId);
  1504. }
  1505. @Override
  1506. public List<String> selectAppCollectList(String userId) {
  1507. return appCollectMapper.selectAppCollectList(userId);
  1508. }
  1509. @Override
  1510. public int insertAppCollect(AppCollect appCollect) {
  1511. AppCollect collect = appCollectMapper.selectAppCollectDetail(appCollect.getAppId(), appCollect.getUserId());
  1512. if (collect == null) {
  1513. return appCollectMapper.insertAppCollect(appCollect);
  1514. }
  1515. return 0;
  1516. }
  1517. @Override
  1518. public int deleteAppCollect(String userId, String appId) {
  1519. return appCollectMapper.delAppCollect(userId, appId);
  1520. }
  1521. @Override
  1522. public List<TakaiApplicationResult> selectRoleApp() {
  1523. return takaiApplicationMapper.selectRoleApp();
  1524. }
  1525. @Override
  1526. public List<TakaiApplicationResult> getChatAppList(List<TakaiApplicationResult> params, String userId) {
  1527. List<TakaiApplicationResult> list = new ArrayList();
  1528. for (TakaiApplicationResult app : params) {
  1529. AppCollect appCollect = appCollectMapper.selectAppCollectDetail(app.getAppId(), userId);
  1530. SysDictData dictData = null;
  1531. if(app.getTypeId() != null && !"".equals(app.getTypeId())){
  1532. dictData = sysDictDataMapper.selectDictDataById(Long.valueOf(app.getTypeId()));
  1533. }
  1534. TakaiApplicationResult appResult = new TakaiApplicationResult();
  1535. appResult.setAppId(app.getAppId());
  1536. appResult.setName(app.getName());
  1537. appResult.setDesc(app.getDesc());
  1538. appResult.setTypeId(app.getTypeId());
  1539. appResult.setCreateTime(app.getCreateTime());
  1540. appResult.setChatMode("LOCAL");
  1541. appResult.setIsCollect(appCollect != null ? true : false);
  1542. appResult.setTypeName(dictData != null ? dictData.getDictLabel() : "");
  1543. list.add(appResult);
  1544. }
  1545. return list;
  1546. }
  1547. private ApprovalNode getFirstApproverNode() {
  1548. List<DocumentAuditConfig> list = documentAuditConfigMapper.selectDocumentAuditConfigListByBo(null);
  1549. if(list != null && list.size() > 0) {
  1550. ApprovalFlowManager flowManager = new ApprovalFlowManager();
  1551. logger.info("开启审核");
  1552. for (DocumentAuditConfig config : list) {
  1553. // 添加审核节点
  1554. flowManager.addNode(new ApprovalNode(config.getId(), config.getNodeOrder(), config.getApprover(), config.getChain()));
  1555. }
  1556. return flowManager.getFirstApprover();
  1557. }
  1558. return null;
  1559. }
  1560. private JSONObject analysisFile(List<UploadDocumentParams> result, TakaiDocumentSettings settings, String flag) {
  1561. String url = deepseekConfig.getBaseurl() + deepseekConfig.getUploadKnowledge();
  1562. JSONObject json = new JSONObject();
  1563. json.put("knowledge_id", settings.getKnowledgeId());
  1564. json.put("docs", result);
  1565. if ("upload".equals(flag)) {
  1566. json.put("set_slice", "0");
  1567. json.put("slice_value", null);
  1568. json.put("set_analyze", "1");
  1569. json.put("set_table", "0");
  1570. json.put("flag", "upload");
  1571. } else {
  1572. json.put("set_slice", settings.getSetSlice());
  1573. json.put("slice_value", settings.getSliceValue());
  1574. json.put("set_analyze", settings.getSetAnalyze());
  1575. json.put("set_table", settings.getSetTable());
  1576. json.put("flag", "update");
  1577. }
  1578. RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), json.toJSONString());
  1579. Request request = buildPostRequest(url, requestBody);
  1580. OkHttpClient client = buildOkHttpClient();
  1581. Response response = null;
  1582. try {
  1583. response = client.newCall(request).execute();
  1584. if (response.isSuccessful()) {
  1585. String body = response.body().string();
  1586. JSONObject obj = JSON.parseObject(body);
  1587. Integer code = obj.getInteger("code");
  1588. if (code == 200) {
  1589. logger.info("上传文档调用python接口成功,返回内容:{}", body);
  1590. } else {
  1591. logger.info("上传文档调用python接口失败,返回内容:{}", body);
  1592. }
  1593. return obj;
  1594. } else {
  1595. logger.error("上传文档调用python接口失败返回code:{}", response.code());
  1596. return null;
  1597. }
  1598. } catch (IOException e) {
  1599. logger.error("上传文档调用python接口失败", e.getMessage());
  1600. return null;
  1601. }
  1602. }
  1603. @Override
  1604. public List<Object> setDialogList(List<TakaiDialogRespDTO> list) {
  1605. //根据时间分组降序排序
  1606. NavigableMap<LocalDateTime, List<TakaiDialogRespDTO>> groupList = list.stream().collect(Collectors.groupingBy(TakaiDialogRespDTO::getCreate_time, TreeMap::new, Collectors.toList())).descendingMap();
  1607. List<Object> obj = new ArrayList();
  1608. if (!groupList.isEmpty()) {
  1609. for (Map.Entry<LocalDateTime, List<TakaiDialogRespDTO>> entry : groupList.entrySet()) {
  1610. List<TakaiDialogRespDTO> aList = entry.getValue();
  1611. List<TakaiDialogRespDTO> detailList = takaiDialogMapper.selectDialogExport(aList.get(0).getId());
  1612. Map<String, Object> map = new HashMap();
  1613. map.put("dialog_name", aList.get(0).getDialog_name());
  1614. map.put("length", detailList.size());
  1615. map.put("create_time", aList.get(0).getCreate_time());
  1616. map.put("did", aList.get(0).getDid());
  1617. map.put("id", aList.get(0).getId());
  1618. obj.add(map);
  1619. }
  1620. }
  1621. return obj;
  1622. }
  1623. private List<Map<String, Object>> setValue(List<TakaiDialogRespDTO> list, String appId) {
  1624. List<Map<String, Object>> l = new ArrayList();
  1625. for (TakaiDialogRespDTO vo : list) {
  1626. Map<String, Object> map = new HashMap();
  1627. map.put("key", vo.getId());
  1628. map.put("label", vo.getDialog_name());
  1629. map.put("appId", appId);
  1630. map.put("showMenu", "false");
  1631. map.put("chatMode", "LOCAL");
  1632. l.add(map);
  1633. }
  1634. return l;
  1635. }
  1636. private OkHttpClient buildOkHttpClient() {
  1637. return new OkHttpClient.Builder()
  1638. .connectTimeout(10, TimeUnit.SECONDS)
  1639. .writeTimeout(50, TimeUnit.SECONDS)
  1640. .readTimeout(20, TimeUnit.MINUTES)
  1641. .build();
  1642. }
  1643. private Request buildGetRequest(String url) {
  1644. return new Request.Builder()
  1645. .addHeader("User-Agent", "insomnia/10.3.1")
  1646. .url(url).get().build();
  1647. }
  1648. private Request buildPostRequest(String url, RequestBody requestBody) {
  1649. return new Request.Builder()
  1650. .addHeader("User-Agent", "insomnia/10.3.1")
  1651. .addHeader("Content-Type", "application/json")
  1652. .url(url).post(requestBody).build();
  1653. }
  1654. private Request buildPutRequest(String url, RequestBody requestBody) {
  1655. return new Request.Builder()
  1656. .addHeader("User-Agent", "insomnia/10.3.1")
  1657. .url(url).put(requestBody).build();
  1658. }
  1659. private Request buildDeleteRequest(String url) {
  1660. return new Request.Builder()
  1661. .addHeader("Content-Type", "multipart/form-data")
  1662. .addHeader("User-Agent", "insomnia/10.3.1")
  1663. .url(url).delete().build();
  1664. }
  1665. private Request buildUploadPostRequest(String url, RequestBody requestBody) {
  1666. return new Request.Builder()
  1667. .addHeader("User-Agent", "insomnia/10.3.1")
  1668. .addHeader("Content-Type", "application/json")
  1669. .url(url).post(requestBody).build();
  1670. }
  1671. private boolean isJsonObject(String data) {
  1672. try {
  1673. JSON.parseObject(data);
  1674. return true;
  1675. } catch (Exception e) {
  1676. return false;
  1677. }
  1678. }
  1679. }