From 569eec5bf82e1f06f1ac17e868016b608a840230 Mon Sep 17 00:00:00 2001 From: xfy Date: Thu, 11 Jun 2026 16:10:42 +0800 Subject: [PATCH] =?UTF-8?q?fix(admin):=20=E8=AF=84=E8=AE=BA=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E9=A1=B5=E5=A4=9A=E9=A1=B9=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复默认头像无法显示:AdminComment 添加 avatar_url 字段 - 修复状态标签换行:移除 w-20 固定宽度,添加 whitespace-nowrap - 操作按钮添加 cursor-pointer - 已处于该状态的评论隐藏对应操作按钮 - 修复操作后页面不自动刷新:将 restart() 移到异步块内 --- src/api/comments/helpers.rs | 4 ++- src/models/comment.rs | 1 + src/pages/admin/comments.rs | 53 +++++++++++++++++++++++-------------- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/src/api/comments/helpers.rs b/src/api/comments/helpers.rs index 8ba54ca..03b3fbc 100644 --- a/src/api/comments/helpers.rs +++ b/src/api/comments/helpers.rs @@ -39,6 +39,7 @@ pub fn row_to_public_comment(row: &tokio_postgres::Row) -> PublicComment { #[cfg(feature = "server")] pub fn row_to_admin_comment(row: &tokio_postgres::Row) -> AdminComment { let status_str: String = row.get("status"); + let email: String = row.get("author_email"); AdminComment { id: row.get("id"), @@ -48,8 +49,9 @@ pub fn row_to_admin_comment(row: &tokio_postgres::Row) -> AdminComment { parent_id: row.get("parent_id"), depth: row.get("depth"), author_name: row.get("author_name"), - author_email: row.get("author_email"), + author_email: email.clone(), author_url: row.get("author_url"), + avatar_url: gravatar_url(&email), content_md: row.get("content_md"), status: CommentStatus::from_str(&status_str), created_at: row.get("created_at"), diff --git a/src/models/comment.rs b/src/models/comment.rs index d1379a3..8cd54d6 100644 --- a/src/models/comment.rs +++ b/src/models/comment.rs @@ -77,6 +77,7 @@ pub struct AdminComment { pub author_name: String, pub author_email: String, pub author_url: Option, + pub avatar_url: String, pub content_md: String, pub status: CommentStatus, pub created_at: DateTime, diff --git a/src/pages/admin/comments.rs b/src/pages/admin/comments.rs index ddab008..a134a78 100644 --- a/src/pages/admin/comments.rs +++ b/src/pages/admin/comments.rs @@ -167,7 +167,7 @@ pub fn AdminCommentsPage(page: i32) -> Element { th { class: "px-4 py-3 font-medium", "作者" } th { class: "px-4 py-3 font-medium", "内容" } th { class: "px-4 py-3 font-medium", "文章" } - th { class: "px-4 py-3 font-medium w-20 text-center", "状态" } + th { class: "px-4 py-3 font-medium text-center", "状态" } th { class: "px-4 py-3 font-medium w-28", "日期" } th { class: "px-4 py-3 font-medium w-32 text-right", "操作" } } @@ -187,26 +187,29 @@ pub fn AdminCommentsPage(page: i32) -> Element { } }, on_approve: { + let mut comments_res = comments_res; let id = comment.id; move |_| { spawn(async move { let _ = approve_comment(id).await; + comments_res.restart(); }); - comments_res.restart(); } }, on_spam: { + let mut comments_res = comments_res; let id = comment.id; move |_| { spawn(async move { let _ = spam_comment(id).await; + comments_res.restart(); }); - comments_res.restart(); } }, on_trash: { #[allow(unused_variables)] - let id = comment.id; + let mut comments_res = comments_res; + let _id = comment.id; move |_| { #[cfg(target_arch = "wasm32")] { @@ -214,11 +217,11 @@ pub fn AdminCommentsPage(page: i32) -> Element { .and_then(|w| w.confirm_with_message("确定要删除这条评论吗?").ok()) .unwrap_or(false) { - let id = id; + let id = _id; spawn(async move { let _ = trash_comment(id).await; + comments_res.restart(); }); - comments_res.restart(); } } } @@ -296,7 +299,11 @@ fn CommentRow( } td { class: "px-4 py-3", div { class: "flex items-center gap-2", - div { class: "w-8 h-8 rounded-full bg-gray-200 dark:bg-[#444] flex-shrink-0" } + img { + class: "w-8 h-8 rounded-full flex-shrink-0", + src: "{comment.avatar_url}", + alt: "{comment.author_name}", + } div { class: "min-w-0", div { class: "text-sm font-medium text-gray-900 dark:text-[#dadadb] truncate", "{comment.author_name}" @@ -320,7 +327,7 @@ fn CommentRow( } } td { class: "px-4 py-3 text-center", - span { class: "inline-flex items-center px-2 py-0.5 rounded text-xs font-medium {badge_class}", + span { class: "inline-flex items-center px-2 py-0.5 rounded text-xs font-medium whitespace-nowrap {badge_class}", "{status_label}" } } @@ -329,20 +336,26 @@ fn CommentRow( } td { class: "px-4 py-3 text-right", div { class: "flex justify-end gap-2", - button { - class: "text-xs text-green-600 hover:text-green-800 dark:text-green-400 dark:hover:text-green-300 transition-colors", - onclick: move |_| on_approve.call(()), - "通过" + if !matches!(comment.status, CommentStatus::Approved) { + button { + class: "text-xs text-green-600 hover:text-green-800 dark:text-green-400 dark:hover:text-green-300 transition-colors cursor-pointer", + onclick: move |_| on_approve.call(()), + "通过" + } } - button { - class: "text-xs text-amber-600 hover:text-amber-800 dark:text-amber-400 dark:hover:text-amber-300 transition-colors", - onclick: move |_| on_spam.call(()), - "垃圾" + if !matches!(comment.status, CommentStatus::Spam) { + button { + class: "text-xs text-amber-600 hover:text-amber-800 dark:text-amber-400 dark:hover:text-amber-300 transition-colors cursor-pointer", + onclick: move |_| on_spam.call(()), + "垃圾" + } } - button { - class: "text-xs text-red-500 hover:text-red-700 dark:hover:text-red-300 transition-colors", - onclick: move |_| on_trash.call(()), - "删除" + if !matches!(comment.status, CommentStatus::Trash) { + button { + class: "text-xs text-red-500 hover:text-red-700 dark:hover:text-red-300 transition-colors cursor-pointer", + onclick: move |_| on_trash.call(()), + "删除" + } } } }