diff --git a/src/services/message/messageService.ts b/src/services/message/messageService.ts index 31e9961..2cacf0f 100644 --- a/src/services/message/messageService.ts +++ b/src/services/message/messageService.ts @@ -94,13 +94,6 @@ class MessageService { } } - private async refreshConversationsFromServer( - page = 1, - pageSize = 20 - ): Promise { - return this.requestOffsetConversationsPage(page, pageSize); - } - /** * 远端会话列表单页(offset / cursor 统一入口) * 两种模式均先写 SQLite 再返回,行为与 NetworkRemoteConversationListPagedSource 配套。 @@ -175,50 +168,6 @@ class MessageService { }; } - // ==================== 会话相关 ==================== - - /** - * 获取会话列表 - * GET /api/v1/conversations/list - */ - async getConversations( - page = 1, - pageSize = 20, - forceRefresh = false - ): Promise { - // 如果强制刷新,直接从服务器获取,不使用缓存 - if (!forceRefresh) { - const cachedList = await conversationRepository.getListCache(); - if (cachedList.length > 0) { - // 后台刷新数据,但不阻塞当前返回 - this.refreshConversationsFromServer(page, pageSize).catch(error => { - console.error('后台刷新会话列表失败:', error); - }); - return { - list: cachedList, - total: cachedList.length, - page: 1, - page_size: cachedList.length, - total_pages: 1, - }; - } - } - - // 强制刷新或没有缓存时,直接从服务器获取 - try { - return await this.refreshConversationsFromServer(page, pageSize); - } catch (error) { - console.error('获取会话列表失败:', error); - return { - list: [], - total: 0, - page: 1, - page_size: pageSize, - total_pages: 0, - }; - } - } - /** * 创建私聊会话 * POST /api/v1/conversations @@ -428,98 +377,6 @@ class MessageService { } } - /** - * 发送文本消息(便捷方法) - */ - async sendTextMessage( - conversationId: string, - content: string, - detailType: 'private' | 'group' = 'private' - ): Promise { - return this.sendTextMessageByAction(detailType, conversationId, content); - } - - /** - * 通过 HTTP POST 发送文本消息 - * @param detailType 消息类型: 'private' 私聊, 'group' 群聊 - * @param conversationId 会话ID - * @param text 文本内容 - * @returns 消息响应 - */ - async sendTextMessageByAction( - detailType: 'private' | 'group', - conversationId: string, - text: string - ): Promise { - const message: MessageSegment[] = [ - { - type: 'text', - data: { - text: text, - }, - }, - ]; - return this.sendMessageByAction(detailType, conversationId, message); - } - - /** - * 发送图片消息(便捷方法) - */ - async sendImageMessage( - conversationId: string, - mediaUrl: string, - content?: string, - detailType: 'private' | 'group' = 'private' - ): Promise { - const message: MessageSegment[] = [ - { - type: 'image', - data: { - url: mediaUrl, - }, - }, - ]; - // 如果有文本说明,添加一个文本段 - if (content) { - message.unshift({ - type: 'text', - data: { text: content }, - }); - } - return this.sendMessageByAction(detailType, conversationId, message); - } - - /** - * 发送 segments 格式消息(新版统一格式) - * @param conversationId 会话ID - * @param segments 消息链数组 - * @param detailType 消息类型 - */ - async sendSegmentsMessage( - conversationId: string, - segments: MessageSegment[], - detailType: 'private' | 'group' = 'private' - ): Promise { - return this.sendMessageByAction(detailType, conversationId, segments); - } - - /** - * 发送带回复的 segments 消息 - * @param conversationId 会话ID - * @param segments 消息链数组 - * @param replyToId 被回复消息的ID - * @param detailType 消息类型 - */ - async sendReplySegmentsMessage( - conversationId: string, - segments: MessageSegment[], - replyToId: string, - detailType: 'private' | 'group' = 'private' - ): Promise { - // 使用 reply_to_id 参数发送回复消息 - return this.sendMessageByAction(detailType, conversationId, segments, replyToId); - } - /** * 撤回/删除消息 * 优先使用WebSocket,失败时降级到HTTP @@ -619,68 +476,6 @@ class MessageService { return response.data?.conversations || []; } - /** - * 获取单个会话未读数 - * GET /api/v1/conversations/unread/count?conversation_id=xxx - */ - async getConversationUnreadCount( - conversationId: string - ): Promise { - try { - const response = await api.get( - '/conversations/unread/count', - { conversation_id: conversationId } - ); - return response.data; - } catch (error) { - console.error('获取会话未读数失败:', error); - return { - conversation_id: conversationId, - unread_count: 0, - }; - } - } - - // ==================== 系统消息相关 ==================== - - /** - * 获取系统消息列表 - * GET /api/v1/messages/system - * @param limit 返回数量限制 - * @param beforeId 获取此ID之前的消息(用于分页) - */ - async getSystemMessages( - pageSize: number = 20, - page: number = 1 - ): Promise { - try { - const response = await api.get<{ - list: any[]; - total: number; - page: number; - page_size: number; - total_pages: number; - }>('/messages/system', { - page, - page_size: pageSize, - }); - - const data = response.data; - return { - messages: data.list || [], - total: data.total || 0, - has_more: data.page < data.total_pages, - }; - } catch (error) { - console.error('获取系统消息列表失败:', error); - return { - messages: [], - total: 0, - has_more: false, - }; - } - } - /** * 获取系统消息未读数 * GET /api/v1/messages/system/unread-count @@ -714,41 +509,6 @@ class MessageService { await api.put('/messages/system/read-all'); } - // ==================== 游标分页方法 ==================== - - /** - * 获取消息列表(游标分页) - * GET /api/v1/conversations/:id/messages/cursor - * @param conversationId 会话ID - * @param params 游标分页请求参数 - */ - async getMessagesCursor( - conversationId: string, - params: CursorPaginationRequest = {} - ): Promise> { - try { - const response = await api.get( - `/conversations/${encodeURIComponent(conversationId)}/messages/cursor`, - params - ); - const raw = response.data; - return { - list: Array.isArray(raw?.list) ? raw.list : [], - next_cursor: raw?.next_cursor ?? null, - prev_cursor: raw?.prev_cursor ?? null, - has_more: raw?.has_more ?? false, - }; - } catch (error) { - console.error('获取消息列表失败:', error); - return { - list: [], - next_cursor: null, - prev_cursor: null, - has_more: false, - }; - } - } - /** * 获取系统消息列表(游标分页) * GET /api/v1/messages/system/cursor diff --git a/src/stores/message/MessageManager.ts b/src/stores/message/MessageManager.ts index b2c1c1b..86806ca 100644 --- a/src/stores/message/MessageManager.ts +++ b/src/stores/message/MessageManager.ts @@ -1,14 +1,8 @@ /** - * MessageManager - 消息管理核心模块(重构版) - * + * MessageManager - 消息管理核心模块 + * * 作为轻量级协调者,整合各个专注的服务模块 * 直接使用 zustand store 进行状态管理 - * - * 重构说明: - * - 移除了 MessageStateManager 包装层 - * - 直接使用 zustand store - * - 服务层移至 services/ 目录 - * - 移除了 SubscriptionManager,改用 Zustand selector 进行响应式订阅 */ import type { ConversationResponse, MessageResponse, MessageSegment, UserDTO } from '../../types/dto'; diff --git a/src/stores/message/baseHooks.ts b/src/stores/message/baseHooks.ts index 4638d03..972aa41 100644 --- a/src/stores/message/baseHooks.ts +++ b/src/stores/message/baseHooks.ts @@ -1,14 +1,9 @@ /** * 消息模块 React Hooks - * + * * 提供React组件与消息状态管理的集成 * 所有hooks都基于zustand store的selector机制 * 确保组件能实时获取状态更新 - * - * 重构说明: - * - 移除了 SubscriptionManager,改用 Zustand selector - * - Zustand 会自动处理依赖追踪和组件重渲染 - * - 不需要手动管理订阅/取消订阅 */ import { useState, useEffect, useCallback, useRef } from 'react'; diff --git a/src/stores/message/index.ts b/src/stores/message/index.ts index e017b10..d5f0b52 100644 --- a/src/stores/message/index.ts +++ b/src/stores/message/index.ts @@ -1,12 +1,5 @@ /** * 消息模块统一导出 - * - * 重构说明: - * - 移除了 MessageStateManager 包装层 - * - 直接使用 zustand store 进行状态管理 - * - 服务层移至 services/ 目录 - * - 新增 hooks.ts 封装常用逻辑 - * - 移除了 SubscriptionManager,改用 Zustand selector 进行响应式订阅 */ // ==================== 主管理器 ==================== diff --git a/src/stores/message/services/ConversationOperations.ts b/src/stores/message/services/ConversationOperations.ts index 6d02184..73549c8 100644 --- a/src/stores/message/services/ConversationOperations.ts +++ b/src/stores/message/services/ConversationOperations.ts @@ -1,10 +1,6 @@ /** * 会话操作服务 * 处理会话的 CRUD 操作 - * - * 重构说明: - * - 直接使用 zustand store 替代 IMessageStateManager - * - 移除了 SubscriptionManager 调用,Zustand 的 set() 会自动触发组件重渲染 */ import type { ConversationResponse } from '../../../types/dto'; diff --git a/src/stores/message/services/MessageSendService.ts b/src/stores/message/services/MessageSendService.ts index 4bfe214..cffd26b 100644 --- a/src/stores/message/services/MessageSendService.ts +++ b/src/stores/message/services/MessageSendService.ts @@ -1,10 +1,6 @@ /** * 消息发送服务 * 处理消息发送相关逻辑 - * - * 重构说明: - * - 直接使用 zustand store 替代 IMessageStateManager - * - 移除了 SubscriptionManager 调用,Zustand 的 set() 会自动触发组件重渲染 */ import type { MessageResponse, MessageSegment, ConversationResponse } from '../../../types/dto'; diff --git a/src/stores/message/services/MessageSyncService.ts b/src/stores/message/services/MessageSyncService.ts index 4c53995..117b99e 100644 --- a/src/stores/message/services/MessageSyncService.ts +++ b/src/stores/message/services/MessageSyncService.ts @@ -1,10 +1,6 @@ /** * 消息同步服务 * 处理消息和会话的服务器同步逻辑 - * - * 重构说明: - * - 直接使用 zustand store 替代 IMessageStateManager - * - 移除了 SubscriptionManager 调用,Zustand 的 set() 会自动触发组件重渲染 */ import type { ConversationResponse, MessageResponse } from '../../../types/dto'; diff --git a/src/stores/message/services/ReadReceiptManager.ts b/src/stores/message/services/ReadReceiptManager.ts index 1cde516..5e18605 100644 --- a/src/stores/message/services/ReadReceiptManager.ts +++ b/src/stores/message/services/ReadReceiptManager.ts @@ -1,10 +1,6 @@ /** * 已读回执管理器 * 管理消息已读状态的同步和保护 - * - * 重构说明: - * - 直接使用 zustand store 替代 IMessageStateManager - * - 移除了 SubscriptionManager 调用,Zustand 的 set() 会自动触发组件重渲染 */ import type { ConversationResponse } from '../../../types/dto'; diff --git a/src/stores/message/services/WSMessageHandler.ts b/src/stores/message/services/WSMessageHandler.ts index a0af095..77d1a19 100644 --- a/src/stores/message/services/WSMessageHandler.ts +++ b/src/stores/message/services/WSMessageHandler.ts @@ -1,10 +1,6 @@ /** * WebSocket 消息处理器 * 处理所有来自 WebSocket 的消息事件 - * - * 重构说明: - * - 直接使用 zustand store 替代 IMessageStateManager - * - 移除了 SubscriptionManager 调用,Zustand 的 set() 会自动触发组件重渲染 */ import type { diff --git a/src/stores/message/services/index.ts b/src/stores/message/services/index.ts index a0e86b2..47ec3f9 100644 --- a/src/stores/message/services/index.ts +++ b/src/stores/message/services/index.ts @@ -1,7 +1,5 @@ /** * 消息服务层统一导出 - * - * 重构说明:所有服务直接使用 zustand store,移除了 IMessageStateManager 接口依赖 */ // 消息去重服务 diff --git a/src/stores/message/store.ts b/src/stores/message/store.ts index cbab6de..1530c4a 100644 --- a/src/stores/message/store.ts +++ b/src/stores/message/store.ts @@ -1,11 +1,6 @@ /** * 消息状态 Zustand Store * 使用 zustand 进行状态管理,提供响应式状态更新 - * - * 重构说明: - * - 移除了 MessageStateManager 包装层 - * - 直接使用 zustand store 进行状态管理 - * - 移除了 SubscriptionManager,改用 Zustand selector 进行响应式订阅 */ import { create } from 'zustand'; @@ -78,7 +73,6 @@ export interface MessageActions { isNotificationMuted: (conversationId: string) => boolean; // 设置状态 - setConversations: (conversations: Map) => void; setConversationsWithUnread: ( conversations: Map, totalUnread: number, @@ -87,8 +81,6 @@ export interface MessageActions { updateConversation: (conversation: ConversationResponse) => void; removeConversation: (conversationId: string) => void; setMessages: (conversationId: string, messages: MessageResponse[]) => void; - addMessage: (conversationId: string, message: MessageResponse) => void; - updateMessage: (conversationId: string, messageId: string, updates: Partial) => void; setUnreadCount: (total: number, system: number) => void; setLastSystemMessageAt: (time: string | null) => void; setSSEConnected: (connected: boolean) => void; @@ -253,21 +245,6 @@ export const useMessageStore = create((set, get) => ({ // ==================== 设置状态 ==================== - setConversations: (conversations: Map) => { - const conversationList = sortConversationList(conversations); - const notificationMutedMap = new Map(); - conversations.forEach((conv, id) => { - if (conv.notification_muted) { - notificationMutedMap.set(id, true); - } - }); - set(state => ({ - conversations, - conversationList, - notificationMutedMap: new Map([...state.notificationMutedMap, ...notificationMutedMap]), - })); - }, - setConversationsWithUnread: ( conversations: Map, totalUnread: number, @@ -348,39 +325,6 @@ export const useMessageStore = create((set, get) => ({ }); }, - addMessage: (conversationId: string, message: MessageResponse) => { - const normalizedId = normalizeConversationId(conversationId); - set(state => { - const existing = state.messagesMap.get(normalizedId) || []; - const exists = existing.some(m => String(m.id) === String(message.id)); - - if (exists) { - return state; - } - - const updated = mergeMessagesById(existing, [message]); - const newMessagesMap = new Map(state.messagesMap); - newMessagesMap.set(normalizedId, updated); - return { messagesMap: newMessagesMap }; - }); - }, - - updateMessage: (conversationId: string, messageId: string, updates: Partial) => { - const normalizedId = normalizeConversationId(conversationId); - set(state => { - const messages = state.messagesMap.get(normalizedId); - if (!messages) return state; - - const updated = messages.map(m => - String(m.id) === String(messageId) ? { ...m, ...updates } : m - ); - - const newMessagesMap = new Map(state.messagesMap); - newMessagesMap.set(normalizedId, updated); - return { messagesMap: newMessagesMap }; - }); - }, - setUnreadCount: (total: number, system: number) => { set({ totalUnreadCount: total, systemUnreadCount: system }); }, diff --git a/src/stores/message/types.ts b/src/stores/message/types.ts index 08e409f..992946a 100644 --- a/src/stores/message/types.ts +++ b/src/stores/message/types.ts @@ -73,7 +73,9 @@ export interface IMessageSyncService { fetchMessages(conversationId: string, afterSeq?: number): Promise; loadMoreMessages(conversationId: string, beforeSeq: number, limit?: number): Promise; fetchUnreadCount(): Promise; + syncBySeq(): Promise; canLoadMoreConversations(): boolean; + restartSources(): void; } export interface IWSMessageHandler {