Files
frontend/src/core/usecases/ProcessPostUseCase.ts
lafay f9f4e73747
Some checks failed
Frontend CI / build-and-push-web (push) Successful in 7m11s
Frontend CI / ota-android (push) Successful in 12m55s
Frontend CI / build-android-apk (push) Has been cancelled
feat(ProcessPostUseCase, HomeScreen, PostDetailScreen, PostService): implement share count synchronization after post sharing
- Added applyShareCountUpdate method in ProcessPostUseCase to synchronize share counts across post lists and details.
- Updated sharePost method in PostService to return the latest shares_count from the server.
- Modified share handling in HomeScreen and PostDetailScreen to utilize the new share count synchronization logic after a successful share operation.
- Enhanced error handling for share operations to improve user feedback.
2026-03-24 05:21:46 +08:00

1036 lines
28 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 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 模式) */
cursor: string | null;
/** 当前页码page 模式) */
currentPage: number;
/** 最后加载时间 */
lastLoadTime: number | null;
/** 上次请求的参数(用于加载更多和刷新) */
lastParams?: GetPostsParams;
}
/**
* 帖子详情状态
*/
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 readonly mergePerfWarnThresholdMs = 12;
// 私有构造函数
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,
currentPage: 1,
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);
}
private getEntityId(item: unknown): string | null {
if (!item || typeof item !== 'object') {
return null;
}
const maybeId = (item as { id?: unknown }).id;
if (typeof maybeId === 'string' || typeof maybeId === 'number') {
return String(maybeId);
}
return null;
}
private mergePostListWithFastPath(previousInput: Post[] | null | undefined, incomingInput: Post[] | null | undefined): Post[] {
const previous = Array.isArray(previousInput) ? previousInput : [];
const incoming = Array.isArray(incomingInput) ? incomingInput : [];
if (incoming.length === 0) {
return previous;
}
if (previous.length === 0) {
return incoming;
}
const lastPrevId = this.getEntityId(previous[previous.length - 1]);
const firstIncomingId = this.getEntityId(incoming[0]);
if (lastPrevId && firstIncomingId && lastPrevId !== firstIncomingId) {
const prevIdSet = new Set(previous.map((item) => this.getEntityId(item)).filter(Boolean) as string[]);
if (!prevIdSet.has(firstIncomingId)) {
return [...previous, ...incoming];
}
}
const merged = [...previous];
const indexById = new Map<string, number>();
for (let i = 0; i < merged.length; i += 1) {
const id = this.getEntityId(merged[i]);
if (id) {
indexById.set(id, i);
}
}
for (const post of incoming) {
const id = this.getEntityId(post);
if (!id) {
merged.push(post);
continue;
}
const existingIndex = indexById.get(id);
if (existingIndex === undefined) {
indexById.set(id, merged.length);
merged.push(post);
} else {
merged[existingIndex] = post;
}
}
return merged;
}
private mergeRefreshWindow(previousInput: Post[] | null | undefined, latestInput: Post[] | null | undefined): Post[] {
const previous = Array.isArray(previousInput) ? previousInput : [];
const latest = Array.isArray(latestInput) ? latestInput : [];
if (latest.length === 0) {
return previous;
}
if (previous.length === 0) {
return latest;
}
const latestIdSet = new Set(
latest.map((item) => this.getEntityId(item)).filter(Boolean) as string[]
);
const remaining = previous.filter((item) => {
const id = this.getEntityId(item);
return !id || !latestIdSet.has(id);
});
return [...latest, ...remaining];
}
/**
* 更新帖子详情状态
* @param postId 帖子ID
* @param partialState 部分状态
*/
private updatePostDetailState(postId: string, partialState: Partial<PostDetailState>): void {
const currentState = this.getPostDetailState(postId);
this.postDetailState.set(postId, {
...currentState,
...partialState,
});
}
/**
* 分享计数上报成功后,同步各列表与详情中的分享数
*/
applyShareCountUpdate(postId: string, sharesCount: number): void {
this.postsState.forEach((state, key) => {
const index = state.posts.findIndex((p) => p.id === postId);
if (index !== -1) {
const newPosts = [...state.posts];
const cur = newPosts[index];
newPosts[index] = {
...cur,
sharesCount,
shares_count: sharesCount,
};
this.updatePostsState(key, { posts: newPosts });
}
});
const detail = this.getPostDetailState(postId);
if (detail.post) {
this.updatePostDetailState(postId, {
post: {
...detail.post,
sharesCount,
shares_count: sharesCount,
},
});
}
}
// ==================== 帖子列表操作 ====================
/**
* 获取帖子列表
* @param params 查询参数
* @param key 列表键(用于区分不同的列表)
*/
async fetchPosts(params?: GetPostsParams, key: string = 'default'): Promise<PostsResult> {
// 更新加载状态
this.updatePostsState(key, { isLoading: true, error: null });
try {
// 默认传递空字符串 cursor 来启动 cursor 模式
// 注意cursor 要放在 ...params 后面,这样只有在 params 没有传 cursor 时才使用默认值
const queryParams: GetPostsParams = {
pageSize: params?.pageSize || DEFAULT_PAGE_SIZE,
...params,
cursor: params?.cursor !== undefined ? params.cursor : '', // 默认使用空字符串启动 cursor 模式
};
const result = await postRepository.getPosts(queryParams);
// 判断是否为 cursor 模式(有 next_cursor 返回)
const isCursorMode = result.nextCursor !== undefined && result.nextCursor !== null;
// 更新状态(保存请求参数以便加载更多时使用)
const mergeStart = Date.now();
const currentState = this.getPostsState(key);
const incomingPosts = Array.isArray(result.posts) ? result.posts : [];
const mergedPosts = this.mergeRefreshWindow(currentState.posts, incomingPosts);
const mergeCost = Date.now() - mergeStart;
if (mergeCost >= this.mergePerfWarnThresholdMs) {
console.log('[PostPerf] fetchPosts merge cost', { key, costMs: mergeCost, prev: currentState.posts.length, next: incomingPosts.length });
}
this.updatePostsState(key, {
posts: mergedPosts,
hasMore: result.hasMore,
cursor: isCursorMode ? result.nextCursor : null, // cursor 模式保存 cursor否则设为 null 表示 page 模式
currentPage: isCursorMode ? undefined : 1, // page 模式从第 1 页开始
isLoading: false,
lastLoadTime: Date.now(),
lastParams: params, // 保存请求参数
});
// 通知订阅者
this.notifySubscribers({
type: 'posts_loaded',
payload: { key, posts: incomingPosts, 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> {
const state = this.getPostsState(key);
// 更新刷新状态
this.updatePostsState(key, { isRefreshing: true, error: null });
try {
// 使用保存的请求参数(如 post_type进行刷新
// 默认传递空字符串 cursor 来启动 cursor 模式
const result = await postRepository.getPosts({
pageSize: DEFAULT_PAGE_SIZE,
...state.lastParams,
cursor: state.lastParams?.cursor !== undefined ? state.lastParams.cursor : '', // 默认使用空字符串启动 cursor 模式
});
// 判断是否为 cursor 模式(有 next_cursor 返回)
const isCursorMode = result.nextCursor !== undefined && result.nextCursor !== null;
// 更新状态
const mergeStart = Date.now();
const incomingPosts = Array.isArray(result.posts) ? result.posts : [];
const mergedPosts = this.mergeRefreshWindow(state.posts, incomingPosts);
const mergeCost = Date.now() - mergeStart;
if (mergeCost >= this.mergePerfWarnThresholdMs) {
console.log('[PostPerf] refreshPosts merge cost', { key, costMs: mergeCost, prev: state.posts.length, next: incomingPosts.length });
}
this.updatePostsState(key, {
posts: mergedPosts,
hasMore: result.hasMore,
cursor: isCursorMode ? result.nextCursor : null,
currentPage: isCursorMode ? undefined : 1,
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 {
// 判断使用哪种分页模式cursor 不为 null 表示使用 cursor 模式
const useCursorMode = state.cursor !== null && state.cursor !== undefined;
// 必须先展开 lastParams再由本次分页字段覆盖。
// lastParams 来自首次 fetch通常含 page:1若写在展开之前会把 nextPage/cursor 覆盖掉,导致永远请求第 1 页、无法加载第 3 页及以后。
const base = { ...(state.lastParams ?? {}) } as GetPostsParams;
let queryParams: GetPostsParams;
if (useCursorMode) {
delete base.page;
queryParams = {
...base,
pageSize: DEFAULT_PAGE_SIZE,
cursor: state.cursor!,
};
} else {
const nextPage = (state.currentPage || 1) + 1;
delete base.cursor;
queryParams = {
...base,
pageSize: DEFAULT_PAGE_SIZE,
page: nextPage,
};
}
const result = await postRepository.getPosts(queryParams);
// 合并新数据
const mergeStart = Date.now();
const incomingPosts = Array.isArray(result.posts) ? result.posts : [];
const newPosts = this.mergePostListWithFastPath(state.posts, incomingPosts);
const mergeCost = Date.now() - mergeStart;
if (mergeCost >= this.mergePerfWarnThresholdMs) {
console.log('[PostPerf] loadMore merge cost', { key, costMs: mergeCost, prev: state.posts.length, incoming: incomingPosts.length, merged: newPosts.length });
}
// 判断响应是否为 cursor 模式(有 next_cursor 返回)
const responseIsCursorMode = result.nextCursor !== undefined && result.nextCursor !== null;
// 更新状态
this.updatePostsState(key, {
posts: newPosts,
hasMore: result.hasMore,
cursor: responseIsCursorMode ? result.nextCursor : null,
currentPage: useCursorMode ? state.currentPage : ((state.currentPage || 1) + 1),
isLoading: false,
lastLoadTime: Date.now(),
});
return {
posts: incomingPosts,
hasMore: result.hasMore,
nextCursor: result.nextCursor,
};
} catch (error) {
const errorMessage = error instanceof Error ? error.message : '加载更多帖子失败';
console.error('[ProcessPostUseCase] Load more error:', errorMessage);
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;