diff --git a/cwd-comments-admin/.env.example b/cwd-comments-admin/.env.example index b6ca4eb..956580b 100644 --- a/cwd-comments-admin/.env.example +++ b/cwd-comments-admin/.env.example @@ -1,3 +1,3 @@ VITE_API_BASE_URL=https://api.example.com -VITE_ADMIN_NAME=anghunk@example.com +VITE_ADMIN_NAME=admin@example.com VITE_ADMIN_PASSWORD=123456 diff --git a/cwd-comments-admin/src/api/admin.ts b/cwd-comments-admin/src/api/admin.ts index 06bc777..acbdb34 100644 --- a/cwd-comments-admin/src/api/admin.ts +++ b/cwd-comments-admin/src/api/admin.ts @@ -37,6 +37,7 @@ export type CommentSettingsResponse = { adminEmail: string | null; adminBadge: string | null; avatarPrefix: string | null; + adminEnabled: boolean; }; export async function loginAdmin(name: string, password: string): Promise { @@ -78,6 +79,7 @@ export function saveCommentSettings(data: { adminEmail?: string; adminBadge?: string; avatarPrefix?: string; + adminEnabled?: boolean; }): Promise<{ message: string }> { return put<{ message: string }>('/admin/settings/comments', data); } diff --git a/cwd-comments-admin/src/views/CommentsView.vue b/cwd-comments-admin/src/views/CommentsView.vue index 3e809e0..7558a68 100644 --- a/cwd-comments-admin/src/views/CommentsView.vue +++ b/cwd-comments-admin/src/views/CommentsView.vue @@ -428,7 +428,7 @@ onMounted(() => { border-radius: 4px; border: 1px solid #d0d7de; background-color: #ffffff; - font-size: 11px; + font-size: 12px; cursor: pointer; } diff --git a/cwd-comments-admin/src/views/SettingsView.vue b/cwd-comments-admin/src/views/SettingsView.vue index d214695..433f7bb 100644 --- a/cwd-comments-admin/src/views/SettingsView.vue +++ b/cwd-comments-admin/src/views/SettingsView.vue @@ -36,6 +36,13 @@ +
+ + +
@@ -64,6 +71,7 @@ const email = ref(""); const commentAdminEmail = ref(""); const commentAdminBadge = ref(""); const avatarPrefix = ref(""); +const commentAdminEnabled = ref(false); const savingEmail = ref(false); const savingComment = ref(false); const loading = ref(false); @@ -81,6 +89,7 @@ async function load() { commentAdminEmail.value = commentRes.adminEmail || ""; commentAdminBadge.value = commentRes.adminBadge || "博主"; avatarPrefix.value = commentRes.avatarPrefix || ""; + commentAdminEnabled.value = !!commentRes.adminEnabled; } catch (e: any) { message.value = e.message || "加载失败"; messageType.value = "error"; @@ -117,6 +126,7 @@ async function saveComment() { adminEmail: commentAdminEmail.value, adminBadge: commentAdminBadge.value, avatarPrefix: avatarPrefix.value, + adminEnabled: commentAdminEnabled.value, }); message.value = res.message || "保存成功"; messageType.value = "success"; @@ -184,6 +194,53 @@ onMounted(() => { box-shadow: 0 0 0 1px rgba(9, 105, 218, 0.2); } +.switch { + position: relative; + display: inline-flex; + width: 40px; + height: 22px; + align-items: center; +} + +.switch input { + opacity: 0; + width: 0; + height: 0; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #d0d7de; + transition: 0.2s; + border-radius: 999px; +} + +.slider::before { + position: absolute; + content: ""; + height: 16px; + width: 16px; + left: 3px; + top: 3px; + background-color: #ffffff; + transition: 0.2s; + border-radius: 50%; + box-shadow: 0 1px 2px rgba(27, 31, 36, 0.15); +} + +.switch input:checked + .slider { + background-color: #0969da; +} + +.switch input:checked + .slider::before { + transform: translateX(16px); +} + .card-actions { display: flex; justify-content: flex-end; diff --git a/cwd-comments-api/src/index.ts b/cwd-comments-api/src/index.ts index e7d0ca6..5b5d55b 100644 --- a/cwd-comments-api/src/index.ts +++ b/cwd-comments-api/src/index.ts @@ -19,12 +19,18 @@ const VERSION = 'v0.0.1'; const COMMENT_ADMIN_EMAIL_KEY = 'comment_admin_email'; const COMMENT_ADMIN_BADGE_KEY = 'comment_admin_badge'; const COMMENT_AVATAR_PREFIX_KEY = 'comment_avatar_prefix'; +const COMMENT_ADMIN_ENABLED_KEY = 'comment_admin_enabled'; async function loadCommentSettings(env: Bindings) { await env.CWD_DB.prepare( 'CREATE TABLE IF NOT EXISTS Settings (key TEXT PRIMARY KEY, value TEXT NOT NULL)' ).run(); - const keys = [COMMENT_ADMIN_EMAIL_KEY, COMMENT_ADMIN_BADGE_KEY, COMMENT_AVATAR_PREFIX_KEY]; + const keys = [ + COMMENT_ADMIN_EMAIL_KEY, + COMMENT_ADMIN_BADGE_KEY, + COMMENT_AVATAR_PREFIX_KEY, + COMMENT_ADMIN_ENABLED_KEY + ]; const { results } = await env.CWD_DB.prepare( 'SELECT key, value FROM Settings WHERE key IN (?, ?, ?)' ) @@ -38,16 +44,25 @@ async function loadCommentSettings(env: Bindings) { } } + const enabledRaw = map.get(COMMENT_ADMIN_ENABLED_KEY) ?? null; + const adminEnabled = enabledRaw === '1'; + return { adminEmail: map.get(COMMENT_ADMIN_EMAIL_KEY) ?? null, adminBadge: map.get(COMMENT_ADMIN_BADGE_KEY) ?? null, - avatarPrefix: map.get(COMMENT_AVATAR_PREFIX_KEY) ?? null + avatarPrefix: map.get(COMMENT_AVATAR_PREFIX_KEY) ?? null, + adminEnabled }; } async function saveCommentSettings( env: Bindings, - settings: { adminEmail?: string; adminBadge?: string; avatarPrefix?: string } + settings: { + adminEmail?: string; + adminBadge?: string; + avatarPrefix?: string; + adminEnabled?: boolean; + } ) { await env.CWD_DB.prepare( 'CREATE TABLE IF NOT EXISTS Settings (key TEXT PRIMARY KEY, value TEXT NOT NULL)' @@ -56,7 +71,16 @@ async function saveCommentSettings( const entries: { key: string; value: string | null | undefined }[] = [ { key: COMMENT_ADMIN_EMAIL_KEY, value: settings.adminEmail }, { key: COMMENT_ADMIN_BADGE_KEY, value: settings.adminBadge }, - { key: COMMENT_AVATAR_PREFIX_KEY, value: settings.avatarPrefix } + { key: COMMENT_AVATAR_PREFIX_KEY, value: settings.avatarPrefix }, + { + key: COMMENT_ADMIN_ENABLED_KEY, + value: + typeof settings.adminEnabled === 'boolean' + ? settings.adminEnabled + ? '1' + : '0' + : undefined + } ]; for (const entry of entries) { @@ -138,10 +162,15 @@ app.put('/admin/settings/comments', async (c) => { const rawAdminEmail = typeof body.adminEmail === 'string' ? body.adminEmail : ''; const rawAdminBadge = typeof body.adminBadge === 'string' ? body.adminBadge : ''; const rawAvatarPrefix = typeof body.avatarPrefix === 'string' ? body.avatarPrefix : ''; + const rawAdminEnabled = body.adminEnabled; const adminEmail = rawAdminEmail.trim(); const adminBadge = rawAdminBadge.trim(); const avatarPrefix = rawAvatarPrefix.trim(); + const adminEnabled = + typeof rawAdminEnabled === 'boolean' + ? rawAdminEnabled + : rawAdminEnabled === '1' || rawAdminEnabled === 1; if (adminEmail && !isValidEmail(adminEmail)) { return c.json({ message: '邮箱格式不正确' }, 400); @@ -150,7 +179,8 @@ app.put('/admin/settings/comments', async (c) => { await saveCommentSettings(c.env, { adminEmail, adminBadge, - avatarPrefix + avatarPrefix, + adminEnabled }); return c.json({ message: '保存成功' }); diff --git a/widget/src/dev.js b/widget/src/dev.js index bc7f76c..87a12e2 100644 --- a/widget/src/dev.js +++ b/widget/src/dev.js @@ -79,6 +79,7 @@ async function loadServerCommentConfig(apiBaseUrl) { return { adminEmail: data.adminEmail || '', adminBadge: data.adminBadge || '', + adminEnabled: !!data.adminEnabled, avatarPrefix: data.avatarPrefix || '', }; } catch (e) { @@ -119,8 +120,12 @@ async function initWidget() { theme: config.theme, avatarPrefix: serverConfig.avatarPrefix || config.avatarPrefix, pageSize: 20, - ...(serverConfig.adminEmail ? { adminEmail: serverConfig.adminEmail } : {}), - ...(serverConfig.adminBadge ? { adminBadge: serverConfig.adminBadge } : {}), + ...(serverConfig.adminEnabled && serverConfig.adminEmail + ? { adminEmail: serverConfig.adminEmail } + : {}), + ...(serverConfig.adminEnabled && serverConfig.adminBadge + ? { adminBadge: serverConfig.adminBadge } + : {}), }); widgetInstance.mount(); console.log('[CWDComments] Widget 初始化成功', config);