refactor(database): migrate to new modular database layer and unify data access
All checks were successful
Frontend CI / build-and-push-web (push) Successful in 2m44s
Frontend CI / ota-android (push) Successful in 12m51s
Frontend CI / build-android-apk (push) Successful in 1h1m26s

- Remove legacy database.ts, LocalDataSource.ts, and MessageRepository.ts
- Create new src/database/ module with messageRepository, userCacheRepository, conversationRepository, and groupCacheRepository
- Update all consumers to import from @/database instead of services/database
- Add web platform blur handling for modal components to fix focus issues
- Flatten SystemMessageItem and NotificationsScreen styles for consistent design
- Add draggable slider in ChatSettingsScreen and dynamic font size support
- Introduce 9 new chat color themes
- Add profile screens for about, terms, and privacy policy with navigation routes
- Add policy links to login and registration screens
- Fix post share URL format from /posts/ to /post/
This commit is contained in:
lafay
2026-04-04 08:01:45 +08:00
parent 189b977fac
commit 82c2970a85
76 changed files with 3382 additions and 2000 deletions

View File

@@ -4,7 +4,7 @@
* 纯业务逻辑无UI依赖
*/
import { messageRepository } from '../../data/repositories/MessageRepository';
import { messageRepository, userCacheRepository, CachedMessage } from '@/database';
import { wsClient, WSEventType } from '../../data/datasources/WSClient';
import {
Message,
@@ -18,6 +18,16 @@ import {
import { messageService } from '../../services/messageService';
import { api } from '../../services/api';
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'],
});
// 事件类型定义
export type MessageUseCaseEventType =
| 'message_received'
@@ -182,7 +192,16 @@ class ProcessMessageUseCase {
// 异步保存到本地数据库
const isRead = _isAck || sender_id === this.currentUserId;
messageRepository.saveMessage(newMessage, isRead).catch((error) => {
messageRepository.saveMessage({
id: newMessage.id,
conversationId: newMessage.conversationId,
senderId: newMessage.senderId,
seq: newMessage.seq,
segments: newMessage.segments,
createdAt: newMessage.createdAt,
status: newMessage.status || 'normal',
isRead,
}).catch((error) => {
console.error('[ProcessMessageUseCase] 保存消息失败:', error);
});
@@ -227,7 +246,7 @@ class ProcessMessageUseCase {
*/
private async getSenderInfo(userId: string): Promise<any | null> {
// 先检查本地缓存
const cachedUser = await messageRepository.getUserCache(userId);
const cachedUser = await userCacheRepository.get(userId);
if (cachedUser) {
return cachedUser;
}
@@ -255,9 +274,9 @@ class ProcessMessageUseCase {
*/
private async fetchUserInfo(userId: string): Promise<any | null> {
try {
const response = await api.get(`/users/${userId}`);
const response = await api.get<any>(`/users/${userId}`);
if (response.code === 0 && response.data) {
await messageRepository.saveUserCache(response.data);
await userCacheRepository.save(response.data as any);
return response.data;
}
return null;
@@ -322,8 +341,8 @@ class ProcessMessageUseCase {
// 更新本地数据库状态
messageRepository
.updateMessageStatus(message_id, 'recalled', true)
.catch((error) => {
.updateStatus(message_id, 'recalled', true)
.catch((error: unknown) => {
console.error('[ProcessMessageUseCase] 更新撤回状态失败:', error);
});
@@ -349,8 +368,8 @@ class ProcessMessageUseCase {
// 更新本地数据库状态
messageRepository
.updateMessageStatus(message_id, 'recalled', true)
.catch((error) => {
.updateStatus(message_id, 'recalled', true)
.catch((error: unknown) => {
console.error('[ProcessMessageUseCase] 更新撤回状态失败:', error);
});
@@ -506,7 +525,16 @@ class ProcessMessageUseCase {
});
// 保存到本地数据库
await messageRepository.saveMessage(message, true);
await messageRepository.saveMessage({
id: message.id,
conversationId: message.conversationId,
senderId: message.senderId,
seq: message.seq,
segments: message.segments,
createdAt: message.createdAt,
status: message.status || 'normal',
isRead: true,
});
return message;
}
@@ -522,7 +550,8 @@ class ProcessMessageUseCase {
* 获取本地消息
*/
async getLocalMessages(conversationId: string, limit: number = 20): Promise<Message[]> {
return messageRepository.getMessagesByConversation(conversationId, limit);
const cached = await messageRepository.getByConversation(conversationId, limit);
return cached.map(cachedMessageToMessage);
}
/**
@@ -534,14 +563,14 @@ class ProcessMessageUseCase {
limit: number = 20
): Promise<Message[]> {
// 先从本地获取
const localMessages = await messageRepository.getMessagesBeforeSeq(
const localMessages = await messageRepository.getBeforeSeq(
conversationId,
beforeSeq,
limit
);
if (localMessages.length >= limit) {
return localMessages;
return localMessages.map(cachedMessageToMessage);
}
// 本地数据不足,从服务端获取
@@ -567,7 +596,16 @@ class ProcessMessageUseCase {
);
// 保存到本地
await messageRepository.saveMessages(serverMessages, false);
await messageRepository.saveMessagesBatch(serverMessages.map((m: any) => ({
id: m.id,
conversationId: m.conversation_id || conversationId,
senderId: m.sender_id,
seq: m.seq,
segments: m.segments || [],
createdAt: m.created_at,
status: m.status || 'normal',
isRead: false,
})));
return serverMessages;
}
@@ -575,7 +613,7 @@ class ProcessMessageUseCase {
console.error('[ProcessMessageUseCase] 获取历史消息失败:', error);
}
return localMessages;
return localMessages.map(cachedMessageToMessage);
}
/**
@@ -602,7 +640,16 @@ class ProcessMessageUseCase {
);
// 保存到本地
await messageRepository.saveMessages(messages, false);
await messageRepository.saveMessagesBatch(messages.map((m: any) => ({
id: m.id,
conversationId: m.conversation_id || conversationId,
senderId: m.sender_id,
seq: m.seq,
segments: m.segments || [],
createdAt: m.created_at,
status: m.status || 'normal',
isRead: false,
})));
return messages;
}