refactor(message): modularize MessageManager architecture
重构消息管理模块,将单体 MessageManager 拆分为职责单一的子模块: - MessageStateManager: 纯状态管理 - MessageDeduplication: 消息去重服务 - UserCacheService: 用户缓存服务 - ReadReceiptManager: 已读回执管理 - ConversationOperations: 会话操作 - MessageSendService: 消息发送 - MessageSyncService: 消息同步 - WSMessageHandler: WebSocket 消息处理 新增类型定义和常量文件,保持原有 API 向后兼容。修复 CallScreen 状态值错误,补充 PostDetailScreen 缺失样式,优化 GroupInfoPanel 导入。
This commit is contained in:
119
src/stores/message/UserCacheService.ts
Normal file
119
src/stores/message/UserCacheService.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* 用户信息缓存服务
|
||||
* 管理用户信息的缓存和获取
|
||||
*/
|
||||
|
||||
import type { MessageResponse, UserDTO } from '../../types/dto';
|
||||
import { api } from '../../services/api';
|
||||
import { getUserCache, saveUserCache } from '../../services/database';
|
||||
import type { IUserCacheService } from './types';
|
||||
|
||||
export class UserCacheService implements IUserCacheService {
|
||||
// 正在获取用户信息的请求映射(用于去重)
|
||||
private pendingUserRequests: Map<string, Promise<UserDTO | null>> = new Map();
|
||||
|
||||
/**
|
||||
* 获取用户信息(带缓存和去重)
|
||||
*/
|
||||
async getSenderInfo(userId: string): Promise<UserDTO | null> {
|
||||
// 1. 先检查本地缓存
|
||||
const cachedUser = await getUserCache(userId);
|
||||
if (cachedUser) {
|
||||
return cachedUser;
|
||||
}
|
||||
|
||||
// 2. 检查是否已有正在进行的请求
|
||||
const pendingRequest = this.pendingUserRequests.get(userId);
|
||||
if (pendingRequest) {
|
||||
return pendingRequest;
|
||||
}
|
||||
|
||||
// 3. 发起新请求
|
||||
const request = this.fetchUserInfo(userId);
|
||||
this.pendingUserRequests.set(userId, request);
|
||||
|
||||
try {
|
||||
const user = await request;
|
||||
return user;
|
||||
} finally {
|
||||
// 请求完成后清理
|
||||
this.pendingUserRequests.delete(userId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从服务器获取用户信息
|
||||
*/
|
||||
private async fetchUserInfo(userId: string): Promise<UserDTO | null> {
|
||||
try {
|
||||
const response = await api.get<UserDTO>(`/users/${userId}`);
|
||||
if (response.code === 0 && response.data) {
|
||||
// 缓存到本地数据库
|
||||
await saveUserCache(response.data);
|
||||
return response.data;
|
||||
}
|
||||
return null;
|
||||
} catch (error) {
|
||||
console.error(`[UserCacheService] 获取用户信息失败: ${userId}`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量异步填充消息的 sender 信息
|
||||
* 填充完成后调用 notifyUpdate 更新内存并通知订阅者
|
||||
*/
|
||||
enrichMessagesWithSenderInfo(
|
||||
conversationId: string,
|
||||
messages: MessageResponse[],
|
||||
notifyUpdate: (conversationId: string, messages: MessageResponse[]) => void
|
||||
): void {
|
||||
// 收集所有需要查询的唯一 sender_id(排除系统用户)
|
||||
const senderIds = [...new Set(
|
||||
messages
|
||||
.filter(m => m.sender_id && m.sender_id !== '10000' && !m.sender)
|
||||
.map(m => m.sender_id)
|
||||
)];
|
||||
|
||||
if (senderIds.length === 0) return;
|
||||
|
||||
// 并发获取所有 sender 信息
|
||||
Promise.all(senderIds.map(id => this.getSenderInfo(id).then(user => ({ id, user }))))
|
||||
.then(results => {
|
||||
const senderMap = new Map<string, UserDTO>();
|
||||
results.forEach(({ id, user }) => {
|
||||
if (user) senderMap.set(id, user);
|
||||
});
|
||||
|
||||
if (senderMap.size === 0) return;
|
||||
|
||||
let changed = false;
|
||||
const updated = messages.map(m => {
|
||||
if (!m.sender && m.sender_id && senderMap.has(m.sender_id)) {
|
||||
changed = true;
|
||||
return { ...m, sender: senderMap.get(m.sender_id) };
|
||||
}
|
||||
return m;
|
||||
});
|
||||
|
||||
if (!changed) return;
|
||||
|
||||
// 调用回调通知更新
|
||||
notifyUpdate(conversationId, updated);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('[UserCacheService] 批量获取 sender 信息失败:', error);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有待处理的请求
|
||||
* 用于测试或需要重置的场景
|
||||
*/
|
||||
reset(): void {
|
||||
this.pendingUserRequests.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// 单例导出
|
||||
export const userCacheService = new UserCacheService();
|
||||
Reference in New Issue
Block a user