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:
550
src/data/repositories/PostRepository.ts
Normal file
550
src/data/repositories/PostRepository.ts
Normal file
@@ -0,0 +1,550 @@
|
||||
/**
|
||||
* PostRepository - 帖子仓库实现
|
||||
* 实现IPostRepository接口,封装帖子相关的数据访问逻辑
|
||||
*/
|
||||
|
||||
import { ApiDataSource, apiDataSource } from '../datasources/ApiDataSource';
|
||||
import { LocalDataSource, localDataSource } from '../datasources/LocalDataSource';
|
||||
import { PostMapper } from '../mappers/PostMapper';
|
||||
import type { Post, PostImage, PostStatus } from '../../core/entities/Post';
|
||||
import { createPost } from '../../core/entities/Post';
|
||||
import type {
|
||||
IPostRepository,
|
||||
GetPostsParams,
|
||||
CreatePostData,
|
||||
UpdatePostData,
|
||||
PostsResult,
|
||||
SearchPostsParams,
|
||||
} from './interfaces/IPostRepository';
|
||||
|
||||
// ==================== 类型定义 ====================
|
||||
|
||||
/**
|
||||
* API帖子响应类型
|
||||
*/
|
||||
interface PostApiResponse {
|
||||
id: number;
|
||||
user_id: number;
|
||||
title: string;
|
||||
content: string;
|
||||
images?: Array<{ url: string; width?: number; height?: number; thumbnail_url?: string }>;
|
||||
likes_count: number;
|
||||
comments_count: number;
|
||||
shares_count: number;
|
||||
views_count: number;
|
||||
favorites_count: number;
|
||||
is_liked: boolean;
|
||||
is_favorited: boolean;
|
||||
is_pinned: boolean;
|
||||
status: string;
|
||||
community_id?: string;
|
||||
tags?: string[];
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
author?: {
|
||||
id: number;
|
||||
username: string;
|
||||
nickname?: string;
|
||||
avatar?: string;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* API帖子列表响应类型
|
||||
*/
|
||||
interface PostsListApiResponse {
|
||||
posts: PostApiResponse[];
|
||||
has_more: boolean;
|
||||
next_cursor?: string;
|
||||
total?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存的帖子数据
|
||||
*/
|
||||
interface CachedPost {
|
||||
id: string;
|
||||
data: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
// ==================== PostRepository 实现 ====================
|
||||
|
||||
export class PostRepository implements IPostRepository {
|
||||
private api: ApiDataSource;
|
||||
private localDb: LocalDataSource;
|
||||
private memoryCache: Map<string, { post: Post; timestamp: number }> = new Map();
|
||||
private readonly CACHE_TTL = 5 * 60 * 1000; // 5分钟缓存过期时间
|
||||
|
||||
constructor(api: ApiDataSource, localDb: LocalDataSource) {
|
||||
this.api = api;
|
||||
this.localDb = localDb;
|
||||
}
|
||||
|
||||
// ==================== 私有辅助方法 ====================
|
||||
|
||||
/**
|
||||
* 将API响应转换为领域实体
|
||||
* 同时设置 camelCase 和 snake_case 字段以保持向后兼容
|
||||
*/
|
||||
private mapToPost(response: PostApiResponse): Post {
|
||||
const model = PostMapper.fromApiResponse(response as any);
|
||||
return {
|
||||
// camelCase 字段(新标准)
|
||||
id: model.id,
|
||||
authorId: model.authorId,
|
||||
author: model.author ? {
|
||||
id: model.author.id,
|
||||
username: model.author.username,
|
||||
nickname: model.author.nickname,
|
||||
avatar: model.author.avatar,
|
||||
} : undefined,
|
||||
title: model.title,
|
||||
content: model.content,
|
||||
images: (model.images || []).map(url => ({
|
||||
url,
|
||||
width: undefined,
|
||||
height: undefined,
|
||||
})) as PostImage[],
|
||||
likesCount: model.likeCount,
|
||||
commentsCount: model.commentCount,
|
||||
sharesCount: model.shareCount,
|
||||
viewsCount: model.viewCount,
|
||||
favoritesCount: model.favoriteCount,
|
||||
isLiked: model.isLiked,
|
||||
isFavorited: model.isFavorited,
|
||||
isPinned: model.isTop,
|
||||
status: model.status,
|
||||
communityId: model.communityId,
|
||||
tags: model.tags || [],
|
||||
createdAt: model.createdAt.toISOString(),
|
||||
updatedAt: model.updatedAt.toISOString(),
|
||||
|
||||
// snake_case 字段(向后兼容)
|
||||
likes_count: model.likeCount,
|
||||
comments_count: model.commentCount,
|
||||
favorites_count: model.favoriteCount,
|
||||
shares_count: model.shareCount,
|
||||
views_count: model.viewCount,
|
||||
is_liked: model.isLiked,
|
||||
is_favorited: model.isFavorited,
|
||||
is_pinned: model.isTop,
|
||||
user_id: model.authorId,
|
||||
created_at: model.createdAt.toISOString(),
|
||||
updated_at: model.updatedAt.toISOString(),
|
||||
community_id: model.communityId,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 从内存缓存获取帖子
|
||||
*/
|
||||
private getFromMemoryCache(id: string): Post | null {
|
||||
const cached = this.memoryCache.get(id);
|
||||
if (!cached) return null;
|
||||
|
||||
// 检查缓存是否过期
|
||||
if (Date.now() - cached.timestamp > this.CACHE_TTL) {
|
||||
this.memoryCache.delete(id);
|
||||
return null;
|
||||
}
|
||||
|
||||
return cached.post;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存帖子到内存缓存
|
||||
*/
|
||||
private saveToMemoryCache(post: Post): void {
|
||||
this.memoryCache.set(post.id, {
|
||||
post,
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 从本地数据库获取缓存的帖子
|
||||
*/
|
||||
private async getFromLocalCache(id: string): Promise<Post | null> {
|
||||
try {
|
||||
await this.localDb.initialize();
|
||||
const result = await this.localDb.getFirst<CachedPost>(
|
||||
'SELECT * FROM posts_cache WHERE id = ?',
|
||||
[id]
|
||||
);
|
||||
|
||||
if (!result) return null;
|
||||
|
||||
const post = JSON.parse(result.data) as Post;
|
||||
return post;
|
||||
} catch (error) {
|
||||
console.error('[PostRepository] 获取本地缓存失败:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存帖子到本地缓存
|
||||
*/
|
||||
private async saveToLocalCache(post: Post): Promise<void> {
|
||||
try {
|
||||
await this.localDb.initialize();
|
||||
await this.localDb.run(
|
||||
`INSERT OR REPLACE INTO posts_cache (id, data, updatedAt) VALUES (?, ?, ?)`,
|
||||
[post.id, JSON.stringify(post), new Date().toISOString()]
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('[PostRepository] 保存本地缓存失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除帖子的本地缓存
|
||||
*/
|
||||
private async clearLocalCache(id: string): Promise<void> {
|
||||
try {
|
||||
await this.localDb.initialize();
|
||||
await this.localDb.run('DELETE FROM posts_cache WHERE id = ?', [id]);
|
||||
} catch (error) {
|
||||
console.error('[PostRepository] 清除本地缓存失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理错误
|
||||
*/
|
||||
private handleError(error: unknown, operation: string): never {
|
||||
const message = error instanceof Error ? error.message : 'Unknown error';
|
||||
console.error(`[PostRepository] ${operation} 失败:`, error);
|
||||
throw new Error(`帖子${operation}失败: ${message}`);
|
||||
}
|
||||
|
||||
// ==================== 帖子查询 ====================
|
||||
|
||||
/**
|
||||
* 获取帖子列表
|
||||
*/
|
||||
async getPosts(params?: GetPostsParams): Promise<PostsResult> {
|
||||
try {
|
||||
const queryParams: Record<string, any> = {};
|
||||
|
||||
if (params?.page) queryParams.page = params.page;
|
||||
if (params?.pageSize) queryParams.page_size = params.pageSize;
|
||||
if (params?.cursor) queryParams.cursor = params.cursor;
|
||||
if (params?.post_type) queryParams.tab = params.post_type;
|
||||
if (params?.communityId) queryParams.community_id = params.communityId;
|
||||
if (params?.authorId) queryParams.author_id = params.authorId;
|
||||
if (params?.tags && params.tags.length > 0) queryParams.tags = params.tags.join(',');
|
||||
if (params?.status) queryParams.status = params.status;
|
||||
if (params?.sortBy) queryParams.sort_by = params.sortBy;
|
||||
if (params?.sortOrder) queryParams.sort_order = params.sortOrder;
|
||||
if (params?.pinnedOnly) queryParams.pinned_only = true;
|
||||
|
||||
const response = await this.api.get<PostsListApiResponse>('/posts', queryParams);
|
||||
|
||||
const posts = response.posts.map(p => this.mapToPost(p));
|
||||
|
||||
// 缓存帖子
|
||||
posts.forEach(post => {
|
||||
this.saveToMemoryCache(post);
|
||||
this.saveToLocalCache(post);
|
||||
});
|
||||
|
||||
return {
|
||||
posts,
|
||||
hasMore: response.has_more,
|
||||
nextCursor: response.next_cursor,
|
||||
total: response.total,
|
||||
};
|
||||
} catch (error) {
|
||||
this.handleError(error, '获取帖子列表');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单个帖子详情
|
||||
*/
|
||||
async getPostById(id: string): Promise<Post | null> {
|
||||
try {
|
||||
// 1. 先查内存缓存
|
||||
const memoryCached = this.getFromMemoryCache(id);
|
||||
if (memoryCached) {
|
||||
return memoryCached;
|
||||
}
|
||||
|
||||
// 2. 查本地数据库缓存
|
||||
const localCached = await this.getFromLocalCache(id);
|
||||
if (localCached) {
|
||||
this.saveToMemoryCache(localCached);
|
||||
return localCached;
|
||||
}
|
||||
|
||||
// 3. 从API获取
|
||||
const response = await this.api.get<PostApiResponse>(`/posts/${id}`);
|
||||
const post = this.mapToPost(response);
|
||||
|
||||
// 更新缓存
|
||||
this.saveToMemoryCache(post);
|
||||
await this.saveToLocalCache(post);
|
||||
|
||||
return post;
|
||||
} catch (error) {
|
||||
// 如果API请求失败,尝试返回本地缓存
|
||||
const localCached = await this.getFromLocalCache(id);
|
||||
if (localCached) {
|
||||
console.warn('[PostRepository] API获取失败,使用本地缓存:', error);
|
||||
return localCached;
|
||||
}
|
||||
this.handleError(error, '获取帖子详情');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户发布的帖子列表
|
||||
*/
|
||||
async getPostsByUser(userId: string, params?: GetPostsParams): Promise<PostsResult> {
|
||||
try {
|
||||
const queryParams: Record<string, any> = { author_id: userId };
|
||||
|
||||
if (params?.page) queryParams.page = params.page;
|
||||
if (params?.pageSize) queryParams.page_size = params.pageSize;
|
||||
if (params?.cursor) queryParams.cursor = params.cursor;
|
||||
if (params?.status) queryParams.status = params.status;
|
||||
if (params?.sortBy) queryParams.sort_by = params.sortBy;
|
||||
if (params?.sortOrder) queryParams.sort_order = params.sortOrder;
|
||||
|
||||
const response = await this.api.get<PostsListApiResponse>(`/users/${userId}/posts`, queryParams);
|
||||
|
||||
const posts = response.posts.map(p => this.mapToPost(p));
|
||||
|
||||
// 缓存帖子
|
||||
posts.forEach(post => {
|
||||
this.saveToMemoryCache(post);
|
||||
this.saveToLocalCache(post);
|
||||
});
|
||||
|
||||
return {
|
||||
posts,
|
||||
hasMore: response.has_more,
|
||||
nextCursor: response.next_cursor,
|
||||
total: response.total,
|
||||
};
|
||||
} catch (error) {
|
||||
this.handleError(error, '获取用户帖子列表');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索帖子
|
||||
*/
|
||||
async searchPosts(params: SearchPostsParams): Promise<PostsResult> {
|
||||
try {
|
||||
const queryParams: Record<string, any> = {
|
||||
keyword: params.keyword,
|
||||
};
|
||||
|
||||
if (params.page) queryParams.page = params.page;
|
||||
if (params.pageSize) queryParams.page_size = params.pageSize;
|
||||
if (params.scope) queryParams.scope = params.scope;
|
||||
if (params.communityId) queryParams.community_id = params.communityId;
|
||||
|
||||
const response = await this.api.get<PostsListApiResponse>('/posts/search', queryParams);
|
||||
|
||||
const posts = response.posts.map(p => this.mapToPost(p));
|
||||
|
||||
// 缓存帖子
|
||||
posts.forEach(post => {
|
||||
this.saveToMemoryCache(post);
|
||||
this.saveToLocalCache(post);
|
||||
});
|
||||
|
||||
return {
|
||||
posts,
|
||||
hasMore: response.has_more,
|
||||
nextCursor: response.next_cursor,
|
||||
total: response.total,
|
||||
};
|
||||
} catch (error) {
|
||||
this.handleError(error, '搜索帖子');
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 帖子操作 ====================
|
||||
|
||||
/**
|
||||
* 创建帖子
|
||||
*/
|
||||
async createPost(data: CreatePostData): Promise<Post> {
|
||||
try {
|
||||
const requestData = PostMapper.createPostRequest(
|
||||
data.title,
|
||||
data.content,
|
||||
data.images?.map(img => img.url),
|
||||
data.communityId
|
||||
);
|
||||
|
||||
if (data.tags && data.tags.length > 0) {
|
||||
requestData.tags = data.tags;
|
||||
}
|
||||
|
||||
if (data.status) {
|
||||
requestData.status = data.status;
|
||||
}
|
||||
|
||||
const response = await this.api.post<PostApiResponse>('/posts', requestData);
|
||||
const post = this.mapToPost(response);
|
||||
|
||||
// 缓存新创建的帖子
|
||||
this.saveToMemoryCache(post);
|
||||
await this.saveToLocalCache(post);
|
||||
|
||||
return post;
|
||||
} catch (error) {
|
||||
this.handleError(error, '创建帖子');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新帖子
|
||||
*/
|
||||
async updatePost(id: string, data: UpdatePostData): Promise<Post> {
|
||||
try {
|
||||
const requestData: Record<string, any> = {};
|
||||
|
||||
if (data.title !== undefined) requestData.title = data.title;
|
||||
if (data.content !== undefined) requestData.content = data.content;
|
||||
if (data.images !== undefined) requestData.images = data.images.map(img => img.url);
|
||||
if (data.tags !== undefined) requestData.tags = data.tags;
|
||||
if (data.status !== undefined) requestData.status = data.status;
|
||||
if (data.isPinned !== undefined) requestData.is_pinned = data.isPinned;
|
||||
|
||||
const response = await this.api.put<PostApiResponse>(`/posts/${id}`, requestData);
|
||||
const post = this.mapToPost(response);
|
||||
|
||||
// 更新缓存
|
||||
this.saveToMemoryCache(post);
|
||||
await this.saveToLocalCache(post);
|
||||
|
||||
return post;
|
||||
} catch (error) {
|
||||
this.handleError(error, '更新帖子');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除帖子
|
||||
*/
|
||||
async deletePost(id: string): Promise<void> {
|
||||
try {
|
||||
await this.api.delete(`/posts/${id}`);
|
||||
|
||||
// 清除缓存
|
||||
this.memoryCache.delete(id);
|
||||
await this.clearLocalCache(id);
|
||||
} catch (error) {
|
||||
this.handleError(error, '删除帖子');
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 互动操作 ====================
|
||||
|
||||
/**
|
||||
* 点赞帖子
|
||||
*/
|
||||
async likePost(id: string): Promise<Post> {
|
||||
try {
|
||||
const response = await this.api.post<PostApiResponse>(`/posts/${id}/like`);
|
||||
const post = this.mapToPost(response);
|
||||
|
||||
// 更新缓存
|
||||
this.saveToMemoryCache(post);
|
||||
await this.saveToLocalCache(post);
|
||||
|
||||
return post;
|
||||
} catch (error) {
|
||||
this.handleError(error, '点赞帖子');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消点赞
|
||||
*/
|
||||
async unlikePost(id: string): Promise<Post> {
|
||||
try {
|
||||
const response = await this.api.delete<PostApiResponse>(`/posts/${id}/like`);
|
||||
const post = this.mapToPost(response);
|
||||
|
||||
// 更新缓存
|
||||
this.saveToMemoryCache(post);
|
||||
await this.saveToLocalCache(post);
|
||||
|
||||
return post;
|
||||
} catch (error) {
|
||||
this.handleError(error, '取消点赞');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 收藏帖子
|
||||
*/
|
||||
async favoritePost(id: string): Promise<Post> {
|
||||
try {
|
||||
const response = await this.api.post<PostApiResponse>(`/posts/${id}/favorite`);
|
||||
const post = this.mapToPost(response);
|
||||
|
||||
// 更新缓存
|
||||
this.saveToMemoryCache(post);
|
||||
await this.saveToLocalCache(post);
|
||||
|
||||
return post;
|
||||
} catch (error) {
|
||||
this.handleError(error, '收藏帖子');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消收藏
|
||||
*/
|
||||
async unfavoritePost(id: string): Promise<Post> {
|
||||
try {
|
||||
const response = await this.api.delete<PostApiResponse>(`/posts/${id}/favorite`);
|
||||
const post = this.mapToPost(response);
|
||||
|
||||
// 更新缓存
|
||||
this.saveToMemoryCache(post);
|
||||
await this.saveToLocalCache(post);
|
||||
|
||||
return post;
|
||||
} catch (error) {
|
||||
this.handleError(error, '取消收藏');
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 缓存管理 ====================
|
||||
|
||||
/**
|
||||
* 清除所有缓存
|
||||
*/
|
||||
async clearAllCache(): Promise<void> {
|
||||
this.memoryCache.clear();
|
||||
try {
|
||||
await this.localDb.initialize();
|
||||
await this.localDb.run('DELETE FROM posts_cache');
|
||||
} catch (error) {
|
||||
console.error('[PostRepository] 清除所有缓存失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使指定帖子的缓存失效
|
||||
*/
|
||||
async invalidateCache(id: string): Promise<void> {
|
||||
this.memoryCache.delete(id);
|
||||
await this.clearLocalCache(id);
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 单例导出 ====================
|
||||
|
||||
export const postRepository = new PostRepository(apiDataSource, localDataSource);
|
||||
export default postRepository;
|
||||
190
src/data/repositories/interfaces/IPostRepository.ts
Normal file
190
src/data/repositories/interfaces/IPostRepository.ts
Normal file
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
* 帖子 Repository 接口
|
||||
* 定义帖子数据访问的抽象
|
||||
*/
|
||||
|
||||
import type { Post, PostImage, PostStatus } from '../../../core/entities/Post';
|
||||
|
||||
// ==================== 请求/响应类型 ====================
|
||||
|
||||
/**
|
||||
* 获取帖子列表参数
|
||||
*/
|
||||
export interface GetPostsParams {
|
||||
/** 分页 - 页码(从1开始) */
|
||||
page?: number;
|
||||
/** 分页 - 每页数量 */
|
||||
pageSize?: number;
|
||||
/** 游标 - 用于无限滚动加载 */
|
||||
cursor?: string;
|
||||
/** 帖子类型筛选(可选):recommend, follow, hot, latest */
|
||||
post_type?: 'recommend' | 'follow' | 'hot' | 'latest';
|
||||
/** 社区ID过滤 */
|
||||
communityId?: string;
|
||||
/** 作者ID过滤 */
|
||||
authorId?: string;
|
||||
/** 标签过滤 */
|
||||
tags?: string[];
|
||||
/** 状态过滤 */
|
||||
status?: PostStatus;
|
||||
/** 排序字段 */
|
||||
sortBy?: 'createdAt' | 'likesCount' | 'commentsCount' | 'viewsCount';
|
||||
/** 排序方向 */
|
||||
sortOrder?: 'asc' | 'desc';
|
||||
/** 是否只获取置顶帖子 */
|
||||
pinnedOnly?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建帖子数据
|
||||
*/
|
||||
export interface CreatePostData {
|
||||
/** 帖子标题 */
|
||||
title: string;
|
||||
/** 帖子内容 */
|
||||
content: string;
|
||||
/** 图片列表 */
|
||||
images?: PostImage[];
|
||||
/** 所属社区ID */
|
||||
communityId?: string;
|
||||
/** 标签列表 */
|
||||
tags?: string[];
|
||||
/** 帖子状态 */
|
||||
status?: PostStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新帖子数据
|
||||
*/
|
||||
export interface UpdatePostData {
|
||||
/** 帖子标题 */
|
||||
title?: string;
|
||||
/** 帖子内容 */
|
||||
content?: string;
|
||||
/** 图片列表 */
|
||||
images?: PostImage[];
|
||||
/** 标签列表 */
|
||||
tags?: string[];
|
||||
/** 帖子状态 */
|
||||
status?: PostStatus;
|
||||
/** 是否置顶 */
|
||||
isPinned?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 帖子列表结果
|
||||
*/
|
||||
export interface PostsResult {
|
||||
/** 帖子列表 */
|
||||
posts: Post[];
|
||||
/** 是否有更多数据 */
|
||||
hasMore: boolean;
|
||||
/** 下一页游标 */
|
||||
nextCursor?: string;
|
||||
/** 总数(如果支持) */
|
||||
total?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索帖子参数
|
||||
*/
|
||||
export interface SearchPostsParams {
|
||||
/** 搜索关键词 */
|
||||
keyword: string;
|
||||
/** 分页 - 页码 */
|
||||
page?: number;
|
||||
/** 分页 - 每页数量 */
|
||||
pageSize?: number;
|
||||
/** 搜索范围:标题、内容、或全部 */
|
||||
scope?: 'title' | 'content' | 'all';
|
||||
/** 社区ID过滤 */
|
||||
communityId?: string;
|
||||
}
|
||||
|
||||
// ==================== Repository 接口 ====================
|
||||
|
||||
export interface IPostRepository {
|
||||
// ==================== 帖子查询 ====================
|
||||
|
||||
/**
|
||||
* 获取帖子列表
|
||||
* @param params 查询参数
|
||||
* @returns 帖子列表结果
|
||||
*/
|
||||
getPosts(params?: GetPostsParams): Promise<PostsResult>;
|
||||
|
||||
/**
|
||||
* 获取单个帖子详情
|
||||
* @param id 帖子ID
|
||||
* @returns 帖子实体,不存在则返回null
|
||||
*/
|
||||
getPostById(id: string): Promise<Post | null>;
|
||||
|
||||
/**
|
||||
* 获取用户发布的帖子列表
|
||||
* @param userId 用户ID
|
||||
* @param params 查询参数
|
||||
* @returns 帖子列表结果
|
||||
*/
|
||||
getPostsByUser(userId: string, params?: GetPostsParams): Promise<PostsResult>;
|
||||
|
||||
/**
|
||||
* 搜索帖子
|
||||
* @param params 搜索参数
|
||||
* @returns 帖子列表结果
|
||||
*/
|
||||
searchPosts(params: SearchPostsParams): Promise<PostsResult>;
|
||||
|
||||
// ==================== 帖子操作 ====================
|
||||
|
||||
/**
|
||||
* 创建帖子
|
||||
* @param data 创建帖子数据
|
||||
* @returns 创建的帖子实体
|
||||
*/
|
||||
createPost(data: CreatePostData): Promise<Post>;
|
||||
|
||||
/**
|
||||
* 更新帖子
|
||||
* @param id 帖子ID
|
||||
* @param data 更新数据
|
||||
* @returns 更新后的帖子实体
|
||||
*/
|
||||
updatePost(id: string, data: UpdatePostData): Promise<Post>;
|
||||
|
||||
/**
|
||||
* 删除帖子
|
||||
* @param id 帖子ID
|
||||
*/
|
||||
deletePost(id: string): Promise<void>;
|
||||
|
||||
// ==================== 互动操作 ====================
|
||||
|
||||
/**
|
||||
* 点赞帖子
|
||||
* @param id 帖子ID
|
||||
* @returns 更新后的帖子实体
|
||||
*/
|
||||
likePost(id: string): Promise<Post>;
|
||||
|
||||
/**
|
||||
* 取消点赞
|
||||
* @param id 帖子ID
|
||||
* @returns 更新后的帖子实体
|
||||
*/
|
||||
unlikePost(id: string): Promise<Post>;
|
||||
|
||||
/**
|
||||
* 收藏帖子
|
||||
* @param id 帖子ID
|
||||
* @returns 更新后的帖子实体
|
||||
*/
|
||||
favoritePost(id: string): Promise<Post>;
|
||||
|
||||
/**
|
||||
* 取消收藏
|
||||
* @param id 帖子ID
|
||||
* @returns 更新后的帖子实体
|
||||
*/
|
||||
unfavoritePost(id: string): Promise<Post>;
|
||||
}
|
||||
Reference in New Issue
Block a user