refactor(message): simplify state management and remove redundant service methods
Refactor the message module to streamline state management by removing the `MessageStateManager` and `SubscriptionManager` layers, relying instead on Zustand's built-in selector mechanism for reactive updates. - Remove redundant `setConversations`, `addMessage`, and `updateMessage` actions from the Zustand store to favor more specialized update methods. - Clean up `MessageService` by removing deprecated conversation and message sending convenience methods. - Update service interfaces to support new synchronization capabilities including `syncBySeq` and `restartSources`. - Simplify documentation and comments across the message store and its associated services.
This commit is contained in:
@@ -94,13 +94,6 @@ class MessageService {
|
||||
}
|
||||
}
|
||||
|
||||
private async refreshConversationsFromServer(
|
||||
page = 1,
|
||||
pageSize = 20
|
||||
): Promise<ConversationListResponse> {
|
||||
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<ConversationListResponse> {
|
||||
// 如果强制刷新,直接从服务器获取,不使用缓存
|
||||
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<MessageResponse> {
|
||||
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<MessageResponse> {
|
||||
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<MessageResponse> {
|
||||
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<MessageResponse> {
|
||||
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<MessageResponse> {
|
||||
// 使用 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<ConversationUnreadCountResponse> {
|
||||
try {
|
||||
const response = await api.get<ConversationUnreadCountResponse>(
|
||||
'/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<SystemMessageListResponse> {
|
||||
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<CursorPaginationResponse<MessageResponse>> {
|
||||
try {
|
||||
const response = await api.get<any>(
|
||||
`/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
|
||||
|
||||
Reference in New Issue
Block a user