refactor: 架构重构 - 解耦过度耦合模块
主要改动: 1. 创建乐观更新工具函数 (optimisticUpdate.ts) - 消除 userStore.ts 中的重复代码 2. 拆分 useResponsive.ts (485行 -> 12个专注模块) - useBreakpoint: 断点检测 - useOrientation: 方向检测 - usePlatform: 平台检测 - useScreenSize: 屏幕尺寸 - useResponsiveValue: 响应式值 - useResponsiveStyle: 响应式样式 - useMediaQuery: 媒体查询 - useColumnCount: 列数计算 - useResponsiveSpacing: 响应式间距 3. 整理数据层 (Repository 层) - ApiDataSource: API数据源 - LocalDataSource: 本地数据源 - CacheDataSource: 缓存数据源 - MessageRepository: 消息仓库 4. 重构 messageManager.ts (2194行 -> 4个模块) - MessageStateManager: 状态管理 - WebSocketMessageHandler: WebSocket处理 - MessageSyncService: 消息同步 - ReadReceiptManager: 已读管理 5. 导航解耦 (MainNavigator.tsx: 1118行 -> 100行) - 创建 NavigationService 解耦层 - 拆分多个 Navigator 组件 架构改进: - 单一职责原则: 每个模块职责明确 - 依赖倒置: 通过接口解耦 - 代码复用: 工具函数可被多处使用 - 可测试性: 各模块可独立测试
This commit is contained in:
220
src/data/repositories/MessageRepository.ts
Normal file
220
src/data/repositories/MessageRepository.ts
Normal file
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
* MessageRepository - 消息仓库实现
|
||||
* 封装所有SQLite数据库操作,不依赖任何UI或状态管理
|
||||
*/
|
||||
|
||||
import {
|
||||
saveMessage as dbSaveMessage,
|
||||
saveMessagesBatch as dbSaveMessagesBatch,
|
||||
getMessagesByConversation as dbGetMessagesByConversation,
|
||||
getMaxSeq as dbGetMaxSeq,
|
||||
getMinSeq as dbGetMinSeq,
|
||||
getMessagesBeforeSeq as dbGetMessagesBeforeSeq,
|
||||
markConversationAsRead as dbMarkConversationAsRead,
|
||||
updateConversationCacheUnreadCount as dbUpdateConversationCacheUnreadCount,
|
||||
getUserCache as dbGetUserCache,
|
||||
saveUserCache as dbSaveUserCache,
|
||||
deleteConversation as dbDeleteConversation,
|
||||
updateMessageStatus as dbUpdateMessageStatus,
|
||||
CachedMessage,
|
||||
} from '../../services/database';
|
||||
import { Message, Conversation, createMessage, createConversation } from '../../core/entities/Message';
|
||||
|
||||
// 数据库消息到领域实体的转换
|
||||
const cachedMessageToMessage = (cached: CachedMessage): Message => ({
|
||||
id: cached.id,
|
||||
conversationId: cached.conversationId,
|
||||
senderId: cached.senderId,
|
||||
seq: cached.seq,
|
||||
segments: cached.segments || [],
|
||||
createdAt: cached.createdAt,
|
||||
status: cached.status as Message['status'],
|
||||
});
|
||||
|
||||
// 领域实体到数据库消息的转换
|
||||
const messageToCachedMessage = (message: Message, isRead: boolean): CachedMessage => ({
|
||||
id: message.id,
|
||||
conversationId: message.conversationId,
|
||||
senderId: message.senderId,
|
||||
content: message.segments
|
||||
.filter((s) => s.type === 'text')
|
||||
.map((s) => s.data?.text || '')
|
||||
.join(''),
|
||||
type: message.segments.find((s) => s.type === 'image') ? 'image' : 'text',
|
||||
isRead,
|
||||
createdAt: message.createdAt,
|
||||
seq: message.seq,
|
||||
status: message.status,
|
||||
segments: message.segments,
|
||||
});
|
||||
|
||||
class MessageRepository {
|
||||
// ==================== 消息操作 ====================
|
||||
|
||||
/**
|
||||
* 保存单条消息
|
||||
*/
|
||||
async saveMessage(message: Message, isRead: boolean): Promise<void> {
|
||||
try {
|
||||
const cachedMessage = messageToCachedMessage(message, isRead);
|
||||
await dbSaveMessage(cachedMessage);
|
||||
} catch (error) {
|
||||
console.error('[MessageRepository] 保存消息失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量保存消息
|
||||
*/
|
||||
async saveMessages(messages: Message[], isRead: boolean): Promise<void> {
|
||||
if (!messages || messages.length === 0) return;
|
||||
|
||||
try {
|
||||
const cachedMessages = messages.map((m) => messageToCachedMessage(m, isRead));
|
||||
await dbSaveMessagesBatch(cachedMessages);
|
||||
} catch (error) {
|
||||
console.error('[MessageRepository] 批量保存消息失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会话的消息
|
||||
*/
|
||||
async getMessagesByConversation(
|
||||
conversationId: string,
|
||||
limit: number = 20
|
||||
): Promise<Message[]> {
|
||||
try {
|
||||
const cachedMessages = await dbGetMessagesByConversation(conversationId, limit);
|
||||
return cachedMessages.map(cachedMessageToMessage);
|
||||
} catch (error) {
|
||||
console.error('[MessageRepository] 获取消息失败:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会话的最大消息序号
|
||||
*/
|
||||
async getMaxSeq(conversationId: string): Promise<number> {
|
||||
try {
|
||||
return await dbGetMaxSeq(conversationId);
|
||||
} catch (error) {
|
||||
console.error('[MessageRepository] 获取最大序号失败:', error);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会话的最小消息序号
|
||||
*/
|
||||
async getMinSeq(conversationId: string): Promise<number> {
|
||||
try {
|
||||
return await dbGetMinSeq(conversationId);
|
||||
} catch (error) {
|
||||
console.error('[MessageRepository] 获取最小序号失败:', error);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定seq之前的历史消息
|
||||
*/
|
||||
async getMessagesBeforeSeq(
|
||||
conversationId: string,
|
||||
beforeSeq: number,
|
||||
limit: number = 20
|
||||
): Promise<Message[]> {
|
||||
try {
|
||||
const cachedMessages = await dbGetMessagesBeforeSeq(conversationId, beforeSeq, limit);
|
||||
return cachedMessages.map(cachedMessageToMessage);
|
||||
} catch (error) {
|
||||
console.error('[MessageRepository] 获取历史消息失败:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记会话的所有消息为已读
|
||||
*/
|
||||
async markConversationAsRead(conversationId: string): Promise<void> {
|
||||
try {
|
||||
await dbMarkConversationAsRead(conversationId);
|
||||
} catch (error) {
|
||||
console.error('[MessageRepository] 标记会话已读失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新会话缓存的未读数
|
||||
*/
|
||||
async updateConversationUnreadCount(
|
||||
conversationId: string,
|
||||
count: number
|
||||
): Promise<void> {
|
||||
try {
|
||||
await dbUpdateConversationCacheUnreadCount(conversationId, count);
|
||||
} catch (error) {
|
||||
console.error('[MessageRepository] 更新会话未读数失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新消息状态(如撤回)
|
||||
*/
|
||||
async updateMessageStatus(
|
||||
messageId: string,
|
||||
status: string,
|
||||
clearContent: boolean = false
|
||||
): Promise<void> {
|
||||
try {
|
||||
await dbUpdateMessageStatus(messageId, status, clearContent);
|
||||
} catch (error) {
|
||||
console.error('[MessageRepository] 更新消息状态失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除会话及其所有消息
|
||||
*/
|
||||
async deleteConversation(conversationId: string): Promise<void> {
|
||||
try {
|
||||
await dbDeleteConversation(conversationId);
|
||||
} catch (error) {
|
||||
console.error('[MessageRepository] 删除会话失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 用户缓存操作 ====================
|
||||
|
||||
/**
|
||||
* 获取用户缓存
|
||||
*/
|
||||
async getUserCache(userId: string): Promise<any | null> {
|
||||
try {
|
||||
return await dbGetUserCache(userId);
|
||||
} catch (error) {
|
||||
console.error('[MessageRepository] 获取用户缓存失败:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存用户缓存
|
||||
*/
|
||||
async saveUserCache(user: any): Promise<void> {
|
||||
try {
|
||||
await dbSaveUserCache(user);
|
||||
} catch (error) {
|
||||
console.error('[MessageRepository] 保存用户缓存失败:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const messageRepository = new MessageRepository();
|
||||
export default messageRepository;
|
||||
Reference in New Issue
Block a user