smart-admin-web 10.15.0 → 10.20.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/README.md +1 -1
- package/dist/api/index.d.ts +4 -2
- package/dist/api/index.js +1 -1
- package/dist/api/index.js.map +1 -1
- package/dist/api/schema.d.ts +39 -5
- package/dist/assets/icons/ph-subset.json.js +5 -5
- package/dist/components/AppIcon.vue.js +9 -9
- package/dist/components/AppIcon.vue.js.map +1 -1
- package/dist/components/AppWatermark.vue.d.ts +14 -0
- package/dist/components/AppWatermark.vue.js +38 -0
- package/dist/components/AppWatermark.vue.js.map +1 -0
- package/dist/components/AppWatermark2.vue.js +5 -0
- package/dist/components/AppWatermark2.vue.js.map +1 -0
- package/dist/components/Chart/PieChart.vue.d.ts +1 -1
- package/dist/components/Chart/echarts.js +15 -20
- package/dist/components/Chart/echarts.js.map +1 -1
- package/dist/components/CronEditor/index.vue.js +1 -1
- package/dist/components/CronEditor/index2.vue.js +2 -1
- package/dist/components/CronEditor/index2.vue.js.map +1 -1
- package/dist/components/DetailPage/index.vue.js +2 -2
- package/dist/components/DetailPage/index2.vue.js.map +1 -1
- package/dist/components/DictTag/index.vue.js.map +1 -1
- package/dist/components/ErrorBoundary/index.vue.js +2 -2
- package/dist/components/ErrorBoundary/index2.vue.js +1 -1
- package/dist/components/ErrorBoundary/index2.vue.js.map +1 -1
- package/dist/components/FormContainer/index.vue.js +91 -56
- package/dist/components/FormContainer/index.vue.js.map +1 -1
- package/dist/components/ImportWizard/index.vue.js +1 -1
- package/dist/components/ImportWizard/index2.vue.js +44 -41
- package/dist/components/ImportWizard/index2.vue.js.map +1 -1
- package/dist/components/MenuSearch.vue.js +2 -2
- package/dist/components/MenuSearch2.vue.js +19 -18
- package/dist/components/MenuSearch2.vue.js.map +1 -1
- package/dist/components/PasswordStrength/index.vue.js +2 -2
- package/dist/components/PasswordStrength/index2.vue.js +20 -18
- package/dist/components/PasswordStrength/index2.vue.js.map +1 -1
- package/dist/components/TableTotal/index.vue.d.ts +6 -0
- package/dist/components/{SelectTable → TableTotal}/index.vue.js +1 -1
- package/dist/components/TableTotal/index2.vue.js +16 -0
- package/dist/components/TableTotal/index2.vue.js.map +1 -0
- package/dist/components/TableZoomButton/index.vue.js.map +1 -1
- package/dist/components/UserPicker/index.vue.js +2 -2
- package/dist/components/UserPicker/index2.vue.js +176 -117
- package/dist/components/UserPicker/index2.vue.js.map +1 -1
- package/dist/composables/useBatchDelete.js.map +1 -1
- package/dist/composables/useLayoutMenu.js +17 -16
- package/dist/composables/useLayoutMenu.js.map +1 -1
- package/dist/composables/useModule.js +39 -29
- package/dist/composables/useModule.js.map +1 -1
- package/dist/composables/useShellBreakpoint.d.ts +19 -0
- package/dist/composables/useShellBreakpoint.js +37 -0
- package/dist/composables/useShellBreakpoint.js.map +1 -0
- package/dist/composables/useSite.d.ts +15 -0
- package/dist/composables/useSite.js +16 -14
- package/dist/composables/useSite.js.map +1 -1
- package/dist/composables/useTabTitle.js.map +1 -1
- package/dist/composables/useTableTitle.d.ts +6 -0
- package/dist/composables/useTableTitle.js +11 -0
- package/dist/composables/useTableTitle.js.map +1 -0
- package/dist/composables/useTableZoom.d.ts +5 -0
- package/dist/composables/useTableZoom.js.map +1 -1
- package/dist/composables/useTheme.d.ts +2 -2
- package/dist/composables/useTheme.js +23 -20
- package/dist/composables/useTheme.js.map +1 -1
- package/dist/createSmartAdmin.d.ts +12 -2
- package/dist/createSmartAdmin.js +72 -60
- package/dist/createSmartAdmin.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +219 -205
- package/dist/index.js.map +1 -1
- package/dist/layouts/AccentPicker.vue.js +8 -0
- package/dist/layouts/AccentPicker.vue.js.map +1 -0
- package/dist/layouts/AccentPicker2.vue.js +131 -0
- package/dist/layouts/AccentPicker2.vue.js.map +1 -0
- package/dist/layouts/AppHeader.vue.d.ts +8 -1
- package/dist/layouts/AppHeader.vue.js +2 -2
- package/dist/layouts/AppHeader2.vue.js +317 -235
- package/dist/layouts/AppHeader2.vue.js.map +1 -1
- package/dist/layouts/NoticeBell.vue.js +2 -2
- package/dist/layouts/NoticeBell2.vue.js +1 -1
- package/dist/layouts/NoticeBell2.vue.js.map +1 -1
- package/dist/layouts/PersonalLayout.vue.js +2 -2
- package/dist/layouts/PersonalLayout2.vue.js +69 -47
- package/dist/layouts/PersonalLayout2.vue.js.map +1 -1
- package/dist/layouts/SettingsDrawer.vue.js +3 -3
- package/dist/layouts/SettingsDrawer2.vue.js +261 -325
- package/dist/layouts/SettingsDrawer2.vue.js.map +1 -1
- package/dist/layouts/TabsBar.vue.js +2 -2
- package/dist/layouts/TabsBar2.vue.js +97 -69
- package/dist/layouts/TabsBar2.vue.js.map +1 -1
- package/dist/layouts/components/SideNav.vue.d.ts +3 -0
- package/dist/layouts/components/SideNav.vue.js +1 -1
- package/dist/layouts/components/SideNav2.vue.js +54 -26
- package/dist/layouts/components/SideNav2.vue.js.map +1 -1
- package/dist/layouts/default.vue.js +1 -1
- package/dist/layouts/default2.vue.js +170 -140
- package/dist/layouts/default2.vue.js.map +1 -1
- package/dist/lib/loginHero.d.ts +2 -2
- package/dist/lib/loginHero.js.map +1 -1
- package/dist/lib/runtime.js +1 -1
- package/dist/lib/watermark.d.ts +110 -0
- package/dist/lib/watermark.js +151 -0
- package/dist/lib/watermark.js.map +1 -0
- package/dist/locales/en-US.d.ts +221 -15
- package/dist/locales/en-US.js +230 -21
- package/dist/locales/en-US.js.map +1 -1
- package/dist/locales/kernelMenuTitles.d.ts +1 -0
- package/dist/locales/kernelMenuTitles.js +128 -0
- package/dist/locales/kernelMenuTitles.js.map +1 -0
- package/dist/locales/menuTitle.d.ts +3 -0
- package/dist/locales/menuTitle.js +14 -12
- package/dist/locales/menuTitle.js.map +1 -1
- package/dist/locales/zh-CN.d.ts +221 -15
- package/dist/locales/zh-CN.js +238 -28
- package/dist/locales/zh-CN.js.map +1 -1
- package/dist/router/index.js +41 -32
- package/dist/router/index.js.map +1 -1
- package/dist/router/namedPage.d.ts +4 -0
- package/dist/router/namedPage.js +7 -7
- package/dist/router/namedPage.js.map +1 -1
- package/dist/router/viewRegistry.js +8 -8
- package/dist/router/viewRegistry.js.map +1 -1
- package/dist/stores/app.d.ts +0 -12
- package/dist/stores/app.js +11 -12
- package/dist/stores/app.js.map +1 -1
- package/dist/stores/tabs.js.map +1 -1
- package/dist/stores/user.d.ts +10 -0
- package/dist/stores/user.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/theme/accentTokens.d.ts +27 -0
- package/dist/theme/accentTokens.js +54 -0
- package/dist/theme/accentTokens.js.map +1 -0
- package/dist/theme/accents.d.ts +21 -1
- package/dist/theme/accents.js +11 -2
- package/dist/theme/accents.js.map +1 -1
- package/dist/theme/mix.d.ts +58 -7
- package/dist/theme/mix.js +115 -30
- package/dist/theme/mix.js.map +1 -1
- package/dist/theme/naive-theme.d.ts +5 -2
- package/dist/theme/naive-theme.js +405 -75
- package/dist/theme/naive-theme.js.map +1 -1
- package/dist/utils/jwt.d.ts +8 -0
- package/dist/utils/jwt.js +14 -0
- package/dist/utils/jwt.js.map +1 -0
- package/dist/utils/menuIcon.d.ts +2 -0
- package/dist/utils/menuIcon.js +8 -0
- package/dist/utils/menuIcon.js.map +1 -0
- package/dist/utils/oauthBrand.js.map +1 -1
- package/dist/utils/tableFilter.d.ts +88 -0
- package/dist/utils/tableFilter.js +116 -0
- package/dist/utils/tableFilter.js.map +1 -0
- package/dist/utils/tableToolbar.d.ts +18 -0
- package/dist/utils/tableToolbar.js +11 -0
- package/dist/utils/tableToolbar.js.map +1 -0
- package/dist/utils/treeFilter.d.ts +20 -0
- package/dist/utils/treeFilter.js +24 -0
- package/dist/utils/treeFilter.js.map +1 -0
- package/dist/views/dashboard/ShortcutPicker.vue.js +1 -1
- package/dist/views/dashboard/ShortcutPicker2.vue.js +73 -48
- package/dist/views/dashboard/ShortcutPicker2.vue.js.map +1 -1
- package/dist/views/dashboard/biz.vue.js +1 -1
- package/dist/views/dashboard/biz2.vue.js +310 -257
- package/dist/views/dashboard/biz2.vue.js.map +1 -1
- package/dist/views/dashboard/workbench.vue.js +2 -2
- package/dist/views/dashboard/workbench2.vue.js +141 -155
- package/dist/views/dashboard/workbench2.vue.js.map +1 -1
- package/dist/views/embed/iframe.vue.js +2 -2
- package/dist/views/embed/iframe2.vue.js +22 -15
- package/dist/views/embed/iframe2.vue.js.map +1 -1
- package/dist/views/error/404.vue.js +2 -2
- package/dist/views/error/4042.vue.js +33 -24
- package/dist/views/error/4042.vue.js.map +1 -1
- package/dist/views/error/BootError.vue.js +1 -1
- package/dist/views/error/BootError2.vue.js +59 -48
- package/dist/views/error/BootError2.vue.js.map +1 -1
- package/dist/views/error/MissingRoute.vue.js +2 -2
- package/dist/views/error/MissingRoute2.vue.js +34 -15
- package/dist/views/error/MissingRoute2.vue.js.map +1 -1
- package/dist/views/login/LoginForm.vue.d.ts +7 -1
- package/dist/views/login/LoginForm.vue.js +2 -2
- package/dist/views/login/LoginForm2.vue.js +580 -488
- package/dist/views/login/LoginForm2.vue.js.map +1 -1
- package/dist/views/login/components/LoginDesk.vue.d.ts +36 -0
- package/dist/views/login/components/LoginDesk.vue.js +9 -0
- package/dist/views/login/components/LoginDesk.vue.js.map +1 -0
- package/dist/views/login/components/LoginDesk2.vue.js +100 -0
- package/dist/views/login/components/LoginDesk2.vue.js.map +1 -0
- package/dist/views/login/components/LoginHeroPanel.vue.js +3 -3
- package/dist/views/login/components/LoginHeroPanel2.vue.js +34 -39
- package/dist/views/login/components/LoginHeroPanel2.vue.js.map +1 -1
- package/dist/views/login/index.vue.js +1 -1
- package/dist/views/login/index2.vue.js +141 -71
- package/dist/views/login/index2.vue.js.map +1 -1
- package/dist/views/login/layout.d.ts +11 -0
- package/dist/views/login/layout.js +27 -0
- package/dist/views/login/layout.js.map +1 -0
- package/dist/views/mfa/index.vue.js +2 -2
- package/dist/views/mfa/index2.vue.js +367 -321
- package/dist/views/mfa/index2.vue.js.map +1 -1
- package/dist/views/module/index.vue.js +2 -2
- package/dist/views/module/index2.vue.js +132 -99
- package/dist/views/module/index2.vue.js.map +1 -1
- package/dist/views/oauth/callback.vue.js +2 -2
- package/dist/views/oauth/callback2.vue.js +65 -51
- package/dist/views/oauth/callback2.vue.js.map +1 -1
- package/dist/views/personal/bindings.vue.js +2 -2
- package/dist/views/personal/bindings2.vue.js +98 -94
- package/dist/views/personal/bindings2.vue.js.map +1 -1
- package/dist/views/personal/notice2.vue.js +103 -76
- package/dist/views/personal/notice2.vue.js.map +1 -1
- package/dist/views/personal/password2.vue.js +47 -40
- package/dist/views/personal/password2.vue.js.map +1 -1
- package/dist/views/personal/profile.vue.js +3 -3
- package/dist/views/personal/profile2.vue.js +24 -18
- package/dist/views/personal/profile2.vue.js.map +1 -1
- package/dist/views/personal/security.vue.js +2 -2
- package/dist/views/personal/security2.vue.js +65 -53
- package/dist/views/personal/security2.vue.js.map +1 -1
- package/dist/views/personal/sessions.vue.js +2 -2
- package/dist/views/personal/sessions2.vue.js +67 -62
- package/dist/views/personal/sessions2.vue.js.map +1 -1
- package/dist/views/system/ai-model/components/ProviderCard.vue.js +2 -2
- package/dist/views/system/ai-model/components/ProviderCard2.vue.js +142 -130
- package/dist/views/system/ai-model/components/ProviderCard2.vue.js.map +1 -1
- package/dist/views/system/ai-model/components/ProviderForm.vue.js +2 -2
- package/dist/views/system/ai-model/components/ProviderForm2.vue.js +71 -70
- package/dist/views/system/ai-model/components/ProviderForm2.vue.js.map +1 -1
- package/dist/views/system/ai-model/index.vue.js +2 -2
- package/dist/views/system/ai-model/index2.vue.js +99 -99
- package/dist/views/system/ai-model/index2.vue.js.map +1 -1
- package/dist/views/system/ai-model/presets.d.ts +1 -1
- package/dist/views/system/ai-model/presets.js +18 -18
- package/dist/views/system/ai-model/presets.js.map +1 -1
- package/dist/views/system/ai-usage/index.vue.js +2 -2
- package/dist/views/system/ai-usage/index2.vue.js +356 -258
- package/dist/views/system/ai-usage/index2.vue.js.map +1 -1
- package/dist/views/system/api-docs/index.vue.js +5 -2
- package/dist/views/system/api-docs/index.vue.js.map +1 -1
- package/dist/views/system/api-docs/index2.vue.js +92 -42
- package/dist/views/system/api-docs/index2.vue.js.map +1 -1
- package/dist/views/system/cache/index.vue.js +2 -2
- package/dist/views/system/cache/index2.vue.js +74 -80
- package/dist/views/system/cache/index2.vue.js.map +1 -1
- package/dist/views/system/config/components/AdminMock.vue.js +2 -2
- package/dist/views/system/config/components/AdminMock2.vue.js +60 -43
- package/dist/views/system/config/components/AdminMock2.vue.js.map +1 -1
- package/dist/views/system/config/components/AdvancedSection.vue.js +5 -2
- package/dist/views/system/config/components/AdvancedSection.vue.js.map +1 -1
- package/dist/views/system/config/components/AdvancedSection2.vue.js +98 -70
- package/dist/views/system/config/components/AdvancedSection2.vue.js.map +1 -1
- package/dist/views/system/config/components/BrandSection.vue.js +2 -2
- package/dist/views/system/config/components/BrandSection2.vue.js +121 -119
- package/dist/views/system/config/components/BrandSection2.vue.js.map +1 -1
- package/dist/views/system/config/components/CfgGroup.vue.js +3 -3
- package/dist/views/system/config/components/CfgGroup2.vue.js.map +1 -1
- package/dist/views/system/config/components/CfgRow.vue.js +1 -1
- package/dist/views/system/config/components/CfgRow2.vue.js +24 -23
- package/dist/views/system/config/components/CfgRow2.vue.js.map +1 -1
- package/dist/views/system/config/components/CfgSegment.vue.js +1 -1
- package/dist/views/system/config/components/CfgSegment2.vue.js +16 -15
- package/dist/views/system/config/components/CfgSegment2.vue.js.map +1 -1
- package/dist/views/system/config/components/ConfigFormModal.vue.js +2 -2
- package/dist/views/system/config/components/ConfigFormModal2.vue.js +35 -33
- package/dist/views/system/config/components/ConfigFormModal2.vue.js.map +1 -1
- package/dist/views/system/config/components/JobSection.vue.js +2 -2
- package/dist/views/system/config/components/JobSection2.vue.js +46 -44
- package/dist/views/system/config/components/JobSection2.vue.js.map +1 -1
- package/dist/views/system/config/components/LoginMock.vue.js +3 -3
- package/dist/views/system/config/components/LoginMock2.vue.js +83 -72
- package/dist/views/system/config/components/LoginMock2.vue.js.map +1 -1
- package/dist/views/system/config/components/LogoCropper.vue.js +1 -1
- package/dist/views/system/config/components/LogoCropper2.vue.js.map +1 -1
- package/dist/views/system/config/components/LogoEditor.vue.js +2 -2
- package/dist/views/system/config/components/LogoEditor2.vue.js +11 -13
- package/dist/views/system/config/components/LogoEditor2.vue.js.map +1 -1
- package/dist/views/system/config/components/ProviderSheet.vue.js +3 -3
- package/dist/views/system/config/components/ProviderSheet2.vue.js.map +1 -1
- package/dist/views/system/config/components/SectionLayout.vue.d.ts +4 -2
- package/dist/views/system/config/components/SectionLayout.vue.js +2 -2
- package/dist/views/system/config/components/SectionLayout2.vue.js +51 -27
- package/dist/views/system/config/components/SectionLayout2.vue.js.map +1 -1
- package/dist/views/system/config/components/SecuritySection.vue.js +2 -2
- package/dist/views/system/config/components/SecuritySection2.vue.js +207 -206
- package/dist/views/system/config/components/SecuritySection2.vue.js.map +1 -1
- package/dist/views/system/config/components/SensitiveSection.vue.js +2 -2
- package/dist/views/system/config/components/SensitiveSection2.vue.js +107 -102
- package/dist/views/system/config/components/SensitiveSection2.vue.js.map +1 -1
- package/dist/views/system/config/components/UploadSection.vue.js +2 -2
- package/dist/views/system/config/components/UploadSection2.vue.js +86 -77
- package/dist/views/system/config/components/UploadSection2.vue.js.map +1 -1
- package/dist/views/system/config/components/WatermarkSection.vue.js +8 -0
- package/dist/views/system/config/components/WatermarkSection.vue.js.map +1 -0
- package/dist/views/system/config/components/WatermarkSection2.vue.js +284 -0
- package/dist/views/system/config/components/WatermarkSection2.vue.js.map +1 -0
- package/dist/views/system/config/draft.d.ts +2 -2
- package/dist/views/system/config/draft.js.map +1 -1
- package/dist/views/system/config/groups.d.ts +4 -1
- package/dist/views/system/config/groups.js +54 -49
- package/dist/views/system/config/groups.js.map +1 -1
- package/dist/views/system/config/index.vue.js +3 -2
- package/dist/views/system/config/index.vue.js.map +1 -1
- package/dist/views/system/config/index2.vue.js +173 -148
- package/dist/views/system/config/index2.vue.js.map +1 -1
- package/dist/views/system/config/layoutMode.d.ts +23 -0
- package/dist/views/system/config/layoutMode.js +28 -0
- package/dist/views/system/config/layoutMode.js.map +1 -0
- package/dist/views/system/dict/index.vue.js +2 -2
- package/dist/views/system/dict/index2.vue.js +471 -366
- package/dist/views/system/dict/index2.vue.js.map +1 -1
- package/dist/views/system/file/index2.vue.js +91 -76
- package/dist/views/system/file/index2.vue.js.map +1 -1
- package/dist/views/system/job/index.vue.js +3 -3
- package/dist/views/system/job/index2.vue.js +897 -828
- package/dist/views/system/job/index2.vue.js.map +1 -1
- package/dist/views/system/job-log/components/AttemptTable.vue.d.ts +8 -0
- package/dist/views/system/job-log/components/AttemptTable.vue.js +5 -0
- package/dist/views/system/job-log/components/AttemptTable.vue.js.map +1 -0
- package/dist/views/system/job-log/components/AttemptTable2.vue.js +54 -0
- package/dist/views/system/job-log/components/AttemptTable2.vue.js.map +1 -0
- package/dist/views/system/job-log/index.vue.js +2 -2
- package/dist/views/system/job-log/index2.vue.js +193 -207
- package/dist/views/system/job-log/index2.vue.js.map +1 -1
- package/dist/views/system/job-log/runStatus.d.ts +13 -0
- package/dist/views/system/job-log/runStatus.js +26 -0
- package/dist/views/system/job-log/runStatus.js.map +1 -0
- package/dist/views/system/job-monitor/index.vue.js +2 -2
- package/dist/views/system/job-monitor/index2.vue.js +172 -180
- package/dist/views/system/job-monitor/index2.vue.js.map +1 -1
- package/dist/views/system/log/exception/index.vue.js +2 -2
- package/dist/views/system/log/exception/index2.vue.js +135 -96
- package/dist/views/system/log/exception/index2.vue.js.map +1 -1
- package/dist/views/system/log/login/index2.vue.js +62 -41
- package/dist/views/system/log/login/index2.vue.js.map +1 -1
- package/dist/views/system/log/op/index.vue.js +2 -2
- package/dist/views/system/log/op/index2.vue.js +200 -162
- package/dist/views/system/log/op/index2.vue.js.map +1 -1
- package/dist/views/system/menu/components/ButtonManager.vue.js +2 -2
- package/dist/views/system/menu/components/ButtonManager2.vue.js +206 -190
- package/dist/views/system/menu/components/ButtonManager2.vue.js.map +1 -1
- package/dist/views/system/menu/components/MenuFormModal.vue.js +2 -2
- package/dist/views/system/menu/components/MenuFormModal2.vue.js +127 -118
- package/dist/views/system/menu/components/MenuFormModal2.vue.js.map +1 -1
- package/dist/views/system/menu/index.vue.js +1 -1
- package/dist/views/system/menu/index2.vue.js +216 -183
- package/dist/views/system/menu/index2.vue.js.map +1 -1
- package/dist/views/system/module/index.vue.js +1 -1
- package/dist/views/system/module/index2.vue.js +177 -144
- package/dist/views/system/module/index2.vue.js.map +1 -1
- package/dist/views/system/monitor/index.vue.js +2 -2
- package/dist/views/system/monitor/index2.vue.js +134 -149
- package/dist/views/system/monitor/index2.vue.js.map +1 -1
- package/dist/views/system/notice/index.vue.js +1 -1
- package/dist/views/system/notice/index2.vue.js +209 -181
- package/dist/views/system/notice/index2.vue.js.map +1 -1
- package/dist/views/system/org/index.vue.js +1 -1
- package/dist/views/system/org/index2.vue.js +278 -248
- package/dist/views/system/org/index2.vue.js.map +1 -1
- package/dist/views/system/position/index.vue.js +5 -2
- package/dist/views/system/position/index.vue.js.map +1 -1
- package/dist/views/system/position/index2.vue.js +128 -92
- package/dist/views/system/position/index2.vue.js.map +1 -1
- package/dist/views/system/recycle/index.vue.js +2 -2
- package/dist/views/system/recycle/index2.vue.js +90 -67
- package/dist/views/system/recycle/index2.vue.js.map +1 -1
- package/dist/views/system/role/components/GrantMenuSheet.vue.d.ts +20 -0
- package/dist/views/system/role/components/GrantMenuSheet.vue.js +8 -0
- package/dist/views/system/role/components/GrantMenuSheet.vue.js.map +1 -0
- package/dist/views/system/role/components/GrantMenuSheet2.vue.js +117 -0
- package/dist/views/system/role/components/GrantMenuSheet2.vue.js.map +1 -0
- package/dist/views/system/role/components/GrantMenuTable.vue.d.ts +6 -4
- package/dist/views/system/role/components/GrantMenuTable.vue.js +2 -2
- package/dist/views/system/role/components/GrantMenuTable2.vue.js +279 -177
- package/dist/views/system/role/components/GrantMenuTable2.vue.js.map +1 -1
- package/dist/views/system/role/components/MatchText.vue.d.ts +7 -0
- package/dist/views/system/role/components/MatchText.vue.js +8 -0
- package/dist/views/system/role/components/MatchText.vue.js.map +1 -0
- package/dist/views/system/role/components/MatchText2.vue.js +29 -0
- package/dist/views/system/role/components/MatchText2.vue.js.map +1 -0
- package/dist/views/system/role/components/grantMenuGroups.d.ts +36 -0
- package/dist/views/system/role/components/grantMenuGroups.js +110 -48
- package/dist/views/system/role/components/grantMenuGroups.js.map +1 -1
- package/dist/views/system/role/index.vue.js +5 -2
- package/dist/views/system/role/index.vue.js.map +1 -1
- package/dist/views/system/role/index2.vue.js +181 -165
- package/dist/views/system/role/index2.vue.js.map +1 -1
- package/dist/views/system/session/index2.vue.js +75 -49
- package/dist/views/system/session/index2.vue.js.map +1 -1
- package/dist/views/system/user/components/ResetPasswordModal.vue.js +2 -2
- package/dist/views/system/user/components/ResetPasswordModal2.vue.js +2 -0
- package/dist/views/system/user/components/ResetPasswordModal2.vue.js.map +1 -1
- package/dist/views/system/user/components/UserFormModal.vue.js +2 -2
- package/dist/views/system/user/components/UserFormModal2.vue.js +77 -76
- package/dist/views/system/user/components/UserFormModal2.vue.js.map +1 -1
- package/dist/views/system/user/index.vue.js +2 -2
- package/dist/views/system/user/index2.vue.js +362 -275
- package/dist/views/system/user/index2.vue.js.map +1 -1
- package/package.json +3 -5
- package/dist/components/SelectTable/index.vue.d.ts +0 -76
- package/dist/components/SelectTable/index2.vue.js +0 -256
- package/dist/components/SelectTable/index2.vue.js.map +0 -1
- package/dist/composables/useTableRowSort.d.ts +0 -20
- package/dist/composables/useTableRowSort.js +0 -59
- package/dist/composables/useTableRowSort.js.map +0 -1
- package/dist/layouts/LayoutModeCards.vue.js +0 -8
- package/dist/layouts/LayoutModeCards.vue.js.map +0 -1
- package/dist/layouts/LayoutModeCards2.vue.js +0 -67
- package/dist/layouts/LayoutModeCards2.vue.js.map +0 -1
- package/dist/layouts/SettingRow.vue.d.ts +0 -16
- package/dist/layouts/SettingRow.vue.js +0 -8
- package/dist/layouts/SettingRow.vue.js.map +0 -1
- package/dist/layouts/SettingRow2.vue.js +0 -23
- package/dist/layouts/SettingRow2.vue.js.map +0 -1
- package/dist/views/login/skins/AuroraGlass.vue.js +0 -8
- package/dist/views/login/skins/AuroraGlass.vue.js.map +0 -1
- package/dist/views/login/skins/AuroraGlass2.vue.js +0 -80
- package/dist/views/login/skins/AuroraGlass2.vue.js.map +0 -1
- package/dist/views/login/skins/SplitPanel.vue.d.ts +0 -3
- package/dist/views/login/skins/SplitPanel.vue.js +0 -8
- package/dist/views/login/skins/SplitPanel.vue.js.map +0 -1
- package/dist/views/login/skins/SplitPanel2.vue.js +0 -65
- package/dist/views/login/skins/SplitPanel2.vue.js.map +0 -1
- package/dist/views/login/skins/Spotlight.vue.d.ts +0 -3
- package/dist/views/login/skins/Spotlight.vue.js +0 -8
- package/dist/views/login/skins/Spotlight.vue.js.map +0 -1
- package/dist/views/login/skins/Spotlight2.vue.js +0 -36
- package/dist/views/login/skins/Spotlight2.vue.js.map +0 -1
- package/dist/views/login/skins.d.ts +0 -8
- package/dist/views/login/skins.js +0 -13
- package/dist/views/login/skins.js.map +0 -1
- /package/dist/components/{SelectTable → TableTotal}/index.vue.js.map +0 -0
- /package/dist/layouts/{LayoutModeCards.vue.d.ts → AccentPicker.vue.d.ts} +0 -0
- /package/dist/views/{login/skins/AuroraGlass.vue.d.ts → system/config/components/WatermarkSection.vue.d.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLayoutMenu.js","sources":["../../src/composables/useLayoutMenu.ts"],"sourcesContent":["// auth.menuTree → n-menu 的 MenuOption,外加混合布局下顶栏一级 / 侧栏二级的选中态联动。\n// 用法:default.vue 与 AppHeader 各自 useLayoutMenu(),createSharedComposable 保证它们共享同一份选中态。\n// 坑:off-menu 路由(如 /personal/*)命中不到任何一级,此时保留上一次的一级选中,别把顶栏清空。\nimport { computed, h, ref, watch } from 'vue'\nimport { NBadge, type MenuOption } from 'naive-ui'\nimport { createSharedComposable } from '@vueuse/core'\nimport AppIcon from '#/components/AppIcon.vue'\nimport { menuBadge } from '#/composables/useMenuBadge'\nimport { router } from '#/router'\nimport { useAuthStore } from '#/stores/auth'\nimport { useAppStore } from '#/stores/app'\nimport { translateMenuTitle } from '#/locales/menuTitle'\nimport { isFullscreenPath, isHttpUrl } from '#/utils/url'\nimport { MenuType, type MenuNode } from '#/types/menu'\n\n/**\n * 新标签页打开的两类 key → window.open;返回是否已处理。\n * - 外链菜单:path 为 http(s) URL。\n * - 站内整屏页:path 以 `/fullscreen/` 开头(大屏看板),站内静态路由,但必须脱离布局壳整屏显示。\n */\nfunction openIfExternal(key: string): boolean {\n if (!isHttpUrl(key) && !isFullscreenPath(key)) return false\n window.open(key, '_blank', 'noopener,noreferrer')\n return true\n}\n\n// 无图标兜底:rail/折叠态的 n-menu 只画图标,缺图标会渲染成空槽、整项像“消失”了,故永不返回 undefined。\n// 走 AppIcon 而非裸 Icon:菜单图标是库里配的,子集外的名字要由它懒加载整集兜底,否则渲染不出来。\nfunction renderIcon(name: string | undefined, fallback = 'ph:dot-outline
|
|
1
|
+
{"version":3,"file":"useLayoutMenu.js","sources":["../../src/composables/useLayoutMenu.ts"],"sourcesContent":["// auth.menuTree → n-menu 的 MenuOption,外加混合布局下顶栏一级 / 侧栏二级的选中态联动。\n// 用法:default.vue 与 AppHeader 各自 useLayoutMenu(),createSharedComposable 保证它们共享同一份选中态。\n// 坑:off-menu 路由(如 /personal/*)命中不到任何一级,此时保留上一次的一级选中,别把顶栏清空。\nimport { computed, h, ref, watch } from 'vue'\nimport { NBadge, type MenuOption } from 'naive-ui'\nimport { createSharedComposable } from '@vueuse/core'\nimport AppIcon from '#/components/AppIcon.vue'\nimport { menuBadge } from '#/composables/useMenuBadge'\nimport { router } from '#/router'\nimport { useAuthStore } from '#/stores/auth'\nimport { useAppStore } from '#/stores/app'\nimport { translateMenuTitle } from '#/locales/menuTitle'\nimport { isFullscreenPath, isHttpUrl } from '#/utils/url'\nimport { lineIcon } from '#/utils/menuIcon'\nimport { MenuType, type MenuNode } from '#/types/menu'\n\n/**\n * 新标签页打开的两类 key → window.open;返回是否已处理。\n * - 外链菜单:path 为 http(s) URL。\n * - 站内整屏页:path 以 `/fullscreen/` 开头(大屏看板),站内静态路由,但必须脱离布局壳整屏显示。\n */\nfunction openIfExternal(key: string): boolean {\n if (!isHttpUrl(key) && !isFullscreenPath(key)) return false\n window.open(key, '_blank', 'noopener,noreferrer')\n return true\n}\n\n// 无图标兜底:rail/折叠态的 n-menu 只画图标,缺图标会渲染成空槽、整项像“消失”了,故永不返回 undefined。\n// 走 AppIcon 而非裸 Icon:菜单图标是库里配的,子集外的名字要由它懒加载整集兜底,否则渲染不出来。\n// 全站统一线条款:库里存的 `-duotone` 名字在这里去掉后缀(见 utils/menuIcon),兜底图标本身也是线条款。\nfunction renderIcon(name: string | undefined, fallback = 'ph:dot-outline') {\n return () => h(AppIcon, { icon: lineIcon(name) || fallback, size: 18 })\n}\n\n// 角标(registerMenuBadge 登记的未读数/待办数)→ n-menu 的 extra 槽。\n// 读值在渲染函数里做,故登记的 ref 一变角标就变,不必重算整棵 options。\n// 折叠 / rail 态 n-menu 只画图标、不渲染 extra,角标随之隐藏——这是 n-menu 的行为,不另做补偿。\nfunction renderBadge(path: string | undefined) {\n if (!path) return undefined\n return () => {\n const value = menuBadge(path)\n if (value === null || value === undefined || value === 0 || value === '') return null\n return h(NBadge, { value, max: 99 })\n }\n}\n\n// 菜单树 → n-menu options:剥按钮、丢空目录、页面叶子 key=路由 path。目录/叶子各自兜底图标。\nfunction toOptions(nodes: MenuNode[]): MenuOption[] {\n return nodes\n .toSorted((a, b) => a.sort - b.sort)\n .filter(n => n.type !== MenuType.Button && n.visible !== false)\n .map<MenuOption | null>(n => {\n if (n.type === MenuType.Catalog) {\n const children = toOptions(n.children ?? [])\n if (!children.length) return null\n return {\n label: translateMenuTitle(n.title, n.path),\n key: `cat-${n.id}`,\n icon: renderIcon(n.icon, 'ph:folder'),\n children,\n }\n }\n return {\n label: translateMenuTitle(n.title, n.path),\n key: n.path ?? `menu-${n.id}`,\n icon: renderIcon(n.icon),\n extra: renderBadge(n.path),\n }\n })\n .filter((o): o is MenuOption => o !== null)\n}\n\nfunction containsKey(opt: MenuOption, path: string): boolean {\n if (opt.key === path) return true\n return ((opt.children as MenuOption[]) ?? []).some(c => containsKey(c, path))\n}\nfunction firstLeafKey(opt: MenuOption): string | undefined {\n if (typeof opt.key === 'string' && opt.key.startsWith('/')) return opt.key\n for (const c of (opt.children as MenuOption[]) ?? []) {\n const k = firstLeafKey(c)\n if (k) return k\n }\n return undefined\n}\n\n/**\n * 布局菜单派生 + 一/二级选中态联动(混合布局用)。\n * createSharedComposable → default.vue 与 AppHeader 共享同一份 selectedL1,不各自漂移。\n * 走 router.currentRoute(全局 ref),不依赖组件上下文的 useRoute。\n */\nfunction useLayoutMenuImpl() {\n const auth = useAuthStore()\n const app = useAppStore()\n\n // 工作台是每个应用菜单树里的一条(Sort=0 → 排第一项),跟着应用变,不用手工 prepend。\n const menuOptions = computed<MenuOption[]>(() => {\n void app.locale // 依赖:切换语言时 i18n key 标题重算\n return toOptions(auth.menuTree)\n })\n\n // 一级(剥 children → n-menu 渲染为可选普通项,无展开箭头)。\n const l1Options = computed<MenuOption[]>(() =>\n menuOptions.value.map(o => ({ label: o.label, key: o.key, icon: o.icon, extra: o.extra })),\n )\n\n const activeKey = computed(() => router.currentRoute.value.path)\n const selectedL1 = ref<string>()\n\n function findActiveL1(path: string): string | undefined {\n const top = menuOptions.value.find(o => containsKey(o, path))\n return top ? String(top.key) : undefined\n }\n\n // 路由 → 一级同步:命中才覆写(off-menu 路由如 /personal/* 保留上次);首次 seed 头一项。\n watch(\n () => router.currentRoute.value.path,\n path => {\n const l1 = findActiveL1(path)\n if (l1) selectedL1.value = l1\n else if (selectedL1.value === undefined)\n selectedL1.value = menuOptions.value[0]?.key as string | undefined\n },\n { immediate: true },\n )\n // 菜单可能晚于首个 watch 到达(F5 重建):补 seed / 修正失效选择。\n watch(menuOptions, opts => {\n if (selectedL1.value === undefined || !opts.some(o => o.key === selectedL1.value)) {\n selectedL1.value = findActiveL1(activeKey.value) ?? (opts[0]?.key as string | undefined)\n }\n })\n\n const l2Options = computed<MenuOption[]>(() => {\n const top = menuOptions.value.find(o => o.key === selectedL1.value)\n return (top?.children as MenuOption[]) ?? []\n })\n\n function onSelect(key: string) {\n if (openIfExternal(key)) return\n if (key.startsWith('/')) router.push(key)\n }\n function onSelectL1(key: string) {\n if (openIfExternal(key)) return\n selectedL1.value = key // 先设,L2 列立即刷新,不等导航\n const top = menuOptions.value.find(o => o.key === key)\n const target = key.startsWith('/') ? key : top ? firstLeafKey(top) : undefined\n if (target) router.push(target)\n }\n\n return { menuOptions, l1Options, l2Options, selectedL1, activeKey, onSelect, onSelectL1 }\n}\n\nexport const useLayoutMenu = createSharedComposable(useLayoutMenuImpl)\n"],"names":["openIfExternal","key","isHttpUrl","isFullscreenPath","renderIcon","name","fallback","AppIcon","lineIcon","renderBadge","path","value","menuBadge","NBadge","toOptions","nodes","a","b","n","MenuType","children","translateMenuTitle","o","containsKey","opt","c","firstLeafKey","k","useLayoutMenuImpl","auth","useAuthStore","app","useAppStore","menuOptions","computed","l1Options","activeKey","router","selectedL1","ref","findActiveL1","top","watch","l1","_a","opts","l2Options","onSelect","onSelectL1","target","useLayoutMenu","createSharedComposable"],"mappings":";;;;;;;;;;;;AAqBA,SAASA,EAAeC,GAAsB;AAC5C,SAAI,CAACC,EAAUD,CAAG,KAAK,CAACE,EAAiBF,CAAG,IAAU,MACtD,OAAO,KAAKA,GAAK,UAAU,qBAAqB,GACzC;AACT;AAKA,SAASG,EAAWC,GAA0BC,IAAW,kBAAkB;AACzE,SAAO,MAAM,EAAEC,GAAS,EAAE,MAAMC,EAASH,CAAI,KAAKC,GAAU,MAAM,IAAI;AACxE;AAKA,SAASG,EAAYC,GAA0B;AAC7C,MAAKA;AACL,WAAO,MAAM;AACX,YAAMC,IAAQC,EAAUF,CAAI;AAC5B,aAAIC,KAAU,QAA+BA,MAAU,KAAKA,MAAU,KAAW,OAC1E,EAAEE,GAAQ,EAAE,OAAAF,GAAO,KAAK,IAAI;AAAA,IACrC;AACF;AAGA,SAASG,EAAUC,GAAiC;AAClD,SAAOA,EACJ,SAAS,CAACC,GAAGC,MAAMD,EAAE,OAAOC,EAAE,IAAI,EAClC,OAAO,CAAAC,MAAKA,EAAE,SAASC,EAAS,UAAUD,EAAE,YAAY,EAAK,EAC7D,IAAuB,CAAAA,MAAK;AAC3B,QAAIA,EAAE,SAASC,EAAS,SAAS;AAC/B,YAAMC,IAAWN,EAAUI,EAAE,YAAY,CAAA,CAAE;AAC3C,aAAKE,EAAS,SACP;AAAA,QACL,OAAOC,EAAmBH,EAAE,OAAOA,EAAE,IAAI;AAAA,QACzC,KAAK,OAAOA,EAAE,EAAE;AAAA,QAChB,MAAMd,EAAWc,EAAE,MAAM,WAAW;AAAA,QACpC,UAAAE;AAAA,MAAA,IAL2B;AAAA,IAO/B;AACA,WAAO;AAAA,MACL,OAAOC,EAAmBH,EAAE,OAAOA,EAAE,IAAI;AAAA,MACzC,KAAKA,EAAE,QAAQ,QAAQA,EAAE,EAAE;AAAA,MAC3B,MAAMd,EAAWc,EAAE,IAAI;AAAA,MACvB,OAAOT,EAAYS,EAAE,IAAI;AAAA,IAAA;AAAA,EAE7B,CAAC,EACA,OAAO,CAACI,MAAuBA,MAAM,IAAI;AAC9C;AAEA,SAASC,EAAYC,GAAiBd,GAAuB;AAC3D,SAAIc,EAAI,QAAQd,IAAa,MACpBc,EAAI,YAA6B,IAAI,KAAK,CAAAC,MAAKF,EAAYE,GAAGf,CAAI,CAAC;AAC9E;AACA,SAASgB,EAAaF,GAAqC;AACzD,MAAI,OAAOA,EAAI,OAAQ,YAAYA,EAAI,IAAI,WAAW,GAAG,EAAG,QAAOA,EAAI;AACvE,aAAWC,KAAMD,EAAI,YAA6B,CAAA,GAAI;AACpD,UAAMG,IAAID,EAAaD,CAAC;AACxB,QAAIE,EAAG,QAAOA;AAAA,EAChB;AAEF;AAOA,SAASC,IAAoB;AAC3B,QAAMC,IAAOC,EAAA,GACPC,IAAMC,EAAA,GAGNC,IAAcC,EAAuB,OACpCH,EAAI,QACFjB,EAAUe,EAAK,QAAQ,EAC/B,GAGKM,IAAYD;AAAA,IAAuB,MACvCD,EAAY,MAAM,IAAI,CAAAX,OAAM,EAAE,OAAOA,EAAE,OAAO,KAAKA,EAAE,KAAK,MAAMA,EAAE,MAAM,OAAOA,EAAE,QAAQ;AAAA,EAAA,GAGrFc,IAAYF,EAAS,MAAMG,EAAO,aAAa,MAAM,IAAI,GACzDC,IAAaC,EAAA;AAEnB,WAASC,EAAa9B,GAAkC;AACtD,UAAM+B,IAAMR,EAAY,MAAM,KAAK,OAAKV,EAAYD,GAAGZ,CAAI,CAAC;AAC5D,WAAO+B,IAAM,OAAOA,EAAI,GAAG,IAAI;AAAA,EACjC;AAGA,EAAAC;AAAA,IACE,MAAML,EAAO,aAAa,MAAM;AAAA,IAChC,CAAA3B,MAAQ;;AACN,YAAMiC,IAAKH,EAAa9B,CAAI;AAC5B,MAAIiC,MAAe,QAAQA,IAClBL,EAAW,UAAU,WAC5BA,EAAW,SAAQM,IAAAX,EAAY,MAAM,CAAC,MAAnB,gBAAAW,EAAsB;AAAA,IAC7C;AAAA,IACA,EAAE,WAAW,GAAA;AAAA,EAAK,GAGpBF,EAAMT,GAAa,CAAAY,MAAQ;;AACzB,KAAIP,EAAW,UAAU,UAAa,CAACO,EAAK,KAAK,CAAAvB,MAAKA,EAAE,QAAQgB,EAAW,KAAK,OAC9EA,EAAW,QAAQE,EAAaJ,EAAU,KAAK,OAAMQ,IAAAC,EAAK,CAAC,MAAN,gBAAAD,EAAS;AAAA,EAElE,CAAC;AAED,QAAME,IAAYZ,EAAuB,MAAM;AAC7C,UAAMO,IAAMR,EAAY,MAAM,KAAK,OAAK,EAAE,QAAQK,EAAW,KAAK;AAClE,YAAQG,KAAA,gBAAAA,EAAK,aAA6B,CAAA;AAAA,EAC5C,CAAC;AAED,WAASM,EAAS9C,GAAa;AAC7B,IAAID,EAAeC,CAAG,KAClBA,EAAI,WAAW,GAAG,KAAGoC,EAAO,KAAKpC,CAAG;AAAA,EAC1C;AACA,WAAS+C,EAAW/C,GAAa;AAC/B,QAAID,EAAeC,CAAG,EAAG;AACzB,IAAAqC,EAAW,QAAQrC;AACnB,UAAMwC,IAAMR,EAAY,MAAM,KAAK,CAAAX,MAAKA,EAAE,QAAQrB,CAAG,GAC/CgD,IAAShD,EAAI,WAAW,GAAG,IAAIA,IAAMwC,IAAMf,EAAae,CAAG,IAAI;AACrE,IAAIQ,KAAQZ,EAAO,KAAKY,CAAM;AAAA,EAChC;AAEA,SAAO,EAAE,aAAAhB,GAAa,WAAAE,GAAW,WAAAW,GAAW,YAAAR,GAAY,WAAAF,GAAW,UAAAW,GAAU,YAAAC,EAAA;AAC/E;AAEO,MAAME,IAAgBC,EAAuBvB,CAAiB;"}
|
|
@@ -1,44 +1,54 @@
|
|
|
1
|
-
import { useAuthStore as
|
|
2
|
-
import { useTabsStore as
|
|
1
|
+
import { useAuthStore as I } from "../stores/auth.js";
|
|
2
|
+
import { useTabsStore as g } from "../stores/tabs.js";
|
|
3
3
|
import { useUserStore as f } from "../stores/user.js";
|
|
4
4
|
import { personalApi as s } from "../api/index.js";
|
|
5
|
-
import { buildRoutesForModule as
|
|
6
|
-
import { router as
|
|
7
|
-
let
|
|
8
|
-
async function
|
|
9
|
-
return await
|
|
5
|
+
import { buildRoutesForModule as M } from "./useAuthMenu.js";
|
|
6
|
+
import { router as S } from "../router/index.js";
|
|
7
|
+
let i = null;
|
|
8
|
+
async function n(r) {
|
|
9
|
+
return await M(r), { chooser: !1, moduleId: r };
|
|
10
10
|
}
|
|
11
|
-
function
|
|
12
|
-
const
|
|
13
|
-
function
|
|
14
|
-
return
|
|
15
|
-
|
|
16
|
-
})),
|
|
11
|
+
function b() {
|
|
12
|
+
const r = I();
|
|
13
|
+
function d() {
|
|
14
|
+
return i ?? (i = c().finally(() => {
|
|
15
|
+
i = null;
|
|
16
|
+
})), i;
|
|
17
17
|
}
|
|
18
18
|
async function c() {
|
|
19
|
-
const [{ modules:
|
|
19
|
+
const [{ modules: o, defaultModuleId: t }, m, a] = await Promise.all([
|
|
20
20
|
s.modules(),
|
|
21
|
-
s.permissions().then((
|
|
22
|
-
s.profile().then((
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
s.permissions().then((e) => ({ ok: !0, codes: e })).catch(() => ({ ok: !1, codes: [] })),
|
|
22
|
+
s.profile().then((e) => ({
|
|
23
|
+
sadm: e.isSuperAdmin,
|
|
24
|
+
avatar: e.avatar ?? null,
|
|
25
|
+
orgName: e.orgName ?? null,
|
|
26
|
+
phoneTail: e.phone ? e.phone.slice(-4) : null
|
|
27
|
+
})).catch(() => {
|
|
28
|
+
var e;
|
|
29
|
+
return {
|
|
30
|
+
sadm: ((e = f().userInfo) == null ? void 0 : e.isSuperAdmin) ?? !1,
|
|
31
|
+
avatar: null,
|
|
32
|
+
orgName: null,
|
|
33
|
+
phoneTail: null
|
|
34
|
+
};
|
|
25
35
|
})
|
|
26
36
|
]);
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
if (
|
|
30
|
-
const
|
|
31
|
-
return
|
|
37
|
+
r.modules = o, r.defaultModuleId = t ?? null, r.permissionCodes = m.codes, r.permissionsLoaded = m.ok, r.isSuperAdmin = a.sadm;
|
|
38
|
+
const u = f();
|
|
39
|
+
if (u.userInfo && (u.userInfo.avatar = a.avatar, u.userInfo.orgName = a.orgName, u.userInfo.phoneTail = a.phoneTail), o.length === 0) return { chooser: !0 };
|
|
40
|
+
const l = r.currentModuleId;
|
|
41
|
+
return l && o.some((e) => e.id === l) ? n(l) : o.length === 1 ? n(o[0].id) : t && o.some((e) => e.id === t) ? n(t) : { chooser: !0 };
|
|
32
42
|
}
|
|
33
|
-
async function p(
|
|
34
|
-
await o
|
|
43
|
+
async function p(o) {
|
|
44
|
+
await n(o), g().clearTabs(), S.replace(r.homePath);
|
|
35
45
|
}
|
|
36
|
-
async function h(
|
|
37
|
-
await s.setDefaultModule(
|
|
46
|
+
async function h(o) {
|
|
47
|
+
await s.setDefaultModule(o), r.defaultModuleId = o;
|
|
38
48
|
}
|
|
39
|
-
return { enter:
|
|
49
|
+
return { enter: n, enterInitial: d, switchModule: p, setDefault: h };
|
|
40
50
|
}
|
|
41
51
|
export {
|
|
42
|
-
|
|
52
|
+
b as useModule
|
|
43
53
|
};
|
|
44
54
|
//# sourceMappingURL=useModule.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useModule.js","sources":["../../src/composables/useModule.ts"],"sourcesContent":["// 多应用门户的进门/切换流程:登录后该直接进哪个应用、还是弹应用选择器,以及切换时清理旧应用的路由与标签。\n// enterInitial() 也是 F5/深链的恢复入口(动态路由只在内存里),路由守卫会调它。\n// 坑:权限码拉取失败时 permissionsLoaded 保持 false,v-auth 走 fail-closed 藏按钮 —— 宁可少显示,不谎报有权限。\nimport { useAuthStore } from '#/stores/auth'\nimport { useTabsStore } from '#/stores/tabs'\nimport { useUserStore } from '#/stores/user'\nimport { personalApi } from '#/api'\nimport { buildRoutesForModule } from './useAuthMenu'\nimport { router } from '#/router'\n\ntype EnterResult = { chooser: true } | { chooser: false; moduleId: number }\n\n// 进门单飞:F5/深链时守卫可能被并发导航各调一次 enterInitial,而 buildRoutesForModule 起手就 resetRouter()\n// —— 后一次会把前一次刚注册的动态路由整片摘掉,表现是偶发 404/白屏。模块级 promise 让并发合流成一次。\nlet entering: Promise<EnterResult> | null = null\n\n/** 进指定应用:重建它的动态路由。 */\nasync function enter(moduleId: number): Promise<EnterResult> {\n await buildRoutesForModule(moduleId)\n return { chooser: false, moduleId }\n}\n\n/** 门户:登录后决定直接进 / 进默认 / 弹选择器,以及切换应用。逻辑与 Naive 无关。 */\nexport function useModule() {\n const auth = useAuthStore()\n\n function enterInitial(): Promise<EnterResult> {\n entering ??= doEnterInitial().finally(() => {\n entering = null\n })\n return entering\n }\n\n async function doEnterInitial(): Promise<EnterResult> {\n // 并行拉模块 + 当前用户权限码。权限码喂 v-auth:成功(哪怕空集=超管)才标 loaded;\n // 失败不阻断进门户,但 permissionsLoaded 保持 false → v-auth fail-closed(藏按钮),不谎报\"有权限\"。\n // profile 拿超管标记喂 v-auth(只对超管 fail-open,普通用户空集则隐藏)+ 顺手回填顶栏头像;失败按普通用户处理(安全侧,不误放行)。\n const [{ modules, defaultModuleId }, perm, profile] = await Promise.all([\n personalApi.modules(),\n personalApi\n .permissions()\n .then(codes => ({ ok: true, codes }))\n .catch(() => ({ ok: false, codes: [] as string[] })),\n personalApi\n .profile()\n .then(p => ({
|
|
1
|
+
{"version":3,"file":"useModule.js","sources":["../../src/composables/useModule.ts"],"sourcesContent":["// 多应用门户的进门/切换流程:登录后该直接进哪个应用、还是弹应用选择器,以及切换时清理旧应用的路由与标签。\n// enterInitial() 也是 F5/深链的恢复入口(动态路由只在内存里),路由守卫会调它。\n// 坑:权限码拉取失败时 permissionsLoaded 保持 false,v-auth 走 fail-closed 藏按钮 —— 宁可少显示,不谎报有权限。\nimport { useAuthStore } from '#/stores/auth'\nimport { useTabsStore } from '#/stores/tabs'\nimport { useUserStore } from '#/stores/user'\nimport { personalApi } from '#/api'\nimport { buildRoutesForModule } from './useAuthMenu'\nimport { router } from '#/router'\n\ntype EnterResult = { chooser: true } | { chooser: false; moduleId: number }\n\n// 进门单飞:F5/深链时守卫可能被并发导航各调一次 enterInitial,而 buildRoutesForModule 起手就 resetRouter()\n// —— 后一次会把前一次刚注册的动态路由整片摘掉,表现是偶发 404/白屏。模块级 promise 让并发合流成一次。\nlet entering: Promise<EnterResult> | null = null\n\n/** 进指定应用:重建它的动态路由。 */\nasync function enter(moduleId: number): Promise<EnterResult> {\n await buildRoutesForModule(moduleId)\n return { chooser: false, moduleId }\n}\n\n/** 门户:登录后决定直接进 / 进默认 / 弹选择器,以及切换应用。逻辑与 Naive 无关。 */\nexport function useModule() {\n const auth = useAuthStore()\n\n function enterInitial(): Promise<EnterResult> {\n entering ??= doEnterInitial().finally(() => {\n entering = null\n })\n return entering\n }\n\n async function doEnterInitial(): Promise<EnterResult> {\n // 并行拉模块 + 当前用户权限码。权限码喂 v-auth:成功(哪怕空集=超管)才标 loaded;\n // 失败不阻断进门户,但 permissionsLoaded 保持 false → v-auth fail-closed(藏按钮),不谎报\"有权限\"。\n // profile 拿超管标记喂 v-auth(只对超管 fail-open,普通用户空集则隐藏)+ 顺手回填顶栏头像;失败按普通用户处理(安全侧,不误放行)。\n const [{ modules, defaultModuleId }, perm, profile] = await Promise.all([\n personalApi.modules(),\n personalApi\n .permissions()\n .then(codes => ({ ok: true, codes }))\n .catch(() => ({ ok: false, codes: [] as string[] })),\n personalApi\n .profile()\n .then(p => ({\n sadm: p.isSuperAdmin,\n avatar: p.avatar ?? null,\n orgName: p.orgName ?? null,\n phoneTail: p.phone ? p.phone.slice(-4) : null,\n }))\n .catch(() => ({\n sadm: useUserStore().userInfo?.isSuperAdmin ?? false,\n avatar: null,\n orgName: null,\n phoneTail: null,\n })),\n ])\n auth.modules = modules\n auth.defaultModuleId = defaultModuleId ?? null\n auth.permissionCodes = perm.codes\n auth.permissionsLoaded = perm.ok\n auth.isSuperAdmin = profile.sadm\n // 顶栏头像:登录出参不含 avatar,这里回填(取不到按无头像处理,顶栏回落图标)\n const user = useUserStore()\n if (user.userInfo) {\n user.userInfo.avatar = profile.avatar\n user.userInfo.orgName = profile.orgName // 水印要印机构和手机尾号,同样只有 profile 里有\n user.userInfo.phoneTail = profile.phoneTail\n }\n if (modules.length === 0) return { chooser: true } // 空态:选择器里提示未分配应用\n // F5/深链优先重建\"上次所在应用\"(持久化的 currentModuleId),让其动态路由复活,跨应用深链不落 404。\n const remembered = auth.currentModuleId\n if (remembered && modules.some(m => m.id === remembered)) return enter(remembered)\n if (modules.length === 1) return enter(modules[0]!.id)\n if (defaultModuleId && modules.some(m => m.id === defaultModuleId))\n return enter(defaultModuleId)\n return { chooser: true }\n }\n\n async function switchModule(moduleId: number): Promise<void> {\n await enter(moduleId)\n useTabsStore().clearTabs() // 切应用 → 标签归零(新应用路由已重建)\n router.replace(auth.homePath) // 落到新应用自己的首页\n }\n\n async function setDefault(moduleId: number): Promise<void> {\n await personalApi.setDefaultModule(moduleId)\n auth.defaultModuleId = moduleId // 本地同步,选择页角标立刻转移,不必重拉 /personal/modules\n }\n\n return { enter, enterInitial, switchModule, setDefault }\n}\n"],"names":["entering","enter","moduleId","buildRoutesForModule","useModule","auth","useAuthStore","enterInitial","doEnterInitial","modules","defaultModuleId","perm","profile","personalApi","codes","p","_a","useUserStore","user","remembered","m","switchModule","useTabsStore","router","setDefault"],"mappings":";;;;;;AAcA,IAAIA,IAAwC;AAG5C,eAAeC,EAAMC,GAAwC;AAC3D,eAAMC,EAAqBD,CAAQ,GAC5B,EAAE,SAAS,IAAO,UAAAA,EAAA;AAC3B;AAGO,SAASE,IAAY;AAC1B,QAAMC,IAAOC,EAAA;AAEb,WAASC,IAAqC;AAC5C,WAAAP,UAAaQ,IAAiB,QAAQ,MAAM;AAC1C,MAAAR,IAAW;AAAA,IACb,CAAC,IACMA;AAAA,EACT;AAEA,iBAAeQ,IAAuC;AAIpD,UAAM,CAAC,EAAE,SAAAC,GAAS,iBAAAC,EAAA,GAAmBC,GAAMC,CAAO,IAAI,MAAM,QAAQ,IAAI;AAAA,MACtEC,EAAY,QAAA;AAAA,MACZA,EACG,YAAA,EACA,KAAK,CAAAC,OAAU,EAAE,IAAI,IAAM,OAAAA,EAAA,EAAQ,EACnC,MAAM,OAAO,EAAE,IAAI,IAAO,OAAO,CAAA,IAAiB;AAAA,MACrDD,EACG,QAAA,EACA,KAAK,CAAAE,OAAM;AAAA,QACV,MAAMA,EAAE;AAAA,QACR,QAAQA,EAAE,UAAU;AAAA,QACpB,SAASA,EAAE,WAAW;AAAA,QACtB,WAAWA,EAAE,QAAQA,EAAE,MAAM,MAAM,EAAE,IAAI;AAAA,MAAA,EACzC,EACD,MAAM,MAAA;;AAAO;AAAA,UACZ,QAAMC,IAAAC,EAAA,EAAe,aAAf,gBAAAD,EAAyB,iBAAgB;AAAA,UAC/C,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,WAAW;AAAA,QAAA;AAAA,OACX;AAAA,IAAA,CACL;AACD,IAAAX,EAAK,UAAUI,GACfJ,EAAK,kBAAkBK,KAAmB,MAC1CL,EAAK,kBAAkBM,EAAK,OAC5BN,EAAK,oBAAoBM,EAAK,IAC9BN,EAAK,eAAeO,EAAQ;AAE5B,UAAMM,IAAOD,EAAA;AAMb,QALIC,EAAK,aACPA,EAAK,SAAS,SAASN,EAAQ,QAC/BM,EAAK,SAAS,UAAUN,EAAQ,SAChCM,EAAK,SAAS,YAAYN,EAAQ,YAEhCH,EAAQ,WAAW,EAAG,QAAO,EAAE,SAAS,GAAA;AAE5C,UAAMU,IAAad,EAAK;AACxB,WAAIc,KAAcV,EAAQ,KAAK,CAAAW,MAAKA,EAAE,OAAOD,CAAU,IAAUlB,EAAMkB,CAAU,IAC7EV,EAAQ,WAAW,IAAUR,EAAMQ,EAAQ,CAAC,EAAG,EAAE,IACjDC,KAAmBD,EAAQ,KAAK,CAAAW,MAAKA,EAAE,OAAOV,CAAe,IACxDT,EAAMS,CAAe,IACvB,EAAE,SAAS,GAAA;AAAA,EACpB;AAEA,iBAAeW,EAAanB,GAAiC;AAC3D,UAAMD,EAAMC,CAAQ,GACpBoB,EAAA,EAAe,UAAA,GACfC,EAAO,QAAQlB,EAAK,QAAQ;AAAA,EAC9B;AAEA,iBAAemB,EAAWtB,GAAiC;AACzD,UAAMW,EAAY,iBAAiBX,CAAQ,GAC3CG,EAAK,kBAAkBH;AAAA,EACzB;AAEA,SAAO,EAAE,OAAAD,GAAO,cAAAM,GAAc,cAAAc,GAAc,YAAAG,EAAA;AAC9C;"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Ref } from 'vue';
|
|
2
|
+
export type ShellBreakpoint = 'wide' | 'mid' | 'narrow';
|
|
3
|
+
/** 壳层 narrow 的上界(不含)。与表格窄档 600 对齐,见文件头。 */
|
|
4
|
+
export declare const SHELL_NARROW_MAX = 600;
|
|
5
|
+
/** 壳层 wide 的下界(含)。 */
|
|
6
|
+
export declare const SHELL_WIDE_MIN = 1400;
|
|
7
|
+
/** 带左侧面板的页面:内容区窄于此值时面板收进抽屉。 */
|
|
8
|
+
export declare const SHELL_PANEL_DRAWER_MAX = 1000;
|
|
9
|
+
/** 纯判定,便于单测。 */
|
|
10
|
+
export declare function shellBreakpointOf(width: number): ShellBreakpoint;
|
|
11
|
+
export interface ShellBreakpointState {
|
|
12
|
+
/** 内容区(`.page` content box)宽度,px */
|
|
13
|
+
width: Ref<number>;
|
|
14
|
+
bp: Readonly<Ref<ShellBreakpoint>>;
|
|
15
|
+
}
|
|
16
|
+
/** 壳层调用:盯住 el 的 content box,把 { width, bp } 提供给后代。 */
|
|
17
|
+
export declare function provideShellBreakpoint(el: Ref<HTMLElement | undefined>): ShellBreakpointState;
|
|
18
|
+
/** 页面 / 组件调用:取壳层档位。壳层之外退回视口宽度(近似,够单测与独立挂载用)。 */
|
|
19
|
+
export declare function useShellBreakpoint(): ShellBreakpointState;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { inject as v, computed as c, ref as h, provide as w, watch as m, onScopeDispose as S } from "vue";
|
|
2
|
+
import { useWindowSize as b } from "@vueuse/core";
|
|
3
|
+
const R = 600, l = 1400;
|
|
4
|
+
function u(t) {
|
|
5
|
+
return t >= l ? "wide" : t >= R ? "mid" : "narrow";
|
|
6
|
+
}
|
|
7
|
+
const p = Symbol("shellBreakpoint");
|
|
8
|
+
function E(t) {
|
|
9
|
+
const n = h(l), d = c(() => u(n.value)), o = { width: n, bp: d };
|
|
10
|
+
w(p, o);
|
|
11
|
+
let e;
|
|
12
|
+
return m(
|
|
13
|
+
t,
|
|
14
|
+
(i, _, f) => {
|
|
15
|
+
!i || typeof ResizeObserver > "u" || (e = new ResizeObserver((a) => {
|
|
16
|
+
var s;
|
|
17
|
+
const r = (s = a[0]) == null ? void 0 : s.contentRect.width;
|
|
18
|
+
r !== void 0 && (n.value = r);
|
|
19
|
+
}), e.observe(i), f(() => e == null ? void 0 : e.disconnect()));
|
|
20
|
+
},
|
|
21
|
+
{ flush: "post" }
|
|
22
|
+
), S(() => e == null ? void 0 : e.disconnect()), o;
|
|
23
|
+
}
|
|
24
|
+
function L() {
|
|
25
|
+
const t = v(p, null);
|
|
26
|
+
if (t) return t;
|
|
27
|
+
const { width: n } = b();
|
|
28
|
+
return { width: n, bp: c(() => u(n.value)) };
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
R as SHELL_NARROW_MAX,
|
|
32
|
+
l as SHELL_WIDE_MIN,
|
|
33
|
+
E as provideShellBreakpoint,
|
|
34
|
+
u as shellBreakpointOf,
|
|
35
|
+
L as useShellBreakpoint
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=useShellBreakpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useShellBreakpoint.js","sources":["../../src/composables/useShellBreakpoint.ts"],"sourcesContent":["// 壳层档位:按「内容区」宽度判(不是视口),侧栏展开 / 收起、抽屉开合都会改变档位。\n//\n// wide ≥ 1400 统计卡等页面栅格铺开\n// mid 600–1399 栅格收窄;带左侧面板的页面在内容区 < 1000 时面板收进抽屉\n// narrow < 600 整页自然滚动,不锁一屏高度;统计卡两列;设置行上下排\n//\n// 阈值 600 = smart-naive-table 的窄档(表格根节点宽 < 600 换卡片)。壳层 narrow 必须和它对齐:\n// 壳层进入「整页自然滚动」时表格一定已是卡片列表;壳层不是 narrow 时表格一定仍是表格。\n// 两层阈值错开会出现一段宽度:页面不定高、表格却还在 fill-height,表体塌成最小高度。\n// 阈值直接取 600:量的是 `.page` 的 content box(ResizeObserver 的 contentRect 本身已扣掉内边距),\n// 留白不进数字,日后改 `.page` 的内边距不用回来改阈值。\n//\n// 用法:default.vue 调 provideShellBreakpoint(el) 绑定被量的元素;页面里调 useShellBreakpoint()\n// 取 { bp, width }(没有壳层时,如单测或独立挂载,退回按视口宽度估算)。\nimport {\n computed,\n inject,\n onScopeDispose,\n provide,\n ref,\n watch,\n type InjectionKey,\n type Ref,\n} from 'vue'\nimport { useWindowSize } from '@vueuse/core'\n\nexport type ShellBreakpoint = 'wide' | 'mid' | 'narrow'\n\n/** 壳层 narrow 的上界(不含)。与表格窄档 600 对齐,见文件头。 */\nexport const SHELL_NARROW_MAX = 600\n/** 壳层 wide 的下界(含)。 */\nexport const SHELL_WIDE_MIN = 1400\n/** 带左侧面板的页面:内容区窄于此值时面板收进抽屉。 */\nexport const SHELL_PANEL_DRAWER_MAX = 1000\n\n/** 纯判定,便于单测。 */\nexport function shellBreakpointOf(width: number): ShellBreakpoint {\n return width >= SHELL_WIDE_MIN ? 'wide' : width >= SHELL_NARROW_MAX ? 'mid' : 'narrow'\n}\n\nexport interface ShellBreakpointState {\n /** 内容区(`.page` content box)宽度,px */\n width: Ref<number>\n bp: Readonly<Ref<ShellBreakpoint>>\n}\n\nconst KEY: InjectionKey<ShellBreakpointState> = Symbol('shellBreakpoint')\n\n/** 壳层调用:盯住 el 的 content box,把 { width, bp } 提供给后代。 */\nexport function provideShellBreakpoint(el: Ref<HTMLElement | undefined>): ShellBreakpointState {\n const width = ref(SHELL_WIDE_MIN) // 首帧按宽档,避免挂载瞬间闪一下 narrow 的自然滚动布局\n const bp = computed(() => shellBreakpointOf(width.value))\n const state: ShellBreakpointState = { width, bp }\n provide(KEY, state)\n\n let ro: ResizeObserver | undefined\n watch(\n el,\n (node, _old, onCleanup) => {\n if (!node || typeof ResizeObserver === 'undefined') return\n ro = new ResizeObserver(entries => {\n const w = entries[0]?.contentRect.width\n if (w !== undefined) width.value = w\n })\n ro.observe(node)\n onCleanup(() => ro?.disconnect())\n },\n { flush: 'post' },\n )\n onScopeDispose(() => ro?.disconnect())\n return state\n}\n\n/** 页面 / 组件调用:取壳层档位。壳层之外退回视口宽度(近似,够单测与独立挂载用)。 */\nexport function useShellBreakpoint(): ShellBreakpointState {\n const injected = inject(KEY, null)\n if (injected) return injected\n const { width } = useWindowSize()\n return { width, bp: computed(() => shellBreakpointOf(width.value)) }\n}\n"],"names":["SHELL_NARROW_MAX","SHELL_WIDE_MIN","shellBreakpointOf","width","KEY","provideShellBreakpoint","el","ref","bp","computed","state","provide","ro","watch","node","_old","onCleanup","entries","w","_a","onScopeDispose","useShellBreakpoint","injected","inject","useWindowSize"],"mappings":";;AA6BO,MAAMA,IAAmB,KAEnBC,IAAiB;AAKvB,SAASC,EAAkBC,GAAgC;AAChE,SAAOA,KAASF,IAAiB,SAASE,KAASH,IAAmB,QAAQ;AAChF;AAQA,MAAMI,IAA0C,OAAO,iBAAiB;AAGjE,SAASC,EAAuBC,GAAwD;AAC7F,QAAMH,IAAQI,EAAIN,CAAc,GAC1BO,IAAKC,EAAS,MAAMP,EAAkBC,EAAM,KAAK,CAAC,GAClDO,IAA8B,EAAE,OAAAP,GAAO,IAAAK,EAAA;AAC7C,EAAAG,EAAQP,GAAKM,CAAK;AAElB,MAAIE;AACJ,SAAAC;AAAA,IACEP;AAAA,IACA,CAACQ,GAAMC,GAAMC,MAAc;AACzB,MAAI,CAACF,KAAQ,OAAO,iBAAmB,QACvCF,IAAK,IAAI,eAAe,CAAAK,MAAW;;AACjC,cAAMC,KAAIC,IAAAF,EAAQ,CAAC,MAAT,gBAAAE,EAAY,YAAY;AAClC,QAAID,MAAM,WAAWf,EAAM,QAAQe;AAAA,MACrC,CAAC,GACDN,EAAG,QAAQE,CAAI,GACfE,EAAU,MAAMJ,KAAA,gBAAAA,EAAI,YAAY;AAAA,IAClC;AAAA,IACA,EAAE,OAAO,OAAA;AAAA,EAAO,GAElBQ,EAAe,MAAMR,KAAA,gBAAAA,EAAI,YAAY,GAC9BF;AACT;AAGO,SAASW,IAA2C;AACzD,QAAMC,IAAWC,EAAOnB,GAAK,IAAI;AACjC,MAAIkB,EAAU,QAAOA;AACrB,QAAM,EAAE,OAAAnB,EAAA,IAAUqB,EAAA;AAClB,SAAO,EAAE,OAAArB,GAAO,IAAIM,EAAS,MAAMP,EAAkBC,EAAM,KAAK,CAAC,EAAA;AACnE;"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { LoginHeroCopy } from '../lib/loginHero';
|
|
2
|
+
import { WatermarkSettings } from '../lib/watermark';
|
|
2
3
|
export interface SiteInfo {
|
|
3
4
|
title: string;
|
|
4
5
|
subtitle: string;
|
|
@@ -9,6 +10,8 @@ export interface SiteInfo {
|
|
|
9
10
|
showFeatures: boolean;
|
|
10
11
|
captchaEnabled: boolean;
|
|
11
12
|
smsLoginEnabled: boolean;
|
|
13
|
+
/** 登录后页面的水印设置(只有版式;每个人印什么由壳层按登录用户拼) */
|
|
14
|
+
watermark: WatermarkSettings;
|
|
12
15
|
}
|
|
13
16
|
export declare function loadSite(force?: boolean): Promise<void>;
|
|
14
17
|
/** 版本号不走后端配置:默认是内核版本(库构建期常量),消费方经 createSmartAdmin({ version }) 换成应用版本。 */
|
|
@@ -23,6 +26,18 @@ export declare function useSite(): {
|
|
|
23
26
|
showFeatures: boolean;
|
|
24
27
|
captchaEnabled: boolean;
|
|
25
28
|
smsLoginEnabled: boolean;
|
|
29
|
+
watermark: {
|
|
30
|
+
enabled: boolean;
|
|
31
|
+
fields: import('../lib/watermark').WatermarkField[];
|
|
32
|
+
text: string;
|
|
33
|
+
timeFormat: import('../lib/watermark').WatermarkTimeFormat;
|
|
34
|
+
layout: import('../lib/watermark').WatermarkLayout;
|
|
35
|
+
fontSize: number;
|
|
36
|
+
opacity: number;
|
|
37
|
+
rotate: number;
|
|
38
|
+
density: import('../lib/watermark').WatermarkDensity;
|
|
39
|
+
cross: boolean;
|
|
40
|
+
};
|
|
26
41
|
};
|
|
27
42
|
appVersion: string;
|
|
28
43
|
loadSite: typeof loadSite;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { reactive as
|
|
2
|
-
import { configApi as
|
|
1
|
+
import { reactive as l } from "vue";
|
|
2
|
+
import { configApi as a } from "../api/index.js";
|
|
3
3
|
import { normalizeLoginHero as n } from "../lib/loginHero.js";
|
|
4
|
-
import { runtime as
|
|
5
|
-
|
|
4
|
+
import { runtime as m } from "../lib/runtime.js";
|
|
5
|
+
import { normalizeWatermark as c, DEFAULT_WATERMARK as o } from "../lib/watermark.js";
|
|
6
|
+
const e = l({
|
|
6
7
|
title: "SmartAdmin",
|
|
7
8
|
subtitle: "",
|
|
8
9
|
copyright: "",
|
|
@@ -11,20 +12,21 @@ const e = r({
|
|
|
11
12
|
loginHero: {},
|
|
12
13
|
showFeatures: !0,
|
|
13
14
|
captchaEnabled: !1,
|
|
14
|
-
smsLoginEnabled: !1
|
|
15
|
+
smsLoginEnabled: !1,
|
|
16
|
+
watermark: { ...o, fields: [...o.fields] }
|
|
15
17
|
});
|
|
16
|
-
let
|
|
17
|
-
function
|
|
18
|
-
return
|
|
19
|
-
t.title && (e.title = t.title), e.subtitle = t.subtitle ?? "", e.copyright = t.copyright ?? "", e.copyrightUrl = t.copyrightUrl ?? "", e.logo = t.logo ?? "", e.loginHero = n(t.loginHero), e.showFeatures = t.showFeatures !== !1, e.captchaEnabled = !!t.captchaEnabled, e.smsLoginEnabled = !!t.smsLoginEnabled;
|
|
18
|
+
let r = null;
|
|
19
|
+
function f(i = !1) {
|
|
20
|
+
return r && !i || (r = a.siteInfo().then((t) => {
|
|
21
|
+
t.title && (e.title = t.title), e.subtitle = t.subtitle ?? "", e.copyright = t.copyright ?? "", e.copyrightUrl = t.copyrightUrl ?? "", e.logo = t.logo ?? "", e.loginHero = n(t.loginHero), e.showFeatures = t.showFeatures !== !1, e.captchaEnabled = !!t.captchaEnabled, e.smsLoginEnabled = !!t.smsLoginEnabled, e.watermark = c(t.watermark);
|
|
20
22
|
}).catch(() => {
|
|
21
|
-
})),
|
|
23
|
+
})), r;
|
|
22
24
|
}
|
|
23
|
-
function
|
|
24
|
-
return { site: e, appVersion:
|
|
25
|
+
function d() {
|
|
26
|
+
return { site: e, appVersion: m.version, loadSite: f };
|
|
25
27
|
}
|
|
26
28
|
export {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
f as loadSite,
|
|
30
|
+
d as useSite
|
|
29
31
|
};
|
|
30
32
|
//# sourceMappingURL=useSite.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSite.js","sources":["../../src/composables/useSite.ts"],"sourcesContent":["import { reactive } from 'vue'\nimport { configApi } from '#/api'\nimport { normalizeLoginHero, type LoginHeroCopy } from '#/lib/loginHero'\nimport { runtime } from '#/lib/runtime'\n\n// 站点品牌信息(匿名 GET /sys/config/site 下发)。App.vue 启动、登录页各皮肤、登录后框架(侧栏/顶栏/水印)\n// 共用同一份响应式数据,只拉一次(模块级缓存);改配置保存后 loadSite(true) 强制重取即时生效。\nexport interface SiteInfo {\n title: string\n subtitle: string\n copyright: string\n copyrightUrl: string\n logo: string\n loginHero: Record<string, LoginHeroCopy>\n showFeatures: boolean\n captchaEnabled: boolean\n smsLoginEnabled: boolean\n}\n\n// title 初值给内置名,防 siteInfo 到达前品牌词首帧空白;createSmartAdmin({ brand.title }) 会在挂载前改写它。\nconst site = reactive<SiteInfo>({\n title: 'SmartAdmin',\n subtitle: '',\n copyright: '',\n copyrightUrl: '',\n logo: '',\n loginHero: {},\n showFeatures: true,\n captchaEnabled: false,\n smsLoginEnabled: false,\n})\n\nlet inflight: Promise<void> | null = null\n\nexport function loadSite(force = false): Promise<void> {\n if (inflight && !force) return inflight\n inflight = configApi\n .siteInfo()\n .then(s => {\n if (s.title) site.title = s.title\n site.subtitle = s.subtitle ?? ''\n site.copyright = s.copyright ?? ''\n site.copyrightUrl = s.copyrightUrl ?? ''\n site.logo = s.logo ?? ''\n site.loginHero = normalizeLoginHero(s.loginHero)\n site.showFeatures = s.showFeatures !== false\n site.captchaEnabled = !!s.captchaEnabled\n site.smsLoginEnabled = !!s.smsLoginEnabled\n })\n .catch(() => {\n // 拉取失败保留内置默认(title=SmartAdmin),不阻塞登录/渲染\n })\n return inflight\n}\n\n/** 版本号不走后端配置:默认是内核版本(库构建期常量),消费方经 createSmartAdmin({ version }) 换成应用版本。 */\nexport function useSite() {\n return { site, appVersion: runtime.version, loadSite }\n}\n"],"names":["site","reactive","inflight","loadSite","force","configApi","s","normalizeLoginHero","useSite","runtime"],"mappings":"
|
|
1
|
+
{"version":3,"file":"useSite.js","sources":["../../src/composables/useSite.ts"],"sourcesContent":["import { reactive } from 'vue'\nimport { configApi } from '#/api'\nimport { normalizeLoginHero, type LoginHeroCopy } from '#/lib/loginHero'\nimport { runtime } from '#/lib/runtime'\nimport { DEFAULT_WATERMARK, normalizeWatermark, type WatermarkSettings } from '#/lib/watermark'\n\n// 站点品牌信息(匿名 GET /sys/config/site 下发)。App.vue 启动、登录页各皮肤、登录后框架(侧栏/顶栏/水印)\n// 共用同一份响应式数据,只拉一次(模块级缓存);改配置保存后 loadSite(true) 强制重取即时生效。\nexport interface SiteInfo {\n title: string\n subtitle: string\n copyright: string\n copyrightUrl: string\n logo: string\n loginHero: Record<string, LoginHeroCopy>\n showFeatures: boolean\n captchaEnabled: boolean\n smsLoginEnabled: boolean\n /** 登录后页面的水印设置(只有版式;每个人印什么由壳层按登录用户拼) */\n watermark: WatermarkSettings\n}\n\n// title 初值给内置名,防 siteInfo 到达前品牌词首帧空白;createSmartAdmin({ brand.title }) 会在挂载前改写它。\nconst site = reactive<SiteInfo>({\n title: 'SmartAdmin',\n subtitle: '',\n copyright: '',\n copyrightUrl: '',\n logo: '',\n loginHero: {},\n showFeatures: true,\n captchaEnabled: false,\n smsLoginEnabled: false,\n watermark: { ...DEFAULT_WATERMARK, fields: [...DEFAULT_WATERMARK.fields] },\n})\n\nlet inflight: Promise<void> | null = null\n\nexport function loadSite(force = false): Promise<void> {\n if (inflight && !force) return inflight\n inflight = configApi\n .siteInfo()\n .then(s => {\n if (s.title) site.title = s.title\n site.subtitle = s.subtitle ?? ''\n site.copyright = s.copyright ?? ''\n site.copyrightUrl = s.copyrightUrl ?? ''\n site.logo = s.logo ?? ''\n site.loginHero = normalizeLoginHero(s.loginHero)\n site.showFeatures = s.showFeatures !== false\n site.captchaEnabled = !!s.captchaEnabled\n site.smsLoginEnabled = !!s.smsLoginEnabled\n site.watermark = normalizeWatermark(s.watermark)\n })\n .catch(() => {\n // 拉取失败保留内置默认(title=SmartAdmin),不阻塞登录/渲染\n })\n return inflight\n}\n\n/** 版本号不走后端配置:默认是内核版本(库构建期常量),消费方经 createSmartAdmin({ version }) 换成应用版本。 */\nexport function useSite() {\n return { site, appVersion: runtime.version, loadSite }\n}\n"],"names":["site","reactive","DEFAULT_WATERMARK","inflight","loadSite","force","configApi","s","normalizeLoginHero","normalizeWatermark","useSite","runtime"],"mappings":";;;;;AAuBA,MAAMA,IAAOC,EAAmB;AAAA,EAC9B,OAAO;AAAA,EACP,UAAU;AAAA,EACV,WAAW;AAAA,EACX,cAAc;AAAA,EACd,MAAM;AAAA,EACN,WAAW,CAAA;AAAA,EACX,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,WAAW,EAAE,GAAGC,GAAmB,QAAQ,CAAC,GAAGA,EAAkB,MAAM,EAAA;AACzE,CAAC;AAED,IAAIC,IAAiC;AAE9B,SAASC,EAASC,IAAQ,IAAsB;AACrD,SAAIF,KAAY,CAACE,MACjBF,IAAWG,EACR,SAAA,EACA,KAAK,CAAAC,MAAK;AACT,IAAIA,EAAE,UAAOP,EAAK,QAAQO,EAAE,QAC5BP,EAAK,WAAWO,EAAE,YAAY,IAC9BP,EAAK,YAAYO,EAAE,aAAa,IAChCP,EAAK,eAAeO,EAAE,gBAAgB,IACtCP,EAAK,OAAOO,EAAE,QAAQ,IACtBP,EAAK,YAAYQ,EAAmBD,EAAE,SAAS,GAC/CP,EAAK,eAAeO,EAAE,iBAAiB,IACvCP,EAAK,iBAAiB,CAAC,CAACO,EAAE,gBAC1BP,EAAK,kBAAkB,CAAC,CAACO,EAAE,iBAC3BP,EAAK,YAAYS,EAAmBF,EAAE,SAAS;AAAA,EACjD,CAAC,EACA,MAAM,MAAM;AAAA,EAEb,CAAC,IACIJ;AACT;AAGO,SAASO,IAAU;AACxB,SAAO,EAAE,MAAAV,GAAM,YAAYW,EAAQ,SAAS,UAAAP,EAAA;AAC9C;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTabTitle.js","sources":["../../src/composables/useTabTitle.ts"],"sourcesContent":["import { useRoute } from 'vue-router'\nimport { useTabsStore } from '#/stores/tabs'\n\n// 详情页动态标签标题:数据加载后调用返回的 setter,把当前标签标题改成记录名(如「张三」「工单 #123」)。\n// 内部走 tabsStore.setTitle → 置 titleFixed,addTab
|
|
1
|
+
{"version":3,"file":"useTabTitle.js","sources":["../../src/composables/useTabTitle.ts"],"sourcesContent":["import { useRoute } from 'vue-router'\nimport { useTabsStore } from '#/stores/tabs'\n\n// 详情页动态标签标题:数据加载后调用返回的 setter,把当前标签标题改成记录名(如「张三」「工单 #123」)。\n// 内部走 tabsStore.setTitle → 置 titleFixed,addTab 复访时不会用静态 meta.title 覆盖它;标题随 tab 持久化,F5 无闪复原。\n// 就地态(列表页内切换详情)不要调用它:那时 route.path 是列表标签,改名会改错标签。\nexport function useTabTitle() {\n const route = useRoute()\n const tabs = useTabsStore()\n return (title: string) => tabs.setTitle(route.path, title)\n}\n"],"names":["useTabTitle","route","useRoute","tabs","useTabsStore","title"],"mappings":";;AAMO,SAASA,IAAc;AAC5B,QAAMC,IAAQC,EAAA,GACRC,IAAOC,EAAA;AACb,SAAO,CAACC,MAAkBF,EAAK,SAASF,EAAM,MAAMI,CAAK;AAC3D;"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { computed as e } from "vue";
|
|
2
|
+
import { useRoute as o } from "vue-router";
|
|
3
|
+
import { translateMenuTitle as r } from "../locales/menuTitle.js";
|
|
4
|
+
function n() {
|
|
5
|
+
const t = o();
|
|
6
|
+
return e(() => r(String(t.meta.title ?? ""), t.path));
|
|
7
|
+
}
|
|
8
|
+
export {
|
|
9
|
+
n as useTableTitle
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=useTableTitle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTableTitle.js","sources":["../../src/composables/useTableTitle.ts"],"sourcesContent":["import { computed } from 'vue'\nimport { useRoute } from 'vue-router'\nimport { translateMenuTitle } from '#/locales/menuTitle'\n\n/**\n * 当前页面的菜单标题。表格工具栏不放标题,内核页面不调用它;保留给下游应用在页面自己需要标题文案时使用。\n * 与侧栏 / 面包屑 / 多标签走同一个翻译入口,切语言即时生效。\n * 同页多张表需要各自的标题时,用各自已有的 i18n 文案,不要共用这个值。\n */\nexport function useTableTitle() {\n const route = useRoute()\n return computed(() => translateMenuTitle(String(route.meta.title ?? ''), route.path))\n}\n"],"names":["useTableTitle","route","useRoute","computed","translateMenuTitle"],"mappings":";;;AASO,SAASA,IAAgB;AAC9B,QAAMC,IAAQC,EAAA;AACd,SAAOC,EAAS,MAAMC,EAAmB,OAAOH,EAAM,KAAK,SAAS,EAAE,GAAGA,EAAM,IAAI,CAAC;AACtF;"}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated smart-naive-table 3.0 起 SmartTable 自带放大按钮:`:toolbar="{ maximize: true }"`
|
|
3
|
+
* (Teleport 到 body、盖住侧栏与顶栏、不调用浏览器全屏 API,与本实现是同一思路)。
|
|
4
|
+
* 本 composable 与 TableZoomButton 没有内核页面在用,仅为已依赖它们的下游应用保留,下一个 .NET 大版本删除。
|
|
5
|
+
*/
|
|
1
6
|
export declare function useTableZoom(): {
|
|
2
7
|
zoomed: import('vue').Ref<boolean, boolean>;
|
|
3
8
|
toggle: () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTableZoom.js","sources":["../../src/composables/useTableZoom.ts"],"sourcesContent":["// 表格「放大」:把某块区域临时铺满视口,给笔记本等窄屏看宽表用。\n//\n// 刻意不用 Fullscreen API(VueUse 的 useFullscreen):Naive 的 NSelect / NPopover 把浮层 teleport 到\n// body,而原生全屏只渲染被全屏那棵子树,浮层会整个看不见 —— 带下拉、气泡的宽表必然踩中。\n// 固定定位遮罩没这个问题:浮层照旧挂在 body 上,z-index 比遮罩高就行(遮罩 50,Naive 浮层 2000+)。\n//\n// 用法:\n// const { zoomed, toggle } = useTableZoom()\n// <div :class=\"{ 'table-zoom': zoomed }\"> ...表格... </div>\n// <n-button @click=\"toggle\">放大/还原</n-button>\n// `.table-zoom` 的样式在 styles/table.css。\nimport { onScopeDispose, ref, watch } from 'vue'\n\n/**\n * body 滚动锁的引用计数。`document.body.style.overflow` 是全局单例,而一个页面上会有多个\n * useTableZoom 实例,各自无条件置/清会互相踩:先退出的那个会在另一个遮罩仍铺满时\n * 把背景滚动放开,正是这把锁要防的现象。\n *\n * 当前 UI 下同时只可能有一个放大态(遮罩不透明且铺满视口,挡住了其它放大按钮),\n * 所以这个计数眼下是防御性的 —— 但别让后来者依赖那个巧合:一旦出现并排/画中画放大就会踩中。\n */\nlet bodyLockCount = 0\nfunction lockBodyScroll() {\n if (bodyLockCount === 0) document.body.style.overflow = 'hidden'\n bodyLockCount++\n}\nfunction unlockBodyScroll() {\n if (bodyLockCount === 0) return\n bodyLockCount--\n if (bodyLockCount === 0) document.body.style.overflow = ''\n}\n\nexport function useTableZoom() {\n const zoomed = ref(false)\n /** 本实例是否持有 body 锁:避免重复加锁/重复解锁把计数带偏 */\n let holdsLock = false\n\n function toggle() {\n zoomed.value = !zoomed.value\n }\n function exit() {\n zoomed.value = false\n }\n\n function onKeydown(e: KeyboardEvent) {\n // 只在放大态拦 Esc;Naive 的下拉/气泡自己也吃 Esc,已经打开时先关浮层再关放大,交给冒泡顺序即可。\n if (e.key === 'Escape') exit()\n }\n\n // 放大时锁掉 body 滚动:遮罩是 fixed,底下的页面还能滚会让滚轮行为很怪。\n watch(zoomed, value => {\n if (value && !holdsLock) {\n holdsLock = true\n lockBodyScroll()\n window.addEventListener('keydown', onKeydown)\n } else if (!value && holdsLock) {\n holdsLock = false\n unlockBodyScroll()\n window.removeEventListener('keydown', onKeydown)\n }\n })\n\n // 组件卸载时(含放大态下直接切路由)务必还锁,否则整站 body 会一直锁着。\n onScopeDispose(() => {\n if (holdsLock) {\n holdsLock = false\n unlockBodyScroll()\n }\n window.removeEventListener('keydown', onKeydown)\n })\n\n return { zoomed, toggle, exit }\n}\n"],"names":["bodyLockCount","lockBodyScroll","unlockBodyScroll","useTableZoom","zoomed","ref","holdsLock","toggle","exit","onKeydown","e","watch","value","onScopeDispose"],"mappings":";AAqBA,IAAIA,IAAgB;AACpB,SAASC,IAAiB;AACxB,EAAID,MAAkB,MAAG,SAAS,KAAK,MAAM,WAAW,WACxDA;AACF;AACA,SAASE,IAAmB;AAC1B,EAAIF,MAAkB,MACtBA,KACIA,MAAkB,MAAG,SAAS,KAAK,MAAM,WAAW;AAC1D;
|
|
1
|
+
{"version":3,"file":"useTableZoom.js","sources":["../../src/composables/useTableZoom.ts"],"sourcesContent":["// 表格「放大」:把某块区域临时铺满视口,给笔记本等窄屏看宽表用。\n//\n// 刻意不用 Fullscreen API(VueUse 的 useFullscreen):Naive 的 NSelect / NPopover 把浮层 teleport 到\n// body,而原生全屏只渲染被全屏那棵子树,浮层会整个看不见 —— 带下拉、气泡的宽表必然踩中。\n// 固定定位遮罩没这个问题:浮层照旧挂在 body 上,z-index 比遮罩高就行(遮罩 50,Naive 浮层 2000+)。\n//\n// 用法:\n// const { zoomed, toggle } = useTableZoom()\n// <div :class=\"{ 'table-zoom': zoomed }\"> ...表格... </div>\n// <n-button @click=\"toggle\">放大/还原</n-button>\n// `.table-zoom` 的样式在 styles/table.css。\nimport { onScopeDispose, ref, watch } from 'vue'\n\n/**\n * body 滚动锁的引用计数。`document.body.style.overflow` 是全局单例,而一个页面上会有多个\n * useTableZoom 实例,各自无条件置/清会互相踩:先退出的那个会在另一个遮罩仍铺满时\n * 把背景滚动放开,正是这把锁要防的现象。\n *\n * 当前 UI 下同时只可能有一个放大态(遮罩不透明且铺满视口,挡住了其它放大按钮),\n * 所以这个计数眼下是防御性的 —— 但别让后来者依赖那个巧合:一旦出现并排/画中画放大就会踩中。\n */\nlet bodyLockCount = 0\nfunction lockBodyScroll() {\n if (bodyLockCount === 0) document.body.style.overflow = 'hidden'\n bodyLockCount++\n}\nfunction unlockBodyScroll() {\n if (bodyLockCount === 0) return\n bodyLockCount--\n if (bodyLockCount === 0) document.body.style.overflow = ''\n}\n\n/**\n * @deprecated smart-naive-table 3.0 起 SmartTable 自带放大按钮:`:toolbar=\"{ maximize: true }\"`\n * (Teleport 到 body、盖住侧栏与顶栏、不调用浏览器全屏 API,与本实现是同一思路)。\n * 本 composable 与 TableZoomButton 没有内核页面在用,仅为已依赖它们的下游应用保留,下一个 .NET 大版本删除。\n */\nexport function useTableZoom() {\n const zoomed = ref(false)\n /** 本实例是否持有 body 锁:避免重复加锁/重复解锁把计数带偏 */\n let holdsLock = false\n\n function toggle() {\n zoomed.value = !zoomed.value\n }\n function exit() {\n zoomed.value = false\n }\n\n function onKeydown(e: KeyboardEvent) {\n // 只在放大态拦 Esc;Naive 的下拉/气泡自己也吃 Esc,已经打开时先关浮层再关放大,交给冒泡顺序即可。\n if (e.key === 'Escape') exit()\n }\n\n // 放大时锁掉 body 滚动:遮罩是 fixed,底下的页面还能滚会让滚轮行为很怪。\n watch(zoomed, value => {\n if (value && !holdsLock) {\n holdsLock = true\n lockBodyScroll()\n window.addEventListener('keydown', onKeydown)\n } else if (!value && holdsLock) {\n holdsLock = false\n unlockBodyScroll()\n window.removeEventListener('keydown', onKeydown)\n }\n })\n\n // 组件卸载时(含放大态下直接切路由)务必还锁,否则整站 body 会一直锁着。\n onScopeDispose(() => {\n if (holdsLock) {\n holdsLock = false\n unlockBodyScroll()\n }\n window.removeEventListener('keydown', onKeydown)\n })\n\n return { zoomed, toggle, exit }\n}\n"],"names":["bodyLockCount","lockBodyScroll","unlockBodyScroll","useTableZoom","zoomed","ref","holdsLock","toggle","exit","onKeydown","e","watch","value","onScopeDispose"],"mappings":";AAqBA,IAAIA,IAAgB;AACpB,SAASC,IAAiB;AACxB,EAAID,MAAkB,MAAG,SAAS,KAAK,MAAM,WAAW,WACxDA;AACF;AACA,SAASE,IAAmB;AAC1B,EAAIF,MAAkB,MACtBA,KACIA,MAAkB,MAAG,SAAS,KAAK,MAAM,WAAW;AAC1D;AAOO,SAASG,IAAe;AAC7B,QAAMC,IAASC,EAAI,EAAK;AAExB,MAAIC,IAAY;AAEhB,WAASC,IAAS;AAChB,IAAAH,EAAO,QAAQ,CAACA,EAAO;AAAA,EACzB;AACA,WAASI,IAAO;AACd,IAAAJ,EAAO,QAAQ;AAAA,EACjB;AAEA,WAASK,EAAUC,GAAkB;AAEnC,IAAIA,EAAE,QAAQ,YAAUF,EAAA;AAAA,EAC1B;AAGA,SAAAG,EAAMP,GAAQ,CAAAQ,MAAS;AACrB,IAAIA,KAAS,CAACN,KACZA,IAAY,IACZL,EAAA,GACA,OAAO,iBAAiB,WAAWQ,CAAS,KACnC,CAACG,KAASN,MACnBA,IAAY,IACZJ,EAAA,GACA,OAAO,oBAAoB,WAAWO,CAAS;AAAA,EAEnD,CAAC,GAGDI,EAAe,MAAM;AACnB,IAAIP,MACFA,IAAY,IACZJ,EAAA,IAEF,OAAO,oBAAoB,WAAWO,CAAS;AAAA,EACjD,CAAC,GAEM,EAAE,QAAAL,GAAQ,QAAAG,GAAQ,MAAAC,EAAA;AAC3B;"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Ref } from 'vue';
|
|
2
2
|
import { GlobalTheme, GlobalThemeOverrides } from 'naive-ui';
|
|
3
3
|
/**
|
|
4
|
-
* 主题落地:随 app.isDark / app.accent / app.density
|
|
4
|
+
* 主题落地:随 app.isDark / app.accent / app.density 变化,
|
|
5
5
|
* 1) 打 data-theme / data-density 到 <html>(裸 CSS 与 tokens 跟着翻);
|
|
6
|
-
* 2) 把 accent
|
|
6
|
+
* 2) 把 accent 派生的强调色令牌(--accent / --acc-solid / --sel-* 等,见 theme/accentTokens.ts)写到 <html>(令消费 tokens 的裸 CSS 换色);
|
|
7
7
|
* 3) 重建 Naive themeOverrides(新对象触发 n-config-provider 重渲染)。
|
|
8
8
|
* 返回类型显式写出:推断出的 Naive 主题类型展开后超出 d.ts 序列化上限,包的类型声明会不完整。
|
|
9
9
|
*/
|
|
@@ -1,30 +1,33 @@
|
|
|
1
|
-
import { ref as
|
|
2
|
-
import { darkTheme as
|
|
3
|
-
import { useAppStore as
|
|
1
|
+
import { ref as i, watch as l, nextTick as p } from "vue";
|
|
2
|
+
import { darkTheme as f } from "naive-ui";
|
|
3
|
+
import { useAppStore as k } from "../stores/app.js";
|
|
4
4
|
import { buildThemeOverrides as y } from "../theme/naive-theme.js";
|
|
5
|
-
import {
|
|
6
|
-
function
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
import { deriveAccentTokens as h } from "../theme/accentTokens.js";
|
|
6
|
+
function D() {
|
|
7
|
+
return typeof document.startViewTransition == "function" && !window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
8
|
+
}
|
|
9
|
+
function x() {
|
|
10
|
+
const e = k(), o = i({}), a = i(null);
|
|
11
|
+
let r = null;
|
|
12
|
+
function s() {
|
|
13
|
+
const t = document.documentElement, { css: n } = h(e.accent, e.isDark);
|
|
14
|
+
for (const [u, d] of Object.entries(n)) t.style.setProperty(u, d);
|
|
15
|
+
}
|
|
9
16
|
function c() {
|
|
10
|
-
const t = document.documentElement;
|
|
11
|
-
|
|
17
|
+
const t = e.isDark, n = document.documentElement;
|
|
18
|
+
n.setAttribute("data-theme", t ? "dark" : ""), n.setAttribute("data-density", e.density), s(), n.style.colorScheme = t ? "dark" : "light", a.value = e.isDark ? f : null, o.value = y({ dark: e.isDark, accent: e.accent });
|
|
12
19
|
}
|
|
13
20
|
function m() {
|
|
14
|
-
const t =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const t = e.isDark;
|
|
19
|
-
c();
|
|
20
|
-
const r = document.documentElement;
|
|
21
|
-
r.setAttribute("data-theme", t ? "dark" : ""), r.setAttribute("data-density", e.density), r.toggleAttribute("data-gray", e.grayscale), m(), a.value = e.isDark ? u : null, n.value = y({ dark: e.isDark, accent: e.accent });
|
|
21
|
+
const t = r !== null && r !== e.isDark;
|
|
22
|
+
r = e.isDark, t && D() ? document.startViewTransition(async () => {
|
|
23
|
+
c(), await p();
|
|
24
|
+
}) : c();
|
|
22
25
|
}
|
|
23
|
-
return
|
|
26
|
+
return l([() => e.isDark, () => e.accent, () => e.density], m, {
|
|
24
27
|
immediate: !0
|
|
25
|
-
}), { overrides:
|
|
28
|
+
}), { overrides: o, naiveTheme: a };
|
|
26
29
|
}
|
|
27
30
|
export {
|
|
28
|
-
|
|
31
|
+
x as useTheme
|
|
29
32
|
};
|
|
30
33
|
//# sourceMappingURL=useTheme.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTheme.js","sources":["../../src/composables/useTheme.ts"],"sourcesContent":["import { ref, watch, type Ref } from 'vue'\nimport { darkTheme, type GlobalTheme, type GlobalThemeOverrides } from 'naive-ui'\nimport { useAppStore } from '#/stores/app'\nimport { buildThemeOverrides } from '#/theme/naive-theme'\nimport {
|
|
1
|
+
{"version":3,"file":"useTheme.js","sources":["../../src/composables/useTheme.ts"],"sourcesContent":["import { nextTick, ref, watch, type Ref } from 'vue'\nimport { darkTheme, type GlobalTheme, type GlobalThemeOverrides } from 'naive-ui'\nimport { useAppStore } from '#/stores/app'\nimport { buildThemeOverrides } from '#/theme/naive-theme'\nimport { deriveAccentTokens } from '#/theme/accentTokens'\n\n// 浏览器支持 View Transitions 且系统没开「减少动态效果」才做交叉淡入\nfunction canCrossFade(): boolean {\n return (\n typeof document.startViewTransition === 'function' &&\n !window.matchMedia('(prefers-reduced-motion: reduce)').matches\n )\n}\n\n/**\n * 主题落地:随 app.isDark / app.accent / app.density 变化,\n * 1) 打 data-theme / data-density 到 <html>(裸 CSS 与 tokens 跟着翻);\n * 2) 把 accent 派生的强调色令牌(--accent / --acc-solid / --sel-* 等,见 theme/accentTokens.ts)写到 <html>(令消费 tokens 的裸 CSS 换色);\n * 3) 重建 Naive themeOverrides(新对象触发 n-config-provider 重渲染)。\n * 返回类型显式写出:推断出的 Naive 主题类型展开后超出 d.ts 序列化上限,包的类型声明会不完整。\n */\nexport function useTheme(): {\n overrides: Ref<GlobalThemeOverrides>\n naiveTheme: Ref<GlobalTheme | null>\n} {\n const app = useAppStore()\n const overrides = ref<GlobalThemeOverrides>({}) as Ref<GlobalThemeOverrides>\n const naiveTheme = ref<GlobalTheme | null>(null) as Ref<GlobalTheme | null>\n\n // 明暗切换的过渡:像 macOS 那样把整屏旧画面与新画面做一次交叉淡入(View Transitions 的快照)。\n // 不给每个元素单独挂颜色过渡——Naive 输入框由边框层 / 状态边框层 / 阴影叠成,各层半透明边框色\n // 各自在中间色上插值,暗→亮时会闪出一圈忽明忽暗的线;快照淡入没有逐元素的中间态。\n // 浏览器不支持、或系统开了「减少动态效果」时直接瞬切。\n let lastDark: boolean | null = null\n\n // 强调色令牌(--accent / --signal / --acc-solid / --sel-* / --tab-* / --ambient-* / --desk-* 等):\n // 写到 <html> 的 style 上,令消费 tokens 的裸 CSS 换色。兼容别名 --color-primary* 在 tokens.css 里引用它们,不用单独写。\n function applyAccentVars() {\n const el = document.documentElement\n const { css } = deriveAccentTokens(app.accent, app.isDark)\n for (const [name, value] of Object.entries(css)) el.style.setProperty(name, value)\n }\n\n function applyNow() {\n const nextDark = app.isDark\n const el = document.documentElement\n el.setAttribute('data-theme', nextDark ? 'dark' : '')\n el.setAttribute('data-density', app.density)\n applyAccentVars()\n el.style.colorScheme = nextDark ? 'dark' : 'light' // 原生滚动条 / 表单控件跟着翻\n naiveTheme.value = app.isDark ? darkTheme : null\n overrides.value = buildThemeOverrides({ dark: app.isDark, accent: app.accent })\n }\n\n function apply() {\n // 只有明暗翻面才做交叉淡入;首次落地、换强调色、换密度都瞬切\n const flipped = lastDark !== null && lastDark !== app.isDark\n lastDark = app.isDark\n if (flipped && canCrossFade()) {\n // 回调里改 DOM,并等 Vue 把 Naive 的新主题渲染完再返回,新快照才是完整的新画面\n document.startViewTransition(async () => {\n applyNow()\n await nextTick()\n })\n } else {\n applyNow()\n }\n }\n\n watch([() => app.isDark, () => app.accent, () => app.density], apply, {\n immediate: true,\n })\n\n return { overrides, naiveTheme }\n}\n"],"names":["canCrossFade","useTheme","app","useAppStore","overrides","ref","naiveTheme","lastDark","applyAccentVars","el","css","deriveAccentTokens","name","value","applyNow","nextDark","darkTheme","buildThemeOverrides","apply","flipped","nextTick","watch"],"mappings":";;;;;AAOA,SAASA,IAAwB;AAC/B,SACE,OAAO,SAAS,uBAAwB,cACxC,CAAC,OAAO,WAAW,kCAAkC,EAAE;AAE3D;AASO,SAASC,IAGd;AACA,QAAMC,IAAMC,EAAA,GACNC,IAAYC,EAA0B,EAAE,GACxCC,IAAaD,EAAwB,IAAI;AAM/C,MAAIE,IAA2B;AAI/B,WAASC,IAAkB;AACzB,UAAMC,IAAK,SAAS,iBACd,EAAE,KAAAC,EAAA,IAAQC,EAAmBT,EAAI,QAAQA,EAAI,MAAM;AACzD,eAAW,CAACU,GAAMC,CAAK,KAAK,OAAO,QAAQH,CAAG,EAAG,CAAAD,EAAG,MAAM,YAAYG,GAAMC,CAAK;AAAA,EACnF;AAEA,WAASC,IAAW;AAClB,UAAMC,IAAWb,EAAI,QACfO,IAAK,SAAS;AACpB,IAAAA,EAAG,aAAa,cAAcM,IAAW,SAAS,EAAE,GACpDN,EAAG,aAAa,gBAAgBP,EAAI,OAAO,GAC3CM,EAAA,GACAC,EAAG,MAAM,cAAcM,IAAW,SAAS,SAC3CT,EAAW,QAAQJ,EAAI,SAASc,IAAY,MAC5CZ,EAAU,QAAQa,EAAoB,EAAE,MAAMf,EAAI,QAAQ,QAAQA,EAAI,QAAQ;AAAA,EAChF;AAEA,WAASgB,IAAQ;AAEf,UAAMC,IAAUZ,MAAa,QAAQA,MAAaL,EAAI;AACtD,IAAAK,IAAWL,EAAI,QACXiB,KAAWnB,MAEb,SAAS,oBAAoB,YAAY;AACvC,MAAAc,EAAA,GACA,MAAMM,EAAA;AAAA,IACR,CAAC,IAEDN,EAAA;AAAA,EAEJ;AAEA,SAAAO,EAAM,CAAC,MAAMnB,EAAI,QAAQ,MAAMA,EAAI,QAAQ,MAAMA,EAAI,OAAO,GAAGgB,GAAO;AAAA,IACpE,WAAW;AAAA,EAAA,CACZ,GAEM,EAAE,WAAAd,GAAW,YAAAE,EAAA;AACtB;"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { App } from 'vue';
|
|
2
2
|
import { Pinia } from 'pinia';
|
|
3
3
|
import { RouteRecordRaw } from 'vue-router';
|
|
4
|
+
import { FilterSerializer } from 'smart-naive-table';
|
|
4
5
|
import { IconifyJSON } from 'smart-naive-icon';
|
|
5
6
|
import { router } from './router';
|
|
6
7
|
import { i18n, ExtModule } from './locales';
|
|
@@ -17,7 +18,7 @@ export interface SmartAdminPlugin {
|
|
|
17
18
|
locales?: Record<string, ExtModule>;
|
|
18
19
|
/** 布局壳之外的顶级静态路由(整屏看板、独立打印页等)。 */
|
|
19
20
|
routes?: RouteRecordRaw[];
|
|
20
|
-
/**
|
|
21
|
+
/** 菜单标题 → i18n key(存量库菜单标题是中文时用):键以 / 开头按路由 path 登记,其余按标题原文登记。内核种子标题已自带。 */
|
|
21
22
|
menuTitles?: Record<string, string>;
|
|
22
23
|
/** 本地 SVG 图标:`import.meta.glob('./assets/svg/*.svg', { query: '?raw', import: 'default', eager: true })`。 */
|
|
23
24
|
icons?: Record<string, string>;
|
|
@@ -37,10 +38,19 @@ export interface SmartAdminOptions extends SmartAdminPlugin {
|
|
|
37
38
|
dev?: boolean;
|
|
38
39
|
/** 品牌默认值:sys.site.* 配置有值时以配置为准,为空时用这里。 */
|
|
39
40
|
brand?: BrandOptions;
|
|
40
|
-
/**
|
|
41
|
+
/**
|
|
42
|
+
* SmartTable 全局默认。
|
|
43
|
+
* `filterSerializer`:条件构造器 / 表头过滤的过滤态 → 请求参数。内核默认用 `flatFilterSerializer`
|
|
44
|
+
* (只翻后端真正支持的那一小撮条件,摊平成扁平参数,见 utils/tableFilter.ts)。
|
|
45
|
+
* 应用的后端已经实现了 3.0 默认的 `filters` 协议(`[{ field, logic, conditions }]`)时,传 `defaultFilterSerializer`
|
|
46
|
+
* (从 smart-naive-table 导入)即可保持原样;自定义形状就传自己的函数。
|
|
47
|
+
*/
|
|
41
48
|
table?: {
|
|
42
49
|
density?: 'comfortable' | 'compact';
|
|
43
50
|
pageSizes?: number[];
|
|
51
|
+
filterSerializer?: FilterSerializer;
|
|
52
|
+
/** 所有数据列默认可拖拽列宽。内核默认 true;设 false 全局关掉,单列用列上的 `resizable` 覆盖。 */
|
|
53
|
+
resizable?: boolean;
|
|
44
54
|
};
|
|
45
55
|
}
|
|
46
56
|
export interface SmartAdminApp {
|