tsurumure 6 mesiacov pred
rodič
commit
72148e508d

+ 12 - 0
src/main/java/com/backendsys/modules/ai/chat/controller/ChatController.java

@@ -43,7 +43,19 @@ public class ChatController {
     @PreAuthorize("@sr.hasPermission('31')")
     @DeleteMapping("/api/ai/chat/deleteChat")
     public Result deleteChat(@Validated(Chat.Delete.class) @RequestBody Chat chat) {
+        // 仅能删除自己的
+        chat.setUser_id(SecurityUtil.getUserId());
         return Result.success().put("data", chatService.deleteChat(chat));
     }
 
+    @Operation(summary = "删除单条对话内容 (软删除)")
+    @PreAuthorize("@sr.hasPermission('31')")
+    @DeleteMapping("/api/ai/chat/deleteChatOne")
+    public Result deleteChatOne(@Validated(Chat.DeleteOne.class) @RequestBody Chat chat) {
+        // 仅能删除自己的
+        chat.setUser_id(SecurityUtil.getUserId());
+        return Result.success().put("data", chatService.deleteChatOne(chat));
+    }
+
+
 }

+ 4 - 0
src/main/java/com/backendsys/modules/ai/chat/entity/Chat.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
 import jakarta.validation.constraints.Size;
 import lombok.Data;
 
