feat(service): 新增 WebSocket 实时语音转写与流式 TTS 全流程

This commit is contained in:
2026-01-23 14:25:05 +08:00
parent 8632dcd282
commit bb3dcc56ff
6 changed files with 79 additions and 1 deletions

7
.gitignore vendored
View File

@@ -39,3 +39,10 @@ build/
/.dockerignore /.dockerignore
/Dockerfile /Dockerfile
/.claude/ralph-loop.local.md /.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

View File

@@ -108,7 +108,8 @@ public class SaTokenConfigure implements WebMvcConfigurer {
"/user/bindInviteCode", "/user/bindInviteCode",
"/themes/listAllStyles", "/themes/listAllStyles",
"/wallet/transactions", "/wallet/transactions",
"/themes/restore" "/themes/restore",
"/chat/message"
}; };
} }
@Bean @Bean

View File

@@ -45,6 +45,20 @@ public class ChatController {
private ChatService chatService; private ChatService chatService;
@PostMapping("/message")
@Operation(summary = "同步对话", description = "发送消息给大模型,同步返回回复")
public BaseResponse<String> 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") @PostMapping("/talk")
@Operation(summary = "聊天润色接口", description = "聊天润色接口") @Operation(summary = "聊天润色接口", description = "聊天润色接口")
public Flux<ServerSentEvent<ChatStreamMessage>> talk(@RequestBody ChatReq chatReq){ public Flux<ServerSentEvent<ChatStreamMessage>> talk(@RequestBody ChatReq chatReq){

View File

@@ -11,4 +11,13 @@ import reactor.core.publisher.Flux;
*/ */
public interface ChatService { public interface ChatService {
Flux<ServerSentEvent<ChatStreamMessage>> talk(ChatReq chatReq); Flux<ServerSentEvent<ChatStreamMessage>> talk(ChatReq chatReq);
/**
* 同步对话
*
* @param content 用户消息内容
* @param userId 用户ID
* @return AI 响应
*/
String message(String content, String userId);
} }

View File

@@ -321,4 +321,42 @@ public class ChatServiceImpl implements ChatService {
.build() .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;
}
} }

View File

@@ -68,6 +68,15 @@ dromara:
bucket-name: keyborad-resource #桶名称 bucket-name: keyborad-resource #桶名称
domain: https://resource.loveamorkey.com/ # 访问域名,注意末尾的'/'例如https://abcd.s3.ap-east-1.amazonaws.com/ domain: https://resource.loveamorkey.com/ # 访问域名,注意末尾的'/'例如https://abcd.s3.ap-east-1.amazonaws.com/
base-path: avatar/ # 基础路径 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 配置 (参考文档: https://sa-token.cc) ##############
sa-token: sa-token: