diff --git a/pom.xml b/pom.xml
index 8104e76..38ddfbe 100644
--- a/pom.xml
+++ b/pom.xml
@@ -34,7 +34,11 @@
org.springframework.ai
spring-ai-starter-model-deepseek
-
+
+
+ com.alibaba.cloud.ai
+ spring-ai-alibaba-starter-dashscope
+
org.springframework.boot
spring-boot-starter-data-redis
@@ -89,6 +93,14 @@
pom
import
+
+
+ com.alibaba.cloud.ai
+ spring-ai-alibaba-bom
+ 1.0.0.2
+ pom
+ import
+
diff --git a/src/main/java/com/ai/app/config/AIConfig.java b/src/main/java/com/ai/app/config/AIConfig.java
index d76ea84..cedcd20 100644
--- a/src/main/java/com/ai/app/config/AIConfig.java
+++ b/src/main/java/com/ai/app/config/AIConfig.java
@@ -1,5 +1,6 @@
package com.ai.app.config;
+import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
@@ -54,9 +55,9 @@ public class AIConfig {
}
/**
- * 配置AI对话客户端
+ * dashScopeChatClient对话客户端
*
- * @param deepSeekChatModel deepseek大模型
+ * @param dashScopeChatModel 千问max大模型
* @param simpleLoggerAdvisor 日志Advisor
* @param messageChatMemoryAdvisor 会话记忆Advisor
* @return: org.springframework.ai.chat.client.ChatClient
@@ -64,9 +65,33 @@ public class AIConfig {
* @date: 2025/8/29 9:06
*/
@Bean
- public ChatClient chatClient(DeepSeekChatModel deepSeekChatModel,
- SimpleLoggerAdvisor simpleLoggerAdvisor,
- MessageChatMemoryAdvisor messageChatMemoryAdvisor) {
+ public ChatClient dashScopeChatClient(DashScopeChatModel dashScopeChatModel,
+ SimpleLoggerAdvisor simpleLoggerAdvisor,
+ MessageChatMemoryAdvisor messageChatMemoryAdvisor) {
+ return ChatClient
+ //模型
+ .builder(dashScopeChatModel)
+ //系统角色
+ .defaultSystem("你是一个小团团")
+ //环绕增强
+ .defaultAdvisors(simpleLoggerAdvisor, messageChatMemoryAdvisor)
+ .build();
+ }
+
+ /**
+ * deepseek 对话客户端
+ *
+ * @param deepSeekChatModel deepseek大模型
+ * @param simpleLoggerAdvisor 日志增强
+ * @param messageChatMemoryAdvisor 会话记忆增强
+ * @return: org.springframework.ai.chat.client.ChatClient
+ * @author kai.liu
+ * @date: 2025/9/3 16:45
+ */
+ @Bean
+ public ChatClient deepSeekChatClient(DeepSeekChatModel deepSeekChatModel,
+ SimpleLoggerAdvisor simpleLoggerAdvisor,
+ MessageChatMemoryAdvisor messageChatMemoryAdvisor) {
return ChatClient
//模型
.builder(deepSeekChatModel)
diff --git a/src/main/java/com/ai/app/controller/ChatController.java b/src/main/java/com/ai/app/controller/ChatController.java
deleted file mode 100644
index 7840b0a..0000000
--- a/src/main/java/com/ai/app/controller/ChatController.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.ai.app.controller;
-
-import com.ai.app.dto.MessageDTO;
-import com.ai.app.service.AIChatMessageService;
-import org.springframework.ai.chat.client.ChatClient;
-import org.springframework.ai.chat.memory.ChatMemory;
-import org.springframework.ai.chat.memory.InMemoryChatMemoryRepository;
-import org.springframework.ai.chat.messages.Message;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-import reactor.core.publisher.Flux;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * @describe AI对话控制器
- * @Author kai.liu
- * @Date 2025/8/28 10:06
- */
-
-@RestController
-@RequestMapping("/ai")
-public class ChatController {
-
- @Autowired
- private ChatClient chatClient;
-
- @Autowired
- private InMemoryChatMemoryRepository inMemoryChatMemoryRepository;
-
- @RequestMapping(value = "/chat", produces = "text/stream;charset=UTF-8")
- public Flux chat(String prompt, String chatId) {
- return chatClient
- .prompt()
- .user(prompt)
- .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, chatId))
- .stream().content();
- }
-
- @RequestMapping("/history/chat")
- public List history() {
- return inMemoryChatMemoryRepository.findConversationIds();
- }
-
- @RequestMapping("/history/chat/{chatId}")
- public List history(@PathVariable("chatId") String chatId) {
- List messages = inMemoryChatMemoryRepository.findByConversationId(chatId);
- return messages.stream().map(e -> {
- return new MessageDTO(e.getMessageType().getValue(), e.getText());
- }).collect(Collectors.toList());
- }
-}
diff --git a/src/main/java/com/ai/app/controller/DashScopeController.java b/src/main/java/com/ai/app/controller/DashScopeController.java
new file mode 100644
index 0000000..7bbf347
--- /dev/null
+++ b/src/main/java/com/ai/app/controller/DashScopeController.java
@@ -0,0 +1,85 @@
+package com.ai.app.controller;
+
+import com.ai.app.dto.MessageDTO;
+import com.ai.app.service.ChatHistoryService;
+import org.springframework.ai.chat.client.ChatClient;
+import org.springframework.ai.chat.memory.ChatMemory;
+import org.springframework.ai.chat.memory.InMemoryChatMemoryRepository;
+import org.springframework.ai.chat.messages.Message;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import reactor.core.publisher.Flux;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @describe AI对话控制器
+ * @Author kai.liu
+ * @Date 2025/8/28 10:06
+ */
+
+@RestController
+@RequestMapping("/dashscope")
+public class DashScopeController {
+
+ @Autowired
+ @Qualifier("dashScopeChatClient")
+ private ChatClient dashScopeChatClient;
+
+ @Autowired
+ private ChatHistoryService chatHistoryService;
+
+ @Autowired
+ private InMemoryChatMemoryRepository inMemoryChatMemoryRepository;
+
+ /**
+ * 对话聊天
+ *
+ * @param prompt 用户提示词
+ * @param chatId 对话ID
+ * @return: reactor.core.publisher.Flux
+ * @author kai.liu
+ * @date: 2025/9/3 17:30
+ */
+ @RequestMapping(value = "/chat", produces = "text/stream;charset=UTF-8")
+ public Flux chat(String prompt, String chatId) {
+ return dashScopeChatClient
+ .prompt()
+ .user(prompt)
+ .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, chatId))
+ .stream().content();
+ }
+
+ /**
+ * 会话ID列表
+ *
+ * @param type 类型
+ * @return: java.util.List
+ * @author kai.liu
+ * @date: 2025/9/3 17:30
+ */
+ @GetMapping("/getHistoryChatIdList/{type}")
+ public List getHistoryChatIdList(@PathVariable("type") String type) {
+ return chatHistoryService.getHistoryChatIds(type);
+ }
+
+ /**
+ * 会话历史
+ *
+ * @param chatId 会话ID
+ * @return: java.util.List
+ * @author kai.liu
+ * @date: 2025/9/3 17:31
+ */
+ @RequestMapping("/getChatHistory/{type}/{chatId}")
+ public List getChatHistory(@PathVariable("type") String type, @PathVariable("chatId") String chatId) {
+ chatHistoryService.saveHistoryChatId(type, chatId);
+ List messages = inMemoryChatMemoryRepository.findByConversationId(chatId);
+ return messages.stream().map(e -> new MessageDTO(e.getMessageType().getValue(), e.getText())).collect(Collectors.toList());
+ }
+}
diff --git a/src/main/java/com/ai/app/service/ChatHistoryService.java b/src/main/java/com/ai/app/service/ChatHistoryService.java
new file mode 100644
index 0000000..b0eac8e
--- /dev/null
+++ b/src/main/java/com/ai/app/service/ChatHistoryService.java
@@ -0,0 +1,15 @@
+package com.ai.app.service;
+
+import java.util.List;
+
+/**
+ * @describe 对话历史接口定义
+ * @Author kai.liu
+ * @Date 2025/9/3 17:05
+ */
+public interface ChatHistoryService {
+
+ void saveHistoryChatId(String type, String chatId);
+
+ List getHistoryChatIds(String type);
+}
diff --git a/src/main/java/com/ai/app/service/impl/ChatHistoryServiceImpl.java b/src/main/java/com/ai/app/service/impl/ChatHistoryServiceImpl.java
new file mode 100644
index 0000000..973e6b5
--- /dev/null
+++ b/src/main/java/com/ai/app/service/impl/ChatHistoryServiceImpl.java
@@ -0,0 +1,67 @@
+package com.ai.app.service.impl;
+
+import com.ai.app.service.ChatHistoryService;
+import com.ai.app.service.RedisTemplateService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @describe
+ * @Author kai.liu
+ * @Date 2025/9/3 17:05
+ */
+@Slf4j
+@Service
+public class ChatHistoryServiceImpl implements ChatHistoryService {
+
+ @Autowired
+ private RedisTemplateService redisTemplateService;
+
+ public static final String CHAT_TYPE_KEY = "ai:history:type:";
+
+ /**
+ * 保存会话ID
+ *
+ * @param type 类型
+ * @param chatId 会话ID
+ * @return: void
+ * @author kai.liu
+ * @date: 2025/9/3 17:14
+ */
+ @Override
+ public void saveHistoryChatId(String type, String chatId) {
+ String key = CHAT_TYPE_KEY + type;
+ List chatIds;
+ if (redisTemplateService.hasKey(key)) {
+ chatIds = (List) redisTemplateService.get(key);
+ } else {
+ chatIds = new ArrayList<>();
+ }
+ if (chatIds.contains(chatId)) {
+ return;
+ }
+ chatIds.add(chatId);
+ redisTemplateService.set(key, chatIds);
+ }
+
+ /**
+ * 获取历史会话id列表
+ *
+ * @param type 类型
+ * @return: java.util.List
+ * @author kai.liu
+ * @date: 2025/9/3 17:08
+ */
+ @Override
+ public List getHistoryChatIds(String type) {
+ String key = CHAT_TYPE_KEY + type;
+ if (redisTemplateService.hasKey(key)) {
+ return (List) redisTemplateService.get(key);
+ }
+ return List.of();
+ }
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index f101b36..30be96d 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -1,7 +1,7 @@
server:
port: 8080
- # servlet:
- # context-path: /ai
+ servlet:
+ context-path: /ai
tomcat:
# 等待队列长度 (所有线程忙碌时,排队等待的连接数, 默认: 100)
accept-count: 1000
@@ -40,10 +40,15 @@ spring:
max-request-size: 100MB
ai:
deepseek:
- api-key: sk-f970111b34c84a8c812919fb4fad8b65
+ api-key: ${DEEPSEEK_API_KEY}
chat:
options:
- model: deepseek-reasoner
+ model: deepseek-r1
+ dashscope:
+ api-key: ${DASHSCOPE_API_KEY}
+ chat:
+ options:
+ model: qwen-max
data:
redis:
host: 180.76.119.46