smart-admin-web 10.25.0 → 10.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"NoticeBell2.vue.js","sources":["../../src/layouts/NoticeBell.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 顶栏消息通知铃铛。富面板(n-popover):无页签单列表 + 正文弹层。\n// 未读=圆点+加粗+淡主色底,已读=整行变淡;\"读没读\"是过滤器不是分类,不做成页签(筛选在个人通知页)。\n// 未读数每 30s 轮询;面板展开时拉取列表。\n// 通知带动作列表时,正文弹层底部渲染成按钮(useNoticeAction):铃铛里直接\"办\",不必先跳到目标页面找按钮。\nimport { ref } from 'vue'\nimport { useRouter } from 'vue-router'\nimport {\n NPopover,\n NBadge,\n NButton,\n NTag,\n NEllipsis,\n NScrollbar,\n NSpace,\n NText,\n NEmpty,\n NModal,\n NSpin,\n useMessage,\n} from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport { useIntervalFn } from '@vueuse/core'\nimport { useI18n } from 'vue-i18n'\nimport { noticeApi } from '#/api'\nimport { noticeBus } from '#/composables/useRealtime'\nimport { useNoticeAction } from '#/composables/useNoticeAction'\nimport { NoticeType, type NoticeAction, type NoticeMineItem } from '#/types/api'\nimport MarkdownView from '#/components/MarkdownEditor/MarkdownView.vue'\nimport { translateError } from '#/utils/error'\nimport { fmtDateTime } from '#/utils/format'\n\nconst { t } = useI18n()\nconst router = useRouter()\nconst message = useMessage()\nconst noticeAction = useNoticeAction()\n\nconst unread = ref(0)\nconst items = ref<NoticeMineItem[]>([])\nconst loading = ref(false)\nconst panelShow = ref(false)\n\nasync function fetchUnread() {\n try {\n unread.value = await noticeApi.unreadCount()\n } catch {\n /* 轮询失败静默,下次自愈 */\n }\n}\n// 无页签单列表:恒拉最近一页混排,未读靠条目样式强调;筛选能力在\"查看全部\"的个人通知页。\nasync function fetchList() {\n loading.value = true\n try {\n const { items: list } = await noticeApi.mine({ page: 1, pageSize: 10 })\n items.value = list\n } catch {\n items.value = []\n } finally {\n loading.value = false\n }\n}\nfunction onShow(show: boolean) {\n if (show) fetchList()\n}\n\n// 正文弹层:内容随列表取回,直接渲染(Markdown,不能纯文本直出);点条目即标记已读。\nconst showNotice = ref(false)\nconst viewNotice = ref<NoticeMineItem | null>(null)\nasync function markRead(item: NoticeMineItem) {\n if (item.isRead) return\n try {\n await noticeApi.markRead(item.id)\n item.isRead = true\n await fetchUnread()\n } catch (e) {\n message.error(translateError(e))\n }\n}\nasync function openNotice(item: NoticeMineItem) {\n viewNotice.value = item\n showNotice.value = true\n await markRead(item)\n}\n// 动作:成功后关掉弹层与面板(页面跳转时尤其要关,否则面板盖在新页面上)。\nconst running = ref<number | null>(null)\nasync function onAction(a: NoticeAction, index: number) {\n running.value = index\n try {\n if (await noticeAction.run(a)) {\n showNotice.value = false\n panelShow.value = false\n }\n } finally {\n running.value = null\n }\n}\nasync function markAllRead() {\n try {\n await noticeApi.markAllRead()\n await Promise.all([fetchUnread(), fetchList()])\n } catch (e) {\n message.error(translateError(e))\n }\n}\nfunction viewAll() {\n panelShow.value = false\n router.push('/personal/notice')\n}\n\n// 类型 → 标签色/文案。新增类型在此补一行即可。\nconst tagType = (ty: NoticeType) =>\n ty === NoticeType.Announcement ? 'warning' : ty === NoticeType.Message ? 'success' : 'info'\nconst typeLabel = (ty: NoticeType) =>\n ty === NoticeType.Announcement\n ? t('notice.typeAnnouncement')\n : ty === NoticeType.Message\n ? t('notice.typeMessage')\n : t('notice.typeNotice')\n\n// 正文摘要:去掉常见 Markdown 记号,压空白,截断。ponytail: 正则够用,要精准渲染再引 md 解析。\nfunction snippet(md?: string | null) {\n if (!md) return ''\n const s = md\n .replace(/!\\[[^\\]]*\\]\\([^)]*\\)/g, '') // 图片\n .replace(/\\[([^\\]]*)\\]\\([^)]*\\)/g, '$1') // 链接留文字\n .replace(/[#>*_`~-]/g, '') // 记号\n .replace(/\\s+/g, ' ')\n .trim()\n return s.length > 60 ? s.slice(0, 60) + '…' : s\n}\n\n// 双腿:实时推送到达即刷新未读(SignalR 开启时,即时);30s 轮询兜底(实时关闭/连接掉线时)。\n// VueUse 的 useEventBus.on 在组件卸载时自动退订。\nnoticeBus.on(() => {\n fetchUnread()\n})\nuseIntervalFn(fetchUnread, 30000)\nfetchUnread()\n</script>\n\n<template>\n <n-popover\n v-model:show=\"panelShow\"\n trigger=\"click\"\n placement=\"bottom-end\"\n :show-arrow=\"false\"\n style=\"padding: 0\"\n @update:show=\"onShow\"\n >\n <template #trigger>\n <!-- offset 的 y 把徽标整体下移:默认它以按钮右上角为中心、一半在按钮顶边之上,\n 顶栏面板 overflow:hidden,两三位数(99+)的胶囊顶边会被切平 -->\n <n-badge :value=\"unread\" :max=\"99\" :show=\"unread > 0\" :offset=\"[0, 5]\">\n <n-button quaternary circle :aria-label=\"t('app.notice.title')\">\n <Icon icon=\"ph:bell\" :width=\"19\" />\n </n-button>\n </n-badge>\n </template>\n\n <div class=\"notice-panel\">\n <div class=\"notice-head\">\n <span class=\"notice-title\">{{ t('app.notice.title') }}</span>\n <n-button text size=\"tiny\" :disabled=\"unread === 0\" @click=\"markAllRead\">\n <template #icon><Icon icon=\"ph:checks\" :width=\"15\" /></template>\n {{ t('app.notice.markAllRead') }}\n </n-button>\n </div>\n\n <n-spin :show=\"loading\">\n <n-scrollbar style=\"max-height: 360px\">\n <div v-if=\"items.length === 0\" class=\"notice-empty\">\n <n-empty :description=\"t('app.notice.empty')\" size=\"small\" />\n </div>\n <ul v-else class=\"notice-list\">\n <li\n v-for=\"n in items\"\n :key=\"n.id\"\n :class=\"['notice-item', n.isRead ? 'read' : 'unread']\"\n @click=\"openNotice(n)\"\n >\n <span v-if=\"!n.isRead\" class=\"dot\" />\n <div class=\"notice-body\">\n <div class=\"line1\">\n <n-tag :type=\"tagType(n.type)\" size=\"tiny\" :bordered=\"false\" round>\n {{ typeLabel(n.type) }}\n </n-tag>\n <n-ellipsis class=\"item-title\" :class=\"{ unread: !n.isRead }\">\n {{ n.title }}\n </n-ellipsis>\n <Icon\n v-if=\"n.actions?.length\"\n icon=\"ph:lightning\"\n :width=\"13\"\n class=\"item-actions-mark\"\n />\n </div>\n <n-text v-if=\"snippet(n.content)\" depth=\"3\" class=\"item-snippet\">\n {{ snippet(n.content) }}\n </n-text>\n <n-text depth=\"3\" class=\"item-time\">\n {{ fmtDateTime(n.publishTime, { seconds: false }) }}\n </n-text>\n </div>\n </li>\n </ul>\n </n-scrollbar>\n </n-spin>\n\n <div class=\"notice-foot\">\n <n-button text size=\"small\" @click=\"viewAll\">\n {{ t('app.notice.viewAll') }}\n <template #icon><Icon icon=\"ph:arrow-right\" :width=\"14\" /></template>\n </n-button>\n </div>\n </div>\n </n-popover>\n\n <n-modal\n v-model:show=\"showNotice\"\n preset=\"card\"\n :title=\"viewNotice?.title || t('notice.detailTitle')\"\n style=\"width: 640px; max-width: 92vw\"\n >\n <MarkdownView :value=\"viewNotice?.content\" />\n <template v-if=\"viewNotice?.actions?.length\" #footer>\n <n-space justify=\"end\">\n <n-button\n v-for=\"(a, i) in viewNotice.actions\"\n :key=\"i\"\n size=\"small\"\n :type=\"noticeAction.buttonType(a)\"\n :loading=\"running === i\"\n :disabled=\"running !== null && running !== i\"\n @click=\"onAction(a, i)\"\n >\n {{ noticeAction.label(a) }}\n </n-button>\n </n-space>\n </template>\n </n-modal>\n</template>\n\n<style scoped>\n.notice-panel {\n width: 360px;\n max-width: 92vw;\n}\n.notice-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px 4px;\n}\n.notice-title {\n font-weight: 600;\n font-size: 15px;\n}\n.notice-empty {\n padding: 32px 0;\n}\n.notice-list {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.notice-item {\n position: relative;\n display: flex;\n gap: 8px;\n padding: 12px 16px;\n cursor: pointer;\n border-top: 1px solid var(--separator);\n transition: background-color var(--transition-fast);\n}\n.notice-item:hover {\n background-color: var(--hover);\n}\n/* 未读:整行淡主色底(明暗主题都成立);已读:整行变淡 */\n.notice-item.unread {\n background-color: color-mix(in srgb, var(--signal) 5%, transparent);\n}\n.notice-item.unread:hover {\n background-color: color-mix(in srgb, var(--signal) 10%, transparent);\n}\n.notice-item.read {\n opacity: 0.55;\n}\n.dot {\n position: absolute;\n left: 6px;\n top: 18px;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--signal);\n}\n.notice-body {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.line1 {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n}\n.item-title {\n flex: 1;\n min-width: 0;\n font-size: 14px;\n}\n.item-title.unread {\n font-weight: 600;\n}\n.item-actions-mark {\n flex-shrink: 0;\n color: var(--signal);\n}\n.item-snippet {\n font-size: 13px;\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n.item-time {\n font-size: 12.5px;\n}\n.notice-foot {\n display: flex;\n justify-content: center;\n padding: 8px;\n border-top: 1px solid var(--separator);\n}\n</style>\n"],"names":["t","useI18n","router","useRouter","message","useMessage","noticeAction","useNoticeAction","unread","ref","items","loading","panelShow","fetchUnread","noticeApi","fetchList","list","onShow","show","showNotice","viewNotice","markRead","item","e","translateError","openNotice","running","onAction","a","index","markAllRead","viewAll","tagType","ty","NoticeType","typeLabel","snippet","md","s","noticeBus","useIntervalFn","_createVNode","_unref","NPopover","$event","NBadge","NButton","Icon","_createElementVNode","_hoisted_1","_hoisted_2","_hoisted_3","_toDisplayString","_createTextVNode","NSpin","NScrollbar","_openBlock","_createElementBlock","_hoisted_4","NEmpty","_hoisted_5","_Fragment","_renderList","n","_normalizeClass","_hoisted_7","_hoisted_8","_hoisted_9","NTag","NEllipsis","_a","_createBlock","NText","fmtDateTime","_hoisted_10","NModal","MarkdownView","_c","_b","NSpace","i"],"mappings":"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"}
1
+ {"version":3,"file":"NoticeBell2.vue.js","sources":["../../src/layouts/NoticeBell.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 顶栏消息通知铃铛。富面板(n-popover):按类型分页签的列表 + 正文弹层。\n// 页签按\"消息从哪来\"分:消息(业务系统推给个人的)与通知(管理员发的通知、公告);\n// \"读没读\"是过滤器不是分类,不做成页签(筛选在个人通知页)。\n// 未读=圆点+加粗+淡主色底,已读=整行变淡。总未读数每 30s 轮询;面板展开时取各页签未读数与当前页签列表。\n// 通知带动作列表时,正文弹层底部渲染成按钮(useNoticeAction):铃铛里直接\"办\",不必先跳到目标页面找按钮。\nimport { computed, reactive, ref } from 'vue'\nimport { useRouter } from 'vue-router'\nimport {\n NPopover,\n NBadge,\n NButton,\n NTabs,\n NTab,\n NTag,\n NEllipsis,\n NScrollbar,\n NSpace,\n NText,\n NEmpty,\n NModal,\n NSpin,\n useMessage,\n} from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport { useIntervalFn } from '@vueuse/core'\nimport { useI18n } from 'vue-i18n'\nimport { noticeApi } from '#/api'\nimport { noticeBus } from '#/composables/useRealtime'\nimport { useNoticeAction } from '#/composables/useNoticeAction'\nimport { NoticeType, type NoticeAction, type NoticeMineItem } from '#/types/api'\nimport MarkdownView from '#/components/MarkdownEditor/MarkdownView.vue'\nimport { translateError } from '#/utils/error'\nimport { fmtDateTime } from '#/utils/format'\n\nconst { t } = useI18n()\nconst router = useRouter()\nconst message = useMessage()\nconst noticeAction = useNoticeAction()\n\n// 页签顺序即打开面板时的优先级:先停在第一个有未读的页签,都没有就停第一个。\nconst TABS = [\n {\n key: 'message',\n types: [NoticeType.Message],\n label: 'app.notice.tabMessage',\n empty: 'app.notice.emptyMessage',\n },\n {\n key: 'notice',\n types: [NoticeType.Notice, NoticeType.Announcement],\n label: 'app.notice.tabNotice',\n empty: 'app.notice.empty',\n },\n] as const\ntype TabKey = (typeof TABS)[number]['key']\nconst typesOf = (key: TabKey) => [...TABS.find(x => x.key === key)!.types]\n\nconst unread = ref(0)\nconst tab = ref<TabKey>(TABS[0].key)\nconst tabUnread = reactive<Record<TabKey, number>>({ message: 0, notice: 0 })\nconst current = computed(() => TABS.find(x => x.key === tab.value)!)\nconst items = ref<NoticeMineItem[]>([])\nconst loading = ref(false)\nconst panelShow = ref(false)\n\n// 页签未读数只在面板开着时取:轮询只数总数,请求量不随页签数翻倍。\nasync function fetchTabUnread() {\n const counts = await Promise.all(TABS.map(x => noticeApi.unreadCount([...x.types])))\n TABS.forEach((x, i) => (tabUnread[x.key] = counts[i]!))\n}\nasync function fetchUnread() {\n try {\n unread.value = await noticeApi.unreadCount()\n if (panelShow.value) await fetchTabUnread()\n } catch {\n /* 轮询失败静默,下次自愈 */\n }\n}\n// 每个页签拉最近一页,未读靠条目样式强调;筛选能力在\"查看全部\"的个人通知页。\nasync function fetchList() {\n const key = tab.value\n loading.value = true\n try {\n const { items: list } = await noticeApi.mine({ page: 1, pageSize: 10, types: typesOf(key) })\n // 快速切页签时,先发的请求可能后回来,不能覆盖当前页签的列表。\n if (key === tab.value) items.value = list\n } catch {\n if (key === tab.value) items.value = []\n } finally {\n if (key === tab.value) loading.value = false\n }\n}\nasync function onShow(show: boolean) {\n if (!show) return\n loading.value = true\n try {\n await fetchTabUnread()\n } catch {\n /* 取不到页签数就停在第一个页签 */\n }\n tab.value = TABS.find(x => tabUnread[x.key] > 0)?.key ?? TABS[0].key\n fetchList()\n}\nfunction onTab(key: TabKey) {\n tab.value = key\n fetchList()\n}\n\n// 正文弹层:内容随列表取回,直接渲染(Markdown,不能纯文本直出);点条目即标记已读。\nconst showNotice = ref(false)\nconst viewNotice = ref<NoticeMineItem | null>(null)\nasync function markRead(item: NoticeMineItem) {\n if (item.isRead) return\n try {\n await noticeApi.markRead(item.id)\n item.isRead = true\n await fetchUnread()\n } catch (e) {\n message.error(translateError(e))\n }\n}\nasync function openNotice(item: NoticeMineItem) {\n viewNotice.value = item\n showNotice.value = true\n await markRead(item)\n}\n// 动作:成功后关掉弹层与面板(页面跳转时尤其要关,否则面板盖在新页面上)。\nconst running = ref<number | null>(null)\nasync function onAction(a: NoticeAction, index: number) {\n running.value = index\n try {\n if (await noticeAction.run(a)) {\n showNotice.value = false\n panelShow.value = false\n }\n } finally {\n running.value = null\n }\n}\nasync function markAllRead() {\n try {\n await noticeApi.markAllRead(typesOf(tab.value))\n await Promise.all([fetchUnread(), fetchList()])\n } catch (e) {\n message.error(translateError(e))\n }\n}\nfunction viewAll() {\n panelShow.value = false\n router.push('/personal/notice')\n}\n\n// 类型 → 标签色/文案。新增类型在此补一行即可。\nconst tagType = (ty: NoticeType) =>\n ty === NoticeType.Announcement ? 'warning' : ty === NoticeType.Message ? 'success' : 'info'\nconst typeLabel = (ty: NoticeType) =>\n ty === NoticeType.Announcement\n ? t('notice.typeAnnouncement')\n : ty === NoticeType.Message\n ? t('notice.typeMessage')\n : t('notice.typeNotice')\n// 页签里只有一种类型时标签不带信息,不显示。\nconst showTag = computed(() => current.value.types.length > 1)\n\n// 正文摘要:去掉常见 Markdown 记号,压空白,截断。ponytail: 正则够用,要精准渲染再引 md 解析。\nfunction snippet(md?: string | null) {\n if (!md) return ''\n const s = md\n .replace(/!\\[[^\\]]*\\]\\([^)]*\\)/g, '') // 图片\n .replace(/\\[([^\\]]*)\\]\\([^)]*\\)/g, '$1') // 链接留文字\n .replace(/[#>*_`~-]/g, '') // 记号\n .replace(/\\s+/g, ' ')\n .trim()\n return s.length > 60 ? s.slice(0, 60) + '…' : s\n}\n\n// 双腿:实时推送到达即刷新未读(SignalR 开启时,即时);30s 轮询兜底(实时关闭/连接掉线时)。\n// VueUse 的 useEventBus.on 在组件卸载时自动退订。\nnoticeBus.on(() => {\n fetchUnread()\n})\nuseIntervalFn(fetchUnread, 30000)\nfetchUnread()\n</script>\n\n<template>\n <n-popover\n v-model:show=\"panelShow\"\n trigger=\"click\"\n placement=\"bottom-end\"\n :show-arrow=\"false\"\n style=\"padding: 0\"\n @update:show=\"onShow\"\n >\n <template #trigger>\n <!-- offset 的 y 把徽标整体下移:默认它以按钮右上角为中心、一半在按钮顶边之上,\n 顶栏面板 overflow:hidden,两三位数(99+)的胶囊顶边会被切平 -->\n <n-badge :value=\"unread\" :max=\"99\" :show=\"unread > 0\" :offset=\"[0, 5]\">\n <n-button quaternary circle :aria-label=\"t('app.notice.title')\">\n <Icon icon=\"ph:bell\" :width=\"19\" />\n </n-button>\n </n-badge>\n </template>\n\n <div class=\"notice-panel\">\n <div class=\"notice-head\">\n <span class=\"notice-title\">{{ t('app.notice.title') }}</span>\n <n-button text size=\"tiny\" :disabled=\"tabUnread[tab] === 0\" @click=\"markAllRead\">\n <template #icon><Icon icon=\"ph:checks\" :width=\"15\" /></template>\n {{ t('app.notice.markAllRead') }}\n </n-button>\n </div>\n\n <n-tabs\n :value=\"tab\"\n type=\"line\"\n size=\"small\"\n :tabs-padding=\"16\"\n class=\"notice-tabs\"\n @update:value=\"onTab\"\n >\n <n-tab v-for=\"x in TABS\" :key=\"x.key\" :name=\"x.key\">\n {{ t(x.label) }}\n <n-badge\n :value=\"tabUnread[x.key]\"\n :max=\"99\"\n :show=\"tabUnread[x.key] > 0\"\n class=\"tab-badge\"\n />\n </n-tab>\n </n-tabs>\n\n <n-spin :show=\"loading\">\n <n-scrollbar style=\"max-height: 360px\">\n <div v-if=\"items.length === 0\" class=\"notice-empty\">\n <n-empty :description=\"t(current.empty)\" size=\"small\" />\n </div>\n <ul v-else class=\"notice-list\">\n <li\n v-for=\"n in items\"\n :key=\"n.id\"\n :class=\"['notice-item', n.isRead ? 'read' : 'unread']\"\n @click=\"openNotice(n)\"\n >\n <span v-if=\"!n.isRead\" class=\"dot\" />\n <div class=\"notice-body\">\n <div class=\"line1\">\n <n-tag v-if=\"showTag\" :type=\"tagType(n.type)\" size=\"tiny\" :bordered=\"false\" round>\n {{ typeLabel(n.type) }}\n </n-tag>\n <n-ellipsis class=\"item-title\" :class=\"{ unread: !n.isRead }\">\n {{ n.title }}\n </n-ellipsis>\n <Icon\n v-if=\"n.actions?.length\"\n icon=\"ph:lightning\"\n :width=\"13\"\n class=\"item-actions-mark\"\n />\n </div>\n <n-text v-if=\"snippet(n.content)\" depth=\"3\" class=\"item-snippet\">\n {{ snippet(n.content) }}\n </n-text>\n <n-text depth=\"3\" class=\"item-time\">\n {{ fmtDateTime(n.publishTime, { seconds: false }) }}\n </n-text>\n </div>\n </li>\n </ul>\n </n-scrollbar>\n </n-spin>\n\n <div class=\"notice-foot\">\n <n-button text size=\"small\" @click=\"viewAll\">\n {{ t('app.notice.viewAll') }}\n <template #icon><Icon icon=\"ph:arrow-right\" :width=\"14\" /></template>\n </n-button>\n </div>\n </div>\n </n-popover>\n\n <n-modal\n v-model:show=\"showNotice\"\n preset=\"card\"\n :title=\"viewNotice?.title || t('notice.detailTitle')\"\n style=\"width: 640px; max-width: 92vw\"\n >\n <MarkdownView :value=\"viewNotice?.content\" />\n <template v-if=\"viewNotice?.actions?.length\" #footer>\n <n-space justify=\"end\">\n <n-button\n v-for=\"(a, i) in viewNotice.actions\"\n :key=\"i\"\n size=\"small\"\n :type=\"noticeAction.buttonType(a)\"\n :loading=\"running === i\"\n :disabled=\"running !== null && running !== i\"\n @click=\"onAction(a, i)\"\n >\n {{ noticeAction.label(a) }}\n </n-button>\n </n-space>\n </template>\n </n-modal>\n</template>\n\n<style scoped>\n.notice-panel {\n width: 360px;\n max-width: 92vw;\n}\n.notice-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px 4px;\n}\n.notice-title {\n font-weight: 600;\n font-size: 15px;\n}\n.tab-badge {\n margin-left: 6px;\n}\n.notice-empty {\n padding: 32px 0;\n}\n.notice-list {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.notice-item {\n position: relative;\n display: flex;\n gap: 8px;\n padding: 12px 16px;\n cursor: pointer;\n border-top: 1px solid var(--separator);\n transition: background-color var(--transition-fast);\n}\n.notice-item:hover {\n background-color: var(--hover);\n}\n/* 未读:整行淡主色底(明暗主题都成立);已读:整行变淡 */\n.notice-item.unread {\n background-color: color-mix(in srgb, var(--signal) 5%, transparent);\n}\n.notice-item.unread:hover {\n background-color: color-mix(in srgb, var(--signal) 10%, transparent);\n}\n.notice-item.read {\n opacity: 0.55;\n}\n.dot {\n position: absolute;\n left: 6px;\n top: 18px;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--signal);\n}\n.notice-body {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.line1 {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n}\n.item-title {\n flex: 1;\n min-width: 0;\n font-size: 14px;\n}\n.item-title.unread {\n font-weight: 600;\n}\n.item-actions-mark {\n flex-shrink: 0;\n color: var(--signal);\n}\n.item-snippet {\n font-size: 13px;\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n.item-time {\n font-size: 12.5px;\n}\n.notice-foot {\n display: flex;\n justify-content: center;\n padding: 8px;\n border-top: 1px solid var(--separator);\n}\n</style>\n"],"names":["t","useI18n","router","useRouter","message","useMessage","noticeAction","useNoticeAction","TABS","NoticeType","typesOf","key","x","unread","ref","tab","tabUnread","reactive","current","computed","items","loading","panelShow","fetchTabUnread","counts","noticeApi","i","fetchUnread","fetchList","list","onShow","show","_a","onTab","showNotice","viewNotice","markRead","item","e","translateError","openNotice","running","onAction","a","index","markAllRead","viewAll","tagType","ty","typeLabel","showTag","snippet","md","s","noticeBus","useIntervalFn","_createVNode","_unref","NPopover","$event","NBadge","NButton","Icon","_createElementVNode","_hoisted_1","_hoisted_2","_hoisted_3","_toDisplayString","_createTextVNode","NTabs","_createElementBlock","_Fragment","_renderList","NTab","NSpin","NScrollbar","_openBlock","_hoisted_4","NEmpty","_hoisted_5","n","_normalizeClass","_hoisted_7","_hoisted_8","_hoisted_9","_createBlock","NTag","NEllipsis","NText","fmtDateTime","_hoisted_10","NModal","MarkdownView","_c","_b","NSpace"],"mappings":"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"}
@@ -2,7 +2,7 @@ const e = {
2
2
  /** API 根地址;空串 = 同源(dev 由 Vite 代理,生产由反代或后端托管 dist) */
3
3
  apiBase: "",
4
4
  /** 登录页页脚展示的版本号;默认内核版本,消费方可覆盖为应用版本 */
5
- version: "10.25.0",
5
+ version: "10.26.0",
6
6
  /** 开发态:登录页预填超管账号、设置抽屉显示「复制配置」 */
7
7
  dev: !1,
8
8
  brand: {}
@@ -110,6 +110,9 @@ declare const _default: {
110
110
  notice: {
111
111
  title: string;
112
112
  empty: string;
113
+ emptyMessage: string;
114
+ tabMessage: string;
115
+ tabNotice: string;
113
116
  markAllRead: string;
114
117
  viewAll: string;
115
118
  };
@@ -112,6 +112,9 @@ const e = {
112
112
  notice: {
113
113
  title: "Notifications",
114
114
  empty: "No notifications",
115
+ emptyMessage: "No messages",
116
+ tabMessage: "Messages",
117
+ tabNotice: "Notices",
115
118
  markAllRead: "Mark all read",
116
119
  viewAll: "View all"
117
120
  }