Bläddra i källkod

修复chat对话流程

tsurumure 6 månader sedan
förälder
incheckning
985f0616bb

+ 1 - 1
db/sys_user_role_menu.sql

@@ -37,7 +37,7 @@ INSERT INTO sys_user_role_menu(id, parent_id, menu_name, menu_name_en, type, pat
 #     (2, '订单管理', 'Orders', 1, '/b2c/order/b2cOrder', '/src/views/b2c/order/b2cOrder.vue', '{}', null, null, 4),
 #     (2, '订单详情', 'Orders Detail', 2, '/b2c/order/b2cOrderDetail', '/src/views/b2c/order/b2cOrderDetail.vue', '{"isBack":true,"isHide":true}', null, null, 4),
 
-    (2, -1, 'AI对话', 'AI Copywriting', 1, '/ai/chat/copywriting', '/src/views/ai/copywriting.vue', '{}', 'Document', '31', 900),
+    (2, -1, 'AI对话', 'AI Chat', 1, '/ai/chat/chat', '/src/views/ai/chat.vue', '{}', 'Document', '31', 900),
 
     (3, -1, 'AI图片生成器', 'AI Image', 1, '/ai/imagePicker', '', '{}', 'Picture', '35', 901),
     (4, 3, 'AI模特', 'AI Model', 1, '/ai/modelCloth/make', '', '{}', '', '', 902),

+ 5 - 0
src/main/java/com/backendsys/modules/ai/chat/dao/ChatDao.java

@@ -4,6 +4,11 @@ import com.backendsys.modules.ai.chat.entity.Chat;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.util.List;
+
 @Mapper
 public interface ChatDao extends BaseMapper<Chat> {
+
+    List<Chat> selectChatList(Chat chat);
+
 }

+ 15 - 1
src/main/java/com/backendsys/modules/ai/chat/entity/ChatSseMessage.java

@@ -1,11 +1,25 @@
 package com.backendsys.modules.ai.chat.entity;
 
+import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 @Data
 public class ChatSseMessage {
 
     private String content;
-    private String content_type;    // (loading: 加载中, reply: 回复, think: 思考)
+    private String content_type;    // (LOADING: 加载中, REPLY: 回复, THINK: 思考)
+    private Long duration;
+
+    public ChatSseMessage(String contentType, String content) {
+        this.content = content;
+        this.content_type = contentType;
+    }
+
+    public ChatSseMessage(String contentType, String content, Long duration) {
+        this.content = content;
+        this.content_type = contentType;
+        this.duration = duration;
+    }
 
 }

+ 3 - 8
src/main/java/com/backendsys/modules/ai/chat/service/impl/ChatServiceImpl.java

@@ -179,17 +179,12 @@ public class ChatServiceImpl implements ChatService {
         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));
+            .eq(ChatHistory::getDel_flag, chat.getDel_flag())
+            .eq(ChatHistory::getHistory_code, history_code));
         if (chatHistory == null) throw new CustException("对话历史不存在");
 
         PageUtils.startPage();  // 分页
-        LambdaQueryWrapper<Chat> wrapper = new LambdaQueryWrapper<>();
-        wrapper.eq(Chat::getHistory_code, history_code);
-        wrapper.eq(Chat::getDel_flag, chat.getDel_flag());
-        wrapper.orderByAsc(Chat::getCreate_time);
-        List<Chat> list = chatDao.selectList(wrapper);
-
+        List<Chat> list = chatDao.selectChatList(chat);
         return new PageInfoResult(list).toEntity();
     }
 

+ 12 - 9
src/main/java/com/backendsys/modules/sdk/deepseek/service/impl/DeepSeekClientImpl.java

