From 1bff2791a6d4a4294795a34581e59f623d138c12 Mon Sep 17 00:00:00 2001
From: ageerle <32251822+ageerle@users.noreply.github.com>
Date: 星期日, 25 五月 2025 14:36:23 +0800
Subject: [PATCH] Merge pull request #108 from liudalian/20250520

---
 ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ZhipuAiChatServiceImpl.java   |   85 ++++++++++++++
 ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/enums/ChatModeType.java                         |    7 +
 ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/StreamAssistant.java               |    7 +
 ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/QianWenAiChatServiceImpl.java |   84 ++++++++++++++
 ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/DeepSeekChatImpl.java         |   77 ++++++++++++
 ruoyi-modules-api/ruoyi-chat-api/pom.xml                                                              |   67 ++++++++++
 ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/IChatService.java                  |    3 
 ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/CozeServiceImpl.java          |    4 
 8 files changed, 326 insertions(+), 8 deletions(-)

diff --git a/ruoyi-modules-api/ruoyi-chat-api/pom.xml b/ruoyi-modules-api/ruoyi-chat-api/pom.xml
index b47d9c3..7e08c9a 100644
--- a/ruoyi-modules-api/ruoyi-chat-api/pom.xml
+++ b/ruoyi-modules-api/ruoyi-chat-api/pom.xml
@@ -34,11 +34,11 @@
     <!-- 瀵硅瘽鍩虹妯″潡 -->
     <dependencies>
 
-<!--        <dependency>-->
-<!--            <groupId>io.modelcontextprotocol.sdk</groupId>-->
-<!--            <artifactId>mcp-spring-webflux</artifactId>-->
-<!--            <version>0.8.0</version>-->
-<!--        </dependency>-->
+        <!--        <dependency>-->
+        <!--            <groupId>io.modelcontextprotocol.sdk</groupId>-->
+        <!--            <artifactId>mcp-spring-webflux</artifactId>-->
+        <!--            <version>0.8.0</version>-->
+        <!--        </dependency>-->
 
         <dependency>
             <groupId>org.ruoyi</groupId>
@@ -83,6 +83,63 @@
             <version>0.3.1</version>
         </dependency>
 
+        <dependency>
+            <groupId>dev.langchain4j</groupId>
+            <artifactId>langchain4j-open-ai</artifactId>
+            <version>1.0.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>dev.langchain4j</groupId>
+            <artifactId>langchain4j-core</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>dev.langchain4j</groupId>
+            <artifactId>langchain4j-http-client-jdk</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>dev.langchain4j</groupId>
+            <artifactId>langchain4j-community-zhipu-ai</artifactId>
+            <version>1.0.1-beta6</version>
+        </dependency>
+
+
+
+        <dependency>
+            <groupId>dev.langchain4j</groupId>
+            <artifactId>langchain4j-community-dashscope</artifactId>
+            <version>1.0.1-beta6</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+            <version>0.12.6</version>
+        </dependency>
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt-api</artifactId>
+            <version>0.12.6</version>
+        </dependency>
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt-impl</artifactId>
+            <version>0.12.6</version>
+        </dependency>
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt-jackson</artifactId>
+            <version>0.12.6</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-webflux</artifactId>
+        </dependency>
+
+
     </dependencies>
 
 </project>
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/enums/ChatModeType.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/enums/ChatModeType.java
index d29bccd..8388ad2 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/enums/ChatModeType.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/enums/ChatModeType.java
@@ -8,6 +8,13 @@
     CHAT("chat", "涓浆妯″瀷"),
     DIFY("dify", "DIFY"),
     COZE("coze", "鎵e瓙"),
