feat: 实现剧本消息版本管理服务

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-28 17:42:11 +08:00
parent e252dc5fd2
commit b11a3463b2
@@ -0,0 +1,144 @@
package com.emotion.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.emotion.dto.response.MessageResponse;
import com.emotion.entity.Conversation;
import com.emotion.entity.EpicScript;
import com.emotion.entity.Message;
import com.emotion.service.ConversationService;
import com.emotion.service.EpicScriptService;
import com.emotion.service.MessageService;
import com.emotion.service.ScriptMessageService;
import com.emotion.util.UserContextHolder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 剧本消息版本管理服务实现
*/
@Service
public class ScriptMessageServiceImpl implements ScriptMessageService {
@Autowired
private MessageService messageService;
@Autowired
private ConversationService conversationService;
@Autowired
private EpicScriptService epicScriptService;
@Override
public List<MessageResponse> listByConversation(String conversationId, boolean includeVersions) {
String currentUserId = UserContextHolder.getCurrentUserId();
Conversation conversation = conversationService.getById(conversationId);
if (conversation == null || !conversation.getUserId().equals(currentUserId)) {
throw new IllegalStateException("对话不存在或无权限");
}
LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Message::getConversationId, conversationId);
if (!includeVersions) {
// 只返回当前生效版本链上的消息:parent_message_id 为空的 script 消息 + 所有 chat 消息
wrapper.and(w -> w.isNull(Message::getParentMessageId).or().ne(Message::getType, "script"));
}
wrapper.orderByAsc(Message::getMessageOrder);
List<Message> messages = messageService.list(wrapper);
return messages.stream().map(this::convertToResponse).collect(Collectors.toList());
}
@Override
public List<MessageResponse> getVersions(String messageId) {
String currentUserId = UserContextHolder.getCurrentUserId();
Message message = messageService.getById(messageId);
if (message == null) {
throw new IllegalStateException("消息不存在");
}
Conversation conversation = conversationService.getById(message.getConversationId());
if (conversation == null || !conversation.getUserId().equals(currentUserId)) {
throw new IllegalStateException("无权限");
}
// 找到根消息
String rootId = message.getParentMessageId() == null ? message.getId() : message.getParentMessageId();
Message root = messageService.getById(rootId);
LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Message::getParentMessageId, rootId)
.orderByAsc(Message::getVersionNumber);
List<Message> versions = messageService.list(wrapper);
List<MessageResponse> result = new ArrayList<>();
if (root != null) {
result.add(convertToResponse(root));
}
result.addAll(versions.stream().map(this::convertToResponse).collect(Collectors.toList()));
return result;
}
@Override
public boolean deleteVersion(String messageId) {
String currentUserId = UserContextHolder.getCurrentUserId();
Message message = messageService.getById(messageId);
if (message == null) {
throw new IllegalStateException("消息不存在");
}
Conversation conversation = conversationService.getById(message.getConversationId());
if (conversation == null || !conversation.getUserId().equals(currentUserId)) {
throw new IllegalStateException("无权限");
}
EpicScript script = epicScriptService.getById(conversation.getScriptId());
if (script == null) {
throw new IllegalStateException("剧本不存在");
}
// 不能删除当前生效版本
if (messageId.equals(script.getCurrentVersionMessageId())) {
throw new IllegalStateException("不能删除当前生效版本");
}
// 不能删除有子版本的父消息
if (message.getParentMessageId() == null) {
LambdaQueryWrapper<Message> childWrapper = new LambdaQueryWrapper<>();
childWrapper.eq(Message::getParentMessageId, messageId);
long childCount = messageService.count(childWrapper);
if (childCount > 0) {
throw new IllegalStateException("不能删除有子版本的父消息");
}
}
String parentId = message.getParentMessageId();
boolean removed = messageService.removeById(messageId);
if (!removed) {
return false;
}
// 重新计算同一 parent 下剩余版本的 version_number
if (StringUtils.hasText(parentId)) {
LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Message::getParentMessageId, parentId)
.orderByAsc(Message::getMessageOrder);
List<Message> siblings = messageService.list(wrapper);
for (int i = 0; i < siblings.size(); i++) {
Message sibling = siblings.get(i);
sibling.setVersionNumber(i + 2);
messageService.updateById(sibling);
}
}
return true;
}
private MessageResponse convertToResponse(Message message) {
MessageResponse response = new MessageResponse();
BeanUtils.copyProperties(message, response);
response.setId(message.getId());
return response;
}
}