551 lines
15 KiB
TypeScript
551 lines
15 KiB
TypeScript
|
|
/**
|
|||
|
|
* 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;
|