From 6e2cbfda22de4acb8a3014bf6cd67c14258fc1c8 Mon Sep 17 00:00:00 2001 From: npmrun <1549469775@qq.com> Date: Mon, 20 Apr 2026 21:02:00 +0800 Subject: [PATCH] fix(comment): add frontend email-notify readiness hints Expose login-state comment notify warnings in comment composer and show incomplete SMTP config status in admin settings to prevent misleading mail-send expectations. Made-with: Cursor --- app/components/PostComments.vue | 42 +++++++++++++++++++++++++++++++++++++ app/pages/me/admin/config/index.vue | 25 ++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/app/components/PostComments.vue b/app/components/PostComments.vue index c9225c2..74af865 100644 --- a/app/components/PostComments.vue +++ b/app/components/PostComments.vue @@ -21,6 +21,16 @@ type CommentsPayload = { comments: CommentNode[] } +type MeConfigPayload = { + config?: Record +} + +type MeProfilePayload = { + profile?: { + email?: string | null + } +} + const props = defineProps<{ mode: 'public-post' | 'unlisted' publicSlug: string @@ -65,6 +75,32 @@ const { data, pending, error, refresh: refreshComments } = await useAsyncData( { watch: [commentsBase] }, ) +const { data: viewerNotifyState } = await useAsyncData( + () => 'viewer-comment-notify-state', + async () => { + if (!loggedIn.value) { + return null + } + const fetcher = import.meta.server ? useRequestFetch() : $fetch + const [meConfigRes, meProfileRes] = await Promise.all([ + fetcher>('/api/config/me'), + fetcher>('/api/me/profile'), + ]) + const cfg = unwrapApiBody(meConfigRes).config ?? {} + const profile = unwrapApiBody(meProfileRes).profile ?? {} + const commentNotifyEnabled = typeof cfg.commentNotifyEnabled === 'boolean' ? cfg.commentNotifyEnabled : true + const email = typeof profile.email === 'string' ? profile.email.trim() : '' + return { + commentNotifyEnabled, + hasEmail: email.length > 0, + } + }, + { watch: [loggedIn] }, +) + +const showNoEmailHint = computed(() => loggedIn.value && viewerNotifyState.value?.hasEmail === false) +const showNotifyDisabledHint = computed(() => loggedIn.value && viewerNotifyState.value?.commentNotifyEnabled === false) + const flatComments = computed(() => flattenTree(data.value?.comments ?? [])) function flattenTree(nodes: CommentNode[], depth = 0): Array<{ node: CommentNode; depth: number }> { @@ -232,6 +268,12 @@ async function submitComment() {

diff --git a/app/pages/me/admin/config/index.vue b/app/pages/me/admin/config/index.vue index 51391d8..6e2a64c 100644 --- a/app/pages/me/admin/config/index.vue +++ b/app/pages/me/admin/config/index.vue @@ -39,6 +39,23 @@ const commentSmtpSecure = ref(true) const commentSmtpUser = ref('') const commentSmtpPass = ref('') +const commentEmailConfigReady = computed(() => { + const from = commentMailFromEmail.value.trim() + const host = commentSmtpHost.value.trim() + const user = commentSmtpUser.value.trim() + const pass = commentSmtpPass.value.trim() + const port = Number(commentSmtpPort.value) + return ( + from.length > 0 + && host.length > 0 + && user.length > 0 + && pass.length > 0 + && Number.isFinite(port) + && port >= 1 + && port <= 65535 + ) +}) + async function ensureAdmin() { await refresh(true) if (user.value?.role !== 'admin') { @@ -183,6 +200,14 @@ async function sendTestEmail() { > +