From 0f831836207d22615a22b3dfc5ee5adb1232791a Mon Sep 17 00:00:00 2001 From: freefire Date: Fri, 7 Aug 2026 05:14:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=9D=BF=E5=9D=97=E5=86=85?= =?UTF-8?q?=E7=BD=AE=E9=A1=B6=EF=BC=8C=E4=B8=8E=E5=85=A8=E5=B1=80=E7=BD=AE?= =?UTF-8?q?=E9=A1=B6=E5=88=86=E7=A6=BB=EF=BC=9A=E9=A6=96=E9=A1=B5=E4=BB=85?= =?UTF-8?q?=E6=8A=AC=E5=8D=87=E5=85=A8=E5=B1=80=E7=BD=AE=E9=A1=B6=EF=BC=8C?= =?UTF-8?q?=E6=9D=BF=E5=9D=97=E5=88=97=E8=A1=A8=E4=BC=98=E5=85=88=E5=85=A8?= =?UTF-8?q?=E5=B1=80=E5=86=8D=E6=9D=BF=E5=9D=97=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- frontend/src/api/client.ts | 4 +++ frontend/src/api/types.ts | 2 ++ frontend/src/components/PostListItem.tsx | 5 +++- frontend/src/pages/PostDetailPage.tsx | 24 +++++++++++++++-- .../src/pages/admin/AdminDashboardPage.tsx | 5 ++-- frontend/src/pages/admin/AdminPostsPage.tsx | 23 +++++++++++++--- frontend/src/styles/global.css | 13 +++++++++ handler/api.go | 27 ++++++++++++++++--- model/models.go | 5 ++-- router/router.go | 1 + service/post.go | 7 +++++ 11 files changed, 103 insertions(+), 13 deletions(-) diff --git a/frontend/src/api/client.ts b/frontend/src/api/client.ts index 6165ae2..a38e9a3 100644 --- a/frontend/src/api/client.ts +++ b/frontend/src/api/client.ts @@ -81,6 +81,10 @@ export const api = { request<{ message: string; pinned: boolean }>(`/api/admin/posts/${id}/pin`, { method: 'POST', body: JSON.stringify({ pinned }), }), + adminBoardPinPost: (id: number, boardPinned: boolean) => + request<{ message: string; board_pinned: boolean }>(`/api/admin/posts/${id}/board-pin`, { + method: 'POST', body: JSON.stringify({ board_pinned: boardPinned }), + }), adminFeaturePost: (id: number, featured: boolean) => request<{ message: string; featured: boolean }>(`/api/admin/posts/${id}/feature`, { method: 'POST', body: JSON.stringify({ featured }), diff --git a/frontend/src/api/types.ts b/frontend/src/api/types.ts index 8fb7372..4045d44 100644 --- a/frontend/src/api/types.ts +++ b/frontend/src/api/types.ts @@ -89,6 +89,8 @@ export interface PostItem { /** 仅问答帖有意义 */ question_resolved?: boolean; pinned: boolean; + /** 板块内置顶(仅板块列表抬升,首页不抬升) */ + board_pinned?: boolean; featured?: boolean; edit_locked?: boolean; status?: 'pending' | 'published' | 'rejected' | string; diff --git a/frontend/src/components/PostListItem.tsx b/frontend/src/components/PostListItem.tsx index de57803..8fb60c3 100644 --- a/frontend/src/components/PostListItem.tsx +++ b/frontend/src/components/PostListItem.tsx @@ -78,7 +78,10 @@ function PostListItem({ post, sort = 'latest', onSelect }: Props) {
{post.pinned && ( - 置顶 + 全局置顶 + )} + {post.board_pinned && ( + 板块置顶 )} {post.featured && ( diff --git a/frontend/src/pages/PostDetailPage.tsx b/frontend/src/pages/PostDetailPage.tsx index e93537a..36439f1 100644 --- a/frontend/src/pages/PostDetailPage.tsx +++ b/frontend/src/pages/PostDetailPage.tsx @@ -475,6 +475,19 @@ export default function PostDetailPage() { } }; + const handleBoardPin = async () => { + if (!post) return; + try { + const r = await api.adminBoardPinPost(postId, !post.board_pinned); + setPost(p => p ? { ...p, board_pinned: r.board_pinned } : p); + clearAllFeedCache(); + window.dispatchEvent(new Event('posts-refresh')); + notify.success(r.message); + } catch (e: unknown) { + notify.error(e instanceof Error ? e.message : '操作失败'); + } + }; + const handleFeature = async () => { if (!post) return; try { @@ -601,7 +614,10 @@ export default function PostDetailPage() {

{post.pinned && ( - 置顶 + 全局置顶 + )} + {post.board_pinned && ( + 板块置顶 )} {post.featured && } {post.status === 'pending' && 审核中} @@ -792,7 +808,11 @@ export default function PostDetailPage() { +

@@ -316,7 +328,8 @@ export default function AdminPostsPage() { 标签 评论 精华 - 置顶 + 全局置顶 + 板块置顶 锁定 点赞 浏览 @@ -348,6 +361,7 @@ export default function AdminPostsPage() { {p.comment_count ?? 0} {p.featured ? : '—'} {p.pinned ? : '—'} + {p.board_pinned ? : '—'} {p.edit_locked ? : '—'} {p.like_count} {p.view_count} @@ -373,7 +387,10 @@ export default function AdminPostsPage() { {p.featured ? '取消精华' : '精华'} +