refactor: restructure core architecture and responsive system
This commit implements a major architectural refactor to improve modularity, type safety, and maintainability across the codebase.
Key changes include:
- **Responsive System Refactor**: Migrated from a monolithic `useResponsive` hook to a set of specialized, granular hooks (`useBreakpoint`, `useOrientation`, `usePlatform`, etc.) located in `src/presentation/hooks/responsive`. This reduces unnecessary re-renders and improves developer experience.
- **Core Service Restructuring**: Introduced a new directory structure for services, including dedicated folders for `datasources`, `mappers`, and domain-specific types (`message`, `post`).
- **Data Layer Improvements**:
- Centralized JSON parsing logic in `src/database/core/jsonUtils.ts`.
- Cleaned up repository implementations by removing redundant local utility functions.
- Refactored `MessageMapper` to use the new centralized JSON utility.
- **Type System Cleanup**:
- Decomposed the large `src/types/dto.ts` into a modular `src/types/dto/` directory.
- Simplified `src/types/index.ts` and introduced backward-compatible aliases for core entities.
- **Utility Consolidation**:
- Created a centralized `src/utils/formatTime.ts` to replace fragmented date formatting logic across various screens and components.
- Removed deprecated responsive utility files in favor of the new hook-based system.
- **Service Logic Refinement**: Refactored `ApiClient` and `WebSocketService` to use a centralized `showVerificationModal` service, removing duplicated state management for verification prompts.
2026-05-05 19:07:33 +08:00
|
|
|
/**
|
|
|
|
|
* 用户数据映射器
|
|
|
|
|
* 负责 User 模型与 API 响应、数据库记录之间的转换
|
|
|
|
|
*/
|
|
|
|
|
|
2026-05-08 13:19:40 +08:00
|
|
|
import { UserModel } from '../../data/models';
|
refactor: restructure core architecture and responsive system
This commit implements a major architectural refactor to improve modularity, type safety, and maintainability across the codebase.
Key changes include:
- **Responsive System Refactor**: Migrated from a monolithic `useResponsive` hook to a set of specialized, granular hooks (`useBreakpoint`, `useOrientation`, `usePlatform`, etc.) located in `src/presentation/hooks/responsive`. This reduces unnecessary re-renders and improves developer experience.
- **Core Service Restructuring**: Introduced a new directory structure for services, including dedicated folders for `datasources`, `mappers`, and domain-specific types (`message`, `post`).
- **Data Layer Improvements**:
- Centralized JSON parsing logic in `src/database/core/jsonUtils.ts`.
- Cleaned up repository implementations by removing redundant local utility functions.
- Refactored `MessageMapper` to use the new centralized JSON utility.
- **Type System Cleanup**:
- Decomposed the large `src/types/dto.ts` into a modular `src/types/dto/` directory.
- Simplified `src/types/index.ts` and introduced backward-compatible aliases for core entities.
- **Utility Consolidation**:
- Created a centralized `src/utils/formatTime.ts` to replace fragmented date formatting logic across various screens and components.
- Removed deprecated responsive utility files in favor of the new hook-based system.
- **Service Logic Refinement**: Refactored `ApiClient` and `WebSocketService` to use a centralized `showVerificationModal` service, removing duplicated state management for verification prompts.
2026-05-05 19:07:33 +08:00
|
|
|
import type { UserDTO } from '../../types/dto';
|
|
|
|
|
|
|
|
|
|
// 数据库用户记录类型
|
|
|
|
|
export interface UserDbRecord {
|
|
|
|
|
id: string;
|
|
|
|
|
data: string;
|
|
|
|
|
updatedAt: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class UserMapper {
|
|
|
|
|
static fromDTO(dto: UserDTO): UserModel {
|
|
|
|
|
return {
|
|
|
|
|
id: String(dto.id || ''),
|
|
|
|
|
username: dto.username || '',
|
|
|
|
|
nickname: dto.nickname,
|
|
|
|
|
avatar: dto.avatar,
|
|
|
|
|
bio: dto.bio,
|
|
|
|
|
website: dto.website,
|
|
|
|
|
location: dto.location,
|
|
|
|
|
email: dto.email,
|
|
|
|
|
phone: dto.phone,
|
|
|
|
|
followersCount: dto.followers_count,
|
|
|
|
|
followingCount: dto.following_count,
|
|
|
|
|
postsCount: dto.posts_count,
|
|
|
|
|
isFollowing: dto.is_following,
|
|
|
|
|
createdAt: dto.created_at ? new Date(dto.created_at) : undefined,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static fromDTOList(dtos: UserDTO[]): UserModel[] {
|
|
|
|
|
return dtos.map(dto => this.fromDTO(dto));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 从数据库记录转换为应用模型
|
|
|
|
|
*/
|
|
|
|
|
static fromDbRecord(record: UserDbRecord): UserModel | null {
|
|
|
|
|
try {
|
|
|
|
|
const data = JSON.parse(record.data) as UserDTO;
|
|
|
|
|
return this.fromDTO(data);
|
|
|
|
|
} catch {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 将应用模型转换为数据库记录
|
|
|
|
|
*/
|
|
|
|
|
static toDbRecord(model: UserModel): UserDbRecord {
|
|
|
|
|
const dto: UserDTO = {
|
|
|
|
|
id: model.id,
|
|
|
|
|
username: model.username,
|
|
|
|
|
nickname: model.nickname || '',
|
|
|
|
|
avatar: model.avatar || '',
|
|
|
|
|
cover_url: '',
|
|
|
|
|
bio: model.bio || '',
|
|
|
|
|
website: model.website || '',
|
|
|
|
|
location: model.location || '',
|
|
|
|
|
email: model.email,
|
|
|
|
|
phone: model.phone,
|
|
|
|
|
followers_count: model.followersCount || 0,
|
|
|
|
|
following_count: model.followingCount || 0,
|
|
|
|
|
posts_count: model.postsCount || 0,
|
|
|
|
|
is_following: model.isFollowing,
|
|
|
|
|
created_at: model.createdAt?.toISOString() || '',
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
id: model.id,
|
|
|
|
|
data: JSON.stringify(dto),
|
|
|
|
|
updatedAt: new Date().toISOString(),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 将应用模型转换为 API 请求数据
|
|
|
|
|
*/
|
|
|
|
|
static toApiRequest(model: Partial<UserModel>): Record<string, any> {
|
|
|
|
|
const request: Record<string, any> = {};
|
|
|
|
|
|
|
|
|
|
if (model.nickname !== undefined) {
|
|
|
|
|
request.nickname = model.nickname;
|
|
|
|
|
}
|
|
|
|
|
if (model.avatar !== undefined) {
|
|
|
|
|
request.avatar = model.avatar;
|
|
|
|
|
}
|
|
|
|
|
if (model.bio !== undefined) {
|
|
|
|
|
request.bio = model.bio;
|
|
|
|
|
}
|
|
|
|
|
if (model.website !== undefined) {
|
|
|
|
|
request.website = model.website;
|
|
|
|
|
}
|
|
|
|
|
if (model.location !== undefined) {
|
|
|
|
|
request.location = model.location;
|
|
|
|
|
}
|
|
|
|
|
if (model.phone !== undefined) {
|
|
|
|
|
request.phone = model.phone;
|
|
|
|
|
}
|
|
|
|
|
if (model.email !== undefined) {
|
|
|
|
|
request.email = model.email;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return request;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 将应用模型转换为 DTO
|
|
|
|
|
*/
|
|
|
|
|
static toDTO(model: UserModel): UserDTO {
|
|
|
|
|
return {
|
|
|
|
|
id: model.id,
|
|
|
|
|
username: model.username,
|
|
|
|
|
nickname: model.nickname || '',
|
|
|
|
|
avatar: model.avatar || '',
|
|
|
|
|
cover_url: '',
|
|
|
|
|
bio: model.bio || '',
|
|
|
|
|
website: model.website || '',
|
|
|
|
|
location: model.location || '',
|
|
|
|
|
email: model.email,
|
|
|
|
|
phone: model.phone,
|
|
|
|
|
followers_count: model.followersCount || 0,
|
|
|
|
|
following_count: model.followingCount || 0,
|
|
|
|
|
posts_count: model.postsCount || 0,
|
|
|
|
|
is_following: model.isFollowing,
|
|
|
|
|
created_at: model.createdAt?.toISOString() || '',
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|