瀏覽代碼

feat(ai): 添加 Dify聊天功能支持

zrd 3 周之前
父節點
當前提交
9d45862ef9

+ 4 - 0
yudao-module-ai/yudao-module-ai-biz/pom.xml

@@ -60,5 +60,9 @@
             <groupId>cn.iocoder.boot</groupId>
             <artifactId>yudao-spring-boot-starter-test</artifactId>
         </dependency>
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-excel</artifactId>
+        </dependency>
     </dependencies>
 </project>

+ 5 - 2
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/vo/message/AiChatMessagePageReqVO.java

@@ -5,6 +5,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 import org.springframework.format.annotation.DateTimeFormat;
 
+import java.io.Serial;
 import java.time.LocalDateTime;
 
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -12,7 +13,9 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
 @Schema(description = "管理后台 - AI 聊天消息的分页 Request VO")
 @Data
 public class AiChatMessagePageReqVO extends PageParam {
-
+    
+    @Serial
+    private static final long serialVersionUID = 83042160850734267L;
     @Schema(description = "对话编号", example = "2048")
     private Long conversationId;
 
@@ -21,7 +24,7 @@ public class AiChatMessagePageReqVO extends PageParam {
 
     @Schema(description = "消息内容", example = "你好")
     private String content;
-
+    private String contentType;
     @Schema(description = "创建时间")
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     private LocalDateTime[] createTime;

+ 1 - 1
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/vo/message/AiChatMessageRespVO.java

@@ -18,7 +18,7 @@ public class AiChatMessageRespVO {
 
     @Schema(description = "回复消息编号", example = "1024")
     private Long replyId;
-
+    private String contentType;
     @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "role")
     private String type; // 参见 MessageType 枚举类
 

+ 1 - 1
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/vo/message/AiChatMessageSendReqVO.java

@@ -26,7 +26,7 @@ public class AiChatMessageSendReqVO {
     private String content;
     @Schema(description = "令牌")
     private String token;
-
+    private String contentType;
     @Schema(description = "是否携带上下文", example = "true")
     private Boolean useContext;
     

+ 1 - 1
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/vo/message/AiChatMessageSendRespVO.java

@@ -25,7 +25,7 @@ public class AiChatMessageSendRespVO {
 
         @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "role")
         private String type; // 参见 MessageType 枚举类
-
+        private String contentType;
         @Schema(description = "聊天内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "你好,你好啊")
         private String content;
         private String event;

+ 9 - 2
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/chat/AiChatMessageDO.java

@@ -9,9 +9,13 @@ import com.baomidou.mybatisplus.annotation.KeySequence;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.*;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
 import org.springframework.ai.chat.messages.MessageType;
 
+import java.io.Serial;
 import java.util.List;
 
 /**
@@ -27,7 +31,9 @@ import java.util.List;
 @NoArgsConstructor
 @AllArgsConstructor
 public class AiChatMessageDO extends BaseDO {
-
+    
+    @Serial
+    private static final long serialVersionUID = 8754536560987460356L;
     /**
      * 编号,作为每条聊天记录的唯一标识符
      */
@@ -87,6 +93,7 @@ public class AiChatMessageDO extends BaseDO {
      * 聊天内容
      */
     private String content;
+    private String contentType;
 
     /**
      * 是否携带上下文

+ 9 - 7
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/chat/AiChatMessageServiceImpl.java

@@ -118,12 +118,12 @@ public class AiChatMessageServiceImpl implements AiChatMessageService {
         // 3. 插入 user 发送消息
         AiChatMessageDO userMessage = createChatMessage(conversation.getId(), null, model,
                 userId, conversation.getRoleId(), MessageType.USER, sendReqVO.getContent(), sendReqVO.getUseContext(),
-                null);
+                null, sendReqVO.getContentType());
 
         // 3.1 插入 assistant 接收消息
         AiChatMessageDO assistantMessage = createChatMessage(conversation.getId(), userMessage.getId(), model,
                 userId, conversation.getRoleId(), MessageType.ASSISTANT, "", sendReqVO.getUseContext(),
-                knowledgeSegments);
+                knowledgeSegments, sendReqVO.getContentType());
 
         // 3.2 创建 chat 需要的 Prompt
         Prompt prompt = buildPrompt(conversation, historyMessages, knowledgeSegments, model, sendReqVO);
@@ -167,12 +167,12 @@ public class AiChatMessageServiceImpl implements AiChatMessageService {
         // 3. 插入 user 发送消息
         AiChatMessageDO userMessage = createChatMessage(conversation.getId(), null, model,
                 userId, conversation.getRoleId(), MessageType.USER, sendReqVO.getContent(), sendReqVO.getUseContext(),
-                null);
+                null, sendReqVO.getContentType());
 
         // 4.1 插入 assistant 接收消息
         AiChatMessageDO assistantMessage = createChatMessage(conversation.getId(), userMessage.getId(), model,
                 userId, conversation.getRoleId(), MessageType.ASSISTANT, "", sendReqVO.getUseContext(),
-                knowledgeSegments);
+                knowledgeSegments, sendReqVO.getContentType());
 
         // 4.2 构建 Prompt,并进行调用
         Prompt prompt = buildPrompt(conversation, historyMessages, knowledgeSegments, model, sendReqVO);
@@ -229,7 +229,7 @@ public class AiChatMessageServiceImpl implements AiChatMessageService {
         // 3. 插入 user 发送消息
         AiChatMessageDO userMessage = createChatMessage(conversation.getId(), null, model,
                 userId, conversation.getRoleId(), MessageType.USER, sendReqVO.getContent(), sendReqVO.getUseContext(),
-                null);
+                null, sendReqVO.getContentType());
         String apiKey = DictFrameworkUtils.parseDictDataValue("ai_key", "多轮对话");
         JSONObject requestBody = new JSONObject();
         if (StrUtil.isNotBlank(conversation.getDifyConversationId())) {
@@ -291,7 +291,7 @@ public class AiChatMessageServiceImpl implements AiChatMessageService {
         StringBuffer difyId = new StringBuffer();
         AiChatMessageDO assistantMessage = createChatMessage(conversation.getId(), userMessage.getId(), model,
                 userId, conversation.getRoleId(), MessageType.ASSISTANT, "", sendReqVO.getUseContext(),
-                knowledgeSegments);
+                knowledgeSegments, sendReqVO.getContentType());
         return flux.map(chunk -> {
             String newContent = chunk.getContent();
             contentBuffer.append(newContent);
@@ -494,12 +494,14 @@ public class AiChatMessageServiceImpl implements AiChatMessageService {
     private AiChatMessageDO createChatMessage(Long conversationId, Long replyId,
             AiModelDO model, Long userId, Long roleId,
             MessageType messageType, String content, Boolean useContext,
-            List<AiKnowledgeSegmentSearchRespBO> knowledgeSegments) {
+                                              List<AiKnowledgeSegmentSearchRespBO> knowledgeSegments,
+                                              String contentType) {
         AiChatMessageDO message = new AiChatMessageDO().setConversationId(conversationId).setReplyId(replyId)
                 .setModel(model.getModel()).setModelId(model.getId()).setUserId(userId).setRoleId(roleId)
                 .setType(messageType.getValue()).setContent(content).setUseContext(useContext)
                 .setSegmentIds(convertList(knowledgeSegments, AiKnowledgeSegmentSearchRespBO::getId));
         message.setCreateTime(LocalDateTime.now());
+        message.setContentType(contentType);
         chatMessageMapper.insert(message);
         return message;
     }