package com.xuqm.im.service; import com.xuqm.im.entity.ImConversationStateEntity; import com.xuqm.im.repository.ImConversationStateRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; import java.util.Collection; import java.util.List; import java.util.UUID; @Service public class ConversationStateService { private final ImConversationStateRepository repository; public ConversationStateService(ImConversationStateRepository repository) { this.repository = repository; } @Transactional public ImConversationStateEntity setPinned(String appId, String userId, String targetId, String chatType, boolean pinned) { ImConversationStateEntity state = getOrCreate(appId, userId, targetId, chatType); state.setPinned(pinned); touch(state); return repository.save(state); } @Transactional public ImConversationStateEntity setMuted(String appId, String userId, String targetId, String chatType, boolean muted) { ImConversationStateEntity state = getOrCreate(appId, userId, targetId, chatType); state.setMuted(muted); touch(state); return repository.save(state); } @Transactional public ImConversationStateEntity markRead(String appId, String userId, String targetId, String chatType) { ImConversationStateEntity state = getOrCreate(appId, userId, targetId, chatType); state.setLastReadAt(LocalDateTime.now()); state.setHidden(false); touch(state); return repository.save(state); } @Transactional public ImConversationStateEntity setDraft(String appId, String userId, String targetId, String chatType, String draft) { ImConversationStateEntity state = getOrCreate(appId, userId, targetId, chatType); state.setDraft(draft); touch(state); return repository.save(state); } @Transactional public ImConversationStateEntity hideConversation(String appId, String userId, String targetId, String chatType) { ImConversationStateEntity state = getOrCreate(appId, userId, targetId, chatType); state.setHidden(true); state.setDraft(null); touch(state); return repository.save(state); } @Transactional public void deleteConversationState(String appId, String userId, String targetId, String chatType) { repository.deleteByAppIdAndUserIdAndTargetIdAndChatType(appId, userId, targetId, chatType); } @Transactional public void deleteConversation(String appId, String userId, String targetId, String chatType, boolean syncAcrossClients) { if (syncAcrossClients) { deleteConversationState(appId, userId, targetId, chatType); return; } hideConversation(appId, userId, targetId, chatType); } @Transactional public void clearHiddenForUsers(String appId, String targetId, String chatType, Collection userIds) { for (String userId : userIds) { ImConversationStateEntity state = repository .findByAppIdAndUserIdAndTargetIdAndChatType(appId, userId, targetId, chatType) .orElse(null); if (state != null && state.isHidden()) { state.setHidden(false); touch(state); repository.save(state); } } } public ImConversationStateEntity getOrCreate(String appId, String userId, String targetId, String chatType) { return repository.findByAppIdAndUserIdAndTargetIdAndChatType(appId, userId, targetId, chatType) .orElseGet(() -> { ImConversationStateEntity entity = new ImConversationStateEntity(); entity.setId(UUID.randomUUID().toString()); entity.setAppId(appId); entity.setUserId(userId); entity.setTargetId(targetId); entity.setChatType(chatType); entity.setPinned(false); entity.setMuted(false); entity.setHidden(false); entity.setDraft(null); entity.setLastReadAt(null); entity.setCreatedAt(LocalDateTime.now()); entity.setUpdatedAt(LocalDateTime.now()); return entity; }); } public ImConversationStateEntity find(String appId, String userId, String targetId, String chatType) { return repository.findByAppIdAndUserIdAndTargetIdAndChatType(appId, userId, targetId, chatType) .orElse(null); } public List listVisible(String appId, String userId) { return repository.findByAppIdAndUserIdAndHiddenFalse(appId, userId); } private void touch(ImConversationStateEntity entity) { entity.setUpdatedAt(LocalDateTime.now()); } }