/** * 帖子服务 * 处理帖子的增删改查、点赞、收藏等功能 * * @deprecated 此服务已弃用,请使用 ProcessPostUseCase 代替 * 互动操作(点赞、收藏)已委托给 processPostUseCase */ import { api, PaginatedData } from './api'; import { Post, CreatePostInput } from '../types'; import { CursorPaginationRequest, CursorPaginationResponse } from '../types/dto'; import { processPostUseCase } from '../core/usecases/ProcessPostUseCase'; import type { Post as PostEntity } from '../core/entities/Post'; // 帖子列表响应 interface PostListResponse { list: Post[]; total: number; page: number; page_size: number; total_pages: number; } // 帖子响应 - API直接返回Post对象 type PostResponse = Post; // 创建帖子请求 interface CreatePostRequest { title: string; content: string; images?: string[]; channel_id?: string; } // 更新帖子请求 interface UpdatePostRequest { title?: string; content?: string; images?: string[]; } // 帖子服务类 class PostService { // 获取帖子列表 async getPosts( page = 1, pageSize = 20, tab?: string, channelId?: string ): Promise> { const params: Record = { page, page_size: pageSize, }; if (tab) { params.tab = tab; } if (channelId) { params.channel_id = channelId; } const response = await api.get('/posts', params); return response.data; } // 获取关注帖子 async getFollowingPosts(page = 1, pageSize = 20): Promise> { return this.getPosts(page, pageSize, 'follow'); } // 获取热门帖子 async getHotPosts(page = 1, pageSize = 20): Promise> { return this.getPosts(page, pageSize, 'hot'); } // 获取最新帖子 async getLatestPosts(page = 1, pageSize = 20): Promise> { return this.getPosts(page, pageSize, 'latest'); } // 获取帖子详情(不增加浏览量) async getPost(postId: string): Promise { try { const response = await api.get(`/posts/${postId}`); return response.data; } catch (error) { console.error('获取帖子详情失败:', error); return null; } } // 记录帖子浏览(增加浏览量) async recordView(postId: string): Promise { try { const response = await api.post(`/posts/${postId}/view`); return response.code === 0; } catch (error) { console.error('记录浏览失败:', error); return false; } } // 创建帖子 async createPost(data: CreatePostRequest): Promise { const response = await api.post('/posts', data); return response.data; } // 更新帖子 async updatePost(postId: string, data: UpdatePostRequest): Promise { try { const response = await api.put(`/posts/${postId}`, data); return response.data; } catch (error) { console.error('更新帖子失败:', error); return null; } } // 删除帖子 async deletePost(postId: string): Promise { try { const response = await api.delete(`/posts/${postId}`); return response.code === 0; } catch (error) { console.error('删除帖子失败:', error); return false; } } // 点赞帖子 // @deprecated 请使用 processPostUseCase.likePost() 代替 async likePost(postId: string): Promise { try { const post = await processPostUseCase.likePost(postId); // 转换为旧版 Post 类型以保持向后兼容 return post as unknown as Post; } catch (error) { console.error('[postService] likePost error:', error); return null; } } // 取消点赞帖子 // @deprecated 请使用 processPostUseCase.unlikePost() 代替 async unlikePost(postId: string): Promise { try { const post = await processPostUseCase.unlikePost(postId); return post as unknown as Post; } catch (error) { console.error('[postService] unlikePost error:', error); return null; } } // 收藏帖子 // @deprecated 请使用 processPostUseCase.favoritePost() 代替 async favoritePost(postId: string): Promise { try { const post = await processPostUseCase.favoritePost(postId); return post as unknown as Post; } catch (error) { console.error('[postService] favoritePost error:', error); return null; } } // 取消收藏帖子 // @deprecated 请使用 processPostUseCase.unfavoritePost() 代替 async unfavoritePost(postId: string): Promise { try { const post = await processPostUseCase.unfavoritePost(postId); return post as unknown as Post; } catch (error) { console.error('[postService] unfavoritePost error:', error); return null; } } // 获取用户帖子列表 async getUserPosts( userId: string, page = 1, pageSize = 20 ): Promise> { try { const response = await api.get(`/users/${userId}/posts`, { page, page_size: pageSize, }); return response.data; } catch (error) { console.error('获取用户帖子列表失败:', error); return { list: [], total: 0, page: 1, page_size: pageSize, total_pages: 0, }; } } // 获取用户收藏列表 async getUserFavorites( userId: string, page = 1, pageSize = 20 ): Promise> { try { const response = await api.get(`/users/${userId}/favorites`, { page, page_size: pageSize, }); return response.data; } catch (error) { console.error('获取用户收藏列表失败:', error); return { list: [], total: 0, page: 1, page_size: pageSize, total_pages: 0, }; } } // 搜索帖子 async searchPosts( keyword: string, page = 1, pageSize = 20 ): Promise> { try { const response = await api.get('/posts/search', { keyword, page, page_size: pageSize, }); return response.data; } catch (error) { console.error('搜索帖子失败:', error); return { list: [], total: 0, page: 1, page_size: pageSize, total_pages: 0, }; } } /** 上报分享成功;返回服务端最新 shares_count 供界面同步 */ async sharePost( postId: string, body?: { channel?: string } ): Promise<{ ok: boolean; shares_count?: number }> { try { const response = await api.post<{ success: boolean; shares_count: number }>( `/posts/${postId}/share`, body && body.channel ? { channel: body.channel } : undefined ); if (response.code !== 0) { return { ok: false }; } const n = response.data?.shares_count; return { ok: true, shares_count: typeof n === 'number' ? n : undefined }; } catch (error) { console.error('分享帖子失败:', error); return { ok: false }; } } // 举报帖子 async reportPost(postId: string, reason: string): Promise { try { const response = await api.post(`/posts/${postId}/report`, { reason }); return response.code === 0; } catch (error) { console.error('举报帖子失败:', error); return false; } } // ==================== 游标分页方法 ==================== /** * 获取帖子列表(游标分页) * GET /api/v1/posts * @param params 游标分页请求参数(包含 post_type 可选:follow, hot, latest) */ async getPostsCursor( params: CursorPaginationRequest = {} ): Promise> { try { // 构建请求参数 // 后端使用 `tab` 参数区分帖子类型,使用 `cursor` 参数启用游标分页 // 始终传递 cursor 参数(空字符串表示首次请求),确保使用游标分页 const requestParams: Record = { cursor: params.cursor || '', // 空字符串表示首次请求 page_size: params.page_size, }; // 将 post_type 映射为后端的 tab 参数 if (params.post_type) { requestParams.tab = params.post_type; } const response = await api.get('/posts', requestParams); const data = response.data; if (data && typeof data === 'object' && Array.isArray(data.list)) { const isPageShape = typeof data.page === 'number' && typeof data.total_pages === 'number' && data.next_cursor === undefined && data.prev_cursor === undefined; if (isPageShape) { const currentPage = data.page || 1; const totalPages = data.total_pages || 1; return { list: data.list, next_cursor: currentPage < totalPages ? String(currentPage + 1) : null, prev_cursor: currentPage > 1 ? String(currentPage - 1) : null, has_more: currentPage < totalPages, }; } return { list: data.list, next_cursor: data.next_cursor ?? null, prev_cursor: data.prev_cursor ?? null, has_more: data.has_more ?? false, }; } return { list: [], next_cursor: null, prev_cursor: null, has_more: false, }; } catch (error) { console.error('获取帖子列表失败:', error); return { list: [], next_cursor: null, prev_cursor: null, has_more: false, }; } } /** * 搜索帖子(游标分页) * GET /api/v1/posts/search * @param query 搜索关键词 * @param params 游标分页请求参数 */ async searchPostsCursor( query: string, params: CursorPaginationRequest = {} ): Promise> { try { const response = await api.get('/posts/search', { ...params, keyword: query, }); const data = response.data; if (data && typeof data === 'object' && Array.isArray(data.list)) { const isPageShape = typeof data.page === 'number' && typeof data.total_pages === 'number' && data.next_cursor === undefined && data.prev_cursor === undefined; if (isPageShape) { const currentPage = data.page || 1; const totalPages = data.total_pages || 1; return { list: data.list, next_cursor: currentPage < totalPages ? String(currentPage + 1) : null, prev_cursor: currentPage > 1 ? String(currentPage - 1) : null, has_more: currentPage < totalPages, }; } return { list: data.list, next_cursor: data.next_cursor ?? null, prev_cursor: data.prev_cursor ?? null, has_more: data.has_more ?? false, }; } return { list: [], next_cursor: null, prev_cursor: null, has_more: false, }; } catch (error) { console.error('搜索帖子失败:', error); return { list: [], next_cursor: null, prev_cursor: null, has_more: false, }; } } /** * 获取用户帖子列表(游标分页) * GET /api/v1/users/:id/posts * @param userId 用户ID * @param params 游标分页请求参数 */ async getUserPostsCursor( userId: string, params: CursorPaginationRequest = {} ): Promise> { try { const response = await api.get( `/users/${userId}/posts`, params ); const data = response.data; if (data && typeof data === 'object' && Array.isArray(data.list)) { const isPageShape = typeof data.page === 'number' && typeof data.total_pages === 'number' && data.next_cursor === undefined && data.prev_cursor === undefined; if (isPageShape) { const currentPage = data.page || 1; const totalPages = data.total_pages || 1; return { list: data.list, next_cursor: currentPage < totalPages ? String(currentPage + 1) : null, prev_cursor: currentPage > 1 ? String(currentPage - 1) : null, has_more: currentPage < totalPages, }; } return { list: data.list, next_cursor: data.next_cursor ?? null, prev_cursor: data.prev_cursor ?? null, has_more: data.has_more ?? false, }; } return { list: [], next_cursor: null, prev_cursor: null, has_more: false, }; } catch (error) { console.error('获取用户帖子列表失败:', error); return { list: [], next_cursor: null, prev_cursor: null, has_more: false, }; } } } // 导出帖子服务实例 export const postService = new PostService();