From a76769e5404b7bd4a83544e7b9165048b319f315 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=8F=A9=E6=8F=90=E5=8F=96=E4=B8=80=E5=8F=B6?=
<616138361@qq.com>
Date: Sun, 25 May 2025 14:30:05 +0800
Subject: [PATCH] =?UTF-8?q?add:=E9=9B=86=E6=88=90=E5=9B=BD=E4=BA=A7?=
=?UTF-8?q?=E5=A4=A7=E6=A8=A1=E5=9E=8B=20ds=E3=80=81zhipu=E3=80=81qianwen?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ruoyi-modules-api/ruoyi-chat-api/pom.xml | 67 +++++++++++++--
.../org/ruoyi/chat/enums/ChatModeType.java | 7 ++
.../ruoyi/chat/service/chat/IChatService.java | 3 +
.../chat/service/chat/StreamAssistant.java | 7 ++
.../service/chat/impl/CozeServiceImpl.java | 4 +-
.../service/chat/impl/DeepSeekChatImpl.java | 77 +++++++++++++++++
.../chat/impl/QianWenAiChatServiceImpl.java | 84 ++++++++++++++++++
.../chat/impl/ZhipuAiChatServiceImpl.java | 85 +++++++++++++++++++
8 files changed, 326 insertions(+), 8 deletions(-)
create mode 100644 ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/StreamAssistant.java
create mode 100644 ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/DeepSeekChatImpl.java
create mode 100644 ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/QianWenAiChatServiceImpl.java
create mode 100644 ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ZhipuAiChatServiceImpl.java
diff --git a/ruoyi-modules-api/ruoyi-chat-api/pom.xml b/ruoyi-modules-api/ruoyi-chat-api/pom.xml
index b47d9c3e..7e08c9af 100644
--- a/ruoyi-modules-api/ruoyi-chat-api/pom.xml
+++ b/ruoyi-modules-api/ruoyi-chat-api/pom.xml
@@ -34,11 +34,11 @@
-
-
-
-
-
+
+
+
+
+
org.ruoyi
@@ -83,6 +83,63 @@
0.3.1
+
+ dev.langchain4j
+ langchain4j-open-ai
+ 1.0.1
+
+
+
+ dev.langchain4j
+ langchain4j-core
+ 1.0.0
+
+
+ dev.langchain4j
+ langchain4j-http-client-jdk
+ 1.0.0
+
+
+ dev.langchain4j
+ langchain4j-community-zhipu-ai
+ 1.0.1-beta6
+
+
+
+
+
+ dev.langchain4j
+ langchain4j-community-dashscope
+ 1.0.1-beta6
+
+
+
+ io.jsonwebtoken
+ jjwt
+ 0.12.6
+
+
+ io.jsonwebtoken
+ jjwt-api
+ 0.12.6
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ 0.12.6
+
+
+ io.jsonwebtoken
+ jjwt-jackson
+ 0.12.6
+
+
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+
+
+
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 d29bccd3..8388ad2f 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 @@ public enum ChatModeType {
CHAT("chat", "中转模型"),
DIFY("dify", "DIFY"),
COZE("coze", "扣子"),
+
+ 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 55ea2ac8..df49209e 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 @@ package org.ruoyi.chat.service.chat;
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 00000000..b1854278
--- /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 6da0988c..7cbb5927 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.ChatEvent;
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 @@ public class CozeServiceImpl implements IChatService {
@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 @@ public class CozeServiceImpl implements IChatService {
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 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 00000000..8e805dd9
--- /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("消息结束,完整消息ID: {}", 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 00000000..6e4308d4
--- /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("消息结束,完整消息ID: {}", 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 00000000..b09d9610
--- /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("消息结束,完整消息ID: {}", 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();
+ }
+}