smart-admin-web 10.22.0 → 10.23.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.
- package/dist/components/FormContainer/index.vue.js +67 -67
- package/dist/components/FormContainer/index.vue.js.map +1 -1
- package/dist/components/SidePanelDrawer/index.vue.d.ts +25 -0
- package/dist/components/SidePanelDrawer/index.vue.js +40 -0
- package/dist/components/SidePanelDrawer/index.vue.js.map +1 -0
- package/dist/components/SidePanelDrawer/index3.vue.js +6 -0
- package/dist/components/SidePanelDrawer/index3.vue.js.map +1 -0
- package/dist/composables/useShellBreakpoint.js +14 -13
- package/dist/composables/useShellBreakpoint.js.map +1 -1
- package/dist/composables/useSidePanel.d.ts +9 -0
- package/dist/composables/useSidePanel.js +12 -0
- package/dist/composables/useSidePanel.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +295 -290
- package/dist/index.js.map +1 -1
- package/dist/layouts/default.vue.js +2 -2
- package/dist/layouts/default2.vue.js.map +1 -1
- package/dist/lib/runtime.js +1 -1
- package/dist/style.css +1 -1
- package/dist/views/system/user/index.vue.js +2 -2
- package/dist/views/system/user/index2.vue.js +269 -281
- package/dist/views/system/user/index2.vue.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default2.vue.js","sources":["../../src/layouts/default.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'\nimport { RouterView } from 'vue-router'\nimport { NDrawer, NDrawerContent, NButton } from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport { useBreakpoints, breakpointsTailwind, onKeyStroke } from '@vueuse/core'\nimport { useI18n } from 'vue-i18n'\nimport { useAppStore, type LayoutMode } from '#/stores/app'\nimport { useUserStore } from '#/stores/user'\nimport { useLayoutMenu } from '#/composables/useLayoutMenu'\nimport { useTabsStore } from '#/stores/tabs'\nimport { useSite } from '#/composables/useSite'\nimport { useRealtime } from '#/composables/useRealtime'\nimport { useVisualViewportHeight } from '#/composables/useVisualViewportHeight'\nimport { provideShellBreakpoint } from '#/composables/useShellBreakpoint'\nimport ErrorBoundary from '#/components/ErrorBoundary/index.vue'\nimport MenuSearch from '#/components/MenuSearch.vue'\nimport AppWatermark from '#/components/AppWatermark.vue'\nimport AppHeader from './AppHeader.vue'\nimport SideNav from './components/SideNav.vue'\nimport TabsBar from './TabsBar.vue'\n\nconst { t } = useI18n()\nconst app = useAppStore()\nconst user = useUserStore()\nconst tabs = useTabsStore()\nconst { site } = useSite()\nconst { menuOptions, l1Options, l2Options, selectedL1, activeKey, onSelect, onSelectL1 } =\n useLayoutMenu()\n\n// 实时通知(SignalR):鉴权外壳挂载即连、卸载即断。后端未开启实时时连接静默失败,退回轮询/惰性 401(纯增强)。\nconst { start: startRealtime, stop: stopRealtime } = useRealtime()\nonMounted(startRealtime)\nonUnmounted(stopRealtime)\n\n// 维护 --vvh(真实可视高度):软键盘弹起时 dvh 不变,只有 visualViewport 会缩。\n// 布局壳自身用 100dvh 就够,变量留给需要贴着键盘排版的页面(见 composables/useVisualViewportHeight)。\nuseVisualViewportHeight()\n\nconst isMobile = useBreakpoints(breakpointsTailwind).smaller('md')\nconst mobileOpen = ref(false)\n// 菜单搜索面板(Ctrl+K 同一个):侧栏里的只读输入框、顶栏的搜索按钮都开它,面板本身在 MenuSearch 里。\nconst searchOpen = ref(false)\n\n// 壳层三档(wide / mid / narrow):按内容区(.page 的 content box)宽度判,盯住的就是下面的 .page。\n// 页面里用 useShellBreakpoint() 读;样式里用 .page 上的 bp-* 类 / data-bp。阈值与理由见 composables/useShellBreakpoint。\nconst pageRef = ref<HTMLElement>()\nconst { bp } = provideShellBreakpoint(pageRef)\n\n// 窄屏忽略 layoutMode,统一走 mobile(单列 + 抽屉侧栏)。\nconst mode = computed<LayoutMode | 'mobile'>(() => (isMobile.value ? 'mobile' : app.layoutMode))\n\n// 除 horizontal(无侧栏)外都有侧栏。\nconst withSider = new Set<LayoutMode>([\n 'vertical',\n 'vertical-mix',\n 'vertical-hybrid-header-first',\n 'top-hybrid-sidebar-first',\n 'top-hybrid-header-first',\n])\n// 顶栏显示品牌的模式(其余由侧栏/rail 顶部显示品牌,保证每种布局品牌只出现一处)。\nconst headerBrandModes = new Set<string>([\n 'horizontal',\n 'vertical-hybrid-header-first',\n 'top-hybrid-sidebar-first',\n 'top-hybrid-header-first',\n])\nconst showSider = computed(() => !isMobile.value && withSider.has(app.layoutMode))\nconst sideShowBrand = computed(() => mode.value === 'vertical' || mode.value === 'vertical-mix')\n// 侧栏整个隐藏时品牌回到顶栏,否则这种布局下品牌无处可显\nconst headerShowBrand = computed(\n () => isMobile.value || headerBrandModes.has(mode.value) || asideHidden.value,\n)\n// 顶栏菜单:horizontal=完整树;两个 header-first=一级;侧边优先=二级(选中的一级的子菜单)。\nconst headerTopMenu = computed<'full' | 'l1' | 'l2' | null>(() => {\n switch (mode.value) {\n case 'horizontal':\n return 'full'\n case 'vertical-hybrid-header-first':\n case 'top-hybrid-header-first':\n return 'l1'\n case 'top-hybrid-sidebar-first':\n return 'l2'\n default:\n return null\n }\n})\n// 折叠按钮:有可折叠树侧栏的模式(侧边优先的一级 rail 固定宽,不折叠)。\nconst collapsibleSider = new Set<string>([\n 'vertical',\n 'vertical-mix',\n 'vertical-hybrid-header-first',\n 'top-hybrid-header-first',\n])\nconst showCollapse = computed(() => !isMobile.value && collapsibleSider.has(mode.value))\n// 折叠 = 把侧栏整个隐藏(不是收成图标条):内容区铺满,再点一次(或 Ctrl/⌘+B)恢复。\nconst asideHidden = computed(\n () => showSider.value && app.collapsed && collapsibleSider.has(mode.value),\n)\n// 侧栏树列自带搜索入口(品牌下的只读输入框)时,顶栏不再重复放搜索按钮;\n// 一级 rail 与侧栏隐藏时侧栏里没有输入框,搜索入口回到顶栏。\nconst sideHasSearch = computed(\n () => showSider.value && !asideHidden.value && mode.value !== 'top-hybrid-sidebar-first',\n)\n\n// Ctrl/⌘+B 收起 / 展开侧栏(只在有可折叠侧栏的布局生效)。\n// 编辑器里 Ctrl+B 是「加粗」,在输入控件 / 富文本 / 代码编辑器里不抢。\nfunction inEditable(target: EventTarget | null) {\n if (!(target instanceof HTMLElement)) return false\n return (\n ['INPUT', 'TEXTAREA', 'SELECT'].includes(target.tagName) ||\n target.isContentEditable ||\n !!target.closest('.cm-editor, .md-editor, .md-editor-v3')\n )\n}\nonKeyStroke('b', e => {\n if (!(e.ctrlKey || e.metaKey) || e.altKey || e.shiftKey) return\n if (!showCollapse.value || inEditable(e.target)) return\n e.preventDefault()\n app.toggleCollapsed()\n})\n\n// 非特殊侧栏内容:vertical=完整树;两个 header-first hybrid=二级子菜单树。\nconst asideOptions = computed(() =>\n mode.value === 'vertical' ? menuOptions.value : l2Options.value,\n)\nconst asideFullWidth = computed(() => {\n if (mode.value === 'vertical-mix') return 'calc(var(--rail-w) + var(--sidebar-w))'\n if (mode.value === 'top-hybrid-sidebar-first') return 'var(--rail-w)' // 一级 icon rail,固定宽\n return 'var(--sidebar-w)'\n})\n// 收起 = 宽度过渡到 0(侧栏不卸载,才有得过渡)。--aside-w 是满宽,内容按它定宽、被 aside 的 overflow 裁掉,\n// 收窄过程中菜单文字不会跟着重排。\nconst asideStyle = computed(() => ({\n '--aside-w': asideFullWidth.value,\n width: asideHidden.value ? '0px' : 'var(--aside-w)',\n}))\n\nconst transitionName = computed(() =>\n app.pageTransition === 'none' ? undefined : app.pageTransition,\n)\n\nconst watermarkWho = computed(() => ({\n name: user.userInfo?.name,\n account: user.userInfo?.account,\n org: user.userInfo?.orgName,\n phoneTail: user.userInfo?.phoneTail,\n}))\n\nfunction onMobileSelect(key: string) {\n onSelect(key)\n mobileOpen.value = false\n}\nfunction onMobileSearch() {\n mobileOpen.value = false\n searchOpen.value = true\n}\n\n// 刷新标签:store 置 excludeName(逐出缓存)+ 递增 reloadKey;这里 v-if 关开一次令当前页重挂,再放行缓存。\nconst rvShow = ref(true)\nwatch(\n () => tabs.reloadKey,\n async () => {\n rvShow.value = false\n await nextTick()\n rvShow.value = true\n await nextTick()\n tabs.excludeName = ''\n },\n)\n</script>\n\n<template>\n <div class=\"layout\" :class=\"[`mode-${mode}`, { 'aside-hidden': asideHidden }]\">\n <!-- 侧栏:玻璃面板,悬浮在壁纸上 -->\n <!-- 收起时仍挂载(宽度过渡到 0),inert 让它退出 Tab 序列与无障碍树 -->\n <aside\n v-if=\"showSider\"\n class=\"aside glass\"\n :class=\"{ 'aside--mix': mode === 'vertical-mix', 'aside--hidden': asideHidden }\"\n :style=\"asideStyle\"\n :inert=\"asideHidden\"\n >\n <template v-if=\"mode === 'vertical-mix'\">\n <SideNav\n class=\"rail\"\n :options=\"l1Options\"\n :value=\"selectedL1\"\n rail\n show-brand\n @select=\"onSelectL1\"\n />\n <SideNav\n class=\"l2col\"\n :options=\"l2Options\"\n :value=\"activeKey\"\n show-search\n @select=\"onSelect\"\n @search=\"searchOpen = true\"\n />\n </template>\n <!-- 顶部混合-侧边优先:侧栏只放一级 icon rail(二级在顶栏) -->\n <SideNav\n v-else-if=\"mode === 'top-hybrid-sidebar-first'\"\n :options=\"l1Options\"\n :value=\"selectedL1\"\n rail\n @select=\"onSelectL1\"\n />\n <SideNav\n v-else\n :options=\"asideOptions\"\n :value=\"activeKey\"\n :show-brand=\"sideShowBrand\"\n show-search\n @select=\"onSelect\"\n @search=\"searchOpen = true\"\n />\n </aside>\n\n <!-- 顶部玻璃面板:工具栏 + 页签条同一块,页签条在工具栏下方、以一条发丝线分隔 -->\n <div class=\"shell-head glass\" :class=\"{ 'shell-head--static': !app.fixedHeader }\">\n <header class=\"toolbar\">\n <n-button\n v-if=\"isMobile\"\n quaternary\n circle\n class=\"hbg\"\n :aria-label=\"t('app.openMenu')\"\n @click=\"mobileOpen = true\"\n >\n <Icon icon=\"ph:sidebar-simple\" :width=\"19\" />\n </n-button>\n <div class=\"apph\">\n <AppHeader\n :show-collapse=\"showCollapse\"\n :show-brand=\"headerShowBrand\"\n :top-menu=\"headerTopMenu\"\n :show-search=\"!sideHasSearch\"\n @search=\"searchOpen = true\"\n />\n </div>\n </header>\n <TabsBar v-if=\"app.showTabs\" />\n </div>\n\n <!-- 内容:壁纸(柔光渐变)上直接摆页面,内容层不挂玻璃 -->\n <main class=\"content\">\n <div ref=\"pageRef\" class=\"page\" :class=\"`bp-${bp}`\" :data-bp=\"bp\">\n <!-- 错误边界包住整个内容区:页面组件抛异常时 Vue 会卸掉整棵子树,没有它就是白屏。\n component :key=路由 path 给稳定身份:out-in 过渡才能正确区分进/出场,否则显示上一页缓存\n (按 path 各自成键,不塌缩缓存)。每个页面经 namedPage 套了一层 <div.page-view> 单元素根,\n out-in 能瞬时过渡任何页。 -->\n <ErrorBoundary>\n <router-view v-slot=\"{ Component }\">\n <transition :name=\"transitionName\" mode=\"out-in\">\n <keep-alive :include=\"tabs.cachedNames\" :exclude=\"tabs.excludeName\">\n <component :is=\"Component\" v-if=\"rvShow\" :key=\"activeKey\" />\n </keep-alive>\n </transition>\n </router-view>\n </ErrorBoundary>\n </div>\n <AppWatermark v-if=\"site.watermark.enabled\" :settings=\"site.watermark\" :who=\"watermarkWho\" />\n </main>\n\n <!-- 移动端抽屉侧栏 -->\n <n-drawer v-model:show=\"mobileOpen\" placement=\"left\" :width=\"236\">\n <n-drawer-content :native-scrollbar=\"false\" body-content-style=\"padding:0\">\n <SideNav\n :options=\"menuOptions\"\n :value=\"activeKey\"\n show-brand\n show-search\n @select=\"onMobileSelect\"\n @search=\"onMobileSearch\"\n />\n </n-drawer-content>\n </n-drawer>\n\n <MenuSearch v-model:show=\"searchOpen\" />\n </div>\n</template>\n\n<style scoped>\n/* 壳层:两块玻璃面板(侧栏 / 顶部)+ 一块内容区,离屏幕边缘 8px、面板之间 8px。\n 背景是一整张氛围壁纸(--wallpaper:由强调色推导的柔光 + 底色,不画网格),玻璃叠在光上才有层次;\n 内容层的卡片不用玻璃(只有侧栏、顶栏、弹层是玻璃)。\n z-index 全部压在 1999 以下:smart-naive-table 的放大层是 1999(刻意低于 naive 浮层的 2000),\n 壳层不能盖住它。 */\n.layout {\n --sidebar-w: 232px;\n --rail-w: 64px;\n --aside-duration: 0.28s; /* 侧栏收起 / 展开,macOS 侧栏滑动的量级 */\n display: grid;\n /* dvh 而非 vh:移动端浏览器地址栏收起时 vh 仍按最小视口算,底部会被裁掉一条 */\n height: 100dvh;\n padding: 8px;\n gap: 8px;\n overflow: hidden;\n background: var(--wallpaper, var(--bg-app));\n}\n/* 竖向壳:侧栏满高在左,顶栏缩进到内容列上方 */\n.mode-vertical,\n.mode-vertical-mix,\n.mode-vertical-hybrid-header-first {\n grid-template-columns: auto minmax(0, 1fr);\n grid-template-rows: auto minmax(0, 1fr);\n grid-template-areas: 'aside header' 'aside content';\n}\n/* 顶栏壳:顶栏通栏,侧栏在其下方左侧 */\n.mode-top-hybrid-sidebar-first,\n.mode-top-hybrid-header-first {\n grid-template-columns: auto minmax(0, 1fr);\n grid-template-rows: auto minmax(0, 1fr);\n grid-template-areas: 'header header' 'aside content';\n}\n.mode-horizontal,\n.mode-mobile {\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: auto minmax(0, 1fr);\n grid-template-areas: 'header' 'content';\n}\n\n/* 侧栏隐藏:列还在,侧栏宽度过渡到 0;列间距也要归零,否则空列旁边还留一道 8px。\n 两者用同一时长与曲线,内容区才是被侧栏「推」着变宽,而不是先后跳两下。 */\n.layout {\n transition: column-gap var(--aside-duration) var(--ease-sheet);\n}\n.layout.aside-hidden {\n column-gap: 0;\n}\n\n/* 玻璃面板:半透明底 + 强模糊 + 发丝描边 + 顶边高光 + 深投影 */\n.glass {\n background: var(--glass-panel);\n backdrop-filter: blur(40px) saturate(180%);\n -webkit-backdrop-filter: blur(40px) saturate(180%);\n border: 1px solid var(--glass-border);\n box-shadow: var(--glass-shadow);\n}\n@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {\n .glass {\n background: var(--glass-solid, var(--glass-panel));\n }\n}\n\n.aside {\n grid-area: aside;\n position: relative;\n z-index: 2;\n height: 100%;\n min-height: 0;\n overflow: hidden;\n border-radius: var(--radius-lg);\n transition:\n width var(--aside-duration) var(--ease-sheet),\n border-width var(--aside-duration) var(--ease-sheet),\n opacity 0.2s ease;\n}\n/* 收起:border-box 下宽 0 仍会留两侧 1px 描边,一并归零;透明度同时带走投影 */\n.aside--hidden {\n border-width: 0;\n opacity: 0;\n}\n/* 内容按满宽定宽,被 .aside 的 overflow:hidden 裁掉,收窄时不重排(mix 模式由下面两条各自定宽) */\n.aside:not(.aside--mix) > * {\n width: var(--aside-w);\n}\n.aside--mix {\n display: flex;\n}\n.aside--mix .rail {\n width: var(--rail-w);\n flex-shrink: 0;\n border-right: 1px solid var(--hairline);\n}\n.aside--mix .l2col {\n flex: none;\n width: var(--sidebar-w);\n}\n\n.shell-head {\n grid-area: header;\n position: relative;\n z-index: 5;\n min-width: 0;\n overflow: hidden;\n border-radius: 14px;\n}\n/* 「固定头部」关闭:顶栏不再模糊背后的内容 */\n.shell-head--static {\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n}\n.toolbar {\n display: flex;\n align-items: stretch;\n height: 44px;\n}\n.hbg {\n align-self: center;\n margin-left: 8px;\n}\n.apph {\n flex: 1;\n min-width: 0;\n height: 100%;\n}\n\n.content {\n grid-area: content;\n display: flex;\n flex-direction: column;\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n}\n/* 页面滚动层。左右只留 2px(让卡片的描边 / 投影不被 overflow 裁掉)。\n 顶部不留白:顶栏到首张卡片永远是面板之间的 8px(--gap-card),满屏页和自然滚动页一样 —— 两类页面顶部间距不同的话,\n 从列表页切到工作台首张卡片会下跳一截。自然滚动页底部留 8px 给卡片投影,满屏页(下条)只留 2px。\n 内边距不进壳层档位的数字:档位量的是这块的 content box,见 composables/useShellBreakpoint。 */\n.page {\n flex: 1;\n min-height: 0;\n overflow: auto;\n padding: 0 2px 8px;\n}\n/* 满屏页(列表 / 左右分栏)吃满一屏,四周只留 2px,滚动发生在表体里 */\n.page:not(.bp-narrow):has(> .page-view > :is(.smart-table, .fill-page, .side-page)) {\n padding: 0 2px 2px;\n}\n/* narrow:整页自然滚动,不再锁一屏高度。满屏列表页的 .page-view 在 layout.css 里被补成 height:100%,\n 这里放回自动高度,内容多长页面就多长、由 .page 滚动。 */\n.page.bp-narrow :deep(.page-view) {\n height: auto;\n}\n</style>\n"],"names":["t","useI18n","app","useAppStore","user","useUserStore","tabs","useTabsStore","site","useSite","menuOptions","l1Options","l2Options","selectedL1","activeKey","onSelect","onSelectL1","useLayoutMenu","startRealtime","stopRealtime","useRealtime","onMounted","onUnmounted","useVisualViewportHeight","isMobile","useBreakpoints","breakpointsTailwind","mobileOpen","ref","searchOpen","pageRef","bp","provideShellBreakpoint","mode","computed","withSider","headerBrandModes","showSider","sideShowBrand","headerShowBrand","asideHidden","headerTopMenu","collapsibleSider","showCollapse","sideHasSearch","inEditable","target","onKeyStroke","e","asideOptions","asideFullWidth","asideStyle","transitionName","watermarkWho","_a","_b","_c","_d","onMobileSelect","key","onMobileSearch","rvShow","watch","nextTick","_createElementBlock","_normalizeClass","_Fragment","_createVNode","SideNav","_unref","_createBlock","_createElementVNode","_hoisted_2","NButton","Icon","_hoisted_3","AppHeader","TabsBar","_hoisted_4","ErrorBoundary","RouterView","_withCtx","Component","_Transition","_KeepAlive","_openBlock","_resolveDynamicComponent","AppWatermark","NDrawer","$event","NDrawerContent","MenuSearch"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAsBA,UAAM,EAAE,GAAAA,EAAA,IAAMC,GAAA,GACRC,IAAMC,GAAA,GACNC,IAAOC,GAAA,GACPC,IAAOC,GAAA,GACP,EAAE,MAAAC,EAAA,IAASC,GAAA,GACX,EAAE,aAAAC,GAAa,WAAAC,GAAW,WAAAC,GAAW,YAAAC,GAAY,WAAAC,GAAW,UAAAC,GAAU,YAAAC,EAAA,IAC1EC,GAAA,GAGI,EAAE,OAAOC,GAAe,MAAMC,EAAA,IAAiBC,GAAA;AACrD,IAAAC,GAAUH,CAAa,GACvBI,GAAYH,CAAY,GAIxBI,GAAA;AAEA,UAAMC,IAAWC,GAAeC,EAAmB,EAAE,QAAQ,IAAI,GAC3DC,IAAaC,EAAI,EAAK,GAEtBC,IAAaD,EAAI,EAAK,GAItBE,IAAUF,EAAA,GACV,EAAE,IAAAG,EAAA,IAAOC,GAAuBF,CAAO,GAGvCG,IAAOC,EAAgC,MAAOV,EAAS,QAAQ,WAAWtB,EAAI,UAAW,GAGzFiC,wBAAgB,IAAgB;AAAA,MACpC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD,GAEKC,wBAAuB,IAAY;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD,GACKC,IAAYH,EAAS,MAAM,CAACV,EAAS,SAASW,EAAU,IAAIjC,EAAI,UAAU,CAAC,GAC3EoC,IAAgBJ,EAAS,MAAMD,EAAK,UAAU,cAAcA,EAAK,UAAU,cAAc,GAEzFM,IAAkBL;AAAA,MACtB,MAAMV,EAAS,SAASY,EAAiB,IAAIH,EAAK,KAAK,KAAKO,EAAY;AAAA,IAAA,GAGpEC,IAAgBP,EAAsC,MAAM;AAChE,cAAQD,EAAK,OAAA;AAAA,QACX,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AAAA,QACL,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT;AACE,iBAAO;AAAA,MAAA;AAAA,IAEb,CAAC,GAEKS,wBAAuB,IAAY;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD,GACKC,IAAeT,EAAS,MAAM,CAACV,EAAS,SAASkB,EAAiB,IAAIT,EAAK,KAAK,CAAC,GAEjFO,IAAcN;AAAA,MAClB,MAAMG,EAAU,SAASnC,EAAI,aAAawC,EAAiB,IAAIT,EAAK,KAAK;AAAA,IAAA,GAIrEW,IAAgBV;AAAA,MACpB,MAAMG,EAAU,SAAS,CAACG,EAAY,SAASP,EAAK,UAAU;AAAA,IAAA;AAKhE,aAASY,EAAWC,GAA4B;AAC9C,aAAMA,aAAkB,cAEtB,CAAC,SAAS,YAAY,QAAQ,EAAE,SAASA,EAAO,OAAO,KACvDA,EAAO,qBACP,CAAC,CAACA,EAAO,QAAQ,uCAAuC,IAJb;AAAA,IAM/C;AACA,IAAAC,GAAY,KAAK,CAAAC,MAAK;AACpB,MAAI,EAAEA,EAAE,WAAWA,EAAE,YAAYA,EAAE,UAAUA,EAAE,YAC3C,CAACL,EAAa,SAASE,EAAWG,EAAE,MAAM,MAC9CA,EAAE,eAAA,GACF9C,EAAI,gBAAA;AAAA,IACN,CAAC;AAGD,UAAM+C,IAAef;AAAA,MAAS,MAC5BD,EAAK,UAAU,aAAavB,EAAY,QAAQE,EAAU;AAAA,IAAA,GAEtDsC,IAAiBhB,EAAS,MAC1BD,EAAK,UAAU,iBAAuB,2CACtCA,EAAK,UAAU,6BAAmC,kBAC/C,kBACR,GAGKkB,IAAajB,EAAS,OAAO;AAAA,MACjC,aAAagB,EAAe;AAAA,MAC5B,OAAOV,EAAY,QAAQ,QAAQ;AAAA,IAAA,EACnC,GAEIY,IAAiBlB;AAAA,MAAS,MAC9BhC,EAAI,mBAAmB,SAAS,SAAYA,EAAI;AAAA,IAAA,GAG5CmD,IAAenB,EAAS,MAAA;;AAAO;AAAA,QACnC,OAAMoB,IAAAlD,EAAK,aAAL,gBAAAkD,EAAe;AAAA,QACrB,UAASC,IAAAnD,EAAK,aAAL,gBAAAmD,EAAe;AAAA,QACxB,MAAKC,IAAApD,EAAK,aAAL,gBAAAoD,EAAe;AAAA,QACpB,YAAWC,IAAArD,EAAK,aAAL,gBAAAqD,EAAe;AAAA,MAAA;AAAA,KAC1B;AAEF,aAASC,GAAeC,GAAa;AACnC,MAAA5C,EAAS4C,CAAG,GACZhC,EAAW,QAAQ;AAAA,IACrB;AACA,aAASiC,KAAiB;AACxB,MAAAjC,EAAW,QAAQ,IACnBE,EAAW,QAAQ;AAAA,IACrB;AAGA,UAAMgC,IAASjC,EAAI,EAAI;AACvB,WAAAkC;AAAA,MACE,MAAMxD,EAAK;AAAA,MACX,YAAY;AACV,QAAAuD,EAAO,QAAQ,IACf,MAAME,EAAA,GACNF,EAAO,QAAQ,IACf,MAAME,EAAA,GACNzD,EAAK,cAAc;AAAA,MACrB;AAAA,IAAA,mBAKA0D,EA4GM,OAAA;AAAA,MA5GD,OAAKC,EAAA,CAAC,UAAQ,CAAA,QAAkBhC,EAAA,KAAI,sBAAsBO,EAAA,MAAA,CAAW,CAAA,CAAA;AAAA,IAAA;MAIhEH,EAAA,cADR2B,EA0CQ,SAAA;AAAA;QAxCN,OAAKC,EAAA,CAAC,eAAa,EAAA,cACKhC,EAAA,2CAA0CO,EAAA,MAAA,CAAW,CAAA;AAAA,QAC5E,UAAOW,EAAA,KAAU;AAAA,QACjB,OAAOX,EAAA;AAAA,MAAA;QAEQP,EAAA,UAAI,uBAApB+B,EAiBWE,IAAA,EAAA,KAAA,KAAA;AAAA,UAhBTC,EAOEC,GAAA;AAAA,YANA,OAAM;AAAA,YACL,SAASC,EAAA1D,CAAA;AAAA,YACT,OAAO0D,EAAAxD,CAAA;AAAA,YACR,MAAA;AAAA,YACA,cAAA;AAAA,YACC,UAAQwD,EAAArD,CAAA;AAAA,UAAA;UAEXmD,EAOEC,GAAA;AAAA,YANA,OAAM;AAAA,YACL,SAASC,EAAAzD,CAAA;AAAA,YACT,OAAOyD,EAAAvD,CAAA;AAAA,YACR,eAAA;AAAA,YACC,UAAQuD,EAAAtD,CAAA;AAAA,YACR,iCAAQc,EAAA,QAAU;AAAA,UAAA;kBAKVI,EAAA,UAAI,mCADjBqC,EAMEF,GAAA;AAAA;UAJC,SAASC,EAAA1D,CAAA;AAAA,UACT,OAAO0D,EAAAxD,CAAA;AAAA,UACR,MAAA;AAAA,UACC,UAAQwD,EAAArD,CAAA;AAAA,QAAA,uDAEXsD,EAQEF,GAAA;AAAA;UANC,SAASnB,EAAA;AAAA,UACT,OAAOoB,EAAAvD,CAAA;AAAA,UACP,cAAYwB,EAAA;AAAA,UACb,eAAA;AAAA,UACC,UAAQ+B,EAAAtD,CAAA;AAAA,UACR,iCAAQc,EAAA,QAAU;AAAA,QAAA;;MAKvB0C,EAuBM,OAAA;AAAA,QAvBD,OAAKN,EAAA,CAAC,oBAAkB,EAAA,sBAAA,CAAkCI,EAAAnE,CAAA,EAAI,aAAW,CAAA;AAAA,MAAA;QAC5EqE,EAoBS,UApBTC,IAoBS;AAAA,UAlBCH,EAAA7C,CAAA,UADR8C,EASWD,EAAAI,EAAA,GAAA;AAAA;YAPT,YAAA;AAAA,YACA,QAAA;AAAA,YACA,OAAM;AAAA,YACL,cAAYJ,EAAArE,CAAA,EAAC,cAAA;AAAA,YACb,gCAAO2B,EAAA,QAAU;AAAA,UAAA;uBAElB,MAA6C;AAAA,cAA7CwC,EAA6CE,EAAAK,EAAA,GAAA;AAAA,gBAAvC,MAAK;AAAA,gBAAqB,OAAO;AAAA,cAAA;;;;UAEzCH,EAQM,OARNI,IAQM;AAAA,YAPJR,EAMES,IAAA;AAAA,cALC,iBAAejC,EAAA;AAAA,cACf,cAAYJ,EAAA;AAAA,cACZ,YAAUE,EAAA;AAAA,cACV,gBAAcG,EAAA;AAAA,cACd,iCAAQf,EAAA,QAAU;AAAA,YAAA;;;QAIVwC,EAAAnE,CAAA,EAAI,iBAAnBoE,EAA+BO,IAAA,EAAA,KAAA,EAAA,CAAA;;MAIjCN,EAiBO,QAjBPO,IAiBO;AAAA,QAhBLP,EAcM,OAAA;AAAA,mBAdG;AAAA,UAAJ,KAAIzC;AAAA,UAAU,OAAKmC,EAAA,CAAC,QAAM,MAAeI,EAAAtC,CAAA,CAAE,EAAA,CAAA;AAAA,UAAK,WAASsC,EAAAtC,CAAA;AAAA,QAAA;UAK5DoC,EAQgBY,IAAA,MAAA;AAAA,uBAPd,MAMc;AAAA,cANdZ,EAMcE,EAAAW,EAAA,GAAA,MAAA;AAAA,gBALZ,SAAAC,EAAA,CAIa,EALQ,WAAAC,QAAS;AAAA,kBAC9Bf,EAIagB,IAAA;AAAA,oBAJA,MAAM/B,EAAA;AAAA,oBAAgB,MAAK;AAAA,kBAAA;+BACtC,MAEa;AAAA,4BAFbkB,EAEac,IAAA;AAAA,wBAFA,SAASf,EAAA/D,CAAA,EAAK;AAAA,wBAAc,SAAS+D,EAAA/D,CAAA,EAAK;AAAA,sBAAA;wBACpBuD,EAAA,SAAjCwB,EAAA,GAAAf,EAA4DgB,GAA5CJ,CAAS,GAAA,EAAiB,KAAKb,EAAAvD,CAAA,EAAA,CAAS;;;;;;;;;;;;QAM9CuD,EAAA7D,CAAA,EAAK,UAAU,gBAAnC8D,EAA6FiB,IAAA;AAAA;UAAhD,UAAUlB,EAAA7D,CAAA,EAAK;AAAA,UAAY,KAAK6C,EAAA;AAAA,QAAA;;MAI/Ec,EAWWE,EAAAmB,EAAA,GAAA;AAAA,QAXO,MAAM7D,EAAA;AAAA,gDAAAA,EAAU,QAAA8D;AAAA,QAAE,WAAU;AAAA,QAAQ,OAAO;AAAA,MAAA;mBAC3D,MASmB;AAAA,UATnBtB,EASmBE,EAAAqB,EAAA,GAAA;AAAA,YATA,oBAAkB;AAAA,YAAO,sBAAmB;AAAA,UAAA;uBAC7D,MAOE;AAAA,cAPFvB,EAOEC,GAAA;AAAA,gBANC,SAASC,EAAA3D,CAAA;AAAA,gBACT,OAAO2D,EAAAvD,CAAA;AAAA,gBACR,cAAA;AAAA,gBACA,eAAA;AAAA,gBACC,UAAQ4C;AAAA,gBACR,UAAQE;AAAA,cAAA;;;;;;;MAKfO,EAAwCwB,IAAA;AAAA,QAApB,MAAM9D,EAAA;AAAA,gDAAAA,EAAU,QAAA4D;AAAA,MAAA;;;;"}
|
|
1
|
+
{"version":3,"file":"default2.vue.js","sources":["../../src/layouts/default.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'\nimport { RouterView } from 'vue-router'\nimport { NDrawer, NDrawerContent, NButton } from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport { useBreakpoints, breakpointsTailwind, onKeyStroke } from '@vueuse/core'\nimport { useI18n } from 'vue-i18n'\nimport { useAppStore, type LayoutMode } from '#/stores/app'\nimport { useUserStore } from '#/stores/user'\nimport { useLayoutMenu } from '#/composables/useLayoutMenu'\nimport { useTabsStore } from '#/stores/tabs'\nimport { useSite } from '#/composables/useSite'\nimport { useRealtime } from '#/composables/useRealtime'\nimport { useVisualViewportHeight } from '#/composables/useVisualViewportHeight'\nimport { provideShellBreakpoint } from '#/composables/useShellBreakpoint'\nimport ErrorBoundary from '#/components/ErrorBoundary/index.vue'\nimport MenuSearch from '#/components/MenuSearch.vue'\nimport AppWatermark from '#/components/AppWatermark.vue'\nimport AppHeader from './AppHeader.vue'\nimport SideNav from './components/SideNav.vue'\nimport TabsBar from './TabsBar.vue'\n\nconst { t } = useI18n()\nconst app = useAppStore()\nconst user = useUserStore()\nconst tabs = useTabsStore()\nconst { site } = useSite()\nconst { menuOptions, l1Options, l2Options, selectedL1, activeKey, onSelect, onSelectL1 } =\n useLayoutMenu()\n\n// 实时通知(SignalR):鉴权外壳挂载即连、卸载即断。后端未开启实时时连接静默失败,退回轮询/惰性 401(纯增强)。\nconst { start: startRealtime, stop: stopRealtime } = useRealtime()\nonMounted(startRealtime)\nonUnmounted(stopRealtime)\n\n// 维护 --vvh(真实可视高度):软键盘弹起时 dvh 不变,只有 visualViewport 会缩。\n// 布局壳自身用 100dvh 就够,变量留给需要贴着键盘排版的页面(见 composables/useVisualViewportHeight)。\nuseVisualViewportHeight()\n\nconst isMobile = useBreakpoints(breakpointsTailwind).smaller('md')\nconst mobileOpen = ref(false)\n// 菜单搜索面板(Ctrl+K 同一个):侧栏里的只读输入框、顶栏的搜索按钮都开它,面板本身在 MenuSearch 里。\nconst searchOpen = ref(false)\n\n// 壳层三档(wide / mid / narrow):按内容区(.page 的 content box)宽度判,盯住的就是下面的 .page。\n// 页面里用 useShellBreakpoint() 读;样式里用 .page 上的 bp-* 类 / data-bp。阈值与理由见 composables/useShellBreakpoint。\nconst pageRef = ref<HTMLElement>()\nconst { bp } = provideShellBreakpoint(pageRef)\n\n// 窄屏忽略 layoutMode,统一走 mobile(单列 + 抽屉侧栏)。\nconst mode = computed<LayoutMode | 'mobile'>(() => (isMobile.value ? 'mobile' : app.layoutMode))\n\n// 除 horizontal(无侧栏)外都有侧栏。\nconst withSider = new Set<LayoutMode>([\n 'vertical',\n 'vertical-mix',\n 'vertical-hybrid-header-first',\n 'top-hybrid-sidebar-first',\n 'top-hybrid-header-first',\n])\n// 顶栏显示品牌的模式(其余由侧栏/rail 顶部显示品牌,保证每种布局品牌只出现一处)。\nconst headerBrandModes = new Set<string>([\n 'horizontal',\n 'vertical-hybrid-header-first',\n 'top-hybrid-sidebar-first',\n 'top-hybrid-header-first',\n])\nconst showSider = computed(() => !isMobile.value && withSider.has(app.layoutMode))\nconst sideShowBrand = computed(() => mode.value === 'vertical' || mode.value === 'vertical-mix')\n// 侧栏整个隐藏时品牌回到顶栏,否则这种布局下品牌无处可显\nconst headerShowBrand = computed(\n () => isMobile.value || headerBrandModes.has(mode.value) || asideHidden.value,\n)\n// 顶栏菜单:horizontal=完整树;两个 header-first=一级;侧边优先=二级(选中的一级的子菜单)。\nconst headerTopMenu = computed<'full' | 'l1' | 'l2' | null>(() => {\n switch (mode.value) {\n case 'horizontal':\n return 'full'\n case 'vertical-hybrid-header-first':\n case 'top-hybrid-header-first':\n return 'l1'\n case 'top-hybrid-sidebar-first':\n return 'l2'\n default:\n return null\n }\n})\n// 折叠按钮:有可折叠树侧栏的模式(侧边优先的一级 rail 固定宽,不折叠)。\nconst collapsibleSider = new Set<string>([\n 'vertical',\n 'vertical-mix',\n 'vertical-hybrid-header-first',\n 'top-hybrid-header-first',\n])\nconst showCollapse = computed(() => !isMobile.value && collapsibleSider.has(mode.value))\n// 折叠 = 把侧栏整个隐藏(不是收成图标条):内容区铺满,再点一次(或 Ctrl/⌘+B)恢复。\nconst asideHidden = computed(\n () => showSider.value && app.collapsed && collapsibleSider.has(mode.value),\n)\n// 侧栏树列自带搜索入口(品牌下的只读输入框)时,顶栏不再重复放搜索按钮;\n// 一级 rail 与侧栏隐藏时侧栏里没有输入框,搜索入口回到顶栏。\nconst sideHasSearch = computed(\n () => showSider.value && !asideHidden.value && mode.value !== 'top-hybrid-sidebar-first',\n)\n\n// Ctrl/⌘+B 收起 / 展开侧栏(只在有可折叠侧栏的布局生效)。\n// 编辑器里 Ctrl+B 是「加粗」,在输入控件 / 富文本 / 代码编辑器里不抢。\nfunction inEditable(target: EventTarget | null) {\n if (!(target instanceof HTMLElement)) return false\n return (\n ['INPUT', 'TEXTAREA', 'SELECT'].includes(target.tagName) ||\n target.isContentEditable ||\n !!target.closest('.cm-editor, .md-editor, .md-editor-v3')\n )\n}\nonKeyStroke('b', e => {\n if (!(e.ctrlKey || e.metaKey) || e.altKey || e.shiftKey) return\n if (!showCollapse.value || inEditable(e.target)) return\n e.preventDefault()\n app.toggleCollapsed()\n})\n\n// 非特殊侧栏内容:vertical=完整树;两个 header-first hybrid=二级子菜单树。\nconst asideOptions = computed(() =>\n mode.value === 'vertical' ? menuOptions.value : l2Options.value,\n)\nconst asideFullWidth = computed(() => {\n if (mode.value === 'vertical-mix') return 'calc(var(--rail-w) + var(--sidebar-w))'\n if (mode.value === 'top-hybrid-sidebar-first') return 'var(--rail-w)' // 一级 icon rail,固定宽\n return 'var(--sidebar-w)'\n})\n// 收起 = 宽度过渡到 0(侧栏不卸载,才有得过渡)。--aside-w 是满宽,内容按它定宽、被 aside 的 overflow 裁掉,\n// 收窄过程中菜单文字不会跟着重排。\nconst asideStyle = computed(() => ({\n '--aside-w': asideFullWidth.value,\n width: asideHidden.value ? '0px' : 'var(--aside-w)',\n}))\n\nconst transitionName = computed(() =>\n app.pageTransition === 'none' ? undefined : app.pageTransition,\n)\n\nconst watermarkWho = computed(() => ({\n name: user.userInfo?.name,\n account: user.userInfo?.account,\n org: user.userInfo?.orgName,\n phoneTail: user.userInfo?.phoneTail,\n}))\n\nfunction onMobileSelect(key: string) {\n onSelect(key)\n mobileOpen.value = false\n}\nfunction onMobileSearch() {\n mobileOpen.value = false\n searchOpen.value = true\n}\n\n// 刷新标签:store 置 excludeName(逐出缓存)+ 递增 reloadKey;这里 v-if 关开一次令当前页重挂,再放行缓存。\nconst rvShow = ref(true)\nwatch(\n () => tabs.reloadKey,\n async () => {\n rvShow.value = false\n await nextTick()\n rvShow.value = true\n await nextTick()\n tabs.excludeName = ''\n },\n)\n</script>\n\n<template>\n <div class=\"layout\" :class=\"[`mode-${mode}`, { 'aside-hidden': asideHidden }]\">\n <!-- 侧栏:玻璃面板,悬浮在壁纸上 -->\n <!-- 收起时仍挂载(宽度过渡到 0),inert 让它退出 Tab 序列与无障碍树 -->\n <aside\n v-if=\"showSider\"\n class=\"aside glass\"\n :class=\"{ 'aside--mix': mode === 'vertical-mix', 'aside--hidden': asideHidden }\"\n :style=\"asideStyle\"\n :inert=\"asideHidden\"\n >\n <template v-if=\"mode === 'vertical-mix'\">\n <SideNav\n class=\"rail\"\n :options=\"l1Options\"\n :value=\"selectedL1\"\n rail\n show-brand\n @select=\"onSelectL1\"\n />\n <SideNav\n class=\"l2col\"\n :options=\"l2Options\"\n :value=\"activeKey\"\n show-search\n @select=\"onSelect\"\n @search=\"searchOpen = true\"\n />\n </template>\n <!-- 顶部混合-侧边优先:侧栏只放一级 icon rail(二级在顶栏) -->\n <SideNav\n v-else-if=\"mode === 'top-hybrid-sidebar-first'\"\n :options=\"l1Options\"\n :value=\"selectedL1\"\n rail\n @select=\"onSelectL1\"\n />\n <SideNav\n v-else\n :options=\"asideOptions\"\n :value=\"activeKey\"\n :show-brand=\"sideShowBrand\"\n show-search\n @select=\"onSelect\"\n @search=\"searchOpen = true\"\n />\n </aside>\n\n <!-- 顶部玻璃面板:工具栏 + 页签条同一块,页签条在工具栏下方、以一条发丝线分隔 -->\n <div class=\"shell-head glass\" :class=\"{ 'shell-head--static': !app.fixedHeader }\">\n <header class=\"toolbar\">\n <n-button\n v-if=\"isMobile\"\n quaternary\n circle\n class=\"hbg\"\n :aria-label=\"t('app.openMenu')\"\n @click=\"mobileOpen = true\"\n >\n <Icon icon=\"ph:sidebar-simple\" :width=\"19\" />\n </n-button>\n <div class=\"apph\">\n <AppHeader\n :show-collapse=\"showCollapse\"\n :show-brand=\"headerShowBrand\"\n :top-menu=\"headerTopMenu\"\n :show-search=\"!sideHasSearch\"\n @search=\"searchOpen = true\"\n />\n </div>\n </header>\n <TabsBar v-if=\"app.showTabs\" />\n </div>\n\n <!-- 内容:壁纸(柔光渐变)上直接摆页面,内容层不挂玻璃 -->\n <main class=\"content\">\n <div ref=\"pageRef\" class=\"page\" :class=\"`bp-${bp}`\" :data-bp=\"bp\">\n <!-- 错误边界包住整个内容区:页面组件抛异常时 Vue 会卸掉整棵子树,没有它就是白屏。\n component :key=路由 path 给稳定身份:out-in 过渡才能正确区分进/出场,否则显示上一页缓存\n (按 path 各自成键,不塌缩缓存)。每个页面经 namedPage 套了一层 <div.page-view> 单元素根,\n out-in 能瞬时过渡任何页。 -->\n <ErrorBoundary>\n <router-view v-slot=\"{ Component }\">\n <transition :name=\"transitionName\" mode=\"out-in\">\n <keep-alive :include=\"tabs.cachedNames\" :exclude=\"tabs.excludeName\">\n <component :is=\"Component\" v-if=\"rvShow\" :key=\"activeKey\" />\n </keep-alive>\n </transition>\n </router-view>\n </ErrorBoundary>\n </div>\n <AppWatermark v-if=\"site.watermark.enabled\" :settings=\"site.watermark\" :who=\"watermarkWho\" />\n </main>\n\n <!-- 移动端抽屉侧栏 -->\n <n-drawer v-model:show=\"mobileOpen\" placement=\"left\" :width=\"236\">\n <n-drawer-content :native-scrollbar=\"false\" body-content-style=\"padding:0\">\n <SideNav\n :options=\"menuOptions\"\n :value=\"activeKey\"\n show-brand\n show-search\n @select=\"onMobileSelect\"\n @search=\"onMobileSearch\"\n />\n </n-drawer-content>\n </n-drawer>\n\n <MenuSearch v-model:show=\"searchOpen\" />\n </div>\n</template>\n\n<style scoped>\n/* 壳层:两块玻璃面板(侧栏 / 顶部)+ 一块内容区,离屏幕边缘 8px、面板之间 8px。\n 背景是一整张氛围壁纸(--wallpaper:由强调色推导的柔光 + 底色,不画网格),玻璃叠在光上才有层次;\n 内容层的卡片不用玻璃(只有侧栏、顶栏、弹层是玻璃)。\n z-index 全部压在 1999 以下:smart-naive-table 的放大层是 1999(刻意低于 naive 浮层的 2000),\n 壳层不能盖住它。 */\n.layout {\n --sidebar-w: 232px;\n --rail-w: 64px;\n --aside-duration: 0.28s; /* 侧栏收起 / 展开,macOS 侧栏滑动的量级 */\n display: grid;\n /* dvh 而非 vh:移动端浏览器地址栏收起时 vh 仍按最小视口算,底部会被裁掉一条 */\n height: 100dvh;\n padding: 8px;\n gap: 8px;\n overflow: hidden;\n background: var(--wallpaper, var(--bg-app));\n}\n/* 竖向壳:侧栏满高在左,顶栏缩进到内容列上方 */\n.mode-vertical,\n.mode-vertical-mix,\n.mode-vertical-hybrid-header-first {\n grid-template-columns: auto minmax(0, 1fr);\n grid-template-rows: auto minmax(0, 1fr);\n grid-template-areas: 'aside header' 'aside content';\n}\n/* 顶栏壳:顶栏通栏,侧栏在其下方左侧 */\n.mode-top-hybrid-sidebar-first,\n.mode-top-hybrid-header-first {\n grid-template-columns: auto minmax(0, 1fr);\n grid-template-rows: auto minmax(0, 1fr);\n grid-template-areas: 'header header' 'aside content';\n}\n.mode-horizontal,\n.mode-mobile {\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: auto minmax(0, 1fr);\n grid-template-areas: 'header' 'content';\n}\n\n/* 侧栏隐藏:列还在,侧栏宽度过渡到 0;列间距也要归零,否则空列旁边还留一道 8px。\n 两者用同一时长与曲线,内容区才是被侧栏「推」着变宽,而不是先后跳两下。 */\n.layout {\n transition: column-gap var(--aside-duration) var(--ease-sheet);\n}\n.layout.aside-hidden {\n column-gap: 0;\n}\n\n/* 玻璃面板:半透明底 + 强模糊 + 发丝描边 + 顶边高光 + 深投影 */\n.glass {\n background: var(--glass-panel);\n backdrop-filter: blur(40px) saturate(180%);\n -webkit-backdrop-filter: blur(40px) saturate(180%);\n border: 1px solid var(--glass-border);\n box-shadow: var(--glass-shadow);\n}\n@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {\n .glass {\n background: var(--glass-solid, var(--glass-panel));\n }\n}\n\n.aside {\n grid-area: aside;\n position: relative;\n z-index: 2;\n height: 100%;\n min-height: 0;\n overflow: hidden;\n border-radius: var(--radius-lg);\n transition:\n width var(--aside-duration) var(--ease-sheet),\n border-width var(--aside-duration) var(--ease-sheet),\n opacity 0.2s ease;\n}\n/* 收起:border-box 下宽 0 仍会留两侧 1px 描边,一并归零;透明度同时带走投影 */\n.aside--hidden {\n border-width: 0;\n opacity: 0;\n}\n/* 内容按满宽定宽,被 .aside 的 overflow:hidden 裁掉,收窄时不重排(mix 模式由下面两条各自定宽) */\n.aside:not(.aside--mix) > * {\n width: var(--aside-w);\n}\n.aside--mix {\n display: flex;\n}\n.aside--mix .rail {\n width: var(--rail-w);\n flex-shrink: 0;\n border-right: 1px solid var(--hairline);\n}\n.aside--mix .l2col {\n flex: none;\n width: var(--sidebar-w);\n}\n\n.shell-head {\n grid-area: header;\n position: relative;\n z-index: 5;\n min-width: 0;\n overflow: hidden;\n border-radius: 14px;\n}\n/* 「固定头部」关闭:顶栏不再模糊背后的内容 */\n.shell-head--static {\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n}\n.toolbar {\n display: flex;\n align-items: stretch;\n height: 44px;\n}\n.hbg {\n align-self: center;\n margin-left: 8px;\n}\n.apph {\n flex: 1;\n min-width: 0;\n height: 100%;\n}\n\n.content {\n grid-area: content;\n display: flex;\n flex-direction: column;\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n}\n/* 页面滚动层。左右只留 2px(让卡片的描边 / 投影不被 overflow 裁掉)。\n 顶部不留白:顶栏到首张卡片永远是面板之间的 8px(--gap-card),满屏页和自然滚动页一样 —— 两类页面顶部间距不同的话,\n 从列表页切到工作台首张卡片会下跳一截。自然滚动页底部留 8px 给卡片投影,满屏页(下条)只留 2px。\n 内边距不进壳层档位的数字:档位量的是这块的 content box,见 composables/useShellBreakpoint。 */\n.page {\n flex: 1;\n min-height: 0;\n overflow: auto;\n padding: 0 2px 8px;\n}\n/* 满屏页(列表 / 左右分栏)吃满一屏,四周只留 2px,滚动发生在表体里 */\n.page:not(.bp-narrow):has(> .page-view > :is(.smart-table, .fill-page, .side-page)) {\n padding: 0 2px 2px;\n}\n/* narrow:整页自然滚动,不再锁一屏高度。满屏列表页的 .page-view 在 layout.css 里被补成 height:100%,\n 这里放回自动高度,内容多长页面就多长、由 .page 滚动。\n 例外在 layout.css ①′:页里还有表格形态的 fill-height 表(没有自然高度)时,那一页在窄档仍保持定高。 */\n.page.bp-narrow :deep(.page-view) {\n height: auto;\n}\n</style>\n"],"names":["t","useI18n","app","useAppStore","user","useUserStore","tabs","useTabsStore","site","useSite","menuOptions","l1Options","l2Options","selectedL1","activeKey","onSelect","onSelectL1","useLayoutMenu","startRealtime","stopRealtime","useRealtime","onMounted","onUnmounted","useVisualViewportHeight","isMobile","useBreakpoints","breakpointsTailwind","mobileOpen","ref","searchOpen","pageRef","bp","provideShellBreakpoint","mode","computed","withSider","headerBrandModes","showSider","sideShowBrand","headerShowBrand","asideHidden","headerTopMenu","collapsibleSider","showCollapse","sideHasSearch","inEditable","target","onKeyStroke","e","asideOptions","asideFullWidth","asideStyle","transitionName","watermarkWho","_a","_b","_c","_d","onMobileSelect","key","onMobileSearch","rvShow","watch","nextTick","_createElementBlock","_normalizeClass","_Fragment","_createVNode","SideNav","_unref","_createBlock","_createElementVNode","_hoisted_2","NButton","Icon","_hoisted_3","AppHeader","TabsBar","_hoisted_4","ErrorBoundary","RouterView","_withCtx","Component","_Transition","_KeepAlive","_openBlock","_resolveDynamicComponent","AppWatermark","NDrawer","$event","NDrawerContent","MenuSearch"],"mappings":"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"}
|