From f79b4ec012347ba01daf4e6fa8569a9954e836e1 Mon Sep 17 00:00:00 2001 From: ageerle <32251822+ageerle@users.noreply.github.com> Date: 星期四, 05 六月 2025 13:53:09 +0800 Subject: [PATCH] Merge pull request #114 from Code-Mr-Jiu/jiuyi-dev --- ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/IChatModelService.java | 6 ++ ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/enums/ChatModeType.java | 4 + ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/impl/ChatModelServiceImpl.java | 7 +++ ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/SseServiceImpl.java | 11 +++++ ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ImageOpenAiServiceImpl.java | 75 +++++++++++++++++++++++++++++++++++++ 5 files changed, 100 insertions(+), 3 deletions(-) diff --git a/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/IChatModelService.java b/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/IChatModelService.java index 86eef8d..62dbf97 100644 --- a/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/IChatModelService.java +++ b/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/IChatModelService.java @@ -53,9 +53,13 @@ * 閫氳繃妯″瀷鍚嶇О鑾峰彇妯″瀷淇℃伅 */ ChatModelVo selectModelByName(String modelName); - + /** + * 閫氳繃妯″瀷鍒嗙被鑾峰彇妯″瀷淇℃伅 + */ + ChatModelVo selectModelByCategory(String image); /** * 鑾峰彇ppt妯″瀷淇℃伅 */ ChatModel getPPT(); + } diff --git a/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/impl/ChatModelServiceImpl.java b/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/impl/ChatModelServiceImpl.java index 4c82f3d..d0b5f5c 100644 --- a/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/impl/ChatModelServiceImpl.java +++ b/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/impl/ChatModelServiceImpl.java @@ -129,6 +129,13 @@ public ChatModelVo selectModelByName(String modelName) { return baseMapper.selectVoOne(Wrappers.<ChatModel>lambdaQuery().eq(ChatModel::getModelName, modelName)); } + /** + * 閫氳繃妯″瀷鍒嗙被鑾峰彇妯″瀷淇℃伅 + */ + @Override + public ChatModelVo selectModelByCategory(String category) { + return baseMapper.selectVoOne(Wrappers.<ChatModel>lambdaQuery().eq(ChatModel::getCategory, category)); + } @Override public ChatModel getPPT() { 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 8388ad2..13a39d9 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 @@ -15,7 +15,9 @@ QIANWEN("qianwen", "閫氫箟鍗冮棶"), - VECTOR("vector", "鐭ヨ瘑搴撳悜閲忔ā鍨�"); + VECTOR("vector", "鐭ヨ瘑搴撳悜閲忔ā鍨�"), + + IMAGE("image", "鍥剧墖璇嗗埆妯″瀷"); private final String code; private final String description; diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ImageOpenAiServiceImpl.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ImageOpenAiServiceImpl.java new file mode 100644 index 0000000..11b4c1e --- /dev/null +++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ImageOpenAiServiceImpl.java @@ -0,0 +1,75 @@ +package org.ruoyi.chat.service.chat.impl; + +import io.modelcontextprotocol.client.McpSyncClient; +import lombok.extern.slf4j.Slf4j; +import org.ruoyi.chat.config.ChatConfig; +import org.ruoyi.chat.enums.ChatModeType; +import org.ruoyi.chat.listener.SSEEventSourceListener; +import org.ruoyi.chat.service.chat.IChatService; +import org.ruoyi.common.chat.entity.chat.ChatCompletion; +import org.ruoyi.common.chat.entity.chat.Message; +import org.ruoyi.common.chat.openai.OpenAiStreamClient; +import org.ruoyi.common.chat.request.ChatRequest; +import org.ruoyi.domain.vo.ChatModelVo; +import org.ruoyi.service.IChatModelService; +import org.springframework.ai.chat.client.ChatClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +import java.util.List; + +/** + * 鍥剧墖璇嗗埆妯″瀷 + */ +@Service +@Slf4j +public class ImageOpenAiServiceImpl implements IChatService { + + @Autowired + private IChatModelService chatModelService; + + private final ChatClient chatClient; + + public ImageOpenAiServiceImpl(ChatClient.Builder chatClientBuilder) { + this.chatClient = chatClientBuilder.build(); + } + + @Override + public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) { + // 浠庢暟鎹簱鑾峰彇 image 绫诲瀷鐨勬ā鍨嬮厤缃� + ChatModelVo chatModelVo = chatModelService.selectModelByCategory(ChatModeType.IMAGE.getCode()); + if (chatModelVo == null) { + log.error("鏈壘鍒� image 绫诲瀷鐨勬ā鍨嬮厤缃�"); + emitter.completeWithError(new IllegalStateException("鏈壘鍒� image 绫诲瀷鐨勬ā鍨嬮厤缃�")); + return emitter; + } + + // 鍒涘缓 OpenAI 娴佸鎴风 + OpenAiStreamClient openAiStreamClient = ChatConfig.createOpenAiStreamClient(chatModelVo.getApiHost(), chatModelVo.getApiKey()); + List<Message> messages = chatRequest.getMessages(); + + // 鍒涘缓 SSE 浜嬩欢婧愮洃鍚櫒 + SSEEventSourceListener listener = new SSEEventSourceListener(emitter, chatRequest.getUserId(), chatRequest.getSessionId()); + + // 鏋勫缓鑱婂ぉ瀹屾垚璇锋眰 + ChatCompletion completion = ChatCompletion + .builder() + .messages(messages) + .model(chatModelVo.getModelName()) // 浣跨敤鏁版嵁搴撲腑閰嶇疆鐨勬ā鍨嬪悕绉� + .stream(true) + .build(); + + // 鍙戣捣娴佸紡鑱婂ぉ瀹屾垚璇锋眰 + openAiStreamClient.streamChatCompletion(completion, listener); + + return emitter; + } + + + @Override + public String getCategory() { + return ChatModeType.IMAGE.getCode(); + } +} diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/SseServiceImpl.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/SseServiceImpl.java index 472fd7b..f7dee9a 100644 --- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/SseServiceImpl.java +++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/SseServiceImpl.java @@ -125,7 +125,16 @@ */ private void buildChatMessageList(ChatRequest chatRequest){ String sysPrompt; - chatModelVo = chatModelService.selectModelByName(chatRequest.getModel()); + // 鐭妯″瀷鍚嶇О 濡傛灉鏄痝pt-image 鍒欐煡璇mage绫诲瀷妯″瀷 鑾峰彇妯″瀷鍚嶇О + if(chatRequest.getModel().equals("gpt-image")) { + chatModelVo = chatModelService.selectModelByCategory("image"); + if (chatModelVo == null) { + log.error("鏈壘鍒癷mage绫诲瀷鐨勬ā鍨嬮厤缃�"); + throw new IllegalStateException("鏈壘鍒癷mage绫诲瀷鐨勬ā鍨嬮厤缃�"); + }// chatRequest.setModel(chatModelVo.getModelName()); + }else{ + chatModelVo = chatModelService.selectModelByName(chatRequest.getModel()); + } // 鑾峰彇瀵硅瘽娑堟伅鍒楄〃 List<Message> messages = chatRequest.getMessages(); // 鏌ヨ鍚戦噺搴撶浉鍏充俊鎭姞鍏ュ埌涓婁笅鏂� -- Gitblit v1.9.3