From bb3dcc56ff3032f2c0d14cf59e687b5c44c8a271 Mon Sep 17 00:00:00 2001 From: ziin Date: Fri, 23 Jan 2026 14:25:05 +0800 Subject: [PATCH] =?UTF-8?q?feat(service):=20=E6=96=B0=E5=A2=9E=20WebSocket?= =?UTF-8?q?=20=E5=AE=9E=E6=97=B6=E8=AF=AD=E9=9F=B3=E8=BD=AC=E5=86=99?= =?UTF-8?q?=E4=B8=8E=E6=B5=81=E5=BC=8F=20TTS=20=E5=85=A8=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 7 ++++ .../keyborad/config/SaTokenConfigure.java | 3 +- .../keyborad/controller/ChatController.java | 14 +++++++ .../yolo/keyborad/service/ChatService.java | 9 +++++ .../service/impl/ChatServiceImpl.java | 38 +++++++++++++++++++ src/main/resources/application-dev.yml | 9 +++++ 6 files changed, 79 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 20a41f6..094988c 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,10 @@ build/ /.dockerignore /Dockerfile /.claude/ralph-loop.local.md +/deepgramAPI.md +/elevenLabs-websocketAPI.md +/elevenlabsAPI.md +/Getting Started with Flux.md +/voice-optimization-plan.md +/docs/websocket-api.md +/src/main/resources/static/ws-test.html diff --git a/src/main/java/com/yolo/keyborad/config/SaTokenConfigure.java b/src/main/java/com/yolo/keyborad/config/SaTokenConfigure.java index 5aad99c..0a61750 100644 --- a/src/main/java/com/yolo/keyborad/config/SaTokenConfigure.java +++ b/src/main/java/com/yolo/keyborad/config/SaTokenConfigure.java @@ -108,7 +108,8 @@ public class SaTokenConfigure implements WebMvcConfigurer { "/user/bindInviteCode", "/themes/listAllStyles", "/wallet/transactions", - "/themes/restore" + "/themes/restore", + "/chat/message" }; } @Bean diff --git a/src/main/java/com/yolo/keyborad/controller/ChatController.java b/src/main/java/com/yolo/keyborad/controller/ChatController.java index 644645a..2ffe6c7 100644 --- a/src/main/java/com/yolo/keyborad/controller/ChatController.java +++ b/src/main/java/com/yolo/keyborad/controller/ChatController.java @@ -45,6 +45,20 @@ public class ChatController { private ChatService chatService; + @PostMapping("/message") + @Operation(summary = "同步对话", description = "发送消息给大模型,同步返回回复") + public BaseResponse message(@RequestParam("content") String content) { + if (StrUtil.isBlank(content)) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "消息内容不能为空"); + } + + String userId = StpUtil.getLoginIdAsString(); + String response = chatService.message(content, userId); + + return ResultUtils.success(response); + } + + @PostMapping("/talk") @Operation(summary = "聊天润色接口", description = "聊天润色接口") public Flux> talk(@RequestBody ChatReq chatReq){ diff --git a/src/main/java/com/yolo/keyborad/service/ChatService.java b/src/main/java/com/yolo/keyborad/service/ChatService.java index 95e0f1f..fb2cd8d 100644 --- a/src/main/java/com/yolo/keyborad/service/ChatService.java +++ b/src/main/java/com/yolo/keyborad/service/ChatService.java @@ -11,4 +11,13 @@ import reactor.core.publisher.Flux; */ public interface ChatService { Flux> talk(ChatReq chatReq); + + /** + * 同步对话 + * + * @param content 用户消息内容 + * @param userId 用户ID + * @return AI 响应 + */ + String message(String content, String userId); } diff --git a/src/main/java/com/yolo/keyborad/service/impl/ChatServiceImpl.java b/src/main/java/com/yolo/keyborad/service/impl/ChatServiceImpl.java index 1ede63d..d95f9d5 100644 --- a/src/main/java/com/yolo/keyborad/service/impl/ChatServiceImpl.java +++ b/src/main/java/com/yolo/keyborad/service/impl/ChatServiceImpl.java @@ -321,4 +321,42 @@ public class ChatServiceImpl implements ChatService { .build() ); } + + /** + * 同步对话 + * + * @param content 用户消息内容 + * @param userId 用户ID + * @return AI 响应 + */ + @Override + public String message(String content, String userId) { + log.info("同步对话请求, userId: {}, content: {}", userId, content); + + long startTime = System.currentTimeMillis(); + + String systemPrompt = """ + ROLE: You are "Tiffany", a 17-year-old popular high school student from Beverly Hills. + You are sassy, judgmental, impatient, but secretly caring. + + TASK: Generate dialogue scripts optimized for ElevenLabs TTS. + Use emotional cues in brackets like [sighs], [giggles], [scoffs], [whispers], [yells]. + Use punctuation for tone: ... for hesitation, ! for energy. + Use fillers naturally: "like", "literally", "omg". + + Keep responses concise (2-3 sentences max) for real-time conversation. + """; + + String response = client + .prompt() + .system(systemPrompt) + .user(content) + .call() + .content(); + + long duration = System.currentTimeMillis() - startTime; + log.info("同步对话完成, userId: {}, 耗时: {}ms, 响应长度: {}", userId, duration, response.length()); + + return response; + } } diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 84baf41..730aa3d 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -68,6 +68,15 @@ dromara: bucket-name: keyborad-resource #桶名称 domain: https://resource.loveamorkey.com/ # 访问域名,注意末尾的'/',例如:https://abcd.s3.ap-east-1.amazonaws.com/ base-path: avatar/ # 基础路径 + - platform: cloudflare-r2-apac # 存储平台标识 + enable-storage: true # 启用存储 + access-key: 550b33cc4d53e05c2e438601f8a0e209 + secret-key: df4d529cdae44e6f614ca04f4dc0f1f9a299e57367181243e8abdc7f7c28e99a + region: APAC # 区域 + end-point: https://b632a61caa85401f63c9b32eef3a74c8.r2.cloudflarestorage.com/keyboardtest # 端点 + bucket-name: keyboardtest #桶名称 + domain: https://cdn.loveamorkey.com/ # 访问域名,注意末尾的'/',例如:https://abcd.s3.ap-east-1.amazonaws.com/ + base-path: / # 基础路径 ############## Sa-Token 配置 (参考文档: https://sa-token.cc) ############## sa-token: