refactor(message): replace MessageStateManager with zustand store
- Remove MessageStateManager wrapper layer in favor of direct zustand store - Move service modules to services/ subdirectory (ConversationOperations, MessageDeduplication, MessageSendService, MessageSyncService, ReadReceiptManager, UserCacheService, WSMessageHandler) - Add new zustand-based store with subscriptionManager for event handling - Introduce React hooks for message state (useConversations, useMessages, useUnreadCount, etc.) - Update exports in index.ts to reflect new module structure - Deprecate messageManager.ts entry point in favor of message/index.ts - Maintain backward compatibility with existing MessageManager API
This commit is contained in:
136
src/stores/message/services/MessageSendService.ts
Normal file
136
src/stores/message/services/MessageSendService.ts
Normal file
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* 消息发送服务
|
||||
* 处理消息发送相关逻辑
|
||||
*
|
||||
* 重构说明:直接使用 zustand store 替代 IMessageStateManager
|
||||
*/
|
||||
|
||||
import type { MessageResponse, MessageSegment, ConversationResponse } from '../../../types/dto';
|
||||
import { messageService } from '../../../services/messageService';
|
||||
import { saveMessage } from '../../../services/database';
|
||||
import type { IMessageSendService } from '../types';
|
||||
import { useMessageStore, subscriptionManager, mergeMessagesById } from '../store';
|
||||
|
||||
export class MessageSendService implements IMessageSendService {
|
||||
private getCurrentUserId: () => string | null;
|
||||
|
||||
constructor(getCurrentUserId: () => string | null) {
|
||||
this.getCurrentUserId = getCurrentUserId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*/
|
||||
async sendMessage(
|
||||
conversationId: string,
|
||||
segments: MessageSegment[],
|
||||
options?: { replyToId?: string }
|
||||
): Promise<MessageResponse | null> {
|
||||
const store = useMessageStore.getState();
|
||||
|
||||
try {
|
||||
// 调用API发送
|
||||
const response = await messageService.sendMessage(conversationId, {
|
||||
segments,
|
||||
reply_to_id: options?.replyToId,
|
||||
});
|
||||
|
||||
if (response) {
|
||||
const currentUserId = this.getCurrentUserId();
|
||||
|
||||
// 添加到本地消息列表
|
||||
const existingMessages = store.getMessages(conversationId);
|
||||
const newMessage: MessageResponse = {
|
||||
id: response.id,
|
||||
conversation_id: conversationId,
|
||||
sender_id: currentUserId || '',
|
||||
seq: response.seq,
|
||||
segments,
|
||||
created_at: new Date().toISOString(),
|
||||
status: 'normal',
|
||||
};
|
||||
|
||||
const updatedMessages = mergeMessagesById(existingMessages, [newMessage]);
|
||||
store.setMessages(conversationId, updatedMessages);
|
||||
|
||||
// 关键:立即广播消息列表更新
|
||||
subscriptionManager.notifySubscribers({
|
||||
type: 'messages_updated',
|
||||
payload: {
|
||||
conversationId,
|
||||
messages: updatedMessages,
|
||||
newMessage,
|
||||
source: 'send',
|
||||
},
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
// 更新会话最后消息
|
||||
this.updateConversationWithNewMessage(conversationId, newMessage);
|
||||
|
||||
// 通知消息已发送
|
||||
subscriptionManager.notifySubscribers({
|
||||
type: 'message_sent',
|
||||
payload: { conversationId, message: newMessage },
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
// 保存到本地数据库
|
||||
const textContent = segments
|
||||
?.filter((s: any) => s.type === 'text')
|
||||
.map((s: any) => s.data?.text || '')
|
||||
.join('') || '';
|
||||
|
||||
saveMessage({
|
||||
id: response.id,
|
||||
conversationId,
|
||||
senderId: currentUserId || '',
|
||||
content: textContent,
|
||||
type: segments?.find((s: any) => s.type === 'image') ? 'image' : 'text',
|
||||
isRead: true,
|
||||
createdAt: newMessage.created_at,
|
||||
seq: response.seq,
|
||||
status: 'normal',
|
||||
segments,
|
||||
}).catch(console.error);
|
||||
|
||||
return newMessage;
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch (error) {
|
||||
console.error('[MessageSendService] 发送消息失败:', error);
|
||||
subscriptionManager.notifySubscribers({
|
||||
type: 'error',
|
||||
payload: { error, context: 'sendMessage' },
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新会话的最后消息信息
|
||||
*/
|
||||
private updateConversationWithNewMessage(
|
||||
conversationId: string,
|
||||
message: MessageResponse
|
||||
): void {
|
||||
const store = useMessageStore.getState();
|
||||
const conversation = store.getConversation(conversationId);
|
||||
const createdAt = message.created_at || new Date().toISOString();
|
||||
|
||||
if (conversation) {
|
||||
// 更新现有会话
|
||||
const updatedConv: ConversationResponse = {
|
||||
...conversation,
|
||||
last_seq: message.seq,
|
||||
last_message: message,
|
||||
last_message_at: createdAt,
|
||||
updated_at: createdAt,
|
||||
};
|
||||
|
||||
store.updateConversation(updatedConv);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user