From 40ad48f5cfa78058ca89e25a72c856277c13f34b Mon Sep 17 00:00:00 2001 From: ctwj <908504609@qq.com> Date: Mon, 20 Oct 2025 23:57:27 +0800 Subject: [PATCH] =?UTF-8?q?update:=20=E5=85=AC=E5=91=8A=E6=94=AF=E6=8C=81h?= =?UTF-8?q?tml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/components/Admin/AnnouncementConfig.vue | 60 ++++++++++++++++++--- web/components/Announcement.vue | 2 +- web/composables/useConfigChangeDetection.ts | 12 ++--- web/pages/admin/site-config.vue | 58 ++++++++++++++++---- 4 files changed, 109 insertions(+), 23 deletions(-) diff --git a/web/components/Admin/AnnouncementConfig.vue b/web/components/Admin/AnnouncementConfig.vue index 5ce4703..bbdc456 100644 --- a/web/components/Admin/AnnouncementConfig.vue +++ b/web/components/Admin/AnnouncementConfig.vue @@ -20,7 +20,7 @@

公告 {{ index + 1 }}

- +
@@ -43,7 +43,8 @@
{ emit('update:modelValue', newValue) } +// 监听单个公告内容变化 +const handleContentChange = (index: number, content: string) => { + const newAnnouncements = [...props.modelValue.announcements] + newAnnouncements[index] = { ...newAnnouncements[index], content } + emit('update:modelValue', { + enable_announcements: props.modelValue.enable_announcements, + announcements: newAnnouncements + }) +} + +// 监听单个公告启用状态变化 +const handleEnabledChange = (index: number, enabled: boolean) => { + const newAnnouncements = [...props.modelValue.announcements] + newAnnouncements[index] = { ...newAnnouncements[index], enabled } + emit('update:modelValue', { + enable_announcements: props.modelValue.enable_announcements, + announcements: newAnnouncements + }) +} + +// 计算属性用于公告内容双向绑定 +const announcementContent = (index: number) => computed({ + get: () => props.modelValue.announcements[index]?.content || '', + set: (value: string) => { + const newAnnouncements = [...props.modelValue.announcements] + newAnnouncements[index] = { ...newAnnouncements[index], content: value } + updateValue({ + enable_announcements: props.modelValue.enable_announcements, + announcements: newAnnouncements + }) + } +}) + +// 计算属性用于公告启用状态双向绑定 +const announcementEnabled = (index: number) => computed({ + get: () => props.modelValue.announcements[index]?.enabled || false, + set: (value: boolean) => { + const newAnnouncements = [...props.modelValue.announcements] + newAnnouncements[index] = { ...newAnnouncements[index], enabled: value } + updateValue({ + enable_announcements: props.modelValue.enable_announcements, + announcements: newAnnouncements + }) + } +}) + // 添加公告 const addAnnouncement = () => { const newAnnouncements = [...props.modelValue.announcements, { content: '', enabled: true }] - updateValue({ + emit('update:modelValue', { enable_announcements: props.modelValue.enable_announcements, announcements: newAnnouncements }) @@ -112,7 +158,7 @@ const addAnnouncement = () => { const removeAnnouncement = (index: number) => { const currentAnnouncements = Array.isArray(props.modelValue.announcements) ? props.modelValue.announcements : [] const newAnnouncements = currentAnnouncements.filter((_, i) => i !== index) - updateValue({ + emit('update:modelValue', { enable_announcements: props.modelValue.enable_announcements, announcements: newAnnouncements }) @@ -126,7 +172,7 @@ const moveAnnouncementUp = (index: number) => { const temp = newAnnouncements[index] newAnnouncements[index] = newAnnouncements[index - 1] newAnnouncements[index - 1] = temp - updateValue({ + emit('update:modelValue', { enable_announcements: props.modelValue.enable_announcements, announcements: newAnnouncements }) @@ -141,7 +187,7 @@ const moveAnnouncementDown = (index: number) => { const temp = newAnnouncements[index] newAnnouncements[index] = newAnnouncements[index + 1] newAnnouncements[index + 1] = temp - updateValue({ + emit('update:modelValue', { enable_announcements: props.modelValue.enable_announcements, announcements: newAnnouncements }) diff --git a/web/components/Announcement.vue b/web/components/Announcement.vue index a1476f6..479ba92 100644 --- a/web/components/Announcement.vue +++ b/web/components/Announcement.vue @@ -5,7 +5,7 @@
- {{ validAnnouncements[currentIndex].content }} +
diff --git a/web/composables/useConfigChangeDetection.ts b/web/composables/useConfigChangeDetection.ts index b2781eb..88f5d82 100644 --- a/web/composables/useConfigChangeDetection.ts +++ b/web/composables/useConfigChangeDetection.ts @@ -71,26 +71,26 @@ export const useConfigChangeDetection = >( } const changedConfig: Partial = {} - + // 遍历所有配置项 for (const key in currentConfig.value) { const currentValue = currentConfig.value[key] const originalValue = originalConfig.value[key] - + // 使用自定义比较函数或默认比较 - const hasChanged = customCompare + const hasChanged = customCompare ? customCompare(key, currentValue, originalValue) : currentValue !== originalValue - + if (hasChanged) { changedConfig[key as keyof T] = currentValue } } - + if (debug) { console.log('useConfigChangeDetection - 检测到的改动:', changedConfig) } - + return changedConfig } diff --git a/web/pages/admin/site-config.vue b/web/pages/admin/site-config.vue index de61e36..76051e8 100644 --- a/web/pages/admin/site-config.vue +++ b/web/pages/admin/site-config.vue @@ -318,6 +318,15 @@ const { saveConfig: saveConfigWithDetection } = useConfigChangeDetection({ debug: true, + // 自定义比较函数,处理数组深层比较 + customCompare: (key: string, currentValue: any, originalValue: any) => { + // 对于数组类型,使用JSON字符串比较 + if (Array.isArray(currentValue) && Array.isArray(originalValue)) { + return JSON.stringify(currentValue) !== JSON.stringify(originalValue) + } + // 其他类型使用默认比较 + return currentValue !== originalValue + }, // 字段映射:前端字段名 -> 后端字段名 fieldMapping: { site_title: 'site_title', @@ -470,37 +479,68 @@ const openLogoSelector = () => { } const clearLogo = () => { - configForm.value.site_logo = '' + configForm.value = { + ...configForm.value, + site_logo: '' + } + // 强制触发更新 + updateCurrentConfig({ ...configForm.value }) } // 子组件更新处理方法 const handleAnnouncementUpdate = (newValue: any) => { - configForm.value.enable_announcements = newValue.enable_announcements - configForm.value.announcements = newValue.announcements + // 直接更新整个表单 + configForm.value = { + ...configForm.value, + enable_announcements: newValue.enable_announcements, + announcements: newValue.announcements + } + // 强制触发更新 + updateCurrentConfig({ ...configForm.value }) } const handleFloatButtonsUpdate = (newValue: any) => { - configForm.value.enable_float_buttons = newValue.enable_float_buttons - configForm.value.wechat_search_image = newValue.wechat_search_image - configForm.value.telegram_qr_image = newValue.telegram_qr_image + configForm.value = { + ...configForm.value, + enable_float_buttons: newValue.enable_float_buttons, + wechat_search_image: newValue.wechat_search_image, + telegram_qr_image: newValue.telegram_qr_image + } + // 强制触发更新 + updateCurrentConfig({ ...configForm.value }) } // Logo选择处理 const handleLogoSelect = (file: any) => { - configForm.value.site_logo = file.access_url + configForm.value = { + ...configForm.value, + site_logo: file.access_url + } showLogoSelector.value = false + // 强制触发更新 + updateCurrentConfig({ ...configForm.value }) } // 微信图片选择处理 const handleWechatImageSelect = (file: any) => { - configForm.value.wechat_search_image = file.access_url + configForm.value = { + ...configForm.value, + wechat_search_image: file.access_url + } showWechatSelector.value = false + // 强制触发更新 + updateCurrentConfig({ ...configForm.value }) } // Telegram图片选择处理 const handleTelegramImageSelect = (file: any) => { - configForm.value.telegram_qr_image = file.access_url + configForm.value = { + ...configForm.value, + telegram_qr_image: file.access_url + } showTelegramSelector.value = false + // 强制触发更新 + updateCurrentConfig({ ...configForm.value }) } // 页面加载时获取配置