@@ -16,9 +17,12 @@ public class Chat {
     public static interface Create{}
     public static interface Update{}
     public static interface Delete{}
+    public static interface DeleteOne{}
 
     @TableId(type = IdType.AUTO)
+    @NotNull(message = "id 不能为空", groups = { DeleteOne.class })
     private Long id;
+
     @Size(max = 36, message = "对话历史记录ID长度不超过 {max} 字符", groups = { Detail.class, Delete.class })
     @NotEmpty(message = "history_code 不能为空", groups = { Detail.class, Delete.class })
     private String history_code;

+ 3 - 0
src/main/java/com/backendsys/modules/ai/chat/service/ChatService.java

@@ -16,4 +16,7 @@ public interface ChatService {
 
     // 删除我的对话 (软删除)
     Map<String, Object> deleteChat(Chat chat);
+
+    // 删除我的对话 (软删除)(单条)
+    Map<String, Object> deleteChatOne(Chat chat);
 }

+ 48 - 20
src/main/java/com/backendsys/modules/ai/chat/service/impl/ChatServiceImpl.java

@@ -103,15 +103,24 @@ public class ChatServiceImpl implements ChatService {
         CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
             try {
 
-                // [DB] 查询对话历史记录 (按时间升序排序,最新的在最后面) (用于对话上下文)
-                LambdaQueryWrapper<Chat> wrapper = new LambdaQueryWrapper<>();
-                wrapper.eq(Chat::getDel_flag, -1);
-                wrapper.eq(Chat::getHistory_code, finalHistory_code);
-                wrapper.orderByDesc(Chat::getCreate_time);
-                List<Chat> chatList = chatDao.selectList(wrapper);
-
-
-                // [INSERT][提问]
+                // [DB] 查询对话历史记录 (用于对话上下文)
+                // - 按 [创建时间]、[Id] 降序,最新的在最后面
+                // - 排除 [THINK-思考] 的内容,但允许 [Null]
+                List<Chat> chatList = chatDao.selectList(
+                    new LambdaQueryWrapper<Chat>()
+                        .eq(Chat::getDel_flag, -1)
+                        .eq(Chat::getHistory_code, finalHistory_code)
+                        .and(wrapper -> wrapper
+                            .ne(Chat::getContent_type, "THINK")
+                            .or()
+                            .isNull(Chat::getContent_type))
+                        .orderByDesc(Chat::getCreate_time)
+                        .orderByDesc(Chat::getId)
+                );
+                System.out.println("chatList size: " + chatList.size());
+
+
+                // [INSERT][提问] 内容
                 Chat userChat = new Chat();
                 BeanUtil.copyProperties(chat, userChat);
                 chatDao.insert(userChat);
@@ -176,11 +185,12 @@ public class ChatServiceImpl implements ChatService {
     @Override
     public PageEntity selectChatList(Chat chat) {
 
-        String history_code = chat.getHistory_code();
-
-        ChatHistory chatHistory = chatHistoryDao.selectOne(new LambdaQueryWrapper<ChatHistory>()
-            .eq(ChatHistory::getDel_flag, chat.getDel_flag())
-            .eq(ChatHistory::getHistory_code, history_code));
+        ChatHistory chatHistory = chatHistoryDao.selectOne(
+            new LambdaQueryWrapper<ChatHistory>()
+                .eq(ChatHistory::getUser_id, chat.getUser_id())
+                .eq(ChatHistory::getHistory_code, chat.getHistory_code())
+                .eq(ChatHistory::getDel_flag, chat.getDel_flag())
+        );
         if (chatHistory == null) throw new CustException("对话历史不存在");
 
         PageUtils.startPage();  // 分页
@@ -195,17 +205,35 @@ public class ChatServiceImpl implements ChatService {
     @Override
     public Map<String, Object> deleteChat(Chat chat) {
 
-        String history_code = chat.getHistory_code();
+        // [软删除] 删除对话
+        chat.setDel_flag(1);
+
+        chatDao.update(chat, new LambdaQueryWrapper<Chat>()
+            .eq(Chat::getUser_id, chat.getUser_id())
+            .eq(Chat::getDel_flag, -1)
+            .eq(Chat::getHistory_code, chat.getHistory_code())
+        );
 
-        LambdaQueryWrapper<Chat> wrapper = new LambdaQueryWrapper<>();
-        wrapper.eq(Chat::getDel_flag, -1);
-        wrapper.eq(Chat::getHistory_code, history_code);
+        return Map.of("history_code", chat.getHistory_code());
+    }
+
+    /**
+     * 删除我的对话 (软删除)(单条)
+     */
+    @Override
+    public Map<String, Object> deleteChatOne(Chat chat) {
 
         // [软删除] 删除对话
         chat.setDel_flag(1);
-        chatDao.update(chat, wrapper);
 
-        return Map.of("history_code", chat.getHistory_code());
+        chatDao.update(chat, new LambdaQueryWrapper<Chat>()
+            .eq(Chat::getUser_id, chat.getUser_id())
+            .eq(Chat::getDel_flag, -1)
+            .eq(Chat::getId, chat.getId())
+        );
+        System.out.println(chat);
+
+        return Map.of("id", chat.getId());
     }
 
 

+ 18 - 6
src/main/java/com/backendsys/modules/sdk/deepseek/service/impl/DeepSeekClientImpl.java

@@ -55,6 +55,8 @@ public class DeepSeekClientImpl implements DeepSeekClient {
     @Override
     public ChatResult chatCompletion(Long user_id, String model, String prompt, List<Chat> chatList) {
 
+        long contentDuration = 0L;
+
         ChatResult chatResult = new ChatResult();
         try {
             System.out.println("向模型: " + model + " 提问: " + prompt);
@@ -208,15 +210,15 @@ public class DeepSeekClientImpl implements DeepSeekClient {
                     }
 
                     System.out.println("-------------------- 结束流式回答. --------------------");
-                    long contentDuration = System.currentTimeMillis() - allStartTime;
+                    contentDuration = System.currentTimeMillis() - allStartTime;
 
                     System.out.println("全部推理: " + allReasoningContent);
                     System.out.println("全部回答: " + allContent);
                     System.out.println("总输出耗时: " + contentDuration + " 毫秒");
 
-                    // [SSE] 发送消息
-                    ChatSseMessage chatSseMessage = new ChatSseMessage("REPLY", "[DONE][REPLY]", contentDuration);
-                    sseUtil.send(user_id, new SseResponse(SseResponseEnum.DEEPSEEK, chatSseMessage).toJsonStr());
+//                    // [SSE] 发送消息
+//                    ChatSseMessage chatSseMessage = new ChatSseMessage("REPLY", "[DONE][REPLY]", contentDuration);
+//                    sseUtil.send(user_id, new SseResponse(SseResponseEnum.DEEPSEEK, chatSseMessage).toJsonStr());
 
                     chatResult.setReasoning_content(allReasoningContent.toString());
                     chatResult.setReasoning_duration(reasoningContentDuration);
@@ -226,16 +228,26 @@ public class DeepSeekClientImpl implements DeepSeekClient {
 
                 }
             } catch (Exception e) {
-                sseUtil.send(user_id, (new SseResponse(SseResponseEnum.DEEPSEEK, e.getMessage())).toJsonStr());
                 System.out.println(e.getMessage());
+                // [SSE] 发送消息
+                ChatSseMessage chatSseMessage = new ChatSseMessage("REPLY", e.getMessage(), contentDuration);
+                sseUtil.send(user_id, new SseResponse(SseResponseEnum.DEEPSEEK, chatSseMessage).toJsonStr());
+
                 chatResult.setContent(e.getMessage());
                 return chatResult;
             }
         } catch (Exception e) {
-            sseUtil.send(user_id, (new SseResponse(SseResponseEnum.DEEPSEEK, e.getMessage())).toJsonStr());
             System.out.println(e.getMessage());
+            // [SSE] 发送消息
+            ChatSseMessage chatSseMessage = new ChatSseMessage("REPLY", e.getMessage(), contentDuration);
+            sseUtil.send(user_id, new SseResponse(SseResponseEnum.DEEPSEEK, chatSseMessage).toJsonStr());
+
             chatResult.setContent(e.getMessage());
             return chatResult;
+        } finally {
+            // [SSE] 发送消息
+            ChatSseMessage chatSseMessage = new ChatSseMessage("REPLY", "[DONE][REPLY]", contentDuration);
+            sseUtil.send(user_id, new SseResponse(SseResponseEnum.DEEPSEEK, chatSseMessage).toJsonStr());
         }
 
     }

+ 23 - 9
src/main/java/com/backendsys/modules/sdk/tencentcloud/huanyuan/service/impl/HunYuanClientImpl.java

@@ -59,6 +59,8 @@ public class HunYuanClientImpl implements HunYuanClient {
     @Override
     public ChatResult chatCompletion(Long user_id, String prompt, List<Chat> chatList) {
 
+        long contentDuration = 0L;
+
         ChatResult chatResult = new ChatResult();
         try {
 
@@ -73,7 +75,7 @@ public class HunYuanClientImpl implements HunYuanClient {
             List<Message> messages = new ArrayList<>();
             if (chatList != null && !chatList.isEmpty()) {
                 chatList.stream().forEach(chat -> {
-//                if (!"THINK".equals(chat.getContent_type())) {
+//                if (!"THINK".equals(chat.getContent_type())) {    // 混元没有 THINK
                     messages.add(setMessage(chat.getRole(), chat.getContent()));
 //                }
                 });
@@ -132,31 +134,43 @@ public class HunYuanClientImpl implements HunYuanClient {
             }
 
             System.out.println("-------------------- 结束流式回答. --------------------");
-            long contentDuration = System.currentTimeMillis() - allStartTime;
+            contentDuration = System.currentTimeMillis() - allStartTime;
 
             System.out.println("全部回答: " + allContent);
             System.out.println("总输出耗时: " + contentDuration + " 毫秒");
 
-            // [SSE] 发送消息
-            ChatSseMessage chatSseMessage = new ChatSseMessage("REPLY", "[DONE][REPLY]", contentDuration);
-            sseUtil.send(user_id, new SseResponse(SseResponseEnum.HUNYUAN, chatSseMessage).toJsonStr());
-
             chatResult.setContent(allContent.toString());
             chatResult.setContent_duration(contentDuration);
             return chatResult;
 
         } catch (TencentCloudSDKException e) {
-            System.out.println(e.getMessage());
+            System.out.println("TencentCloudSDKException: " + e.getMessage());
+            // [SSE] 发送消息
+            ChatSseMessage chatSseMessage = new ChatSseMessage("REPLY", e.getMessage(), contentDuration);
+            sseUtil.send(user_id, new SseResponse(SseResponseEnum.HUNYUAN, chatSseMessage).toJsonStr());
+
             chatResult.setContent(e.getMessage());
             return chatResult;
         } catch (JsonMappingException e) {
-            System.out.println(e.getMessage());
+            System.out.println("JsonMappingException: " + e.getMessage());
+            // [SSE] 发送消息
+            ChatSseMessage chatSseMessage = new ChatSseMessage("REPLY", e.getMessage(), contentDuration);
+            sseUtil.send(user_id, new SseResponse(SseResponseEnum.HUNYUAN, chatSseMessage).toJsonStr());
+
             chatResult.setContent(e.getMessage());
             return chatResult;
         } catch (JsonProcessingException e) {
-            System.out.println(e.getMessage());
+            System.out.println("JsonProcessingException: " + e.getMessage());
+            // [SSE] 发送消息
+            ChatSseMessage chatSseMessage = new ChatSseMessage("REPLY", e.getMessage(), contentDuration);
+            sseUtil.send(user_id, new SseResponse(SseResponseEnum.HUNYUAN, chatSseMessage).toJsonStr());
+
             chatResult.setContent(e.getMessage());
             return chatResult;
+        } finally {
+            // [SSE] 发送消息
+            ChatSseMessage chatSseMessage = new ChatSseMessage("REPLY", "[DONE][REPLY]", contentDuration);
+            sseUtil.send(user_id, new SseResponse(SseResponseEnum.HUNYUAN, chatSseMessage).toJsonStr());
         }
 
     }