From 97ae5a46cd54b2d5b10fca6a69c04874002162b0 Mon Sep 17 00:00:00 2001 From: ageerle <ageerle@163.com> Date: 星期四, 05 六月 2025 16:16:32 +0800 Subject: [PATCH] feat: 调整sql脚本 --- ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ImageServiceImpl.java | 151 +++++++++++++++++++++++++++++++++++++ script/sql/ruoyi-ai.sql | 4 script/sql/update/20250605.sql | 1 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/QianWenAiChatServiceImpl.java | 2 ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/SseServiceImpl.java | 11 ++ 8 files changed, 181 insertions(+), 5 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/ImageServiceImpl.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ImageServiceImpl.java new file mode 100644 index 0000000..a7eee8e --- /dev/null +++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ImageServiceImpl.java @@ -0,0 +1,151 @@ +package org.ruoyi.chat.service.chat.impl; + +import lombok.SneakyThrows; +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.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +import java.util.*; + +/** + * 鍥剧墖璇嗗埆妯″瀷 + */ +@Service +@Slf4j +public class ImageServiceImpl implements IChatService { + + @Autowired + private IChatModelService chatModelService; + + @SneakyThrows +// @Override +// public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) { +// ChatModelVo chatModelVo = chatModelService.selectModelByCategory("image"); +// +// // 鍙戦�佹祦寮忔秷鎭� +// +// MultiModalConversation conv = new MultiModalConversation(); +// MultiModalMessage systemMessage = MultiModalMessage.builder().role(Role.SYSTEM.getValue()) +// .content(Arrays.asList( +// Collections.singletonMap("text",chatRequest.getSysPrompt()))).build(); +// // 鑾峰彇鐢ㄦ埛娑堟伅鍐呭 +// List<Message> messages = chatRequest.getMessages(); +// MultiModalMessage userMessage = null; +// //婕暱鐨勬牸寮忚浆鎹� +// // 閬嶅巻娑堟伅鍒楄〃锛屾彁鍙栨枃鏈唴瀹� +// if (messages != null && !messages.isEmpty()) { +// Object content = messages.get(messages.size() - 1).getContent(); +// List<Map<String, Object>> contentList = new ArrayList<>(); +// StringBuilder textContent = new StringBuilder(); +// if (content instanceof List<?>) { +// for (Object item : (List<?>) content) { +// if (item instanceof Map<?, ?> mapItem) { +// String type = (String) mapItem.get("type"); +// if ("text".equals(type)) { +// String text = (String) mapItem.get("text"); +// if (text != null) { +// textContent.append(text).append(" "); +// } +// } else if ("image_url".equals(type)) { +// Map<String, String> imageUrl = (Map<String, String>) mapItem.get("image_url"); +// contentList.add(Collections.singletonMap("image", imageUrl.get("url"))); +// } +// } +// } +// } +// // 灏嗘嫾鎺ュ悗鐨勬枃鏈唴瀹规坊鍔犲埌 contentList +// if (textContent.length() > 0) { +// contentList.add(Collections.singletonMap("text", textContent.toString().trim())); +// } +// userMessage = MultiModalMessage.builder() +// .role(Role.USER.getValue()) +// .content(contentList) +// .build(); +// } +// MultiModalConversationParam param = MultiModalConversationParam.builder() +// .apiKey(chatModelVo.getApiKey()) +// .model(chatModelVo.getModelName()) +// .messages(Arrays.asList(systemMessage, userMessage)) +// .incrementalOutput(true) +// .build(); +// +// +// try { +// final QwenStreamingResponseBuilder responseBuilder = new QwenStreamingResponseBuilder(param.getModel(),param.getIncrementalOutput() ); +// conv.streamCall(param, new ResultCallback<>() { +// @SneakyThrows +// public void onEvent(MultiModalConversationResult result) { +// +// String delta = responseBuilder.append(result); +// if (Utils.isNotNullOrEmpty(delta)) { +// +// emitter.send(delta); +// log.info("鏀跺埌娑堟伅鐗囨: {}", delta); +// } +// } +// public void onComplete() { +// emitter.complete(); +// log.info("娑堟伅缁撴潫", responseBuilder.build()); +// } +// public void onError(Exception e) { +// log.info("璇锋眰澶辫触", e.getMessage()); +// } +// }); +// } catch (NoApiKeyException e) { +// emitter.send("璇峰厛閰嶇疆API瀵嗛挜"); +// throw new RuntimeException(e); +// } catch (UploadFileException e) { +// throw new RuntimeException(e); +// } +// +// +// return emitter; +// } + + @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/QianWenAiChatServiceImpl.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/QianWenAiChatServiceImpl.java index 1d6e061..850ebf6 100644 --- 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 @@ -35,6 +35,8 @@ .modelName(chatModelVo.getModelName()) .build(); + + // 鍙戦�佹祦寮忔秷鎭� try { model.chat(chatRequest.getPrompt(), new StreamingChatResponseHandler() { 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..d8c61a9 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绫诲瀷鐨勬ā鍨嬮厤缃�"); + } + }else{ + chatModelVo = chatModelService.selectModelByName(chatRequest.getModel()); + } // 鑾峰彇瀵硅瘽娑堟伅鍒楄〃 List<Message> messages = chatRequest.getMessages(); // 鏌ヨ鍚戦噺搴撶浉鍏充俊鎭姞鍏ュ埌涓婁笅鏂� diff --git a/script/sql/ruoyi-ai.sql b/script/sql/ruoyi-ai.sql index ed5eb31..f4356fd 100644 --- a/script/sql/ruoyi-ai.sql +++ b/script/sql/ruoyi-ai.sql @@ -132,8 +132,8 @@ INSERT INTO `chat_model` VALUES (1828324413241466881, '000000', 'vector', 'baai/bge-m3', 'baai/bge-m3', 0.01, '2', '1', NULL, 'https://api.ppinfra.com/v3/openai', 'sk-xx', NULL, 103, 1, '2024-08-27 14:51:23', 1, '2025-05-24 17:33:11', 'BGE-M3 鏄竴娆惧叿澶囧缁村害鑳藉姏鐨勬枃鏈祵鍏ユā鍨嬶紝鍙悓鏃跺疄鐜板瘑闆嗘绱€�佸鍚戦噺妫�绱㈠拰绋�鐤忔绱笁澶ф牳蹇冨姛鑳姐�傝妯″瀷璁捐涓婂吋瀹硅秴杩�100绉嶈瑷�锛屽苟鏀寔浠庣煭鍙ュ埌闀胯揪8192璇嶅厓鐨勯暱鏂囨湰绛夊绉嶈緭鍏ュ舰寮忋�傚湪璺ㄨ瑷�妫�绱换鍔′腑锛孊GE-M3灞曠幇鍑烘樉钁椾紭鍔匡紝鍏舵�ц兘鍦∕IRACL銆丮KQA绛夊浗闄呭熀鍑嗘祴璇曚腑浣嶅眳鍓嶅垪銆傛澶栵紝閽堝闀挎枃妗f绱㈠満鏅紝璇ユā鍨嬪湪MLDR銆丯arritiveQA绛夋暟鎹泦涓婄殑琛ㄧ幇鍚屾牱杈惧埌琛屼笟棰嗗厛姘村钩銆�'); INSERT INTO `chat_model` VALUES (1859570229117022211, '000000', 'chat', 'deepseek/deepseek-v3-0324', 'deepseek/deepseek-v3-0324', 0.1, '1', '0', '', 'https://api.ppinfra.com/v3/openai/chat/completions', 'sk-xx', NULL, 103, 1, '2024-11-21 20:11:06', 1, '2025-05-24 17:56:22', 'DeepSeek V3 0324 鏄繁搴︽眰绱紙DeepSeek锛夊洟闃熸棗鑸扮骇瀵硅瘽妯″瀷绯诲垪鐨勬渶鏂扮増鏈紝閲囩敤娣峰悎涓撳锛圡ixture-of-Experts, MoE锛夋灦鏋勶紝鍙傛暟閲忚揪685B鍙傛暟銆�'); INSERT INTO `chat_model` VALUES (1859570229117022212, '000000', 'chat', 'deepseek/deepseek-r1', 'deepseek/deepseek-r1', 0.1, '1', '0', '', 'https://api.ppinfra.com/v3/openai/chat/completions', 'sk-xx', NULL, 103, 1, '2024-11-21 20:11:06', 1, '2025-05-24 17:56:14', 'DeepSeek R1鏄疍eepSeek鍥㈤槦鍙戝竷鐨勬渶鏂板紑婧愭ā鍨嬶紝鍏峰闈炲父寮烘倣鐨勬帹鐞嗘�ц兘锛屽挨鍏跺湪鏁板銆佺紪绋嬪拰鎺ㄧ悊浠诲姟涓婅揪鍒颁簡涓嶰penAI鐨刼1妯″瀷鐩稿綋鐨勬按骞炽��'); -INSERT INTO `chat_model` VALUES (1926215622017482754, '000000', 'chat', 'gpt-4o-mini', 'gpt-4o-mini', 0.1, '1', '0', NULL, 'https://api.pandarobot.chat/v1/chat/completions/', 'sk-xx', NULL, 103, 1, '2025-05-24 17:56:06', 1, '2025-05-24 17:56:06', 'gpt 澶氭ā鎬佹ā鍨�'); -INSERT INTO `chat_model` VALUES (1926215622017482755, '000000', 'chat', 'gpt-4-all', 'gpt-4-all', 0.5, '2', '0', NULL, 'https://api.pandarobot.chat/v1/chat/completions/', 'sk-xx', NULL, 103, 1, '2025-05-24 17:56:06', 1, '2025-05-24 17:59:21', 'gpt 閫嗗悜澶氭ā鎬佹ā鍨�'); +INSERT INTO `chat_model` VALUES (1930184891812147202, '000000', 'image', 'qwen/qwen2.5-vl-72b-instruct', 'qwen/qwen2.5-vl-72b-instruct', 0.003, '2', '0', NULL, 'https://api.ppinfra.com/v3/openai/chat/completions', 'xx', NULL, 103, 1, '2025-06-04 16:48:34', 1, '2025-06-04 16:48:34', '瑙嗚妯″瀷'); + -- ---------------------------- -- Table structure for chat_pay_order diff --git a/script/sql/update/20250605.sql b/script/sql/update/20250605.sql new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/script/sql/update/20250605.sql @@ -0,0 +1 @@ + -- Gitblit v1.9.3