feat: 实现剧本消息版本管理服务
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user