fix: 修复剧本对话创建服务实现问题

- 添加系统欢迎语消息(messageOrder=1, sender=system)
- 调整用户消息顺序为 messageOrder=2
- 添加 AI 助手开场白消息(messageOrder=3, sender=assistant, type=script)
- 从 AI 生成结果中解析标题并更新到剧本实体
- 修复 messageCount 为 3 以匹配实际消息数量
- 删除不再需要的 buildTitle 方法
- 新增 buildSystemWelcome 方法构建系统欢迎语

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-28 17:24:47 +08:00
parent 56369fdeb2
commit 752fd30686
@@ -67,7 +67,7 @@ public class EpicScriptDialogueServiceImpl implements EpicScriptDialogueService
EpicScript script = new EpicScript();
script.setId(scriptId);
script.setUserId(currentUserId);
script.setTitle(buildTitle(request.getTheme()));
script.setTitle("我的人生剧本"); // 默认标题,后续会被 AI 生成的标题覆盖
script.setTheme(request.getTheme());
script.setStyle(StringUtils.hasText(request.getStyle()) ? request.getStyle() : "career");
script.setLength(StringUtils.hasText(request.getLength()) ? request.getLength() : "medium");
@@ -90,7 +90,41 @@ public class EpicScriptDialogueServiceImpl implements EpicScriptDialogueService
conversation.setMessageCount(0);
conversationService.save(conversation);
// 3. 保存用户消息
// 3. 调用 AI 生成完整剧本
String aiOutput = invokeScriptGenerate(request, currentUserId, conversationId, null);
// 4. 解析 AI 输出获取剧本元数据
Map<String, Object> metadata = parseScriptOutput(aiOutput);
// 从 AI 输出中提取标题,如果没有则使用默认值
String aiTitle = (String) metadata.getOrDefault("title", null);
if (StringUtils.hasText(aiTitle)) {
script.setTitle(aiTitle);
}
script.setPlotIntro((String) metadata.getOrDefault("plotIntro", ""));
script.setPlotTurning((String) metadata.getOrDefault("plotTurning", ""));
script.setPlotClimax((String) metadata.getOrDefault("plotClimax", ""));
script.setPlotEnding((String) metadata.getOrDefault("plotEnding", ""));
Map<String, Object> plotJson = script.getPlotJson();
plotJson.putAll(metadata);
script.setPlotJson(plotJson);
// 5. 创建系统欢迎消息(messageOrder = 1
Message systemWelcome = new Message();
systemWelcome.setId(snowflakeIdGenerator.nextIdAsString());
systemWelcome.setConversationId(conversationId);
systemWelcome.setScriptId(scriptId);
systemWelcome.setUserId(currentUserId);
systemWelcome.setContent(buildSystemWelcome(metadata));
systemWelcome.setType("system");
systemWelcome.setSender("system");
systemWelcome.setTimestamp(now);
systemWelcome.setMessageOrder(1L);
systemWelcome.setStatus("sent");
systemWelcome.setIsRead(1);
messageService.createMessage(systemWelcome);
// 6. 创建用户消息(messageOrder = 2
Message userMessage = new Message();
userMessage.setId(snowflakeIdGenerator.nextIdAsString());
userMessage.setConversationId(conversationId);
@@ -100,51 +134,38 @@ public class EpicScriptDialogueServiceImpl implements EpicScriptDialogueService
userMessage.setType("chat");
userMessage.setSender("user");
userMessage.setTimestamp(now);
userMessage.setMessageOrder(1L);
userMessage.setMessageOrder(2L);
userMessage.setStatus("sent");
userMessage.setIsRead(1);
messageService.createMessage(userMessage);
// 4. 调用 AI 生成完整剧本
String aiOutput = invokeScriptGenerate(request, currentUserId, conversationId, userMessage.getId());
// 5. 解析并保存 AI 剧本消息
Map<String, Object> metadata = parseScriptOutput(aiOutput);
String content = buildDisplayContent(metadata);
// 7. 创建 AI 助手开场白消息(messageOrder = 3
String aiContent = buildDisplayContent(metadata);
Message aiMessage = new Message();
aiMessage.setId(snowflakeIdGenerator.nextIdAsString());
aiMessage.setConversationId(conversationId);
aiMessage.setScriptId(scriptId);
aiMessage.setUserId(currentUserId);
aiMessage.setContent(content);
aiMessage.setContent(aiContent);
aiMessage.setType("script");
aiMessage.setSender("assistant");
aiMessage.setTimestamp(LocalDateTime.now());
aiMessage.setMessageOrder(2L);
aiMessage.setMessageOrder(3L);
aiMessage.setVersionNumber(1);
aiMessage.setStatus("sent");
aiMessage.setMetadata(JSON.toJSONString(metadata));
messageService.createMessage(aiMessage);
// 6. 更新剧本快照
// 8. 更新剧本信息(已在前面完成)
script.setCurrentVersionMessageId(aiMessage.getId());
script.setTitle((String) metadata.getOrDefault("title", script.getTitle()));
script.setPlotIntro((String) metadata.getOrDefault("plotIntro", ""));
script.setPlotTurning((String) metadata.getOrDefault("plotTurning", ""));
script.setPlotClimax((String) metadata.getOrDefault("plotClimax", ""));
script.setPlotEnding((String) metadata.getOrDefault("plotEnding", ""));
Map<String, Object> plotJson = script.getPlotJson();
plotJson.putAll(metadata);
script.setPlotJson(plotJson);
epicScriptService.updateById(script);
// 7. 更新对话当前消息
// 9. 更新对话当前消息和消息计数
conversation.setCurrentMessageId(aiMessage.getId());
conversation.setMessageCount(2);
conversation.setMessageCount(3);
conversationService.updateById(conversation);
// 8. 构建响应
// 10. 构建响应
EpicScriptCreateWithDialogueResponse response = new EpicScriptCreateWithDialogueResponse();
BeanUtils.copyProperties(script, response);
response.setScriptId(scriptId);
@@ -153,13 +174,6 @@ public class EpicScriptDialogueServiceImpl implements EpicScriptDialogueService
return response;
}
private String buildTitle(String theme) {
if (!StringUtils.hasText(theme)) {
return "我的人生剧本";
}
return theme.length() > 20 ? theme.substring(0, 20) + "..." : theme;
}
private String invokeScriptGenerate(EpicScriptCreateWithDialogueRequest request, String userId,
String conversationId, String userMessageId) {
JSONObject inputs = new JSONObject();
@@ -213,6 +227,18 @@ public class EpicScriptDialogueServiceImpl implements EpicScriptDialogueService
return sb.toString();
}
private String buildSystemWelcome(Map<String, Object> metadata) {
if (metadata == null || metadata.isEmpty()) {
return "欢迎来到情绪博物馆,让我们一起探索你的内心世界。";
}
String title = (String) metadata.getOrDefault("title", "我的人生剧本");
StringBuilder sb = new StringBuilder();
sb.append("欢迎来到《").append(title).append("》剧本世界。\n\n");
sb.append("在这里,你将体验一段关于");
sb.append(metadata.getOrDefault("plotIntro", "情感探索")).append("的旅程。");
return sb.toString();
}
private void appendSection(StringBuilder sb, Object value, String label) {
if (value == null) {
return;