smart-admin-web 10.15.0 → 10.20.1
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 +19 -18
- 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 +407 -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":"biz2.vue.js","sources":["../../../src/views/dashboard/biz.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 业务系统的工作台。每个应用一个首页组件——这里和 dashboard/workbench.vue 是两个独立页面,\n// 由各自应用的「工作台」菜单(component 字段)指向,切应用即换首页。\n// 全部真数据拼装:欢迎横幅(user store + sessions + last-login)+ 待办事项(工作台待办扩展点,\n// 内核默认空)+ 快捷方式(手动置顶 + 高频自动补位)+ 我的通知(notice/mine)。\n// 应用要换成自己的业务统计,在自己的 views/ 下放同 key(dashboard/biz)的页面覆盖本页;别造写死的假数字。\nimport { computed, onMounted, onUnmounted, ref } from 'vue'\nimport { NCard, NButton, NList, NListItem, NEmpty, NTag } from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport { useI18n } from 'vue-i18n'\nimport { useRoute, useRouter } from 'vue-router'\nimport { useUserStore } from '#/stores/user'\nimport { useAppStore } from '#/stores/app'\nimport { btnGrad } from '#/theme/mix'\nimport { noticeApi, personalApi } from '#/api'\nimport type {\n NoticeMineItem,\n LastLoginInfo,\n WorkbenchTodoSummary,\n UserShortcutItem,\n} from '#/types/api'\nimport { useMenuFlat } from '#/composables/useMenuFlat'\nimport { translateMenuTitle } from '#/locales/menuTitle'\nimport { onlineDurationParts } from './onlineDuration'\nimport { buildShortcutGroups } from './shortcutGroups'\nimport ShortcutPicker from './ShortcutPicker.vue'\nimport AppIcon from '#/components/AppIcon.vue'\nimport { fmtDateTime } from '#/utils/format'\nimport { uaSummary } from '#/utils/ua'\n\nconst { t } = useI18n()\nconst user = useUserStore()\nconst app = useAppStore()\nconst route = useRoute()\nconst router = useRouter()\nconst leaves = useMenuFlat()\n\nconst avatarStyle = computed(() => ({ background: btnGrad(app.accent) }))\n\n// ── 在线时长 + 上次登录 ─────────────────────────────────────\nconst currentLoginTime = ref<string | null>(null)\nconst lastLogin = ref<LastLoginInfo | null>(null)\nconst now = ref(new Date())\nlet tickTimer: ReturnType<typeof setInterval> | undefined\n\nconst onlineText = computed(() => {\n if (!currentLoginTime.value) return ''\n const { hours, minutes } = onlineDurationParts(currentLoginTime.value, now.value)\n return hours > 0\n ? t('biz.onlineDuration', { hours, minutes })\n : t('biz.onlineDurationShort', { minutes })\n})\nconst lastLoginText = computed(() => {\n if (!lastLogin.value) return t('biz.firstLogin')\n const device = uaSummary(lastLogin.value.userAgent)\n const ip = lastLogin.value.ip ? ` · ${lastLogin.value.ip}` : ''\n const base = t('biz.lastLogin', { time: fmtDateTime(lastLogin.value.time, { seconds: false }) })\n return `${base}${ip}${device ? ` · ${device}` : ''}`\n})\n\n// ── 待办事项:内核默认空,消费方接入真实审批/工单系统后有内容 ──────────\nconst todo = ref<WorkbenchTodoSummary | null>(null)\n\n// ── 快捷方式 ─────────────────────────────────────────────\nconst shortcuts = ref<UserShortcutItem[]>([])\nconst pickerShow = ref(false)\n// 排除本页自身:工作台自己也是菜单树里的一条,不该出现在\"去哪儿\"的快捷方式里\nconst groups = computed(() =>\n buildShortcutGroups(\n shortcuts.value.filter(s => s.menuPath !== route.path),\n leaves.value,\n ),\n)\nconst pinnedPaths = computed(() => shortcuts.value.filter(s => s.pinned).map(s => s.menuPath))\n\nasync function loadShortcuts() {\n try {\n shortcuts.value = await personalApi.shortcuts()\n } catch {\n shortcuts.value = []\n }\n}\nasync function pin(path: string) {\n await personalApi.pinShortcut(path)\n await loadShortcuts()\n}\nasync function unpin(path: string) {\n await personalApi.unpinShortcut(path)\n await loadShortcuts()\n}\n\n// ── 通知 ────────────────────────────────────────────────\nconst notices = ref<NoticeMineItem[]>([])\n\nonMounted(async () => {\n tickTimer = setInterval(() => {\n now.value = new Date()\n }, 60_000)\n\n try {\n const sessions = await personalApi.sessions()\n currentLoginTime.value = sessions.find(s => s.isCurrent)?.loginTime ?? null\n } catch {\n // 在线时长拿不到就不显示这一段,不影响页面其余部分\n }\n try {\n lastLogin.value = await personalApi.lastLogin()\n } catch {\n lastLogin.value = null\n }\n try {\n todo.value = await personalApi.workbenchTodo()\n } catch {\n todo.value = null\n }\n await loadShortcuts()\n try {\n notices.value = (await noticeApi.mine({ page: 1, pageSize: 5 })).items\n } catch {\n // 首页不因一张卡挂了糊用户一脸红:通知取不到就空态,其余照常可用。\n }\n})\nonUnmounted(() => {\n if (tickTimer) clearInterval(tickTimer)\n})\n</script>\n\n<template>\n <div class=\"view\">\n <!-- 欢迎横幅:身份 + 在线状态,一行说完 -->\n <div class=\"banner\">\n <div class=\"avatar\" :style=\"avatarStyle\">\n <Icon icon=\"ph:user\" :width=\"26\" color=\"#fff\" />\n </div>\n <div class=\"banner-body\">\n <div class=\"hi\">\n {{ t('biz.welcome', { name: user.userInfo?.name ?? user.userInfo?.account ?? '' }) }}\n </div>\n <div class=\"tip\">{{ t('biz.subtitle') }}</div>\n <div v-if=\"onlineText || lastLoginText\" class=\"meta-row\">\n <span v-if=\"onlineText\">{{ onlineText }}</span>\n <span v-if=\"onlineText && lastLoginText\" class=\"meta-dot\" />\n <span>{{ lastLoginText }}</span>\n </div>\n </div>\n </div>\n\n <div class=\"row\">\n <!-- 待办事项:内核默认空,消费方接入真实审批/工单系统后有内容 -->\n <n-card :title=\"t('biz.todo')\" :bordered=\"true\">\n <template v-if=\"todo && todo.totalCount > 0\" #header-extra>\n <n-tag type=\"error\" round size=\"small\">{{ todo.totalCount }}</n-tag>\n </template>\n <div v-if=\"todo && todo.items.length\" class=\"todo-list\">\n <div\n v-for=\"i in todo.items\"\n :key=\"i.id\"\n class=\"todo-row\"\n @click=\"i.url && router.push(i.url)\"\n >\n <div class=\"todo-main\">\n <div class=\"todo-title\">{{ i.title }}</div>\n <div v-if=\"i.description\" class=\"todo-sub\">{{ i.description }}</div>\n </div>\n <span class=\"todo-time\">{{ fmtDateTime(i.createTime, { seconds: false }) }}</span>\n </div>\n </div>\n <n-empty v-else :description=\"t('biz.todoEmpty')\" />\n </n-card>\n\n <!-- 快捷方式:实心星=手动置顶(可移除),虚线框+空心星=高频访问自动推荐(点固定即置顶) -->\n <n-card :title=\"t('biz.quick')\" :bordered=\"true\">\n <template #header-extra>\n <n-button size=\"small\" quaternary circle @click=\"pickerShow = true\">\n <template #icon><Icon icon=\"ph:plus\" :width=\"16\" /></template>\n </n-button>\n </template>\n <div v-if=\"groups.pinned.length || groups.suggested.length\">\n <div v-if=\"groups.pinned.length\" class=\"quick-group-label\">\n {{ t('biz.quickPinned') }}\n </div>\n <div v-if=\"groups.pinned.length\" class=\"quick-grid\">\n <div v-for=\"s in groups.pinned\" :key=\"s.path\" class=\"quick-item\">\n <button\n class=\"quick-star active\"\n type=\"button\"\n :aria-label=\"t('biz.quickUnpin')\"\n @click.stop=\"unpin(s.path)\"\n >\n <Icon icon=\"ph:star-fill\" :width=\"12\" />\n </button>\n <div class=\"quick-body\" @click=\"router.push(s.path)\">\n <AppIcon :icon=\"s.icon\" :size=\"17\" />\n <span class=\"quick-name\">{{ translateMenuTitle(s.title) }}</span>\n </div>\n </div>\n </div>\n <div v-if=\"groups.suggested.length\" class=\"quick-group-label\">\n {{ t('biz.quickSuggested') }}\n </div>\n <div v-if=\"groups.suggested.length\" class=\"quick-grid\">\n <div v-for=\"s in groups.suggested\" :key=\"s.path\" class=\"quick-item suggested\">\n <button\n class=\"quick-star\"\n type=\"button\"\n :aria-label=\"t('biz.quickPin')\"\n @click.stop=\"pin(s.path)\"\n >\n <Icon icon=\"ph:star\" :width=\"12\" />\n </button>\n <div class=\"quick-body\" @click=\"router.push(s.path)\">\n <AppIcon :icon=\"s.icon\" :size=\"17\" />\n <span class=\"quick-name\">{{ translateMenuTitle(s.title) }}</span>\n </div>\n </div>\n </div>\n </div>\n <n-empty v-else :description=\"t('biz.noMenus')\" />\n </n-card>\n </div>\n\n <!-- 通知:没有\"查看全部\"——卡片本身就是完整内容 -->\n <n-card :title=\"t('biz.notices')\" :bordered=\"true\">\n <n-list v-if=\"notices.length\" :show-divider=\"false\">\n <n-list-item v-for=\"n in notices\" :key=\"n.id\">\n <div class=\"notice-row\" @click=\"router.push('/personal/notice')\">\n <span class=\"notice-title\">\n <span v-if=\"!n.isRead\" class=\"dot\" />\n {{ n.title }}\n </span>\n <span class=\"notice-time\">{{ fmtDateTime(n.publishTime, { seconds: false }) }}</span>\n </div>\n </n-list-item>\n </n-list>\n <n-empty v-else :description=\"t('biz.noticesEmpty')\" />\n </n-card>\n\n <ShortcutPicker\n v-model:show=\"pickerShow\"\n :exclude-paths=\"[...pinnedPaths, route.path]\"\n @pick=\"pin\"\n />\n </div>\n</template>\n\n<style scoped>\n.view {\n display: flex;\n flex-direction: column;\n gap: var(--gap-card);\n}\n.banner {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 24px;\n border-radius: var(--radius-lg);\n background: var(--color-primary-light);\n}\n.avatar {\n flex-shrink: 0;\n width: 52px;\n height: 52px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.banner-body {\n min-width: 0;\n}\n.hi {\n font-size: var(--font-size-lg);\n font-weight: 600;\n color: var(--color-text-primary);\n}\n.tip {\n color: var(--color-text-secondary);\n margin-top: 4px;\n}\n.meta-row {\n margin-top: 8px;\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 13px;\n color: var(--color-text-tertiary);\n font-variant-numeric: tabular-nums;\n}\n.meta-dot {\n width: 3px;\n height: 3px;\n border-radius: 50%;\n background: var(--color-text-disabled);\n flex-shrink: 0;\n}\n.row {\n display: grid;\n grid-template-columns: 1.35fr 1fr;\n gap: var(--gap-card);\n align-items: start;\n}\n@media (max-width: 760px) {\n .row {\n grid-template-columns: 1fr;\n }\n}\n.todo-list {\n display: flex;\n flex-direction: column;\n}\n.todo-row {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 12px;\n padding: 10px 0;\n border-bottom: 1px solid var(--color-border);\n cursor: pointer;\n}\n.todo-row:last-child {\n border-bottom: none;\n}\n.todo-title {\n color: var(--color-text-primary);\n font-weight: 500;\n}\n.todo-sub {\n margin-top: 2px;\n font-size: 12px;\n color: var(--color-text-tertiary);\n}\n.todo-time {\n flex-shrink: 0;\n font-size: 12px;\n color: var(--color-text-tertiary);\n}\n.quick-group-label {\n font-size: 12px;\n color: var(--color-text-tertiary);\n margin: 4px 0 8px;\n}\n.quick-grid {\n display: flex;\n flex-wrap: wrap;\n gap: 10px;\n margin-bottom: 4px;\n}\n.quick-item {\n position: relative;\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n.quick-item.suggested {\n border-style: dashed;\n}\n.quick-body {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 14px 8px 10px;\n cursor: pointer;\n}\n.quick-name {\n font-size: 13px;\n color: var(--color-text-secondary);\n}\n.quick-star {\n position: absolute;\n top: -6px;\n right: -6px;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n border: 1px solid var(--color-border);\n background: var(--color-bg-elevated);\n color: var(--color-text-disabled);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n}\n.quick-star.active {\n color: var(--color-warning);\n}\n.notice-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n cursor: pointer;\n}\n.notice-title {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--color-text-primary);\n}\n.dot {\n flex-shrink: 0;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--color-primary);\n}\n.notice-time {\n flex-shrink: 0;\n color: var(--color-text-secondary);\n font-size: 12px;\n}\n</style>\n"],"names":["t","useI18n","user","useUserStore","app","useAppStore","route","useRoute","router","useRouter","leaves","useMenuFlat","avatarStyle","computed","btnGrad","currentLoginTime","ref","lastLogin","now","tickTimer","onlineText","hours","minutes","onlineDurationParts","lastLoginText","device","uaSummary","ip","fmtDateTime","todo","shortcuts","pickerShow","groups","buildShortcutGroups","s","pinnedPaths","loadShortcuts","personalApi","pin","path","unpin","notices","onMounted","sessions","_a","noticeApi","onUnmounted","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_createVNode","_unref","Icon","_hoisted_3","_hoisted_4","_toDisplayString","_hoisted_5","_hoisted_6","_hoisted_8","_hoisted_9","NCard","_hoisted_10","_Fragment","_renderList","i","$event","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_createBlock","NEmpty","NTag","_createTextVNode","NButton","_hoisted_16","_hoisted_17","_hoisted_18","_withModifiers","AppIcon","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_26","NList","n","NListItem","_cache","_hoisted_27","_hoisted_28","_hoisted_29","ShortcutPicker"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"biz2.vue.js","sources":["../../../src/views/dashboard/biz.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 业务系统的工作台。每个应用一个首页组件——这里和 dashboard/workbench.vue 是两个独立页面,\n// 由各自应用的「工作台」菜单(component 字段)指向,切应用即换首页。\n// 全部真数据拼装:欢迎横幅(user store + sessions + last-login)+ 待办事项(工作台待办扩展点,\n// 内核默认空)+ 快捷方式(手动置顶 + 高频自动补位)+ 我的通知(notice/mine)。\n// 应用要换成自己的业务统计,在自己的 views/ 下放同 key(dashboard/biz)的页面覆盖本页;别造写死的假数字。\nimport { computed, onMounted, onUnmounted, ref } from 'vue'\nimport { NCard, NButton, NList, NListItem, NEmpty, NTag } from 'naive-ui'\nimport { useElementSize } from '@vueuse/core'\nimport { Icon } from '@iconify/vue'\nimport { useI18n } from 'vue-i18n'\nimport { useRoute, useRouter } from 'vue-router'\nimport { useUserStore } from '#/stores/user'\nimport { noticeApi, personalApi } from '#/api'\nimport type {\n NoticeMineItem,\n LastLoginInfo,\n WorkbenchTodoSummary,\n UserShortcutItem,\n} from '#/types/api'\nimport { useMenuFlat } from '#/composables/useMenuFlat'\nimport { translateMenuTitle } from '#/locales/menuTitle'\nimport { onlineDurationParts } from './onlineDuration'\nimport { buildShortcutGroups } from './shortcutGroups'\nimport ShortcutPicker from './ShortcutPicker.vue'\nimport AppIcon from '#/components/AppIcon.vue'\nimport { fmtDateTime } from '#/utils/format'\nimport { uaSummary } from '#/utils/ua'\n\nconst { t } = useI18n()\nconst user = useUserStore()\nconst route = useRoute()\nconst router = useRouter()\nconst leaves = useMenuFlat()\n\n// 内容区宽度(不是视口):窄档元信息的小圆点隐藏、通知时间换到标题下一行\nconst viewRef = ref<HTMLElement | null>(null)\nconst { width: pw } = useElementSize(viewRef)\nconst twoCols = computed(() => pw.value === 0 || pw.value >= 760)\nconst wideRow = computed(() => pw.value === 0 || pw.value >= 600)\n\n// ── 在线时长 + 上次登录 ─────────────────────────────────────\nconst currentLoginTime = ref<string | null>(null)\nconst lastLogin = ref<LastLoginInfo | null>(null)\nconst now = ref(new Date())\nlet tickTimer: ReturnType<typeof setInterval> | undefined\n\nconst onlineText = computed(() => {\n if (!currentLoginTime.value) return ''\n const { hours, minutes } = onlineDurationParts(currentLoginTime.value, now.value)\n return hours > 0\n ? t('biz.onlineDuration', { hours, minutes })\n : t('biz.onlineDurationShort', { minutes })\n})\nconst lastLoginText = computed(() => {\n if (!lastLogin.value) return t('biz.firstLogin')\n const device = uaSummary(lastLogin.value.userAgent)\n const ip = lastLogin.value.ip ? ` · ${lastLogin.value.ip}` : ''\n const base = t('biz.lastLogin', { time: fmtDateTime(lastLogin.value.time, { seconds: false }) })\n return `${base}${ip}${device ? ` · ${device}` : ''}`\n})\n\n// ── 待办事项:内核默认空,消费方接入真实审批/工单系统后有内容 ──────────\nconst todo = ref<WorkbenchTodoSummary | null>(null)\n\n// ── 快捷方式 ─────────────────────────────────────────────\nconst shortcuts = ref<UserShortcutItem[]>([])\nconst pickerShow = ref(false)\n// 排除本页自身:工作台自己也是菜单树里的一条,不该出现在\"去哪儿\"的快捷方式里\nconst groups = computed(() =>\n buildShortcutGroups(\n shortcuts.value.filter(s => s.menuPath !== route.path),\n leaves.value,\n ),\n)\nconst pinnedPaths = computed(() => shortcuts.value.filter(s => s.pinned).map(s => s.menuPath))\n\nasync function loadShortcuts() {\n try {\n shortcuts.value = await personalApi.shortcuts()\n } catch {\n shortcuts.value = []\n }\n}\nasync function pin(path: string) {\n await personalApi.pinShortcut(path)\n await loadShortcuts()\n}\nasync function unpin(path: string) {\n await personalApi.unpinShortcut(path)\n await loadShortcuts()\n}\n\n// ── 通知 ────────────────────────────────────────────────\nconst notices = ref<NoticeMineItem[]>([])\n\nonMounted(async () => {\n tickTimer = setInterval(() => {\n now.value = new Date()\n }, 60_000)\n\n try {\n const sessions = await personalApi.sessions()\n currentLoginTime.value = sessions.find(s => s.isCurrent)?.loginTime ?? null\n } catch {\n // 在线时长拿不到就不显示这一段,不影响页面其余部分\n }\n try {\n lastLogin.value = await personalApi.lastLogin()\n } catch {\n lastLogin.value = null\n }\n try {\n todo.value = await personalApi.workbenchTodo()\n } catch {\n todo.value = null\n }\n await loadShortcuts()\n try {\n notices.value = (await noticeApi.mine({ page: 1, pageSize: 5 })).items\n } catch {\n // 首页不因一张卡挂了糊用户一脸红:通知取不到就空态,其余照常可用。\n }\n})\nonUnmounted(() => {\n if (tickTimer) clearInterval(tickTimer)\n})\n</script>\n\n<template>\n <div ref=\"viewRef\" class=\"view\">\n <!-- 欢迎横幅:身份 + 在线状态,一行说完 -->\n <n-card class=\"a-card banner-card\" :bordered=\"true\" content-style=\"padding: 18px 20px\">\n <div class=\"banner\">\n <div class=\"avatar\">\n <Icon icon=\"ph:user\" :width=\"26\" />\n </div>\n <div class=\"banner-body\">\n <div class=\"hi\">\n {{ t('biz.welcome', { name: user.userInfo?.name ?? user.userInfo?.account ?? '' }) }}\n </div>\n <div class=\"tip\">{{ t('biz.subtitle') }}</div>\n <div v-if=\"onlineText || lastLoginText\" class=\"meta-row\">\n <span v-if=\"onlineText\">{{ onlineText }}</span>\n <span\n v-if=\"onlineText && lastLoginText && wideRow\"\n class=\"meta-dot\"\n aria-hidden=\"true\"\n />\n <span>{{ lastLoginText }}</span>\n </div>\n </div>\n </div>\n </n-card>\n\n <div\n class=\"row\"\n :style=\"{\n gridTemplateColumns: twoCols ? 'minmax(0, 1.35fr) minmax(0, 1fr)' : 'minmax(0, 1fr)',\n }\"\n >\n <!-- 待办事项:内核默认空,消费方接入真实审批/工单系统后有内容 -->\n <n-card\n class=\"a-card\"\n :title=\"t('biz.todo')\"\n :bordered=\"true\"\n content-style=\"padding: 2px 8px 8px\"\n >\n <template v-if=\"todo && todo.totalCount > 0\" #header-extra>\n <n-tag type=\"error\" round size=\"small\" :bordered=\"false\">{{ todo.totalCount }}</n-tag>\n </template>\n <n-list v-if=\"todo && todo.items.length\" hoverable :show-divider=\"false\">\n <n-list-item\n v-for=\"i in todo.items\"\n :key=\"i.id\"\n class=\"list-item\"\n :style=\"{ cursor: i.url ? 'pointer' : 'default' }\"\n @click=\"i.url && router.push(i.url)\"\n >\n <div class=\"todo-row\">\n <div class=\"todo-main\">\n <div class=\"todo-title\">{{ i.title }}</div>\n <div v-if=\"i.description\" class=\"todo-sub\">{{ i.description }}</div>\n </div>\n <span class=\"todo-time\">{{ fmtDateTime(i.createTime, { seconds: false }) }}</span>\n </div>\n </n-list-item>\n </n-list>\n <n-empty v-else :description=\"t('biz.todoEmpty')\" class=\"empty\" />\n </n-card>\n\n <!-- 快捷方式:实心星 + 实线框=手动置顶(可移除),空心星 + 虚线框=高频访问自动推荐(点星即置顶) -->\n <n-card\n class=\"a-card\"\n :title=\"t('biz.quick')\"\n :bordered=\"true\"\n content-style=\"padding: 4px 16px 16px\"\n >\n <template #header-extra>\n <n-button quaternary circle :aria-label=\"t('biz.quickAdd')\" @click=\"pickerShow = true\">\n <template #icon><Icon icon=\"ph:plus\" :width=\"16\" /></template>\n </n-button>\n </template>\n <div v-if=\"groups.pinned.length || groups.suggested.length\">\n <template v-if=\"groups.pinned.length\">\n <div class=\"quick-group-label\">{{ t('biz.quickPinned') }}</div>\n <div class=\"quick-grid\">\n <div v-for=\"s in groups.pinned\" :key=\"s.path\" class=\"quick-item pinned\">\n <n-button quaternary class=\"quick-body\" @click=\"router.push(s.path)\">\n <template #icon><AppIcon :icon=\"s.icon\" :size=\"17\" /></template>\n <span class=\"quick-name\">{{ translateMenuTitle(s.title) }}</span>\n </n-button>\n <n-button\n quaternary\n circle\n class=\"quick-star\"\n :aria-label=\"t('biz.quickUnpin')\"\n @click.stop=\"unpin(s.path)\"\n >\n <template #icon>\n <Icon icon=\"ph:star-fill\" :width=\"14\" class=\"star-on\" />\n </template>\n </n-button>\n </div>\n </div>\n </template>\n <template v-if=\"groups.suggested.length\">\n <div class=\"quick-group-label\" :class=\"{ 'after-pinned': groups.pinned.length }\">\n {{ t('biz.quickSuggested') }}\n </div>\n <div class=\"quick-grid\">\n <div v-for=\"s in groups.suggested\" :key=\"s.path\" class=\"quick-item suggested\">\n <n-button quaternary class=\"quick-body\" @click=\"router.push(s.path)\">\n <template #icon><AppIcon :icon=\"s.icon\" :size=\"17\" /></template>\n <span class=\"quick-name\">{{ translateMenuTitle(s.title) }}</span>\n </n-button>\n <n-button\n quaternary\n circle\n class=\"quick-star\"\n :aria-label=\"t('biz.quickPin')\"\n @click.stop=\"pin(s.path)\"\n >\n <template #icon><Icon icon=\"ph:star\" :width=\"14\" class=\"star-off\" /></template>\n </n-button>\n </div>\n </div>\n </template>\n </div>\n <n-empty v-else :description=\"t('biz.noMenus')\" class=\"empty\" />\n </n-card>\n </div>\n\n <!-- 通知:没有\"查看全部\"——卡片本身就是完整内容;整行点击进「我的通知」 -->\n <n-card\n class=\"a-card\"\n :title=\"t('biz.notices')\"\n :bordered=\"true\"\n content-style=\"padding: 2px 8px 8px\"\n >\n <n-list v-if=\"notices.length\" hoverable clickable :show-divider=\"false\">\n <n-list-item\n v-for=\"n in notices\"\n :key=\"n.id\"\n class=\"list-item\"\n @click=\"router.push('/personal/notice')\"\n >\n <!-- 用 grid 而不是 flex:标题单行省略要靠 minmax(0, 1fr) 才收得住;窄屏时间换到标题下一行。\n 已读的圆点位置留空占位,标题与未读对齐 -->\n <div class=\"notice-row\" :class=\"{ stacked: !wideRow }\">\n <span class=\"dot\" :class=\"{ unread: !n.isRead }\" />\n <span class=\"notice-title\" :class=\"{ unread: !n.isRead }\" :title=\"n.title\">\n {{ n.title }}\n </span>\n <span class=\"notice-time\">{{ fmtDateTime(n.publishTime, { seconds: false }) }}</span>\n </div>\n </n-list-item>\n </n-list>\n <n-empty v-else :description=\"t('biz.noticesEmpty')\" class=\"empty\" />\n </n-card>\n\n <ShortcutPicker\n v-model:show=\"pickerShow\"\n :exclude-paths=\"[...pinnedPaths, route.path]\"\n @pick=\"pin\"\n />\n </div>\n</template>\n\n<style scoped>\n.view {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n gap: var(--gap-card);\n align-content: start;\n}\n/* 横幅卡底色取选中态令牌(主色 6% / 暗色 14%),与管理工作台同一套 */\n.banner-card {\n background-image: linear-gradient(var(--sel-bg), var(--sel-bg));\n}\n.banner {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n.avatar {\n flex: none;\n width: 52px;\n height: 52px;\n border-radius: 50%;\n display: grid;\n place-items: center;\n color: var(--on-acc);\n background-image: linear-gradient(135deg, var(--signal), var(--login-accent-2));\n box-shadow: 0 8px 20px -8px var(--signal-glow);\n}\n.banner-body {\n min-width: 0;\n flex: 1;\n}\n.hi {\n font-size: 18px;\n font-weight: 600;\n letter-spacing: -0.02em;\n color: var(--text-1);\n}\n.tip {\n margin-top: 2px;\n font-size: 14px;\n color: var(--text-2);\n}\n.meta-row {\n margin-top: 8px;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 2px 8px;\n font-size: 13px;\n color: var(--text-3);\n font-variant-numeric: tabular-nums;\n}\n.meta-dot {\n width: 3px;\n height: 3px;\n border-radius: 50%;\n background: currentColor;\n opacity: 0.7;\n flex-shrink: 0;\n}\n.row {\n display: grid;\n align-items: start;\n gap: var(--gap-card);\n}\n/* 列表行:圆角 10px,悬停底色由 NList 自带 */\n.list-item {\n border-radius: var(--radius-md);\n padding: 8px 10px;\n}\n.empty {\n padding: 26px 0;\n}\n.todo-row {\n display: flex;\n flex-wrap: wrap;\n justify-content: space-between;\n align-items: flex-start;\n gap: 2px 16px;\n}\n.todo-main {\n flex: 1 1 220px;\n min-width: 0;\n}\n.todo-title {\n font-weight: 500;\n color: var(--text-1);\n}\n.todo-sub {\n margin-top: 2px;\n font-size: 13px;\n color: var(--text-3);\n}\n.todo-time {\n font-size: 13px;\n white-space: nowrap;\n color: var(--text-3);\n font-variant-numeric: tabular-nums;\n}\n.quick-group-label {\n margin: 0 0 8px;\n font-size: 13px;\n color: var(--text-3);\n}\n.quick-group-label.after-pinned {\n margin-top: 16px;\n}\n.quick-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));\n gap: 10px;\n}\n.quick-item {\n display: flex;\n align-items: center;\n min-width: 0;\n border-radius: var(--radius-md);\n}\n.quick-item.pinned {\n border: 1px solid var(--hairline-strong);\n background: var(--fill);\n}\n.quick-item.suggested {\n border: 1px dashed var(--hairline-strong);\n}\n.quick-body {\n flex: 1 1 auto;\n min-width: 0;\n height: 40px;\n justify-content: flex-start;\n}\n.quick-name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.quick-star {\n flex: none;\n margin-right: 3px;\n}\n.star-on {\n color: var(--warn);\n}\n.star-off {\n color: var(--text-3);\n}\n.notice-row {\n display: grid;\n grid-template-columns: 6px minmax(0, 1fr) auto;\n align-items: center;\n column-gap: 10px;\n row-gap: 2px;\n overflow: hidden;\n}\n.notice-row.stacked {\n grid-template-columns: 6px minmax(0, 1fr);\n}\n.notice-row.stacked .notice-time {\n grid-column: 2;\n}\n.dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: transparent;\n}\n.dot.unread {\n background: var(--signal);\n}\n.notice-title {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--text-1);\n}\n.notice-title.unread {\n font-weight: 500;\n}\n.notice-time {\n font-size: 13px;\n white-space: nowrap;\n color: var(--text-3);\n font-variant-numeric: tabular-nums;\n}\n</style>\n"],"names":["t","useI18n","user","useUserStore","route","useRoute","router","useRouter","leaves","useMenuFlat","viewRef","ref","pw","useElementSize","twoCols","computed","wideRow","currentLoginTime","lastLogin","now","tickTimer","onlineText","hours","minutes","onlineDurationParts","lastLoginText","device","uaSummary","ip","fmtDateTime","todo","shortcuts","pickerShow","groups","buildShortcutGroups","pinnedPaths","loadShortcuts","personalApi","pin","path","unpin","notices","onMounted","sessions","_a","s","noticeApi","onUnmounted","_createElementBlock","_createVNode","_unref","NCard","_createElementVNode","_hoisted_1","_hoisted_2","Icon","_hoisted_3","_hoisted_4","_toDisplayString","_hoisted_5","_openBlock","_hoisted_6","_hoisted_8","_normalizeStyle","_createBlock","NList","_Fragment","_renderList","i","NListItem","$event","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","NEmpty","NTag","_createTextVNode","NButton","_hoisted_14","_hoisted_15","_hoisted_16","AppIcon","_hoisted_17","_withModifiers","_hoisted_18","_hoisted_19","n","_cache","_normalizeClass","_hoisted_20","_hoisted_21","ShortcutPicker"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import o from "./workbench2.vue.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import r from "../../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
-
const
|
|
4
|
+
const m = /* @__PURE__ */ r(o, [["__scopeId", "data-v-4b676ea4"]]);
|
|
5
5
|
export {
|
|
6
|
-
|
|
6
|
+
m as default
|
|
7
7
|
};
|
|
8
8
|
//# sourceMappingURL=workbench.vue.js.map
|
|
@@ -1,195 +1,181 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
import {
|
|
1
|
+
import { defineComponent as D, ref as _, onMounted as E, computed as i, openBlock as n, createElementBlock as y, createVNode as u, unref as t, withCtx as p, createElementVNode as o, toDisplayString as h, normalizeStyle as k, Fragment as I, renderList as L, createBlock as c } from "vue";
|
|
2
|
+
import { NCard as f, NSkeleton as b } from "naive-ui";
|
|
3
|
+
import { useElementSize as z } from "@vueuse/core";
|
|
3
4
|
import { Icon as x } from "@iconify/vue";
|
|
4
|
-
import { useI18n as
|
|
5
|
+
import { useI18n as R } from "vue-i18n";
|
|
5
6
|
import { useUserStore as U } from "../../stores/user.js";
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
import j from "../../components/Chart/PieChart.vue.js";
|
|
11
|
-
const q = { class: "view" }, H = { class: "banner" }, J = { class: "hi" }, K = { class: "tip" }, O = { class: "stat" }, P = { class: "stat-body" }, Q = {
|
|
7
|
+
import { dashboardApi as V } from "../../api/index.js";
|
|
8
|
+
import F from "../../components/Chart/LineChart.vue.js";
|
|
9
|
+
import M from "../../components/Chart/PieChart.vue.js";
|
|
10
|
+
const j = { class: "banner" }, q = { class: "avatar" }, G = { class: "banner-body" }, H = { class: "hi" }, J = { class: "tip" }, K = { class: "stat-body" }, O = {
|
|
12
11
|
key: 1,
|
|
13
12
|
class: "stat-val tabular"
|
|
14
|
-
},
|
|
13
|
+
}, P = { class: "stat-label" }, oe = /* @__PURE__ */ D({
|
|
15
14
|
__name: "workbench",
|
|
16
|
-
setup(
|
|
17
|
-
const { t:
|
|
18
|
-
|
|
15
|
+
setup(Q) {
|
|
16
|
+
const { t: s } = R(), C = U(), r = _(null), v = _(!0);
|
|
17
|
+
E(async () => {
|
|
19
18
|
try {
|
|
20
|
-
|
|
19
|
+
r.value = await V.summary();
|
|
21
20
|
} catch {
|
|
22
21
|
} finally {
|
|
23
|
-
|
|
22
|
+
v.value = !1;
|
|
24
23
|
}
|
|
25
24
|
});
|
|
26
|
-
function
|
|
27
|
-
return
|
|
25
|
+
function m(e) {
|
|
26
|
+
return e === void 0 ? "—" : e;
|
|
28
27
|
}
|
|
29
|
-
const
|
|
30
|
-
var
|
|
28
|
+
const S = i(() => {
|
|
29
|
+
var e, l, a, g;
|
|
31
30
|
return [
|
|
32
31
|
{
|
|
33
32
|
key: "roles",
|
|
34
|
-
icon: "ph:shield
|
|
35
|
-
value:
|
|
36
|
-
color: "var(--
|
|
33
|
+
icon: "ph:shield",
|
|
34
|
+
value: m((e = r.value) == null ? void 0 : e.roles),
|
|
35
|
+
color: "var(--chart-1)"
|
|
37
36
|
},
|
|
38
37
|
{
|
|
39
38
|
key: "users",
|
|
40
|
-
icon: "ph:users
|
|
41
|
-
value:
|
|
42
|
-
color: "var(--
|
|
39
|
+
icon: "ph:users",
|
|
40
|
+
value: m((l = r.value) == null ? void 0 : l.users),
|
|
41
|
+
color: "var(--chart-2)"
|
|
43
42
|
},
|
|
44
43
|
{
|
|
45
44
|
key: "perms",
|
|
46
|
-
icon: "ph:key
|
|
47
|
-
value:
|
|
48
|
-
color: "var(--
|
|
45
|
+
icon: "ph:key",
|
|
46
|
+
value: m((a = r.value) == null ? void 0 : a.perms),
|
|
47
|
+
color: "var(--chart-3)"
|
|
49
48
|
},
|
|
50
49
|
{
|
|
51
50
|
key: "online",
|
|
52
|
-
icon: "ph:broadcast
|
|
53
|
-
value:
|
|
54
|
-
color: "var(--
|
|
51
|
+
icon: "ph:broadcast",
|
|
52
|
+
value: m((g = r.value) == null ? void 0 : g.onlineSessions),
|
|
53
|
+
color: "var(--chart-4)"
|
|
55
54
|
}
|
|
56
55
|
];
|
|
57
|
-
}),
|
|
58
|
-
var
|
|
59
|
-
return ((
|
|
60
|
-
}),
|
|
61
|
-
var
|
|
56
|
+
}), $ = i(() => {
|
|
57
|
+
var e;
|
|
58
|
+
return ((e = r.value) == null ? void 0 : e.trendDays) ?? [];
|
|
59
|
+
}), N = i(() => {
|
|
60
|
+
var e, l;
|
|
62
61
|
return [
|
|
63
|
-
{ name:
|
|
64
|
-
{ name:
|
|
62
|
+
{ name: s("workbench.trendLogins"), data: ((e = r.value) == null ? void 0 : e.trendLogins) ?? [] },
|
|
63
|
+
{ name: s("workbench.trendActive"), data: ((l = r.value) == null ? void 0 : l.trendActiveUsers) ?? [] }
|
|
65
64
|
];
|
|
66
|
-
}),
|
|
67
|
-
var
|
|
65
|
+
}), T = i(() => {
|
|
66
|
+
var e, l, a;
|
|
68
67
|
return [
|
|
69
|
-
{ name:
|
|
70
|
-
{ name:
|
|
71
|
-
{ name:
|
|
68
|
+
{ name: s("workbench.roles"), value: ((e = r.value) == null ? void 0 : e.roles) ?? 0 },
|
|
69
|
+
{ name: s("workbench.users"), value: ((l = r.value) == null ? void 0 : l.users) ?? 0 },
|
|
70
|
+
{ name: s("workbench.perms"), value: ((a = r.value) == null ? void 0 : a.perms) ?? 0 }
|
|
72
71
|
];
|
|
73
|
-
});
|
|
74
|
-
return (
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
l(e(g), {
|
|
94
|
-
cols: "1 s:2 l:4",
|
|
95
|
-
responsive: "screen",
|
|
96
|
-
"x-gap": 16,
|
|
97
|
-
"y-gap": 16
|
|
98
|
-
}, {
|
|
99
|
-
default: u(() => [
|
|
100
|
-
(s(!0), _($, null, E(B.value, (i) => (s(), d(e(f), {
|
|
101
|
-
key: i.key
|
|
102
|
-
}, {
|
|
103
|
-
default: u(() => [
|
|
104
|
-
l(e(k), { bordered: !0 }, {
|
|
105
|
-
default: u(() => [
|
|
106
|
-
n("div", O, [
|
|
107
|
-
n("div", {
|
|
108
|
-
class: "stat-ico",
|
|
109
|
-
style: w({ color: i.color })
|
|
110
|
-
}, [
|
|
111
|
-
l(e(x), {
|
|
112
|
-
icon: i.icon,
|
|
113
|
-
width: 28
|
|
114
|
-
}, null, 8, ["icon"])
|
|
115
|
-
], 4),
|
|
116
|
-
n("div", P, [
|
|
117
|
-
m.value ? (s(), d(e(y), {
|
|
118
|
-
key: 0,
|
|
119
|
-
text: "",
|
|
120
|
-
width: "72px",
|
|
121
|
-
height: "34px"
|
|
122
|
-
})) : (s(), _("div", Q, h(i.value), 1)),
|
|
123
|
-
n("div", R, h(e(r)(`workbench.${i.key}`)), 1)
|
|
124
|
-
])
|
|
125
|
-
])
|
|
126
|
-
]),
|
|
127
|
-
_: 2
|
|
128
|
-
}, 1024)
|
|
72
|
+
}), w = _(null), { width: d } = z(w), A = i(() => d.value === 0 ? 4 : d.value < 520 ? 1 : d.value < 1e3 ? 2 : 4), B = i(() => d.value === 0 || d.value >= 1e3 ? 2 : 1);
|
|
73
|
+
return (e, l) => (n(), y("div", {
|
|
74
|
+
ref_key: "viewRef",
|
|
75
|
+
ref: w,
|
|
76
|
+
class: "view"
|
|
77
|
+
}, [
|
|
78
|
+
u(t(f), {
|
|
79
|
+
class: "a-card banner-card",
|
|
80
|
+
bordered: !0,
|
|
81
|
+
"content-style": "padding: 18px 20px"
|
|
82
|
+
}, {
|
|
83
|
+
default: p(() => {
|
|
84
|
+
var a;
|
|
85
|
+
return [
|
|
86
|
+
o("div", j, [
|
|
87
|
+
o("div", q, [
|
|
88
|
+
u(t(x), {
|
|
89
|
+
icon: "ph:user",
|
|
90
|
+
width: 26
|
|
91
|
+
})
|
|
129
92
|
]),
|
|
130
|
-
|
|
131
|
-
|
|
93
|
+
o("div", G, [
|
|
94
|
+
o("div", H, h(t(s)("workbench.welcome", { name: ((a = t(C).userInfo) == null ? void 0 : a.name) ?? "" })), 1),
|
|
95
|
+
o("div", J, h(t(s)("workbench.subtitle")), 1)
|
|
96
|
+
])
|
|
97
|
+
])
|
|
98
|
+
];
|
|
99
|
+
}),
|
|
100
|
+
_: 1
|
|
101
|
+
}),
|
|
102
|
+
o("div", {
|
|
103
|
+
class: "grid",
|
|
104
|
+
style: k({ gridTemplateColumns: `repeat(${A.value}, minmax(0, 1fr))` })
|
|
105
|
+
}, [
|
|
106
|
+
(n(!0), y(I, null, L(S.value, (a) => (n(), c(t(f), {
|
|
107
|
+
key: a.key,
|
|
108
|
+
class: "a-card",
|
|
109
|
+
bordered: !0,
|
|
110
|
+
"content-style": "display: flex; align-items: center; gap: 16px; padding: 14px 16px"
|
|
111
|
+
}, {
|
|
112
|
+
default: p(() => [
|
|
113
|
+
o("div", {
|
|
114
|
+
class: "stat-ico",
|
|
115
|
+
style: k({ color: a.color })
|
|
116
|
+
}, [
|
|
117
|
+
u(t(x), {
|
|
118
|
+
icon: a.icon,
|
|
119
|
+
width: 28
|
|
120
|
+
}, null, 8, ["icon"])
|
|
121
|
+
], 4),
|
|
122
|
+
o("div", K, [
|
|
123
|
+
v.value ? (n(), c(t(b), {
|
|
124
|
+
key: 0,
|
|
125
|
+
text: "",
|
|
126
|
+
width: "72px",
|
|
127
|
+
height: "34px"
|
|
128
|
+
})) : (n(), y("div", O, h(a.value), 1)),
|
|
129
|
+
o("div", P, h(t(s)(`workbench.${a.key}`)), 1)
|
|
130
|
+
])
|
|
131
|
+
]),
|
|
132
|
+
_: 2
|
|
133
|
+
}, 1024))), 128))
|
|
134
|
+
], 4),
|
|
135
|
+
o("div", {
|
|
136
|
+
class: "grid",
|
|
137
|
+
style: k({ gridTemplateColumns: `repeat(${B.value}, minmax(0, 1fr))` })
|
|
138
|
+
}, [
|
|
139
|
+
u(t(f), {
|
|
140
|
+
class: "a-card",
|
|
141
|
+
title: t(s)("workbench.trendTitle"),
|
|
142
|
+
bordered: !0
|
|
143
|
+
}, {
|
|
144
|
+
default: p(() => [
|
|
145
|
+
v.value ? (n(), c(t(b), {
|
|
146
|
+
key: 0,
|
|
147
|
+
height: "320px",
|
|
148
|
+
sharp: !1
|
|
149
|
+
})) : (n(), c(F, {
|
|
150
|
+
key: 1,
|
|
151
|
+
categories: $.value,
|
|
152
|
+
series: N.value
|
|
153
|
+
}, null, 8, ["categories", "series"]))
|
|
132
154
|
]),
|
|
133
155
|
_: 1
|
|
134
|
-
}),
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
"y-gap": 16
|
|
156
|
+
}, 8, ["title"]),
|
|
157
|
+
u(t(f), {
|
|
158
|
+
class: "a-card",
|
|
159
|
+
title: t(s)("workbench.distributionTitle"),
|
|
160
|
+
bordered: !0
|
|
140
161
|
}, {
|
|
141
|
-
default:
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
key: 0,
|
|
151
|
-
height: "320px",
|
|
152
|
-
sharp: !1
|
|
153
|
-
})) : (s(), d(M, {
|
|
154
|
-
key: 1,
|
|
155
|
-
categories: C.value,
|
|
156
|
-
series: D.value
|
|
157
|
-
}, null, 8, ["categories", "series"]))
|
|
158
|
-
]),
|
|
159
|
-
_: 1
|
|
160
|
-
}, 8, ["title"])
|
|
161
|
-
]),
|
|
162
|
-
_: 1
|
|
163
|
-
}),
|
|
164
|
-
l(e(f), null, {
|
|
165
|
-
default: u(() => [
|
|
166
|
-
l(e(k), {
|
|
167
|
-
title: e(r)("workbench.distributionTitle"),
|
|
168
|
-
bordered: !0
|
|
169
|
-
}, {
|
|
170
|
-
default: u(() => [
|
|
171
|
-
m.value ? (s(), d(e(y), {
|
|
172
|
-
key: 0,
|
|
173
|
-
height: "320px",
|
|
174
|
-
sharp: !1
|
|
175
|
-
})) : (s(), d(j, {
|
|
176
|
-
key: 1,
|
|
177
|
-
data: G.value
|
|
178
|
-
}, null, 8, ["data"]))
|
|
179
|
-
]),
|
|
180
|
-
_: 1
|
|
181
|
-
}, 8, ["title"])
|
|
182
|
-
]),
|
|
183
|
-
_: 1
|
|
184
|
-
})
|
|
162
|
+
default: p(() => [
|
|
163
|
+
v.value ? (n(), c(t(b), {
|
|
164
|
+
key: 0,
|
|
165
|
+
height: "320px",
|
|
166
|
+
sharp: !1
|
|
167
|
+
})) : (n(), c(M, {
|
|
168
|
+
key: 1,
|
|
169
|
+
data: T.value
|
|
170
|
+
}, null, 8, ["data"]))
|
|
185
171
|
]),
|
|
186
172
|
_: 1
|
|
187
|
-
})
|
|
188
|
-
])
|
|
189
|
-
|
|
173
|
+
}, 8, ["title"])
|
|
174
|
+
], 4)
|
|
175
|
+
], 512));
|
|
190
176
|
}
|
|
191
177
|
});
|
|
192
178
|
export {
|
|
193
|
-
|
|
179
|
+
oe as default
|
|
194
180
|
};
|
|
195
181
|
//# sourceMappingURL=workbench2.vue.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workbench2.vue.js","sources":["../../../src/views/dashboard/workbench.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, ref } from 'vue'\nimport { NGrid, NGi, NCard, NSkeleton } from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport { useI18n } from 'vue-i18n'\nimport { useUserStore } from '#/stores/user'\nimport { useAppStore } from '#/stores/app'\nimport { btnGrad } from '#/theme/mix'\nimport { dashboardApi } from '#/api'\nimport type { DashboardSummary } from '#/types/api'\nimport LineChart from '#/components/Chart/LineChart.vue'\nimport PieChart from '#/components/Chart/PieChart.vue'\n\nconst { t } = useI18n()\nconst user = useUserStore()\nconst app = useAppStore()\n\nconst avatarStyle = computed(() => ({ background: btnGrad(app.accent) }))\n\nconst summary = ref<DashboardSummary | null>(null)\nconst loading = ref(true)\n\nonMounted(async () => {\n try {\n summary.value = await dashboardApi.summary()\n } catch {\n // 首页不该因为一张统计图挂了就糊用户一脸红:统计取不到就显示 —,页面其余部分照常可用。\n } finally {\n loading.value = false\n }\n})\n\n/** 计数未到位时显示 —,而不是先闪个 0 再跳到真值。 */\nfunction num(v: number | undefined) {\n return v === undefined ? '—' : v\n}\n\nconst stats = computed(() => [\n {\n key: 'roles',\n icon: 'ph:shield-duotone',\n value: num(summary.value?.roles),\n color: 'var(--color-primary)',\n },\n {\n key: 'users',\n icon: 'ph:users-duotone',\n value: num(summary.value?.users),\n color: 'var(--color-success)',\n },\n {\n key: 'perms',\n icon: 'ph:key-duotone',\n value: num(summary.value?.perms),\n color: 'var(--color-warning)',\n },\n {\n key: 'online',\n icon: 'ph:broadcast-duotone',\n value: num(summary.value?.onlineSessions),\n color: 'var(--color-danger)',\n },\n])\n\nconst trendDays = computed(() => summary.value?.trendDays ?? [])\nconst trendSeries = computed(() => [\n { name: t('workbench.trendLogins'), data: summary.value?.trendLogins ?? [] },\n { name: t('workbench.trendActive'), data: summary.value?.trendActiveUsers ?? [] },\n])\n// 资源分布就是前三个计数,不必让后端再返一份\nconst distribution = computed(() => [\n { name: t('workbench.roles'), value: summary.value?.roles ?? 0 },\n { name: t('workbench.users'), value: summary.value?.users ?? 0 },\n { name: t('workbench.perms'), value: summary.value?.perms ?? 0 },\n])\n</script>\n\n<template>\n <div class=\"view\">\n <!-- 欢迎横幅(英雄区:btnGrad 头像)-->\n <div class=\"banner\">\n <div class=\"avatar\" :style=\"avatarStyle\">\n <Icon icon=\"ph:user\" :width=\"26\" color=\"#fff\" />\n </div>\n <div>\n <div class=\"hi\">{{ t('workbench.welcome', { name: user.userInfo?.name ?? '' }) }}</div>\n <div class=\"tip\">{{ t('workbench.subtitle') }}</div>\n </div>\n </div>\n\n <n-grid :cols=\"'1 s:2 l:4'\" responsive=\"screen\" :x-gap=\"16\" :y-gap=\"16\">\n <n-gi v-for=\"s in stats\" :key=\"s.key\">\n <n-card :bordered=\"true\">\n <div class=\"stat\">\n <div class=\"stat-ico\" :style=\"{ color: s.color }\">\n <Icon :icon=\"s.icon\" :width=\"28\" />\n </div>\n <div class=\"stat-body\">\n <!-- 骨架而非先闪 0 再跳真值:数字位宽固定,到数时不抖 -->\n <n-skeleton v-if=\"loading\" text width=\"72px\" height=\"34px\" />\n <div v-else class=\"stat-val tabular\">{{ s.value }}</div>\n <div class=\"stat-label\">{{ t(`workbench.${s.key}`) }}</div>\n </div>\n </div>\n </n-card>\n </n-gi>\n </n-grid>\n\n <n-grid :cols=\"'1 l:2'\" responsive=\"screen\" :x-gap=\"16\" :y-gap=\"16\">\n <n-gi>\n <n-card :title=\"t('workbench.trendTitle')\" :bordered=\"true\">\n <n-skeleton v-if=\"loading\" height=\"320px\" :sharp=\"false\" />\n <LineChart v-else :categories=\"trendDays\" :series=\"trendSeries\" />\n </n-card>\n </n-gi>\n <n-gi>\n <n-card :title=\"t('workbench.distributionTitle')\" :bordered=\"true\">\n <n-skeleton v-if=\"loading\" height=\"320px\" :sharp=\"false\" />\n <PieChart v-else :data=\"distribution\" />\n </n-card>\n </n-gi>\n </n-grid>\n </div>\n</template>\n\n<style scoped>\n.view {\n display: flex;\n flex-direction: column;\n gap: var(--gap-card);\n}\n.banner {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 24px;\n border-radius: var(--radius-lg);\n background: var(--color-primary-light);\n}\n.avatar {\n width: 52px;\n height: 52px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.hi {\n font-size: var(--font-size-lg);\n font-weight: 600;\n color: var(--color-text-primary);\n}\n.tip {\n color: var(--color-text-secondary);\n margin-top: 4px;\n}\n.stat {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n/* 骨架与真值换位时高度一致,卡片不跳 */\n.stat-body {\n min-width: 0;\n}\n/* 图标底盘:取当前语义色 12% 作浅底圆角,呼应 banner 头像,避免图标\"裸浮\" */\n.stat-ico {\n flex-shrink: 0;\n width: 48px;\n height: 48px;\n border-radius: var(--radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, currentColor 12%, transparent);\n}\n.stat-val {\n font-size: 28px;\n font-weight: 700;\n color: var(--color-text-primary);\n line-height: 1.1;\n}\n.stat-label {\n color: var(--color-text-secondary);\n margin-top: 2px;\n}\n</style>\n"],"names":["t","useI18n","user","useUserStore","app","useAppStore","avatarStyle","computed","btnGrad","summary","ref","loading","onMounted","dashboardApi","num","v","stats","_a","_b","_c","_d","trendDays","trendSeries","distribution","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_createVNode","_unref","Icon","_hoisted_3","_toDisplayString","_hoisted_4","NGrid","_Fragment","_renderList","s","_createBlock","NGi","NCard","_hoisted_5","_normalizeStyle","_hoisted_6","NSkeleton","_hoisted_7","_hoisted_8","LineChart","PieChart"],"mappings":";;;;;;;;;;;;;;;;AAaA,UAAM,EAAE,GAAAA,EAAA,IAAMC,EAAA,GACRC,IAAOC,EAAA,GACPC,IAAMC,EAAA,GAENC,IAAcC,EAAS,OAAO,EAAE,YAAYC,EAAQJ,EAAI,MAAM,EAAA,EAAI,GAElEK,IAAUC,EAA6B,IAAI,GAC3CC,IAAUD,EAAI,EAAI;AAExB,IAAAE,EAAU,YAAY;AACpB,UAAI;AACF,QAAAH,EAAQ,QAAQ,MAAMI,EAAa,QAAA;AAAA,MACrC,QAAQ;AAAA,MAER,UAAA;AACE,QAAAF,EAAQ,QAAQ;AAAA,MAClB;AAAA,IACF,CAAC;AAGD,aAASG,EAAIC,GAAuB;AAClC,aAAOA,MAAM,SAAY,MAAMA;AAAA,IACjC;AAEA,UAAMC,IAAQT,EAAS,MAAA;;AAAM;AAAA,QAC3B;AAAA,UACE,KAAK;AAAA,UACL,MAAM;AAAA,UACN,OAAOO,GAAIG,IAAAR,EAAQ,UAAR,gBAAAQ,EAAe,KAAK;AAAA,UAC/B,OAAO;AAAA,QAAA;AAAA,QAET;AAAA,UACE,KAAK;AAAA,UACL,MAAM;AAAA,UACN,OAAOH,GAAII,IAAAT,EAAQ,UAAR,gBAAAS,EAAe,KAAK;AAAA,UAC/B,OAAO;AAAA,QAAA;AAAA,QAET;AAAA,UACE,KAAK;AAAA,UACL,MAAM;AAAA,UACN,OAAOJ,GAAIK,IAAAV,EAAQ,UAAR,gBAAAU,EAAe,KAAK;AAAA,UAC/B,OAAO;AAAA,QAAA;AAAA,QAET;AAAA,UACE,KAAK;AAAA,UACL,MAAM;AAAA,UACN,OAAOL,GAAIM,IAAAX,EAAQ,UAAR,gBAAAW,EAAe,cAAc;AAAA,UACxC,OAAO;AAAA,QAAA;AAAA,MACT;AAAA,KACD,GAEKC,IAAYd,EAAS,MAAA;;AAAM,eAAAU,IAAAR,EAAQ,UAAR,gBAAAQ,EAAe,cAAa;KAAE,GACzDK,IAAcf,EAAS,MAAA;;AAAM;AAAA,QACjC,EAAE,MAAMP,EAAE,uBAAuB,GAAG,QAAMiB,IAAAR,EAAQ,UAAR,gBAAAQ,EAAe,gBAAe,GAAC;AAAA,QACzE,EAAE,MAAMjB,EAAE,uBAAuB,GAAG,QAAMkB,IAAAT,EAAQ,UAAR,gBAAAS,EAAe,qBAAoB,CAAA,EAAC;AAAA,MAAE;AAAA,KACjF,GAEKK,IAAehB,EAAS,MAAA;;AAAM;AAAA,QAClC,EAAE,MAAMP,EAAE,iBAAiB,GAAG,SAAOiB,IAAAR,EAAQ,UAAR,gBAAAQ,EAAe,UAAS,EAAA;AAAA,QAC7D,EAAE,MAAMjB,EAAE,iBAAiB,GAAG,SAAOkB,IAAAT,EAAQ,UAAR,gBAAAS,EAAe,UAAS,EAAA;AAAA,QAC7D,EAAE,MAAMlB,EAAE,iBAAiB,GAAG,SAAOmB,IAAAV,EAAQ,UAAR,gBAAAU,EAAe,UAAS,EAAA;AAAA,MAAE;AAAA,KAChE;;;AAIC,aAAAK,EAAA,GAAAC,EA4CM,OA5CNC,GA4CM;AAAA,QA1CJC,EAQM,OARNC,GAQM;AAAA,UAPJD,EAEM,OAAA;AAAA,YAFD,OAAM;AAAA,YAAU,SAAOrB,EAAA,KAAW;AAAA,UAAA;YACrCuB,EAAgDC,EAAAC,CAAA,GAAA;AAAA,cAA1C,MAAK;AAAA,cAAW,OAAO;AAAA,cAAI,OAAM;AAAA,YAAA;;UAEzCJ,EAGM,OAAA,MAAA;AAAA,YAFJA,EAAuF,OAAvFK,GAAuFC,EAApEH,EAAA9B,CAAA,iCAA+B8B,IAAAA,EAAA5B,CAAA,EAAK,aAAL4B,gBAAAA,EAAe,SAAI,IAAA,CAAA,GAAA,CAAA;AAAA,YACrEH,EAAoD,OAApDO,GAAoDD,EAAhCH,EAAA9B,CAAA,EAAC,oBAAA,CAAA,GAAA,CAAA;AAAA,UAAA;;QAIzB6B,EAgBSC,EAAAK,CAAA,GAAA;AAAA,UAhBA,MAAM;AAAA,UAAa,YAAW;AAAA,UAAU,SAAO;AAAA,UAAK,SAAO;AAAA,QAAA;qBAC5D,MAAkB;AAAA,oBAAxBV,EAcOW,GAAA,MAAAC,EAdWrB,EAAA,OAAK,CAAVsB,YAAbC,EAcOT,EAAAU,CAAA,GAAA;AAAA,cAdmB,KAAKF,EAAE;AAAA,YAAA;yBAC/B,MAYS;AAAA,gBAZTT,EAYSC,EAAAW,CAAA,GAAA,EAZA,UAAU,MAAI;AAAA,6BACrB,MAUM;AAAA,oBAVNd,EAUM,OAVNe,GAUM;AAAA,sBATJf,EAEM,OAAA;AAAA,wBAFD,OAAM;AAAA,wBAAY,OAAKgB,EAAA,EAAA,OAAWL,EAAE,OAAK;AAAA,sBAAA;wBAC5CT,EAAmCC,EAAAC,CAAA,GAAA;AAAA,0BAA5B,MAAMO,EAAE;AAAA,0BAAO,OAAO;AAAA,wBAAA;;sBAE/BX,EAKM,OALNiB,GAKM;AAAA,wBAHcjC,EAAA,cAAlB4B,EAA6DT,EAAAe,CAAA,GAAA;AAAA;0BAAlC,MAAA;AAAA,0BAAK,OAAM;AAAA,0BAAO,QAAO;AAAA,wBAAA,OACpDrB,EAAA,GAAAC,EAAwD,OAAxDqB,GAAwDb,EAAhBK,EAAE,KAAK,GAAA,CAAA;AAAA,wBAC/CX,EAA2D,OAA3DoB,GAA2Dd,EAAhCH,KAAC,aAAcQ,EAAE,GAAG,EAAA,CAAA,GAAA,CAAA;AAAA,sBAAA;;;;;;;;;;;QAOzDT,EAaSC,EAAAK,CAAA,GAAA;AAAA,UAbA,MAAM;AAAA,UAAS,YAAW;AAAA,UAAU,SAAO;AAAA,UAAK,SAAO;AAAA,QAAA;qBAC9D,MAKO;AAAA,YALPN,EAKOC,EAAAU,CAAA,GAAA,MAAA;AAAA,yBAJL,MAGS;AAAA,gBAHTX,EAGSC,EAAAW,CAAA,GAAA;AAAA,kBAHA,OAAOX,EAAA9B,CAAA,EAAC,sBAAA;AAAA,kBAA2B,UAAU;AAAA,gBAAA;6BACpD,MAA2D;AAAA,oBAAzCW,EAAA,cAAlB4B,EAA2DT,EAAAe,CAAA,GAAA;AAAA;sBAAhC,QAAO;AAAA,sBAAS,OAAO;AAAA,oBAAA,YAClDN,EAAkES,GAAA;AAAA;sBAA/C,YAAY3B,EAAA;AAAA,sBAAY,QAAQC,EAAA;AAAA,oBAAA;;;;;;;YAGvDO,EAKOC,EAAAU,CAAA,GAAA,MAAA;AAAA,yBAJL,MAGS;AAAA,gBAHTX,EAGSC,EAAAW,CAAA,GAAA;AAAA,kBAHA,OAAOX,EAAA9B,CAAA,EAAC,6BAAA;AAAA,kBAAkC,UAAU;AAAA,gBAAA;6BAC3D,MAA2D;AAAA,oBAAzCW,EAAA,cAAlB4B,EAA2DT,EAAAe,CAAA,GAAA;AAAA;sBAAhC,QAAO;AAAA,sBAAS,OAAO;AAAA,oBAAA,YAClDN,EAAwCU,GAAA;AAAA;sBAAtB,MAAM1B,EAAA;AAAA,oBAAA;;;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"workbench2.vue.js","sources":["../../../src/views/dashboard/workbench.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, ref } from 'vue'\nimport { NCard, NSkeleton } from 'naive-ui'\nimport { useElementSize } from '@vueuse/core'\nimport { Icon } from '@iconify/vue'\nimport { useI18n } from 'vue-i18n'\nimport { useUserStore } from '#/stores/user'\nimport { dashboardApi } from '#/api'\nimport type { DashboardSummary } from '#/types/api'\nimport LineChart from '#/components/Chart/LineChart.vue'\nimport PieChart from '#/components/Chart/PieChart.vue'\n\nconst { t } = useI18n()\nconst user = useUserStore()\n\nconst summary = ref<DashboardSummary | null>(null)\nconst loading = ref(true)\n\nonMounted(async () => {\n try {\n summary.value = await dashboardApi.summary()\n } catch {\n // 首页不该因为一张统计图挂了就糊用户一脸红:统计取不到就显示 —,页面其余部分照常可用。\n } finally {\n loading.value = false\n }\n})\n\n/** 计数未到位时显示 —,而不是先闪个 0 再跳到真值。 */\nfunction num(v: number | undefined) {\n return v === undefined ? '—' : v\n}\n\nconst stats = computed(() => [\n {\n key: 'roles',\n icon: 'ph:shield',\n value: num(summary.value?.roles),\n color: 'var(--chart-1)',\n },\n {\n key: 'users',\n icon: 'ph:users',\n value: num(summary.value?.users),\n color: 'var(--chart-2)',\n },\n {\n key: 'perms',\n icon: 'ph:key',\n value: num(summary.value?.perms),\n color: 'var(--chart-3)',\n },\n {\n key: 'online',\n icon: 'ph:broadcast',\n value: num(summary.value?.onlineSessions),\n color: 'var(--chart-4)',\n },\n])\n\nconst trendDays = computed(() => summary.value?.trendDays ?? [])\nconst trendSeries = computed(() => [\n { name: t('workbench.trendLogins'), data: summary.value?.trendLogins ?? [] },\n { name: t('workbench.trendActive'), data: summary.value?.trendActiveUsers ?? [] },\n])\n// 资源分布就是前三个计数,不必让后端再返一份\nconst distribution = computed(() => [\n { name: t('workbench.roles'), value: summary.value?.roles ?? 0 },\n { name: t('workbench.users'), value: summary.value?.users ?? 0 },\n { name: t('workbench.perms'), value: summary.value?.perms ?? 0 },\n])\n\n// 栅格按内容区宽度分档(不是视口:侧栏展开 / 收起会改变可用宽度)。\n// 统计卡 <520 一列 / <1000 两列 / 否则四列;图表卡 <1000 一列 / 否则并排。宽度还没量到(0)时按宽档,免得首帧闪成单列。\nconst viewRef = ref<HTMLElement | null>(null)\nconst { width: pw } = useElementSize(viewRef)\nconst statCols = computed(() => (pw.value === 0 ? 4 : pw.value < 520 ? 1 : pw.value < 1000 ? 2 : 4))\nconst chartCols = computed(() => (pw.value === 0 || pw.value >= 1000 ? 2 : 1))\n</script>\n\n<template>\n <div ref=\"viewRef\" class=\"view\">\n <!-- 欢迎横幅:浅主题色底 + 渐变头像,不受接口失败影响 -->\n <n-card class=\"a-card banner-card\" :bordered=\"true\" content-style=\"padding: 18px 20px\">\n <div class=\"banner\">\n <div class=\"avatar\">\n <Icon icon=\"ph:user\" :width=\"26\" />\n </div>\n <div class=\"banner-body\">\n <div class=\"hi\">{{ t('workbench.welcome', { name: user.userInfo?.name ?? '' }) }}</div>\n <div class=\"tip\">{{ t('workbench.subtitle') }}</div>\n </div>\n </div>\n </n-card>\n\n <div class=\"grid\" :style=\"{ gridTemplateColumns: `repeat(${statCols}, minmax(0, 1fr))` }\">\n <n-card\n v-for=\"s in stats\"\n :key=\"s.key\"\n class=\"a-card\"\n :bordered=\"true\"\n content-style=\"display: flex; align-items: center; gap: 16px; padding: 14px 16px\"\n >\n <div class=\"stat-ico\" :style=\"{ color: s.color }\">\n <Icon :icon=\"s.icon\" :width=\"28\" />\n </div>\n <div class=\"stat-body\">\n <!-- 骨架而非先闪 0 再跳真值:数字位宽固定,到数时不抖 -->\n <n-skeleton v-if=\"loading\" text width=\"72px\" height=\"34px\" />\n <div v-else class=\"stat-val tabular\">{{ s.value }}</div>\n <div class=\"stat-label\">{{ t(`workbench.${s.key}`) }}</div>\n </div>\n </n-card>\n </div>\n\n <div class=\"grid\" :style=\"{ gridTemplateColumns: `repeat(${chartCols}, minmax(0, 1fr))` }\">\n <n-card class=\"a-card\" :title=\"t('workbench.trendTitle')\" :bordered=\"true\">\n <n-skeleton v-if=\"loading\" height=\"320px\" :sharp=\"false\" />\n <LineChart v-else :categories=\"trendDays\" :series=\"trendSeries\" />\n </n-card>\n <n-card class=\"a-card\" :title=\"t('workbench.distributionTitle')\" :bordered=\"true\">\n <n-skeleton v-if=\"loading\" height=\"320px\" :sharp=\"false\" />\n <PieChart v-else :data=\"distribution\" />\n </n-card>\n </div>\n </div>\n</template>\n\n<style scoped>\n.view {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n gap: var(--gap-card);\n align-content: start;\n}\n.grid {\n display: grid;\n gap: var(--gap-card);\n}\n/* 横幅卡底色取选中态令牌(主色 6% / 暗色 14%),与业务工作台同一套 */\n.banner-card {\n background-image: linear-gradient(var(--sel-bg), var(--sel-bg));\n}\n.banner {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n.avatar {\n flex: none;\n width: 52px;\n height: 52px;\n border-radius: 50%;\n display: grid;\n place-items: center;\n color: var(--on-acc);\n background-image: linear-gradient(135deg, var(--signal), var(--login-accent-2));\n box-shadow: 0 8px 20px -8px var(--signal-glow);\n}\n.banner-body {\n min-width: 0;\n flex: 1;\n}\n.hi {\n font-size: 18px;\n font-weight: 600;\n letter-spacing: -0.02em;\n color: var(--text-1);\n}\n.tip {\n margin-top: 2px;\n font-size: 14px;\n color: var(--text-2);\n}\n/* 图标底盘:取当前语义色 12% 作浅底圆角 */\n.stat-ico {\n flex-shrink: 0;\n width: 48px;\n height: 48px;\n border-radius: var(--radius-lg);\n display: grid;\n place-items: center;\n background: color-mix(in srgb, currentColor 12%, transparent);\n}\n/* 骨架与真值换位时高度一致(34px),卡片不跳 */\n.stat-body {\n min-width: 0;\n}\n.stat-val {\n font-size: 28px;\n line-height: 34px;\n font-weight: 600;\n letter-spacing: -0.04em;\n color: var(--text-1);\n}\n.stat-label {\n font-size: 14px;\n color: var(--text-2);\n}\n</style>\n"],"names":["t","useI18n","user","useUserStore","summary","ref","loading","onMounted","dashboardApi","num","v","stats","computed","_a","_b","_c","_d","trendDays","trendSeries","distribution","viewRef","pw","useElementSize","statCols","chartCols","_createElementBlock","_createVNode","_unref","NCard","_createElementVNode","_hoisted_1","_hoisted_2","Icon","_hoisted_3","_hoisted_4","_toDisplayString","_hoisted_5","_Fragment","_renderList","s","_createBlock","_normalizeStyle","_hoisted_6","NSkeleton","_openBlock","_hoisted_7","_hoisted_8","LineChart","PieChart"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import o from "./iframe2.vue.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import r from "../../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
-
const
|
|
4
|
+
const m = /* @__PURE__ */ r(o, [["__scopeId", "data-v-f642de1e"]]);
|
|
5
5
|
export {
|
|
6
|
-
|
|
6
|
+
m as default
|
|
7
7
|
};
|
|
8
8
|
//# sourceMappingURL=iframe.vue.js.map
|
|
@@ -1,21 +1,28 @@
|
|
|
1
|
-
import { defineComponent as t, openBlock as
|
|
2
|
-
import { useRoute as
|
|
3
|
-
|
|
1
|
+
import { defineComponent as t, openBlock as o, createBlock as a, unref as e, withCtx as s, createElementBlock as c, createCommentVNode as n } from "vue";
|
|
2
|
+
import { useRoute as l } from "vue-router";
|
|
3
|
+
import { NCard as m } from "naive-ui";
|
|
4
|
+
const p = ["src"], k = /* @__PURE__ */ t({
|
|
4
5
|
__name: "iframe",
|
|
5
|
-
setup(
|
|
6
|
-
const
|
|
7
|
-
return (
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
6
|
+
setup(i) {
|
|
7
|
+
const r = l().meta.iframeSrc;
|
|
8
|
+
return (f, d) => (o(), a(e(m), {
|
|
9
|
+
class: "embed-wrap",
|
|
10
|
+
"content-style": "padding: 0"
|
|
11
|
+
}, {
|
|
12
|
+
default: s(() => [
|
|
13
|
+
e(r) ? (o(), c("iframe", {
|
|
14
|
+
key: 0,
|
|
15
|
+
src: e(r),
|
|
16
|
+
class: "embed",
|
|
17
|
+
referrerpolicy: "no-referrer",
|
|
18
|
+
sandbox: "allow-same-origin allow-scripts allow-forms allow-popups"
|
|
19
|
+
}, null, 8, p)) : n("", !0)
|
|
20
|
+
]),
|
|
21
|
+
_: 1
|
|
22
|
+
}));
|
|
16
23
|
}
|
|
17
24
|
});
|
|
18
25
|
export {
|
|
19
|
-
|
|
26
|
+
k as default
|
|
20
27
|
};
|
|
21
28
|
//# sourceMappingURL=iframe2.vue.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iframe2.vue.js","sources":["../../../src/views/embed/iframe.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 内嵌外部页面:URL 由菜单约定放进 route.meta.iframeSrc(component 字段为 URL 时,见 useAuthMenu)。\n// 每个内嵌菜单经 namedPage 有独立组件身份、meta 恒定 → src 取一次快照即可,**不能**跟全局当前路由响应式:\n// 否则被 keep-alive 缓存的实例会在切到别的路由时把 src 重算成 undefined(卸载 iframe → 回访白重载)\n// 或另一内嵌页的 URL(后台悄悄加载对方站点)。setup 只跑一次,快照天然正确。\nimport { useRoute } from 'vue-router'\n\nconst src = useRoute().meta.iframeSrc as string | undefined\n</script>\n\n<template>\n <
|
|
1
|
+
{"version":3,"file":"iframe2.vue.js","sources":["../../../src/views/embed/iframe.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 内嵌外部页面:URL 由菜单约定放进 route.meta.iframeSrc(component 字段为 URL 时,见 useAuthMenu)。\n// 每个内嵌菜单经 namedPage 有独立组件身份、meta 恒定 → src 取一次快照即可,**不能**跟全局当前路由响应式:\n// 否则被 keep-alive 缓存的实例会在切到别的路由时把 src 重算成 undefined(卸载 iframe → 回访白重载)\n// 或另一内嵌页的 URL(后台悄悄加载对方站点)。setup 只跑一次,快照天然正确。\nimport { useRoute } from 'vue-router'\nimport { NCard } from 'naive-ui'\n\nconst src = useRoute().meta.iframeSrc as string | undefined\n</script>\n\n<template>\n <!-- 无边框 iframe 放进卡片:圆角由卡片裁出,内容区高度撑满 -->\n <n-card class=\"embed-wrap\" content-style=\"padding: 0\">\n <iframe\n v-if=\"src\"\n :src=\"src\"\n class=\"embed\"\n referrerpolicy=\"no-referrer\"\n sandbox=\"allow-same-origin allow-scripts allow-forms allow-popups\"\n />\n </n-card>\n</template>\n\n<style scoped>\n.embed-wrap {\n height: 100%;\n min-height: calc(100dvh - 160px);\n overflow: hidden;\n}\n.embed-wrap :deep(.n-card__content) {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: calc(100dvh - 160px);\n}\n.embed {\n display: block;\n flex: 1 1 0;\n width: 100%;\n min-height: calc(100dvh - 160px);\n border: 0;\n}\n</style>\n"],"names":["src","useRoute","_createBlock","_unref","NCard","_createElementBlock"],"mappings":";;;;;;AAQA,UAAMA,IAAMC,IAAW,KAAK;2BAK1BC,EAQSC,EAAAC,CAAA,GAAA;AAAA,MARD,OAAM;AAAA,MAAa,iBAAc;AAAA,IAAA;iBACvC,MAME;AAAA,QALMD,EAAAH,CAAA,UADRK,EAME,UAAA;AAAA;UAJC,KAAKF,EAAAH,CAAA;AAAA,UACN,OAAM;AAAA,UACN,gBAAe;AAAA,UACf,SAAQ;AAAA,QAAA;;;;;;"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import o from "./4042.vue.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import t from "../../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
-
const
|
|
4
|
+
const f = /* @__PURE__ */ t(o, [["__scopeId", "data-v-67a3298f"]]);
|
|
5
5
|
export {
|
|
6
|
-
|
|
6
|
+
f as default
|
|
7
7
|
};
|
|
8
8
|
//# sourceMappingURL=404.vue.js.map
|