diff --git a/client/src/pages/admin/config.vue b/client/src/pages/admin/config.vue index f6fbe92..7c30f95 100644 --- a/client/src/pages/admin/config.vue +++ b/client/src/pages/admin/config.vue @@ -60,6 +60,7 @@ import Icon from '@/components/Icon/Icon.vue' const loading = ref(true) const saving = ref(false) +const initialLoaded = ref(false) const form = reactive({ app_version: '', @@ -70,30 +71,26 @@ const form = reactive({ onMounted(async () => { await waitForReady() try { - const config = await getConfig() - form.app_version = config.app_version || '1.0.0' - form.app_slogan = config.app_slogan || '' - form.app_description = config.app_description || '' + await loadConfig() } catch (e: any) { uni.showToast({ title: e.message || '加载失败', icon: 'none' }) } finally { loading.value = false + initialLoaded.value = true } }) // 加载配置数据 async function loadConfig() { - try { - const config = await getConfig() - form.app_version = config.app_version || '1.0.0' - form.app_slogan = config.app_slogan || '' - form.app_description = config.app_description || '' - } catch {} + const config = await getConfig() + form.app_version = config.app_version || '1.0.0' + form.app_slogan = config.app_slogan || '' + form.app_description = config.app_description || '' } // 返回页面时静默刷新 onShow(() => { - loadConfig() + if (initialLoaded.value) loadConfig() }) onPullDownRefresh(async () => { diff --git a/client/src/pages/index/index.vue b/client/src/pages/index/index.vue index 5f46da1..828357f 100644 --- a/client/src/pages/index/index.vue +++ b/client/src/pages/index/index.vue @@ -552,23 +552,14 @@ function goBills() { /* 强提醒公告弹窗 */ .modal-mask { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0, 0, 0, 0.5); - z-index: 300; - display: flex; - align-items: center; - justify-content: center; + @include modal-mask-high; } .urgent-modal { width: 80%; max-height: 70vh; - background: #FFFFFF; - border-radius: 32rpx; + background: $surface; + border-radius: $radius-2xl; overflow: hidden; display: flex; flex-direction: column; @@ -577,52 +568,52 @@ function goBills() { .urgent-header { display: flex; align-items: center; - gap: 12rpx; - padding: 32rpx 32rpx 16rpx; + gap: $space-sm; + padding: $space-xl $space-lg $space-md; } .urgent-title { - font-size: 32rpx; + font-size: $font-xl; font-weight: 600; - color: #2D1B1B; + color: $text; flex: 1; } .urgent-body { flex: 1; - padding: 0 32rpx 24rpx; + padding: 0 $space-lg $space-lg; max-height: 50vh; } .urgent-image { width: 100%; - border-radius: 16rpx; - margin-bottom: 16rpx; + border-radius: $radius-md; + margin-bottom: $space-sm; } .urgent-content { - font-size: 28rpx; - color: #2D1B1B; + font-size: $font-lg; + color: $text; line-height: 1.6; } .urgent-link { - margin-top: 16rpx; - padding: 12rpx 0; + margin-top: $space-sm; + padding: $space-xs 0; } .urgent-link-text { - font-size: 28rpx; - color: #FF8C69; + font-size: $font-lg; + color: $primary; text-decoration: underline; } .urgent-footer { - padding: 24rpx 32rpx; - border-top: 2rpx solid #F0E0D6; + padding: $space-lg; + border-top: 2rpx solid $border; text-align: center; - &:active { background: #FFF8F0; } + &:active { background: $surface-warm; } } .urgent-btn-text { diff --git a/client/src/pages/notifications/index.vue b/client/src/pages/notifications/index.vue index 17c0a9b..5ac8ea1 100644 --- a/client/src/pages/notifications/index.vue +++ b/client/src/pages/notifications/index.vue @@ -104,6 +104,7 @@ const page = ref(1) const total = ref(0) const loading = ref(false) const detailItem = ref(null) +const initialLoaded = ref(false) let loadSeq = 0 const noMore = computed(() => list.value.length >= total.value && total.value > 0) @@ -111,9 +112,11 @@ const noMore = computed(() => list.value.length >= total.value && total.value > onMounted(async () => { await waitForReady() await loadNotifications(true) + initialLoaded.value = true }) onShow(() => { + if (!initialLoaded.value) return notifStore.fetchUnreadCount() // 返回页面时刷新列表(如全部已读后) if (list.value.length > 0) { @@ -374,8 +377,8 @@ onReachBottom(() => { .notif-image { width: 100%; - border-radius: $radius-sm; - margin-top: 12rpx; + border-radius: $radius-md; + margin-top: $space-sm; } .notif-meta { diff --git a/client/src/pages/profile/index.vue b/client/src/pages/profile/index.vue index a85b3a1..9d653e0 100644 --- a/client/src/pages/profile/index.vue +++ b/client/src/pages/profile/index.vue @@ -562,13 +562,7 @@ async function exportData() { } .modal-mask { - position: fixed; - top: 0; left: 0; right: 0; bottom: 0; - background: rgba(0, 0, 0, 0.5); - display: flex; - align-items: center; - justify-content: center; - z-index: 999; + @include modal-mask-high; } .modal { diff --git a/client/src/stores/notification.ts b/client/src/stores/notification.ts index e8b1f12..0dbb2ae 100644 --- a/client/src/stores/notification.ts +++ b/client/src/stores/notification.ts @@ -8,26 +8,42 @@ export const useNotificationStore = defineStore('notification', () => { const urgentNotifications = ref([]) async function fetchUnreadCount() { - const data = await api.getUnreadCount() - unreadCount.value = data.count + try { + const data = await api.getUnreadCount() + unreadCount.value = data.count + } catch { + // 静默失败,不影响页面 + } } /** 获取未读的强提醒公告(首页弹窗用) */ async function fetchUrgentNotifications() { - urgentNotifications.value = await api.getPinnedNotifications() + try { + urgentNotifications.value = await api.getPinnedNotifications() + } catch { + // 静默失败 + } } async function markRead(id: number) { - await api.markRead(id) - if (unreadCount.value > 0) unreadCount.value-- - // 从强提醒列表中移除 - urgentNotifications.value = urgentNotifications.value.filter(n => n.id !== id) + try { + await api.markRead(id) + if (unreadCount.value > 0) unreadCount.value-- + // 从强提醒列表中移除 + urgentNotifications.value = urgentNotifications.value.filter(n => n.id !== id) + } catch { + // 静默失败 + } } async function markAllRead() { - await api.markAllRead() - unreadCount.value = 0 - urgentNotifications.value = [] + try { + await api.markAllRead() + unreadCount.value = 0 + urgentNotifications.value = [] + } catch { + // 静默失败 + } } return { unreadCount, urgentNotifications, fetchUnreadCount, fetchUrgentNotifications, markRead, markAllRead } diff --git a/client/src/styles/mixins.scss b/client/src/styles/mixins.scss index c8933bd..84dc698 100644 --- a/client/src/styles/mixins.scss +++ b/client/src/styles/mixins.scss @@ -109,6 +109,17 @@ align-items: flex-end; } +// 高层级弹窗(紧急公告、身份选择等需要覆盖其他弹窗的场景) +@mixin modal-mask-high { + position: fixed; + top: 0; left: 0; right: 0; bottom: 0; + background: rgba(0, 0, 0, 0.5); + z-index: 300; + display: flex; + align-items: center; + justify-content: center; +} + @mixin bottom-modal { width: 100%; max-height: 80vh;