blob: 83e514f2394875dc83c2865d3beaa84cde007ecb [file] [log] [blame]
TRM-codingd1cbf672025-06-18 15:15:08 +08001// src/api/posts.js
trm36915ed2025-06-20 09:48:51 +00002const BASE = 'http://192.168.5.235:5714' // 如果有代理可以留空,否则填完整域名,如 'http://localhost:3000'
TRM-codingd1cbf672025-06-18 15:15:08 +08003
4/**
wu2f28f672025-06-19 14:29:30 +08005 * 获取帖子列表
6 * - GET /posts
7 * - GET /posts?user_id=123
8 *
9 * @param {number?} userId 可选,传了就加 ?user_id= 用户 ID
10 * @returns Promise<[{ id, title, status, heat, created_at }, …]>
TRM-codingd1cbf672025-06-18 15:15:08 +080011 */
wu2f28f672025-06-19 14:29:30 +080012export async function fetchPosts(userId) {
13 // 自动拼接 query
14 const url = userId != null
15 ? `${BASE}/posts?user_id=${encodeURIComponent(userId)}`
16 : `${BASE}/posts`
17
18 const res = await fetch(url)
19 if (!res.ok) {
20 throw new Error(`fetchPosts${userId != null ? `(user ${userId})` : ''}: ${res.status}`)
21 }
22 return res.json()
TRM-codingd1cbf672025-06-18 15:15:08 +080023}
24
25/**
26 * 查看单个帖子详情
27 * GET /posts/{postId}
28 */
29export async function fetchPost(postId) {
30 const res = await fetch(`${BASE}/posts/${postId}`)
31 if (!res.ok) throw new Error(`fetchPost(${postId}): ${res.status}`)
32 return res.json() // 返回完整的帖子对象
33}
34
35/**
36 * 发布新帖
37 * POST /posts
38 */
TRM-codingf55d2372025-06-20 16:22:37 +080039export async function createPost(formData) {
TRM-codingd1cbf672025-06-18 15:15:08 +080040 const res = await fetch(`${BASE}/posts`, {
41 method: 'POST',
TRM-codingf55d2372025-06-20 16:22:37 +080042 // 不设置Content-Type,让浏览器自动设置multipart/form-data
43 body: formData
TRM-codingd1cbf672025-06-18 15:15:08 +080044 })
45 if (!res.ok) {
46 const err = await res.json().catch(() => null)
47 throw new Error(err?.error || `createPost: ${res.status}`)
48 }
49 return res.json() // { id }
50}
51
52/**
53 * 修改帖子
54 * PUT /posts/{postId}
55 */
TRM-codingf55d2372025-06-20 16:22:37 +080056export async function updatePost(postId, formData) {
TRM-codingd1cbf672025-06-18 15:15:08 +080057 const res = await fetch(`${BASE}/posts/${postId}`, {
58 method: 'PUT',
TRM-codingf55d2372025-06-20 16:22:37 +080059 // 如果是FormData则不设置Content-Type,否则设置JSON
60 headers: formData instanceof FormData ? {} : { 'Content-Type': 'application/json' },
61 body: formData instanceof FormData ? formData : JSON.stringify(formData)
TRM-codingd1cbf672025-06-18 15:15:08 +080062 })
63 if (!res.ok) throw new Error(`updatePost(${postId}): ${res.status}`)
64 // 204 No Content
65}
66
67/**
68 * 删除帖子
69 * DELETE /posts/{postId}
70 */
71export async function deletePost(postId) {
72 const res = await fetch(`${BASE}/posts/${postId}`, {
73 method: 'DELETE'
74 })
75 if (!res.ok) throw new Error(`deletePost(${postId}): ${res.status}`)
76}
77
78/**
79 * 点赞
80 * POST /posts/{postId}/like
81 */
82export async function likePost(postId, userId) {
83 const res = await fetch(`${BASE}/posts/${postId}/like`, {
84 method: 'POST',
85 headers: { 'Content-Type': 'application/json' },
86 body: JSON.stringify({ user_id: userId })
87 })
88 if (!res.ok) {
89 const err = await res.json().catch(() => null)
90 throw new Error(err?.error || `likePost: ${res.status}`)
91 }
92}
93
94/**
95 * 取消点赞
96 * DELETE /posts/{postId}/like
97 */
98export async function unlikePost(postId, userId) {
99 const res = await fetch(`${BASE}/posts/${postId}/like`, {
100 method: 'DELETE',
101 headers: { 'Content-Type': 'application/json' },
102 body: JSON.stringify({ user_id: userId })
103 })
104 if (!res.ok) {
105 const err = await res.json().catch(() => null)
106 throw new Error(err?.error || `unlikePost: ${res.status}`)
107 }
108}
109
110/**
111 * 收藏、取消收藏、浏览、分享 等接口:
112 * POST /posts/{postId}/favorite
113 * DELETE /posts/{postId}/favorite
114 * POST /posts/{postId}/view
115 * POST /posts/{postId}/share
116 * 用法同上,替换路径即可
117 */
118
119/**
120 * 添加评论
121 * POST /posts/{postId}/comments
122 */
123export async function addComment(postId, payload) {
124 const res = await fetch(`${BASE}/posts/${postId}/comments`, {
125 method: 'POST',
126 headers: { 'Content-Type': 'application/json' },
127 body: JSON.stringify(payload)
128 })
129 if (!res.ok) throw new Error(`addComment: ${res.status}`)
130 return res.json() // { id }
131}
132
133/**
134 * 获取评论列表
135 * GET /posts/{postId}/comments
136 */
137export async function fetchComments(postId) {
138 const res = await fetch(`${BASE}/posts/${postId}/comments`)
139 if (!res.ok) throw new Error(`fetchComments: ${res.status}`)
140 return res.json()
141}