feat: AI 场景路由、ASR 服务及前后端全链路同步

- 新增 AI 场景路由控制器和管理接口
- 新增 ASR 语音识别服务及前后端集成
- 同步 AI Runtime 客户端到 Web/小程序/Life-Script
- 完善 AI 配置测试修复和管理后台路由配置
- 新增数据库迁移脚本

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-23 13:25:21 +08:00
parent d77090aa5e
commit 89fc42819d
72 changed files with 4584 additions and 383 deletions
@@ -10,6 +10,7 @@ import org.junit.jupiter.api.RepeatedTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.util.AopTestUtils;
import java.lang.reflect.Method;
import java.util.HashMap;
@@ -35,6 +36,8 @@ public class CozeWorkflowIntegrationTest {
@Autowired
private AiChatService aiChatService;
private AiChatServiceImpl aiChatServiceImpl;
@Autowired
private AiConfigService aiConfigService;
@@ -49,6 +52,7 @@ public class CozeWorkflowIntegrationTest {
@BeforeEach
public void setUp() {
random = new Random();
aiChatServiceImpl = AopTestUtils.getTargetObject(aiChatService);
}
// ==================== Property 1: Request Format Correctness ====================
@@ -82,7 +86,7 @@ public class CozeWorkflowIntegrationTest {
@SuppressWarnings("unchecked")
Map<String, Object> requestBody = (Map<String, Object>) buildWorkflowRequestMethod.invoke(
aiChatService, config, parameters, userId);
aiChatServiceImpl, config, parameters, userId);
// 验证必需字段
// 2.1: workflow_id - 应该与数据库配置一致
@@ -155,7 +159,7 @@ public class CozeWorkflowIntegrationTest {
parseMethod.setAccessible(true);
java.util.stream.Stream<String> lines = sseResponse.lines();
String result = (String) parseMethod.invoke(aiChatService, lines);
String result = (String) parseMethod.invoke(aiChatServiceImpl, lines);
// 验证正确提取output内容
assertEquals("这是AI生成的内容", result,
@@ -184,7 +188,7 @@ public class CozeWorkflowIntegrationTest {
parseMethod.setAccessible(true);
java.util.stream.Stream<String> lines = sseResponse.lines();
String result = (String) parseMethod.invoke(aiChatService, lines);
String result = (String) parseMethod.invoke(aiChatServiceImpl, lines);
// 验证正确提取随机output内容
assertEquals(randomOutput, result,
@@ -218,7 +222,7 @@ public class CozeWorkflowIntegrationTest {
parseMethod.setAccessible(true);
java.util.stream.Stream<String> lines = sseResponse.lines();
String result = (String) parseMethod.invoke(aiChatService, lines);
String result = (String) parseMethod.invoke(aiChatServiceImpl, lines);
// 验证只提取End节点的内容
assertEquals("最终输出内容", result,
@@ -244,7 +248,7 @@ public class CozeWorkflowIntegrationTest {
parseMethod.setAccessible(true);
java.util.stream.Stream<String> lines = sseResponse.lines();
String result = (String) parseMethod.invoke(aiChatService, lines);
String result = (String) parseMethod.invoke(aiChatServiceImpl, lines);
// 当content不是JSON或没有output字段时,应返回原始content
assertEquals("直接内容,没有output字段", result,
@@ -276,7 +280,7 @@ public class CozeWorkflowIntegrationTest {
@SuppressWarnings("unchecked")
Map<String, Object> mergedParams = (Map<String, Object>) mergeMethod.invoke(
aiChatService, config, runtimeParams);
aiChatServiceImpl, config, runtimeParams);
// 验证运行时参数被正确设置
assertEquals(runtimeInput, mergedParams.get("input"),
@@ -295,7 +299,7 @@ public class CozeWorkflowIntegrationTest {
extractMethod.setAccessible(true);
String content = "{\"output\":\"提取的内容\"}";
String result = (String) extractMethod.invoke(aiChatService, content);
String result = (String) extractMethod.invoke(aiChatServiceImpl, content);
assertEquals("提取的内容", result, "应正确提取output字段");
}
@@ -308,7 +312,7 @@ public class CozeWorkflowIntegrationTest {
extractMethod.setAccessible(true);
String content = "这不是JSON内容";
String result = (String) extractMethod.invoke(aiChatService, content);
String result = (String) extractMethod.invoke(aiChatServiceImpl, content);
assertEquals("这不是JSON内容", result, "非JSON内容应原样返回");
}
@@ -324,7 +328,7 @@ public class CozeWorkflowIntegrationTest {
String randomOutput = "随机输出_" + UUID.randomUUID().toString();
String content = "{\"output\":\"" + randomOutput + "\"}";
String result = (String) extractMethod.invoke(aiChatService, content);
String result = (String) extractMethod.invoke(aiChatServiceImpl, content);
assertEquals(randomOutput, result, "应正确提取随机生成的output内容");
}