@@ -124,9 +124,7 @@ public class DeepSeekClientImpl implements DeepSeekClient {
                     System.out.println("-------------------- 开始流式回答: --------------------");
 
                     // [SSE] 发送消息
-                    ChatSseMessage chatLoadingSseMessage = new ChatSseMessage();
-                    chatLoadingSseMessage.setContent_type("loading");
-                    chatLoadingSseMessage.setContent("正在思考");
+                    ChatSseMessage chatLoadingSseMessage = new ChatSseMessage("LOADING", "正在思考");
                     sseUtil.send(user_id, new SseResponse(SseResponseEnum.DEEPSEEK, chatLoadingSseMessage).toJsonStr());
 
                     StringBuilder allContent = new StringBuilder();
@@ -171,9 +169,7 @@ public class DeepSeekClientImpl implements DeepSeekClient {
                                 System.out.println("reasoning_content: " + reasoning_content);
 
                                 // [SSE] 发送消息
-                                ChatSseMessage chatSseMessage = new ChatSseMessage();
-                                chatSseMessage.setContent_type("think");
-                                chatSseMessage.setContent(reasoning_content);
+                                ChatSseMessage chatSseMessage = new ChatSseMessage("THINK", reasoning_content);
                                 sseUtil.send(user_id, new SseResponse(SseResponseEnum.DEEPSEEK, chatSseMessage).toJsonStr());
 
                                 // 收集推理内容
@@ -190,14 +186,17 @@ public class DeepSeekClientImpl implements DeepSeekClient {
                                     reasoningContentDuration = thinkStartTime - allStartTime;
                                     System.out.println("推理耗时: " + reasoningContentDuration + "毫秒");
                                     System.out.println("-----------------------------------------------");
+
+                                    // [SSE] 发送消息
+                                    ChatSseMessage chatSseMessage = new ChatSseMessage("THINK", "[DONE][THINK]", reasoningContentDuration);
+                                    sseUtil.send(user_id, new SseResponse(SseResponseEnum.DEEPSEEK, chatSseMessage).toJsonStr());
+
                                 }
 
                                 System.out.println("content: " + content);
 
                                 // [SSE] 发送消息
-                                ChatSseMessage chatSseMessage = new ChatSseMessage();
-                                chatSseMessage.setContent_type("reply");
-                                chatSseMessage.setContent(content);
+                                ChatSseMessage chatSseMessage = new ChatSseMessage("REPLY", content);
                                 sseUtil.send(user_id, new SseResponse(SseResponseEnum.DEEPSEEK, chatSseMessage).toJsonStr());
 
                                 // 收集回答内容
@@ -215,6 +214,10 @@ public class DeepSeekClientImpl implements DeepSeekClient {
                     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());
+
                     chatResult.setReasoning_content(allReasoningContent.toString());
                     chatResult.setReasoning_duration(reasoningContentDuration);
                     chatResult.setContent(allContent.toString());

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

@@ -59,8 +59,6 @@ public class HunYuanClientImpl implements HunYuanClient {
     @Override
     public ChatResult chatCompletion(Long user_id, String prompt, List<Chat> chatList) {
 
-        System.out.println("(chatCompletion) user_id = " + user_id);
-
         ChatResult chatResult = new ChatResult();
         try {
 
@@ -125,9 +123,7 @@ public class HunYuanClientImpl implements HunYuanClient {
                 String content = delta.path("Content").asText("");
 
                 // [SSE] 发送消息
-                ChatSseMessage chatSseMessage = new ChatSseMessage();
-                chatSseMessage.setContent_type("reply");
-                chatSseMessage.setContent(content);
+                ChatSseMessage chatSseMessage = new ChatSseMessage("REPLY", content);
                 sseUtil.send(user_id, new SseResponse(SseResponseEnum.HUNYUAN, chatSseMessage).toJsonStr());
 
                 // 收集回答内容
@@ -141,6 +137,10 @@ public class HunYuanClientImpl implements HunYuanClient {
             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;

+ 55 - 0
src/main/resources/mapper/ai/chat/ChatDao.xml

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.backendsys.modules.ai.chat.dao.ChatDao">
+
+    <sql id="includeChat">
+        id,
+        history_code,
+        model,
+        model_version,
+        role,
+        COALESCE(content_type, '') content_type,
+        content,
+        COALESCE(duration, '') duration,
+        user_id,
+        COALESCE(robot_code, '') robot_code,
+        del_flag,
+        create_time,
+        update_time
+    </sql>
+
+    <resultMap id="resultMapChat" type="com.backendsys.modules.ai.chat.entity.Chat">
+        <id property="id" column="id" jdbcType="BIGINT" />
+        <result property="history_code" column="history_code" />
+        <result property="model" column="model" />
+        <result property="model_version" column="model_version" />
+        <result property="role" column="role" />
+        <result property="content_type" column="content_type" />
+        <result property="content" column="content" />
+        <result property="duration" column="duration" javaType="java.lang.Long" />
+        <result property="user_id" column="user_id" javaType="java.lang.Long" />
+        <result property="robot_code" column="robot_code" />
+        <result property="del_flag" column="del_flag" javaType="java.lang.Integer" />
+        <result property="create_time" column="create_time" />
+        <result property="update_time" column="update_time" />
+    </resultMap>
+
+    <!-- 查 列表 -->
+    <select id="selectChatList" resultMap="resultMapChat">
+        SELECT <include refid="includeChat" />
+        FROM ai_chat
+        <where>
+            <if test="user_id != null and user_id != ''">
+                AND user_id = #{user_id}
+            </if>
+            <if test="history_code != null and history_code != ''">
+                AND history_code = #{history_code}
+            </if>
+            <if test="del_flag != null and del_flag != ''">
+                AND del_flag = #{del_flag}
+            </if>
+        </where>
+        ORDER BY create_time DESC, id DESC
+    </select>
+
+</mapper>