+
+    ZHIPU("zhipu", "鏅鸿氨娓呰█"),
+
+    DEEPSEEK("deepseek", "娣卞害姹傜储"),
+
+    QIANWEN("qianwen", "閫氫箟鍗冮棶"),
+
     VECTOR("vector", "鐭ヨ瘑搴撳悜閲忔ā鍨�");
 
     private final String code;
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/IChatService.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/IChatService.java
index 55ea2ac..df49209 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/IChatService.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/IChatService.java
@@ -3,6 +3,9 @@
 import org.ruoyi.common.chat.request.ChatRequest;
 import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
 
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+
 /**
  * 瀵硅瘽Service鎺ュ彛
  *
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/StreamAssistant.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/StreamAssistant.java
new file mode 100644
index 0000000..b185427
--- /dev/null
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/StreamAssistant.java
@@ -0,0 +1,7 @@
+package org.ruoyi.chat.service.chat;
+
+import dev.langchain4j.service.TokenStream;
+
+public interface StreamAssistant {
+    TokenStream chat(String message);
+}
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/CozeServiceImpl.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/CozeServiceImpl.java
index 6da0988..7cbb592 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/CozeServiceImpl.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/CozeServiceImpl.java
@@ -5,7 +5,6 @@
 import com.coze.openapi.client.chat.model.ChatEventType;
 import com.coze.openapi.client.connversations.message.model.Message;
 import com.coze.openapi.service.auth.TokenAuth;
-import com.coze.openapi.service.config.Consts;
 import com.coze.openapi.service.service.CozeAPI;
 import io.reactivex.Flowable;
 import lombok.extern.slf4j.Slf4j;
@@ -37,7 +36,6 @@
     @Override
     public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) {
         ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel());
-
         TokenAuth authCli = new TokenAuth(chatModelVo.getApiKey());
         CozeAPI coze =
                 new CozeAPI.Builder()
@@ -49,7 +47,7 @@
                 CreateChatReq.builder()
                         .botID(chatModelVo.getModelName())
                         .userID(chatRequest.getUserId().toString())
-                        .messages(Collections.singletonList(Message.buildUserQuestionText("What can you do?")))
+                        .messages(Collections.singletonList(Message.buildUserQuestionText(chatRequest.getPrompt())))
                         .build();
 
         Flowable<ChatEvent> resp = coze.chat().stream(req);
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/DeepSeekChatImpl.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/DeepSeekChatImpl.java
new file mode 100644
index 0000000..8e805dd
--- /dev/null
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/DeepSeekChatImpl.java
@@ -0,0 +1,77 @@
+package org.ruoyi.chat.service.chat.impl;
+
+
+import dev.langchain4j.model.chat.StreamingChatModel;
+import dev.langchain4j.model.chat.response.ChatResponse;
+import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
+import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.ruoyi.chat.enums.ChatModeType;
+import org.ruoyi.chat.service.chat.IChatService;
+import org.ruoyi.common.chat.request.ChatRequest;
+import org.ruoyi.domain.vo.ChatModelVo;
+import org.ruoyi.service.IChatModelService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * deepseek
+ */
+@Service
+@Slf4j
+public class DeepSeekChatImpl  implements IChatService {
+
+    @Autowired
+    private IChatModelService chatModelService;
+
+    @Override
+    public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) {
+        ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel());
+        StreamingChatModel chatModel = OpenAiStreamingChatModel.builder()
+                .baseUrl(chatModelVo.getApiHost())
+                .apiKey(chatModelVo.getApiKey())
+                .modelName(chatModelVo.getModelName())
+                .logRequests(true)
+                .logResponses(true)
+                .temperature(0.8)
+                .build();
+        // 鍙戦�佹祦寮忔秷鎭�
+        try {
+            chatModel.chat(chatRequest.getPrompt(), new StreamingChatResponseHandler() {
+                @SneakyThrows
+                @Override
+                public void onPartialResponse(String partialResponse) {
+                    emitter.send(partialResponse);
+                    log.info("鏀跺埌娑堟伅鐗囨: {}", partialResponse);
+                    System.out.print(partialResponse);
+                }
+
+                @Override
+                public void onCompleteResponse(ChatResponse completeResponse) {
+                    emitter.complete();
+                    log.info("娑堟伅缁撴潫锛屽畬鏁存秷鎭疘D: {}", completeResponse);
+                }
+
+                @Override
+                public void onError(Throwable error) {
+                    System.err.println("閿欒: " + error.getMessage());
+                }
+            });
+
+        } catch (Exception e) {
+            log.error("deepseek璇锋眰澶辫触锛歿}", e.getMessage());
+        }
+
+        return emitter;
+    }
+
+    @Override
+    public String getCategory() {
+        return ChatModeType.DEEPSEEK.getCode();
+    }
+}
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/QianWenAiChatServiceImpl.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/QianWenAiChatServiceImpl.java
new file mode 100644
index 0000000..6e4308d
--- /dev/null
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/QianWenAiChatServiceImpl.java
@@ -0,0 +1,84 @@
+package org.ruoyi.chat.service.chat.impl;
+
+import dev.langchain4j.community.model.dashscope.QwenStreamingChatModel;
+import dev.langchain4j.community.model.zhipu.ZhipuAiStreamingChatModel;
+import dev.langchain4j.model.chat.StreamingChatModel;
+import dev.langchain4j.model.chat.response.ChatResponse;
+import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.ruoyi.chat.enums.ChatModeType;
+import org.ruoyi.chat.service.chat.IChatService;
+import org.ruoyi.common.chat.request.ChatRequest;
+import org.ruoyi.domain.ChatMessage;
+import org.ruoyi.domain.vo.ChatModelVo;
+import org.ruoyi.service.IChatModelService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
+
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+
+import static dev.langchain4j.data.message.SystemMessage.systemMessage;
+import static dev.langchain4j.data.message.UserMessage.userMessage;
+import static java.util.Arrays.asList;
+
+
+/**
+ * 闃块噷閫氫箟鍗冮棶
+ */
+@Service
+@Slf4j
+public class QianWenAiChatServiceImpl  implements IChatService {
+
+    @Autowired
+    private IChatModelService chatModelService;
+
+
+    @Override
+    public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) {
+        ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel());
+        StreamingChatModel model = QwenStreamingChatModel.builder()
+                .apiKey(chatModelVo.getApiKey())
+                .modelName(chatModelVo.getModelName())
+                .build();
+
+        // 鍙戦�佹祦寮忔秷鎭�
+        try {
+            model.chat(chatRequest.getPrompt(), new StreamingChatResponseHandler() {
+                @SneakyThrows
+                @Override
+                public void onPartialResponse(String partialResponse) {
+                    emitter.send(partialResponse);
+                    log.info("鏀跺埌娑堟伅鐗囨: {}", partialResponse);
+                }
+
+                @Override
+                public void onCompleteResponse(ChatResponse completeResponse) {
+                    emitter.complete();
+                    log.info("娑堟伅缁撴潫锛屽畬鏁存秷鎭疘D: {}", completeResponse);
+                }
+
+                @Override
+                public void onError(Throwable error) {
+                    error.printStackTrace();
+                }
+            });
+        } catch (Exception e) {
+            log.error("鍗冮棶璇锋眰澶辫触锛歿}", e.getMessage());
+        }
+
+        return emitter;
+
+    }
+
+    @Override
+    public String getCategory() {
+        return ChatModeType.QIANWEN.getCode();
+    }
+
+
+
+}
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ZhipuAiChatServiceImpl.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ZhipuAiChatServiceImpl.java
new file mode 100644
index 0000000..b09d961
--- /dev/null
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ZhipuAiChatServiceImpl.java
@@ -0,0 +1,85 @@
+package org.ruoyi.chat.service.chat.impl;
+
+import dev.langchain4j.agent.tool.ToolSpecification;
+import dev.langchain4j.community.model.zhipu.ZhipuAiStreamingChatModel;
+import dev.langchain4j.model.chat.StreamingChatModel;
+import dev.langchain4j.model.chat.response.ChatResponse;
+import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.ruoyi.chat.enums.ChatModeType;
+import org.ruoyi.chat.service.chat.IChatService;
+import org.ruoyi.common.chat.request.ChatRequest;
+import org.ruoyi.domain.vo.ChatModelVo;
+import org.ruoyi.service.IChatModelService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+
+
+/**
+ * 鏅鸿氨AI
+ */
+@Service
+@Slf4j
+public class ZhipuAiChatServiceImpl  implements IChatService {
+
+    @Autowired
+    private IChatModelService chatModelService;
+
+
+    ToolSpecification currentTime = ToolSpecification.builder()
+            .name("currentTime")
+            .description("currentTime")
+            .build();
+
+
+    @Override
+    public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter){
+        ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel());
+        // 鍙戦�佹祦寮忔秷鎭�
+        try {
+            StreamingChatResponseHandler handler = new StreamingChatResponseHandler() {
+                @SneakyThrows
+                @Override
+                public void onPartialResponse(String token) {
+                    System.out.println(token);
+                    emitter.send(token);
+                }
+
+                @SneakyThrows
+                @Override
+                public void onError(Throwable error) {
+                    System.out.println(error.getMessage());
+                    emitter.send(error.getMessage());
+                }
+
+                @Override
+                public void onCompleteResponse(ChatResponse response) {
+                    emitter.complete();
+                    log.info("娑堟伅缁撴潫锛屽畬鏁存秷鎭疘D: {}", response.aiMessage());
+                }
+            };
+
+            StreamingChatModel model = ZhipuAiStreamingChatModel.builder()
+                    .model(chatModelVo.getModelName())
+                    .apiKey(chatModelVo.getApiKey())
+                    .logRequests(true)
+                    .logResponses(true)
+                    .build();
+            model.chat(chatRequest.getPrompt(), handler);
+        } catch (Exception e) {
+            log.error("鏅鸿氨娓呰█璇锋眰澶辫触锛歿}", e.getMessage());
+        }
+
+        return emitter;
+    }
+
+    @Override
+    public String getCategory() {
+        return ChatModeType.ZHIPU.getCode();
+    }
+}

--
Gitblit v1.9.3