办学质量监测教学评价系统
菩提取一叶
2025-05-25 a76769e5404b7bd4a83544e7b9165048b319f315
add:集成国产大模型 ds、zhipu、qianwen
已修改4个文件
已添加4个文件
334 ■■■■■ 文件已修改
ruoyi-modules-api/ruoyi-chat-api/pom.xml 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/enums/ChatModeType.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/IChatService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/StreamAssistant.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/CozeServiceImpl.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/DeepSeekChatImpl.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/QianWenAiChatServiceImpl.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ZhipuAiChatServiceImpl.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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>
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/enums/ChatModeType.java
@@ -8,6 +8,13 @@
    CHAT("chat", "中转模型"),
    DIFY("dify", "DIFY"),
    COZE("coze", "扣子"),
    ZHIPU("zhipu", "智谱清言"),
    DEEPSEEK("deepseek", "深度求索"),
    QIANWEN("qianwen", "通义千问"),
    VECTOR("vector", "知识库向量模型");
    private final String code;
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接口
 *
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);
}
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);
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();
    }
}
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();
    }
}
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();
    }
}