refactor: migrate post operations to use case architecture with differential updates
Migrate post-related operations from direct service/store calls to a new use case architecture featuring differential updates. Key changes include: (1) introduce ProcessPostUseCase to handle like, unlike, favorite, unfavorite, delete, and fetch operations with proper state management, (2) add useDifferentialPosts hook for efficient list rendering with minimal re-renders, (3) add PostDiffCalculator and PostUpdateBatcher in infrastructure layer for incremental updates, (4) deprecate NotificationItem component in favor of SystemMessageItem, (5) remove deprecated interactive methods from userStore, (6) add posts_cache table to local datasource, (7) clean up legacy MessageDTO and ConversationDTO types, (8) remove deprecated hook useBreakpointCheck, (9) refactor MessageBubble to use measureInWindow directly for better React Native compatibility
This commit is contained in:
863
src/core/usecases/ProcessPostUseCase.ts
Normal file
863
src/core/usecases/ProcessPostUseCase.ts
Normal file
@@ -0,0 +1,863 @@
|
||||
/**
|
||||
* ProcessPostUseCase - 处理帖子用例
|
||||
* 处理帖子的业务逻辑,协调 Repository 和状态管理
|
||||
* 纯业务逻辑,无UI依赖
|
||||
*/
|
||||
|
||||
import { postRepository } from '../../data/repositories/PostRepository';
|
||||
import type { Post } from '../entities/Post';
|
||||
import type {
|
||||
GetPostsParams,
|
||||
CreatePostData,
|
||||
UpdatePostData,
|
||||
PostsResult,
|
||||
SearchPostsParams,
|
||||
} from '../../data/repositories/interfaces/IPostRepository';
|
||||
import { PaginationStateManager } from '../../infrastructure/pagination/PaginationStateManager';
|
||||
import type { PaginationState } from '../../infrastructure/pagination/types';
|
||||
|
||||
// ==================== 事件类型定义 ====================
|
||||
|
||||
/**
|
||||
* 帖子用例事件类型
|
||||
*/
|
||||
export type PostUseCaseEventType =
|
||||
| 'posts_loaded'
|
||||
| 'post_created'
|
||||
| 'post_updated'
|
||||
| 'post_deleted'
|
||||
| 'post_liked'
|
||||
| 'post_unliked'
|
||||
| 'post_favorited'
|
||||
| 'post_unfavorited'
|
||||
| 'loading_changed'
|
||||
| 'error_occurred'
|
||||
| 'state_changed';
|
||||
|
||||
/**
|
||||
* 帖子用例事件
|
||||
*/
|
||||
export interface PostUseCaseEvent {
|
||||
type: PostUseCaseEventType;
|
||||
payload: any;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件订阅者类型
|
||||
*/
|
||||
export type PostUseCaseSubscriber = (event: PostUseCaseEvent) => void;
|
||||
|
||||
// ==================== 状态类型定义 ====================
|
||||
|
||||
/**
|
||||
* 帖子列表状态
|
||||
*/
|
||||
export interface PostsState {
|
||||
/** 帖子列表 */
|
||||
posts: Post[];
|
||||
/** 是否正在加载 */
|
||||
isLoading: boolean;
|
||||
/** 是否正在刷新 */
|
||||
isRefreshing: boolean;
|
||||
/** 是否有更多数据 */
|
||||
hasMore: boolean;
|
||||
/** 错误信息 */
|
||||
error: string | null;
|
||||
/** 当前游标 */
|
||||
cursor: string | null;
|
||||
/** 最后加载时间 */
|
||||
lastLoadTime: number | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 帖子详情状态
|
||||
*/
|
||||
export interface PostDetailState {
|
||||
/** 帖子详情 */
|
||||
post: Post | null;
|
||||
/** 是否正在加载 */
|
||||
isLoading: boolean;
|
||||
/** 错误信息 */
|
||||
error: string | null;
|
||||
}
|
||||
|
||||
// ==================== 默认配置 ====================
|
||||
|
||||
const DEFAULT_PAGE_SIZE = 20;
|
||||
|
||||
// ==================== ProcessPostUseCase 类 ====================
|
||||
|
||||
class ProcessPostUseCase {
|
||||
// 单例实例
|
||||
private static instance: ProcessPostUseCase;
|
||||
|
||||
// 订阅者管理
|
||||
private subscribers: Set<PostUseCaseSubscriber> = new Set();
|
||||
|
||||
// 状态管理
|
||||
private postsState: Map<string, PostsState> = new Map();
|
||||
private postDetailState: Map<string, PostDetailState> = new Map();
|
||||
|
||||
// 分页状态管理器
|
||||
private paginationManager: PaginationStateManager;
|
||||
|
||||
// 当前用户ID
|
||||
private currentUserId: string | null = null;
|
||||
|
||||
// 私有构造函数
|
||||
private constructor() {
|
||||
this.paginationManager = new PaginationStateManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单例实例
|
||||
*/
|
||||
static getInstance(): ProcessPostUseCase {
|
||||
if (!ProcessPostUseCase.instance) {
|
||||
ProcessPostUseCase.instance = new ProcessPostUseCase();
|
||||
}
|
||||
return ProcessPostUseCase.instance;
|
||||
}
|
||||
|
||||
// ==================== 初始化和销毁 ====================
|
||||
|
||||
/**
|
||||
* 初始化用例
|
||||
* @param currentUserId 当前用户ID
|
||||
*/
|
||||
initialize(currentUserId: string | null = null): void {
|
||||
this.currentUserId = currentUserId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁用例
|
||||
*/
|
||||
destroy(): void {
|
||||
this.subscribers.clear();
|
||||
this.postsState.clear();
|
||||
this.postDetailState.clear();
|
||||
this.paginationManager.clear();
|
||||
this.currentUserId = null;
|
||||
}
|
||||
|
||||
// ==================== 订阅机制 ====================
|
||||
|
||||
/**
|
||||
* 订阅事件
|
||||
* @param subscriber 订阅者函数
|
||||
* @returns 取消订阅函数
|
||||
*/
|
||||
subscribe(subscriber: PostUseCaseSubscriber): () => void {
|
||||
this.subscribers.add(subscriber);
|
||||
return () => {
|
||||
this.subscribers.delete(subscriber);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知所有订阅者
|
||||
* @param event 事件对象
|
||||
*/
|
||||
private notifySubscribers(event: PostUseCaseEvent): void {
|
||||
this.subscribers.forEach((subscriber) => {
|
||||
try {
|
||||
subscriber(event);
|
||||
} catch (error) {
|
||||
console.error('[ProcessPostUseCase] 订阅者执行失败:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知状态变化
|
||||
* @param key 列表键
|
||||
*/
|
||||
private notifyStateChanged(key: string): void {
|
||||
const state = this.getPostsState(key);
|
||||
this.notifySubscribers({
|
||||
type: 'state_changed',
|
||||
payload: { key, state },
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
}
|
||||
|
||||
// ==================== 状态管理 ====================
|
||||
|
||||
/**
|
||||
* 获取帖子列表状态
|
||||
* @param key 列表键(默认为 'default')
|
||||
*/
|
||||
getPostsState(key: string = 'default'): PostsState {
|
||||
let state = this.postsState.get(key);
|
||||
if (!state) {
|
||||
state = {
|
||||
posts: [],
|
||||
isLoading: false,
|
||||
isRefreshing: false,
|
||||
hasMore: true,
|
||||
error: null,
|
||||
cursor: null,
|
||||
lastLoadTime: null,
|
||||
};
|
||||
this.postsState.set(key, state);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取帖子详情状态
|
||||
* @param postId 帖子ID
|
||||
*/
|
||||
getPostDetailState(postId: string): PostDetailState {
|
||||
let state = this.postDetailState.get(postId);
|
||||
if (!state) {
|
||||
state = {
|
||||
post: null,
|
||||
isLoading: false,
|
||||
error: null,
|
||||
};
|
||||
this.postDetailState.set(postId, state);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新帖子列表状态
|
||||
* @param key 列表键
|
||||
* @param partialState 部分状态
|
||||
*/
|
||||
private updatePostsState(key: string, partialState: Partial<PostsState>): void {
|
||||
const currentState = this.getPostsState(key);
|
||||
this.postsState.set(key, {
|
||||
...currentState,
|
||||
...partialState,
|
||||
});
|
||||
this.notifyStateChanged(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新帖子详情状态
|
||||
* @param postId 帖子ID
|
||||
* @param partialState 部分状态
|
||||
*/
|
||||
private updatePostDetailState(postId: string, partialState: Partial<PostDetailState>): void {
|
||||
const currentState = this.getPostDetailState(postId);
|
||||
this.postDetailState.set(postId, {
|
||||
...currentState,
|
||||
...partialState,
|
||||
});
|
||||
}
|
||||
|
||||
// ==================== 帖子列表操作 ====================
|
||||
|
||||
/**
|
||||
* 获取帖子列表
|
||||
* @param params 查询参数
|
||||
* @param key 列表键(用于区分不同的列表)
|
||||
*/
|
||||
async fetchPosts(params?: GetPostsParams, key: string = 'default'): Promise<PostsResult> {
|
||||
const state = this.getPostsState(key);
|
||||
|
||||
// 更新加载状态
|
||||
this.updatePostsState(key, { isLoading: true, error: null });
|
||||
|
||||
try {
|
||||
// 合并分页参数
|
||||
const queryParams: GetPostsParams = {
|
||||
page: params?.page || 1,
|
||||
pageSize: params?.pageSize || DEFAULT_PAGE_SIZE,
|
||||
cursor: params?.cursor || state.cursor || undefined,
|
||||
...params,
|
||||
};
|
||||
|
||||
const result = await postRepository.getPosts(queryParams);
|
||||
|
||||
// 更新状态
|
||||
this.updatePostsState(key, {
|
||||
posts: result.posts,
|
||||
hasMore: result.hasMore,
|
||||
cursor: result.nextCursor || null,
|
||||
isLoading: false,
|
||||
lastLoadTime: Date.now(),
|
||||
});
|
||||
|
||||
// 通知订阅者
|
||||
this.notifySubscribers({
|
||||
type: 'posts_loaded',
|
||||
payload: { key, posts: result.posts, hasMore: result.hasMore },
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : '获取帖子列表失败';
|
||||
this.updatePostsState(key, {
|
||||
isLoading: false,
|
||||
error: errorMessage,
|
||||
});
|
||||
|
||||
this.notifySubscribers({
|
||||
type: 'error_occurred',
|
||||
payload: { key, error: errorMessage },
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新帖子列表
|
||||
* @param key 列表键
|
||||
*/
|
||||
async refreshPosts(key: string = 'default'): Promise<PostsResult> {
|
||||
// 更新刷新状态
|
||||
this.updatePostsState(key, { isRefreshing: true, error: null });
|
||||
|
||||
try {
|
||||
const result = await postRepository.getPosts({
|
||||
page: 1,
|
||||
pageSize: DEFAULT_PAGE_SIZE,
|
||||
});
|
||||
|
||||
// 更新状态
|
||||
this.updatePostsState(key, {
|
||||
posts: result.posts,
|
||||
hasMore: result.hasMore,
|
||||
cursor: result.nextCursor || null,
|
||||
isRefreshing: false,
|
||||
lastLoadTime: Date.now(),
|
||||
});
|
||||
|
||||
// 重置分页状态
|
||||
this.paginationManager.reset(key);
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : '刷新帖子列表失败';
|
||||
this.updatePostsState(key, {
|
||||
isRefreshing: false,
|
||||
error: errorMessage,
|
||||
});
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载更多帖子
|
||||
* @param key 列表键
|
||||
*/
|
||||
async loadMorePosts(key: string = 'default'): Promise<PostsResult> {
|
||||
const state = this.getPostsState(key);
|
||||
|
||||
// 检查是否还有更多数据
|
||||
if (!state.hasMore) {
|
||||
return {
|
||||
posts: [],
|
||||
hasMore: false,
|
||||
};
|
||||
}
|
||||
|
||||
// 检查是否正在加载
|
||||
if (state.isLoading) {
|
||||
return {
|
||||
posts: [],
|
||||
hasMore: state.hasMore,
|
||||
};
|
||||
}
|
||||
|
||||
// 更新加载状态
|
||||
this.updatePostsState(key, { isLoading: true, error: null });
|
||||
|
||||
try {
|
||||
const queryParams: GetPostsParams = {
|
||||
pageSize: DEFAULT_PAGE_SIZE,
|
||||
cursor: state.cursor || undefined,
|
||||
};
|
||||
|
||||
const result = await postRepository.getPosts(queryParams);
|
||||
|
||||
// 合并新数据
|
||||
const newPosts = [...state.posts, ...result.posts];
|
||||
|
||||
// 更新状态
|
||||
this.updatePostsState(key, {
|
||||
posts: newPosts,
|
||||
hasMore: result.hasMore,
|
||||
cursor: result.nextCursor || null,
|
||||
isLoading: false,
|
||||
lastLoadTime: Date.now(),
|
||||
});
|
||||
|
||||
return {
|
||||
posts: result.posts,
|
||||
hasMore: result.hasMore,
|
||||
nextCursor: result.nextCursor,
|
||||
};
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : '加载更多帖子失败';
|
||||
this.updatePostsState(key, {
|
||||
isLoading: false,
|
||||
error: errorMessage,
|
||||
});
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 帖子详情操作 ====================
|
||||
|
||||
/**
|
||||
* 获取单个帖子详情
|
||||
* @param id 帖子ID
|
||||
*/
|
||||
async fetchPostById(id: string): Promise<Post | null> {
|
||||
// 更新加载状态
|
||||
this.updatePostDetailState(id, { isLoading: true, error: null });
|
||||
|
||||
try {
|
||||
const post = await postRepository.getPostById(id);
|
||||
|
||||
// 更新状态
|
||||
this.updatePostDetailState(id, {
|
||||
post,
|
||||
isLoading: false,
|
||||
});
|
||||
|
||||
return post;
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : '获取帖子详情失败';
|
||||
this.updatePostDetailState(id, {
|
||||
isLoading: false,
|
||||
error: errorMessage,
|
||||
});
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 帖子CRUD操作 ====================
|
||||
|
||||
/**
|
||||
* 创建帖子
|
||||
* @param data 创建数据
|
||||
*/
|
||||
async createPost(data: CreatePostData): Promise<Post> {
|
||||
try {
|
||||
const post = await postRepository.createPost(data);
|
||||
|
||||
// 通知订阅者
|
||||
this.notifySubscribers({
|
||||
type: 'post_created',
|
||||
payload: { post },
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
// 更新所有列表(新帖子应该出现在列表顶部)
|
||||
this.postsState.forEach((state, key) => {
|
||||
this.updatePostsState(key, {
|
||||
posts: [post, ...state.posts],
|
||||
});
|
||||
});
|
||||
|
||||
return post;
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : '创建帖子失败';
|
||||
this.notifySubscribers({
|
||||
type: 'error_occurred',
|
||||
payload: { operation: 'create', error: errorMessage },
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新帖子
|
||||
* @param id 帖子ID
|
||||
* @param data 更新数据
|
||||
*/
|
||||
async updatePost(id: string, data: UpdatePostData): Promise<Post> {
|
||||
try {
|
||||
const post = await postRepository.updatePost(id, data);
|
||||
|
||||
// 更新详情状态
|
||||
this.updatePostDetailState(id, { post });
|
||||
|
||||
// 更新列表中的帖子
|
||||
this.updatePostInLists(id, post);
|
||||
|
||||
// 通知订阅者
|
||||
this.notifySubscribers({
|
||||
type: 'post_updated',
|
||||
payload: { postId: id, post },
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
return post;
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : '更新帖子失败';
|
||||
this.notifySubscribers({
|
||||
type: 'error_occurred',
|
||||
payload: { operation: 'update', postId: id, error: errorMessage },
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除帖子
|
||||
* @param id 帖子ID
|
||||
*/
|
||||
async deletePost(id: string): Promise<void> {
|
||||
try {
|
||||
await postRepository.deletePost(id);
|
||||
|
||||
// 从详情状态中移除
|
||||
this.postDetailState.delete(id);
|
||||
|
||||
// 从所有列表中移除
|
||||
this.postsState.forEach((state, key) => {
|
||||
const filteredPosts = state.posts.filter((post) => post.id !== id);
|
||||
this.updatePostsState(key, {
|
||||
posts: filteredPosts,
|
||||
});
|
||||
});
|
||||
|
||||
// 通知订阅者
|
||||
this.notifySubscribers({
|
||||
type: 'post_deleted',
|
||||
payload: { postId: id },
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : '删除帖子失败';
|
||||
this.notifySubscribers({
|
||||
type: 'error_occurred',
|
||||
payload: { operation: 'delete', postId: id, error: errorMessage },
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 互动操作 ====================
|
||||
|
||||
/**
|
||||
* 点赞帖子
|
||||
* @param id 帖子ID
|
||||
*/
|
||||
async likePost(id: string): Promise<Post> {
|
||||
try {
|
||||
const post = await postRepository.likePost(id);
|
||||
|
||||
// 更新详情状态
|
||||
this.updatePostDetailState(id, { post });
|
||||
|
||||
// 更新列表中的帖子
|
||||
this.updatePostInLists(id, post);
|
||||
|
||||
// 通知订阅者
|
||||
this.notifySubscribers({
|
||||
type: 'post_liked',
|
||||
payload: { postId: id, post },
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
return post;
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : '点赞失败';
|
||||
this.notifySubscribers({
|
||||
type: 'error_occurred',
|
||||
payload: { operation: 'like', postId: id, error: errorMessage },
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消点赞
|
||||
* @param id 帖子ID
|
||||
*/
|
||||
async unlikePost(id: string): Promise<Post> {
|
||||
try {
|
||||
const post = await postRepository.unlikePost(id);
|
||||
|
||||
// 更新详情状态
|
||||
this.updatePostDetailState(id, { post });
|
||||
|
||||
// 更新列表中的帖子
|
||||
this.updatePostInLists(id, post);
|
||||
|
||||
// 通知订阅者
|
||||
this.notifySubscribers({
|
||||
type: 'post_unliked',
|
||||
payload: { postId: id, post },
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
return post;
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : '取消点赞失败';
|
||||
this.notifySubscribers({
|
||||
type: 'error_occurred',
|
||||
payload: { operation: 'unlike', postId: id, error: errorMessage },
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 收藏帖子
|
||||
* @param id 帖子ID
|
||||
*/
|
||||
async favoritePost(id: string): Promise<Post> {
|
||||
try {
|
||||
const post = await postRepository.favoritePost(id);
|
||||
|
||||
// 更新详情状态
|
||||
this.updatePostDetailState(id, { post });
|
||||
|
||||
// 更新列表中的帖子
|
||||
this.updatePostInLists(id, post);
|
||||
|
||||
// 通知订阅者
|
||||
this.notifySubscribers({
|
||||
type: 'post_favorited',
|
||||
payload: { postId: id, post },
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
return post;
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : '收藏失败';
|
||||
this.notifySubscribers({
|
||||
type: 'error_occurred',
|
||||
payload: { operation: 'favorite', postId: id, error: errorMessage },
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消收藏
|
||||
* @param id 帖子ID
|
||||
*/
|
||||
async unfavoritePost(id: string): Promise<Post> {
|
||||
try {
|
||||
const post = await postRepository.unfavoritePost(id);
|
||||
|
||||
// 更新详情状态
|
||||
this.updatePostDetailState(id, { post });
|
||||
|
||||
// 更新列表中的帖子
|
||||
this.updatePostInLists(id, post);
|
||||
|
||||
// 通知订阅者
|
||||
this.notifySubscribers({
|
||||
type: 'post_unfavorited',
|
||||
payload: { postId: id, post },
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
return post;
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : '取消收藏失败';
|
||||
this.notifySubscribers({
|
||||
type: 'error_occurred',
|
||||
payload: { operation: 'unfavorite', postId: id, error: errorMessage },
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 搜索操作 ====================
|
||||
|
||||
/**
|
||||
* 搜索帖子
|
||||
* @param params 搜索参数
|
||||
* @param key 列表键
|
||||
*/
|
||||
async searchPosts(params: SearchPostsParams, key: string = 'search'): Promise<PostsResult> {
|
||||
// 更新加载状态
|
||||
this.updatePostsState(key, { isLoading: true, error: null });
|
||||
|
||||
try {
|
||||
const result = await postRepository.searchPosts(params);
|
||||
|
||||
// 更新状态
|
||||
this.updatePostsState(key, {
|
||||
posts: result.posts,
|
||||
hasMore: result.hasMore,
|
||||
cursor: result.nextCursor || null,
|
||||
isLoading: false,
|
||||
lastLoadTime: Date.now(),
|
||||
});
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : '搜索帖子失败';
|
||||
this.updatePostsState(key, {
|
||||
isLoading: false,
|
||||
error: errorMessage,
|
||||
});
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 用户帖子操作 ====================
|
||||
|
||||
/**
|
||||
* 获取用户发布的帖子
|
||||
* @param userId 用户ID
|
||||
* @param params 查询参数
|
||||
* @param key 列表键
|
||||
*/
|
||||
async fetchPostsByUser(
|
||||
userId: string,
|
||||
params?: GetPostsParams,
|
||||
key?: string
|
||||
): Promise<PostsResult> {
|
||||
const listKey = key || `user_${userId}`;
|
||||
|
||||
// 更新加载状态
|
||||
this.updatePostsState(listKey, { isLoading: true, error: null });
|
||||
|
||||
try {
|
||||
const result = await postRepository.getPostsByUser(userId, params);
|
||||
|
||||
// 更新状态
|
||||
this.updatePostsState(listKey, {
|
||||
posts: result.posts,
|
||||
hasMore: result.hasMore,
|
||||
cursor: result.nextCursor || null,
|
||||
isLoading: false,
|
||||
lastLoadTime: Date.now(),
|
||||
});
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : '获取用户帖子失败';
|
||||
this.updatePostsState(listKey, {
|
||||
isLoading: false,
|
||||
error: errorMessage,
|
||||
});
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 辅助方法 ====================
|
||||
|
||||
/**
|
||||
* 更新所有列表中的帖子
|
||||
* @param postId 帖子ID
|
||||
* @param updatedPost 更新后的帖子
|
||||
*/
|
||||
private updatePostInLists(postId: string, updatedPost: Post): void {
|
||||
this.postsState.forEach((state, key) => {
|
||||
const index = state.posts.findIndex((post) => post.id === postId);
|
||||
if (index !== -1) {
|
||||
const newPosts = [...state.posts];
|
||||
newPosts[index] = updatedPost;
|
||||
this.updatePostsState(key, { posts: newPosts });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除指定列表的状态
|
||||
* @param key 列表键
|
||||
*/
|
||||
clearPostsState(key: string = 'default'): void {
|
||||
this.postsState.delete(key);
|
||||
this.paginationManager.reset(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除帖子详情状态
|
||||
* @param postId 帖子ID
|
||||
*/
|
||||
clearPostDetailState(postId: string): void {
|
||||
this.postDetailState.delete(postId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有状态
|
||||
*/
|
||||
clearAllStates(): void {
|
||||
this.postsState.clear();
|
||||
this.postDetailState.clear();
|
||||
this.paginationManager.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户ID
|
||||
*/
|
||||
getCurrentUserId(): string | null {
|
||||
return this.currentUserId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前用户ID
|
||||
*/
|
||||
setCurrentUserId(userId: string | null): void {
|
||||
this.currentUserId = userId;
|
||||
}
|
||||
|
||||
// ==================== 分页状态管理集成 ====================
|
||||
|
||||
/**
|
||||
* 获取分页状态
|
||||
* @param key 列表键
|
||||
*/
|
||||
getPaginationState(key: string): PaginationState {
|
||||
return this.paginationManager.getState(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置分页状态
|
||||
* @param key 列表键
|
||||
*/
|
||||
resetPagination(key: string): void {
|
||||
this.paginationManager.reset(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否正在加载
|
||||
* @param key 列表键
|
||||
*/
|
||||
isLoading(key: string = 'default'): boolean {
|
||||
return this.getPostsState(key).isLoading;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否有错误
|
||||
* @param key 列表键
|
||||
*/
|
||||
hasError(key: string = 'default'): boolean {
|
||||
return this.getPostsState(key).error !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取错误信息
|
||||
* @param key 列表键
|
||||
*/
|
||||
getError(key: string = 'default'): string | null {
|
||||
return this.getPostsState(key).error;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 导出 ====================
|
||||
|
||||
// 导出单例实例
|
||||
export const processPostUseCase = ProcessPostUseCase.getInstance();
|
||||
export default processPostUseCase;
|
||||
Reference in New Issue
Block a user