smart-admin-web 10.14.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 +6 -6
- package/dist/api/index.d.ts +41 -2
- package/dist/api/index.js +36 -15
- package/dist/api/index.js.map +1 -1
- package/dist/api/schema.d.ts +418 -6
- package/dist/assets/icons/ph-subset.json.js +7 -7
- package/dist/assets/smart-logo.svg.js +5 -0
- package/dist/assets/smart-logo.svg.js.map +1 -0
- 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/SmartLogo.vue.d.ts +3 -0
- package/dist/components/SmartLogo.vue.js +1 -1
- package/dist/components/SmartLogo2.vue.js +22 -64
- package/dist/components/SmartLogo2.vue.js.map +1 -1
- package/dist/{views/system/config/components/GroupExtraConfig.vue.d.ts → components/TableTotal/index.vue.d.ts} +1 -4
- 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/useLoginHero.d.ts +2 -0
- package/dist/composables/useLoginHero.js +22 -0
- package/dist/composables/useLoginHero.js.map +1 -0
- package/dist/composables/useModule.js +39 -29
- package/dist/composables/useModule.js.map +1 -1
- package/dist/composables/usePageTitle.js +16 -14
- package/dist/composables/usePageTitle.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 +20 -0
- package/dist/composables/useSite.js +18 -13
- 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 +223 -208
- 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/favicon.d.ts +1 -0
- package/dist/lib/favicon.js +12 -0
- package/dist/lib/favicon.js.map +1 -0
- package/dist/lib/loginHero.d.ts +16 -0
- package/dist/lib/loginHero.js +33 -0
- package/dist/lib/loginHero.js.map +1 -0
- package/dist/lib/logoCrop.d.ts +25 -0
- package/dist/lib/logoCrop.js +22 -0
- package/dist/lib/logoCrop.js.map +1 -0
- package/dist/lib/runtime.d.ts +2 -0
- package/dist/lib/runtime.js +1 -1
- package/dist/lib/runtime.js.map +1 -1
- package/dist/lib/securityRules.d.ts +26 -0
- package/dist/lib/securityRules.js +86 -0
- package/dist/lib/securityRules.js.map +1 -0
- 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 +462 -42
- package/dist/locales/en-US.js +491 -78
- 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 +462 -42
- package/dist/locales/zh-CN.js +490 -81
- 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 +12 -12
- 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.d.ts +34 -9
- package/dist/utils/oauthBrand.js +70 -74
- 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.d.ts +18 -0
- package/dist/views/login/components/LoginHeroPanel.vue.js +8 -0
- package/dist/views/login/components/LoginHeroPanel.vue.js.map +1 -0
- package/dist/views/login/components/LoginHeroPanel2.vue.js +61 -0
- package/dist/views/login/components/LoginHeroPanel2.vue.js.map +1 -0
- 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 +8 -0
- package/dist/views/system/config/components/AdminMock.vue.js.map +1 -0
- package/dist/views/system/config/components/AdminMock2.vue.js +93 -0
- package/dist/views/system/config/components/AdminMock2.vue.js.map +1 -0
- package/dist/views/system/config/components/AdvancedSection.vue.js +8 -0
- package/dist/views/system/config/components/AdvancedSection.vue.js.map +1 -0
- package/dist/views/system/config/components/AdvancedSection2.vue.js +163 -0
- package/dist/views/system/config/components/AdvancedSection2.vue.js.map +1 -0
- package/dist/views/system/config/components/BrandSection.vue.d.ts +7 -0
- package/dist/views/system/config/components/BrandSection.vue.js +8 -0
- package/dist/views/system/config/components/BrandSection.vue.js.map +1 -0
- package/dist/views/system/config/components/BrandSection2.vue.js +266 -0
- package/dist/views/system/config/components/BrandSection2.vue.js.map +1 -0
- package/dist/views/system/config/components/CfgGroup.vue.d.ts +18 -0
- package/dist/views/system/config/components/CfgGroup.vue.js +8 -0
- package/dist/views/system/config/components/CfgGroup.vue.js.map +1 -0
- package/dist/views/system/config/components/CfgGroup2.vue.js +22 -0
- package/dist/views/system/config/components/CfgGroup2.vue.js.map +1 -0
- package/dist/views/system/config/components/CfgRow.vue.d.ts +26 -0
- package/dist/views/system/config/components/CfgRow.vue.js +9 -0
- package/dist/views/system/config/components/CfgRow.vue.js.map +1 -0
- package/dist/views/system/config/components/CfgRow2.vue.js +54 -0
- package/dist/views/system/config/components/CfgRow2.vue.js.map +1 -0
- package/dist/views/system/config/components/CfgSegment.vue.d.ts +28 -0
- package/dist/views/system/config/components/CfgSegment.vue.js +8 -0
- package/dist/views/system/config/components/CfgSegment.vue.js.map +1 -0
- package/dist/views/system/config/components/CfgSegment2.vue.js +45 -0
- package/dist/views/system/config/components/CfgSegment2.vue.js.map +1 -0
- package/dist/views/system/config/components/ConfigFormModal.vue.js +4 -1
- package/dist/views/system/config/components/ConfigFormModal.vue.js.map +1 -1
- package/dist/views/system/config/components/ConfigFormModal2.vue.js +72 -60
- package/dist/views/system/config/components/ConfigFormModal2.vue.js.map +1 -1
- package/dist/views/system/config/components/JobSection.vue.js +8 -0
- package/dist/views/system/config/components/JobSection.vue.js.map +1 -0
- package/dist/views/system/config/components/JobSection2.vue.js +140 -0
- package/dist/views/system/config/components/JobSection2.vue.js.map +1 -0
- package/dist/views/system/config/components/LoginMock.vue.d.ts +8 -0
- package/dist/views/system/config/components/LoginMock.vue.js +8 -0
- package/dist/views/system/config/components/LoginMock.vue.js.map +1 -0
- package/dist/views/system/config/components/LoginMock2.vue.js +132 -0
- package/dist/views/system/config/components/LoginMock2.vue.js.map +1 -0
- package/dist/views/system/config/components/LogoCropper.vue.d.ts +10 -0
- package/dist/views/system/config/components/LogoCropper.vue.js +8 -0
- package/dist/views/system/config/components/LogoCropper.vue.js.map +1 -0
- package/dist/views/system/config/components/LogoCropper2.vue.js +122 -0
- package/dist/views/system/config/components/LogoCropper2.vue.js.map +1 -0
- package/dist/views/system/config/components/LogoEditor.vue.js +8 -0
- package/dist/views/system/config/components/LogoEditor.vue.js.map +1 -0
- package/dist/views/system/config/components/LogoEditor2.vue.js +161 -0
- package/dist/views/system/config/components/LogoEditor2.vue.js.map +1 -0
- package/dist/views/system/config/components/ProviderSheet.vue.d.ts +17 -0
- package/dist/views/system/config/components/ProviderSheet.vue.js +8 -0
- package/dist/views/system/config/components/ProviderSheet.vue.js.map +1 -0
- package/dist/views/system/config/components/ProviderSheet2.vue.js +343 -0
- package/dist/views/system/config/components/ProviderSheet2.vue.js.map +1 -0
- package/dist/{layouts/SettingRow.vue.d.ts → views/system/config/components/ScaleToFit.vue.d.ts} +2 -1
- package/dist/views/system/config/components/ScaleToFit.vue.js +8 -0
- package/dist/views/system/config/components/ScaleToFit.vue.js.map +1 -0
- package/dist/views/system/config/components/ScaleToFit2.vue.js +41 -0
- package/dist/views/system/config/components/ScaleToFit2.vue.js.map +1 -0
- package/dist/views/system/config/components/SectionLayout.vue.d.ts +30 -0
- package/dist/views/system/config/components/SectionLayout.vue.js +8 -0
- package/dist/views/system/config/components/SectionLayout.vue.js.map +1 -0
- package/dist/views/system/config/components/SectionLayout2.vue.js +69 -0
- package/dist/views/system/config/components/SectionLayout2.vue.js.map +1 -0
- package/dist/views/system/config/components/SecuritySection.vue.js +8 -0
- package/dist/views/system/config/components/SecuritySection.vue.js.map +1 -0
- package/dist/views/system/config/components/SecuritySection2.vue.js +417 -0
- package/dist/views/system/config/components/SecuritySection2.vue.js.map +1 -0
- package/dist/views/system/config/components/SensitiveSection.vue.js +8 -0
- package/dist/views/system/config/components/SensitiveSection.vue.js.map +1 -0
- package/dist/views/system/config/components/SensitiveSection2.vue.js +214 -0
- package/dist/views/system/config/components/SensitiveSection2.vue.js.map +1 -0
- package/dist/views/system/config/components/SigninSection.vue.js +8 -0
- package/dist/views/system/config/components/SigninSection.vue.js.map +1 -0
- package/dist/views/system/config/components/SigninSection2.vue.js +201 -0
- package/dist/views/system/config/components/SigninSection2.vue.js.map +1 -0
- package/dist/views/system/config/components/UploadSection.vue.js +8 -0
- package/dist/views/system/config/components/UploadSection.vue.js.map +1 -0
- package/dist/views/system/config/components/UploadSection2.vue.js +176 -0
- package/dist/views/system/config/components/UploadSection2.vue.js.map +1 -0
- 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 +148 -0
- package/dist/views/system/config/draft.js +170 -0
- package/dist/views/system/config/draft.js.map +1 -0
- package/dist/views/system/config/flash.d.ts +2 -0
- package/dist/views/system/config/flash.js +9 -0
- package/dist/views/system/config/flash.js.map +1 -0
- package/dist/views/system/config/groups.d.ts +38 -7
- package/dist/views/system/config/groups.js +104 -14
- package/dist/views/system/config/groups.js.map +1 -1
- package/dist/views/system/config/index.vue.js +6 -2
- package/dist/views/system/config/index.vue.js.map +1 -1
- package/dist/views/system/config/index2.vue.js +201 -111
- 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/config/providerForm.d.ts +33 -0
- package/dist/views/system/config/providerForm.js +63 -0
- package/dist/views/system/config/providerForm.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 +6 -8
- 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.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.js +0 -8
- package/dist/views/login/skins/SplitPanel.vue.js.map +0 -1
- package/dist/views/login/skins/SplitPanel2.vue.js +0 -85
- package/dist/views/login/skins/SplitPanel2.vue.js.map +0 -1
- 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/views/system/config/components/ExternalAuthConfig.vue.js +0 -8
- package/dist/views/system/config/components/ExternalAuthConfig.vue.js.map +0 -1
- package/dist/views/system/config/components/ExternalAuthConfig2.vue.js +0 -218
- package/dist/views/system/config/components/ExternalAuthConfig2.vue.js.map +0 -1
- package/dist/views/system/config/components/GroupExtraConfig.vue.js +0 -8
- package/dist/views/system/config/components/GroupExtraConfig.vue.js.map +0 -1
- package/dist/views/system/config/components/GroupExtraConfig2.vue.js +0 -108
- package/dist/views/system/config/components/GroupExtraConfig2.vue.js.map +0 -1
- package/dist/views/system/config/components/HighSensConfig.vue.js +0 -5
- package/dist/views/system/config/components/HighSensConfig.vue.js.map +0 -1
- package/dist/views/system/config/components/HighSensConfig2.vue.js +0 -134
- package/dist/views/system/config/components/HighSensConfig2.vue.js.map +0 -1
- package/dist/views/system/config/components/JobConfig.vue.js +0 -5
- package/dist/views/system/config/components/JobConfig.vue.js.map +0 -1
- package/dist/views/system/config/components/JobConfig2.vue.js +0 -116
- package/dist/views/system/config/components/JobConfig2.vue.js.map +0 -1
- package/dist/views/system/config/components/OtherConfig.vue.js +0 -5
- package/dist/views/system/config/components/OtherConfig.vue.js.map +0 -1
- package/dist/views/system/config/components/OtherConfig2.vue.js +0 -121
- package/dist/views/system/config/components/OtherConfig2.vue.js.map +0 -1
- package/dist/views/system/config/components/SecurityConfig.vue.js +0 -8
- package/dist/views/system/config/components/SecurityConfig.vue.js.map +0 -1
- package/dist/views/system/config/components/SecurityConfig2.vue.js +0 -456
- package/dist/views/system/config/components/SecurityConfig2.vue.js.map +0 -1
- package/dist/views/system/config/components/SysBaseConfig.vue.js +0 -5
- package/dist/views/system/config/components/SysBaseConfig.vue.js.map +0 -1
- package/dist/views/system/config/components/SysBaseConfig2.vue.js +0 -107
- package/dist/views/system/config/components/SysBaseConfig2.vue.js.map +0 -1
- package/dist/views/system/config/components/UploadConfig.vue.d.ts +0 -3
- package/dist/views/system/config/components/UploadConfig.vue.js +0 -5
- package/dist/views/system/config/components/UploadConfig.vue.js.map +0 -1
- package/dist/views/system/config/components/UploadConfig2.vue.js +0 -135
- package/dist/views/system/config/components/UploadConfig2.vue.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/AdminMock.vue.d.ts} +0 -0
- /package/dist/views/{login/skins/SplitPanel.vue.d.ts → system/config/components/AdvancedSection.vue.d.ts} +0 -0
- /package/dist/views/{login/skins/Spotlight.vue.d.ts → system/config/components/JobSection.vue.d.ts} +0 -0
- /package/dist/views/system/config/components/{ExternalAuthConfig.vue.d.ts → LogoEditor.vue.d.ts} +0 -0
- /package/dist/views/system/config/components/{HighSensConfig.vue.d.ts → SecuritySection.vue.d.ts} +0 -0
- /package/dist/views/system/config/components/{JobConfig.vue.d.ts → SensitiveSection.vue.d.ts} +0 -0
- /package/dist/views/system/config/components/{OtherConfig.vue.d.ts → SigninSection.vue.d.ts} +0 -0
- /package/dist/views/system/config/components/{SecurityConfig.vue.d.ts → UploadSection.vue.d.ts} +0 -0
- /package/dist/views/system/config/components/{SysBaseConfig.vue.d.ts → WatermarkSection.vue.d.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppHeader2.vue.js","sources":["../../src/layouts/AppHeader.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, h, ref } from 'vue'\nimport { useRoute, useRouter } from 'vue-router'\nimport {\n NAvatar,\n NButton,\n NDropdown,\n NTooltip,\n NMenu,\n NBreadcrumb,\n NBreadcrumbItem,\n useMessage,\n type DropdownOption,\n} from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport { useI18n } from 'vue-i18n'\nimport { useAppStore, type Locale } from '#/stores/app'\nimport { useUserStore } from '#/stores/user'\nimport { useAuthStore } from '#/stores/auth'\nimport { useLayoutMenu } from '#/composables/useLayoutMenu'\nimport { useMenuFlat } from '#/composables/useMenuFlat'\nimport { useSite } from '#/composables/useSite'\nimport { useFullscreenToggle } from '#/composables/useFullscreenToggle'\nimport { useHeaderTools } from '#/composables/useHeaderTools'\nimport { authApi } from '#/api'\nimport { clearClientCache } from '#/composables/clearClientCache'\nimport { beginVoluntaryLogout } from '#/composables/useRealtime'\nimport { resetRouter } from '#/router'\nimport { translateError } from '#/utils/error'\nimport SmartLogo from '#/components/SmartLogo.vue'\nimport AppIcon from '#/components/AppIcon.vue'\nimport SettingsDrawer from './SettingsDrawer.vue'\nimport MenuSearch from '#/components/MenuSearch.vue'\nimport NoticeBell from './NoticeBell.vue'\n\nwithDefaults(\n defineProps<{\n showCollapse?: boolean\n showBrand?: boolean\n topMenu?: 'full' | 'l1' | 'l2' | null\n }>(),\n { showCollapse: true, showBrand: false, topMenu: null },\n)\n\nconst app = useAppStore()\nconst { site } = useSite()\nconst user = useUserStore()\nconst auth = useAuthStore()\nconst route = useRoute()\nconst router = useRouter()\nconst message = useMessage()\nconst { t } = useI18n()\n// 自研而非 VueUse useFullscreen:后者在 iPadOS 上只探标准 API,把明明能全屏的设备判成不支持。\n// isSupported=false(如 iPhone)时整个按钮不渲染,不留点了没反应的按钮。\nconst {\n isSupported: fullscreenSupported,\n isFullscreen,\n toggle: toggleFullscreen,\n} = useFullscreenToggle()\nconst { menuOptions, l1Options, l2Options, activeKey, selectedL1, onSelect, onSelectL1 } =\n useLayoutMenu()\nconst flat = useMenuFlat()\n// 扩展模块登记的顶栏入口(registerHeaderTool),渲染在内置铃铛左侧。\nconst headerTools = useHeaderTools()\n\nconst settingsOpen = ref(false)\nconst searchOpen = ref(false)\n\nconst title = computed(() => {\n const m = route.meta.title as string | undefined\n if (!m) return ''\n return m.includes('.') ? t(m) : m\n})\nconst crumbs = computed(() => flat.value.find(l => l.path === route.path)?.breadcrumb ?? [])\n\n// 语言名按各自书写系统展示,不随当前 locale 翻译。\nconst localeOptions: DropdownOption[] = [\n { label: '简体中文', key: 'zh-CN' },\n { label: 'English', key: 'en-US' },\n]\nfunction onLocale(key: string) {\n app.setLocale(key as Locale)\n}\n\n// 下拉图标(用户菜单:个人中心 / 清除缓存 / 退出)。\n// color 用于危险项(退出)整行红字+红图标。\nconst renderUserIcon = (name: string, color?: string) => () =>\n h(Icon, { icon: name, width: 16, style: color ? { color } : undefined })\n\n// 下拉:个人中心 / 清除缓存 / 退出;五块能力进 /personal 二级壳(见 PersonalLayout)。\nconst userOptions = computed<DropdownOption[]>(() => [\n { label: t('app.personalCenter'), key: 'personal', icon: renderUserIcon('ph:user') },\n { label: t('app.clearCache'), key: 'clearCache', icon: renderUserIcon('ph:broom') },\n { type: 'divider', key: 'd1' },\n // 退出用危险色突出,避免与普通项同权。\n {\n label: t('app.logout'),\n key: 'logout',\n icon: renderUserIcon('ph:sign-out', 'var(--color-danger)'),\n props: { style: 'color: var(--color-danger)' },\n },\n])\nasync function onUser(key: string) {\n if (key === 'personal') router.push('/personal/profile')\n else if (key === 'clearCache') await onClearCache()\n else if (key === 'logout') await logout()\n}\nasync function onClearCache() {\n try {\n await clearClientCache()\n message.success(t('app.cacheCleared'))\n } catch (e) {\n message.error(translateError(e))\n }\n}\nasync function logout() {\n // 先断实时并标记自愿退出:logout API 会 Revoke 会话并推 force-logout,避免误弹「您已被强制下线」。\n await beginVoluntaryLogout()\n try {\n await authApi.logout()\n } catch (e) {\n message.error(translateError(e)) // 尽力而为,不阻断登出\n }\n resetRouter()\n auth.reset() // 内部会 clearTabs()\n user.clear()\n router.replace('/login')\n}\n</script>\n\n<template>\n <div class=\"bar\">\n <div class=\"left\">\n <n-button\n v-if=\"showCollapse\"\n quaternary\n circle\n :aria-label=\"t('app.collapse')\"\n @click=\"app.toggleCollapsed()\"\n >\n <Icon :icon=\"app.collapsed ? 'ph:list' : 'ph:sidebar-simple'\" :width=\"20\" />\n </n-button>\n <div v-if=\"showBrand\" class=\"brand\">\n <SmartLogo :size=\"26\" />\n <span class=\"brand-name mobile-hide\">{{ site.title }}</span>\n </div>\n <n-breadcrumb v-if=\"app.showBreadcrumb && crumbs.length\">\n <n-breadcrumb-item v-for=\"(c, i) in crumbs\" :key=\"i\">{{ c }}</n-breadcrumb-item>\n </n-breadcrumb>\n <span v-else class=\"title\">{{ title }}</span>\n </div>\n\n <div v-if=\"topMenu\" class=\"center\">\n <n-menu\n v-if=\"topMenu === 'full'\"\n mode=\"horizontal\"\n responsive\n :options=\"menuOptions\"\n :value=\"activeKey\"\n @update:value=\"onSelect\"\n />\n <n-menu\n v-else-if=\"topMenu === 'l1'\"\n mode=\"horizontal\"\n responsive\n :options=\"l1Options\"\n :value=\"selectedL1\"\n @update:value=\"onSelectL1\"\n />\n <n-menu\n v-else\n mode=\"horizontal\"\n responsive\n :options=\"l2Options\"\n :value=\"activeKey\"\n @update:value=\"onSelect\"\n />\n </div>\n\n <!-- mobile-hide:窄屏(<768px)藏起来的次要项。顶栏总宽 > 屏宽时右端会被 layout 的 overflow:hidden 裁掉,\n 而全站唯一的登出入口就在最右边的用户下拉里 —— 手机上不能因为一排图标而退不出登录。\n 搜索有 Ctrl+K 兜底、全屏在手机上无意义、语言与设置属低频(设置抽屉本就是宽屏调布局用的)。 -->\n <div class=\"right\">\n <n-tooltip>\n <template #trigger>\n <n-button quaternary circle class=\"mobile-hide\" @click=\"searchOpen = true\">\n <Icon icon=\"ph:magnifying-glass\" :width=\"18\" />\n </n-button>\n </template>\n {{ t('app.search') }} (Ctrl+K)\n </n-tooltip>\n\n <n-tooltip v-if=\"fullscreenSupported\">\n <template #trigger>\n <n-button\n quaternary\n circle\n class=\"mobile-hide\"\n :aria-label=\"isFullscreen ? t('app.exitFullscreen') : t('app.fullscreen')\"\n @click=\"toggleFullscreen()\"\n >\n <Icon :icon=\"isFullscreen ? 'ph:arrows-in' : 'ph:arrows-out'\" :width=\"18\" />\n </n-button>\n </template>\n {{ isFullscreen ? t('app.exitFullscreen') : t('app.fullscreen') }}\n </n-tooltip>\n\n <n-tooltip>\n <template #trigger>\n <n-button quaternary circle @click=\"app.toggleDark()\">\n <Icon :icon=\"app.isDark ? 'ph:moon-stars' : 'ph:sun'\" :width=\"18\" />\n </n-button>\n </template>\n {{ app.isDark ? t('app.dark') : t('app.light') }}\n </n-tooltip>\n\n <n-dropdown :options=\"localeOptions\" @select=\"onLocale\">\n <n-button quaternary circle class=\"mobile-hide\" :aria-label=\"t('app.language')\">\n <Icon icon=\"ph:translate\" :width=\"18\" />\n </n-button>\n </n-dropdown>\n\n <n-tooltip>\n <template #trigger>\n <n-button quaternary circle class=\"mobile-hide\" @click=\"settingsOpen = true\">\n <Icon icon=\"ph:gear-six\" :width=\"18\" />\n </n-button>\n </template>\n {{ t('app.settings') }}\n </n-tooltip>\n\n <!-- 导航到应用选择页,而非下拉直切:应用一多下拉就难用,且\"设为默认\"只在选择页上。 -->\n <n-tooltip v-if=\"auth.modules.length > 1\">\n <template #trigger>\n <n-button\n quaternary\n circle\n :aria-label=\"t('app.switchModule')\"\n @click=\"router.push('/module')\"\n >\n <Icon icon=\"ph:squares-four\" :width=\"18\" />\n </n-button>\n </template>\n {{ t('app.switchModule') }}\n </n-tooltip>\n\n <!-- 扩展模块的入口:图标模式画成同款圆形按钮,组件模式整块交给它自己(自带角标/弹层时用) -->\n <template v-for=\"tool in headerTools\" :key=\"tool.key\">\n <component :is=\"tool.component\" v-if=\"tool.component\" />\n <n-tooltip v-else>\n <template #trigger>\n <n-button\n quaternary\n circle\n :class=\"{ 'mobile-hide': !tool.keepOnMobile }\"\n :aria-label=\"tool.label\"\n @click=\"tool.onClick()\"\n >\n <AppIcon :icon=\"tool.icon\" :size=\"18\" />\n </n-button>\n </template>\n {{ tool.label }}\n </n-tooltip>\n </template>\n\n <NoticeBell />\n\n <n-dropdown :options=\"userOptions\" @select=\"onUser\">\n <n-button quaternary :aria-label=\"t('app.profile')\">\n <!-- 有头像用头像(profile 页可传),没有回落原图标;头像来源见 stores/user.ts 的 avatar 注释 -->\n <n-avatar v-if=\"user.userInfo?.avatar\" round :size=\"22\" :src=\"user.userInfo.avatar\" />\n <Icon v-else icon=\"ph:user-circle\" :width=\"20\" />\n <span class=\"uname mobile-hide\">\n {{ user.userInfo?.name ?? user.userInfo?.account ?? '' }}\n </span>\n </n-button>\n </n-dropdown>\n </div>\n\n <SettingsDrawer v-model:show=\"settingsOpen\" />\n <MenuSearch v-model:show=\"searchOpen\" />\n </div>\n</template>\n\n<style scoped>\n.bar {\n height: 100%;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 0 16px;\n}\n/* 可收缩(min-width:0 + overflow):右侧那组是刚需(含唯一的登出入口),要挤先挤左边的标题/面包屑。 */\n.left {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n overflow: hidden;\n}\n.brand {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--color-text-primary);\n font-weight: 600;\n flex-shrink: 0;\n}\n.brand-name {\n font-size: var(--font-size-md);\n}\n.title {\n font-size: var(--font-size-md);\n font-weight: 500;\n color: var(--color-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.uname {\n margin-left: 6px;\n}\n.center {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n}\n.right {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-left: auto;\n flex-shrink: 0;\n}\n\n/* 窄屏(断点与 layouts/default.vue 的 breakpointsTailwind.smaller('md') 一致):\n 只留暗色/应用切换/铃铛/用户下拉,其余隐藏,保证最右的登出入口不被裁掉。 */\n@media (max-width: 767px) {\n .bar {\n gap: 8px;\n padding: 0 8px;\n }\n .mobile-hide {\n display: none;\n }\n}\n</style>\n"],"names":["app","useAppStore","site","useSite","user","useUserStore","auth","useAuthStore","route","useRoute","router","useRouter","message","useMessage","t","useI18n","fullscreenSupported","isFullscreen","toggleFullscreen","useFullscreenToggle","menuOptions","l1Options","l2Options","activeKey","selectedL1","onSelect","onSelectL1","useLayoutMenu","flat","useMenuFlat","headerTools","useHeaderTools","settingsOpen","ref","searchOpen","title","computed","m","crumbs","_a","l","localeOptions","onLocale","key","renderUserIcon","name","color","h","Icon","userOptions","onUser","onClearCache","logout","clearClientCache","e","translateError","beginVoluntaryLogout","authApi","resetRouter","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","__props","_createBlock","_unref","NButton","_cache","$event","_createVNode","_hoisted_3","SmartLogo","_hoisted_4","_toDisplayString","NBreadcrumb","_Fragment","_renderList","c","i","NBreadcrumbItem","_hoisted_5","_hoisted_6","NMenu","_hoisted_7","NTooltip","_createTextVNode","NDropdown","tool","_resolveDynamicComponent","_normalizeClass","AppIcon","NoticeBell","NAvatar","_hoisted_8","SettingsDrawer","MenuSearch"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AppHeader2.vue.js","sources":["../../src/layouts/AppHeader.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, h, nextTick, onMounted, onScopeDispose, ref } from 'vue'\nimport { useRoute, useRouter } from 'vue-router'\nimport {\n NAvatar,\n NButton,\n NButtonGroup,\n NDropdown,\n NTooltip,\n NMenu,\n NBreadcrumb,\n NBreadcrumbItem,\n useMessage,\n type DropdownOption,\n} from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport { useBreakpoints, breakpointsTailwind } from '@vueuse/core'\nimport { useI18n } from 'vue-i18n'\nimport { useAppStore, type Locale } from '#/stores/app'\nimport { useUserStore } from '#/stores/user'\nimport { useAuthStore } from '#/stores/auth'\nimport { useLayoutMenu } from '#/composables/useLayoutMenu'\nimport { useMenuFlat } from '#/composables/useMenuFlat'\nimport { useSite } from '#/composables/useSite'\nimport { useFullscreenToggle } from '#/composables/useFullscreenToggle'\nimport { useHeaderTools } from '#/composables/useHeaderTools'\nimport { authApi } from '#/api'\nimport { clearClientCache } from '#/composables/clearClientCache'\nimport { beginVoluntaryLogout } from '#/composables/useRealtime'\nimport { resetRouter } from '#/router'\nimport { translateError } from '#/utils/error'\nimport SmartLogo from '#/components/SmartLogo.vue'\nimport AppIcon from '#/components/AppIcon.vue'\nimport SettingsDrawer from './SettingsDrawer.vue'\nimport NoticeBell from './NoticeBell.vue'\n\nwithDefaults(\n defineProps<{\n showCollapse?: boolean\n showBrand?: boolean\n topMenu?: 'full' | 'l1' | 'l2' | null\n /** 顶栏是否出搜索按钮:侧栏已经带搜索入口时由 default.vue 关掉,免得同屏两个入口 */\n showSearch?: boolean\n }>(),\n { showCollapse: true, showBrand: false, topMenu: null, showSearch: true },\n)\nconst emit = defineEmits<{ search: [] }>()\n\nconst app = useAppStore()\nconst { site } = useSite()\nconst user = useUserStore()\nconst auth = useAuthStore()\nconst route = useRoute()\nconst router = useRouter()\nconst message = useMessage()\nconst { t } = useI18n()\n// 手机视口(< 768,与 layouts/default.vue 同一断点):顶栏只留侧栏开关 / 通知 / 头像,\n// 其余入口(外观设置、切换应用、语言)收进头像菜单,见 userOptions。\nconst isMobile = useBreakpoints(breakpointsTailwind).smaller('md')\n// 自研而非 VueUse useFullscreen:后者在 iPadOS 上只探标准 API,把明明能全屏的设备判成不支持。\n// isSupported=false(如 iPhone)时整个按钮不渲染,不留点了没反应的按钮。\nconst {\n isSupported: fullscreenSupported,\n isFullscreen,\n toggle: toggleFullscreen,\n} = useFullscreenToggle()\nconst { menuOptions, l1Options, l2Options, activeKey, selectedL1, onSelect, onSelectL1 } =\n useLayoutMenu()\nconst flat = useMenuFlat()\n// 扩展模块登记的顶栏入口(registerHeaderTool),渲染在内置铃铛左侧。\nconst headerTools = useHeaderTools()\n\nconst settingsOpen = ref(false)\n\nconst title = computed(() => {\n const m = route.meta.title as string | undefined\n if (!m) return ''\n return m.includes('.') ? t(m) : m\n})\nconst crumbs = computed(() => flat.value.find(l => l.path === route.path)?.breadcrumb ?? [])\n\n// 前进 / 后退:读 vue-router 写进 history.state 的 back / forward 指针,没有可去的地方就置灰。\n// 页签切换也是 router.push,所以后退会沿着浏览历史回到上一个页签的页面,和浏览器自己的后退一致。\nconst canBack = ref(false)\nconst canForward = ref(false)\nfunction syncHistory() {\n const s = window.history.state as { back?: string | null; forward?: string | null } | null\n canBack.value = !!s?.back\n canForward.value = !!s?.forward\n}\nonMounted(syncHistory)\n// afterEach 在 history.state 更新之后触发;nextTick 再兜一层,保证读到的是落定后的值。\nconst stopHistoryHook = router.afterEach(() => void nextTick(syncHistory))\nonScopeDispose(stopHistoryHook)\n\n// 语言名按各自书写系统展示,不随当前 locale 翻译。\nconst localeOptions: DropdownOption[] = [\n { label: '简体中文', key: 'zh-CN' },\n { label: 'English', key: 'en-US' },\n]\nfunction onLocale(key: string) {\n app.setLocale(key as Locale)\n}\n\n// 下拉图标(用户菜单:个人中心 / 外观设置 / 切换应用 / 清除缓存 / 退出)。\n// color 用于危险项(退出)整行红字+红图标。\nconst renderUserIcon = (name: string, color?: string) => () =>\n h(Icon, { icon: name, width: 16, style: color ? { color } : undefined })\n\nconst displayName = computed(() => user.userInfo?.name ?? user.userInfo?.account ?? '')\nconst initial = computed(() => displayName.value.trim().slice(0, 1).toUpperCase())\n\n// 下拉:账号信息头 / 个人中心 / 外观设置 / 切换应用 / 清除缓存 / 退出;五块能力进 /personal 二级壳(见 PersonalLayout)。\n// 下拉层 Teleport 到 body,不吃本组件的 scoped 样式,账号头用行内样式。\nconst userOptions = computed<DropdownOption[]>(() => {\n const list: DropdownOption[] = [\n {\n key: 'header',\n type: 'render',\n render: () =>\n h(\n 'div',\n {\n style:\n 'display:flex;flex-direction:column;gap:2px;padding:8px 12px 6px;min-width:200px;',\n },\n [\n h('b', { style: 'font-size:var(--font-size-md);font-weight:600;' }, displayName.value),\n user.userInfo?.account && user.userInfo.account !== displayName.value\n ? h(\n 'span',\n { style: 'font-size:var(--font-size-sm);color:var(--text-3);' },\n user.userInfo.account,\n )\n : null,\n ],\n ),\n },\n { type: 'divider', key: 'd0' },\n { label: t('app.personalCenter'), key: 'personal', icon: renderUserIcon('ph:user-circle') },\n { label: t('app.appearance'), key: 'settings', icon: renderUserIcon('ph:sliders-horizontal') },\n ]\n // 切换应用:多应用门户才有;顶栏那颗圆形按钮在手机上被收起,这里是它的落脚点\n if (auth.modules.length > 1)\n list.push({\n label: t('app.switchModule'),\n key: 'module',\n icon: renderUserIcon('ph:squares-four'),\n })\n // 语言:顶栏的语言按钮在手机上被收起,收进二级菜单\n if (isMobile.value)\n list.push({\n label: t('app.language'),\n key: 'locale',\n icon: renderUserIcon('ph:translate'),\n children: localeOptions.map(o => ({ ...o, key: `locale:${o.key}` })),\n })\n list.push(\n { label: t('app.clearCache'), key: 'clearCache', icon: renderUserIcon('ph:broom') },\n { type: 'divider', key: 'd1' },\n // 退出用危险色突出,避免与普通项同权。\n {\n label: t('app.logout'),\n key: 'logout',\n icon: renderUserIcon('ph:sign-out', 'var(--err)'),\n props: { style: 'color: var(--err)' },\n },\n )\n return list\n})\nasync function onUser(key: string) {\n if (key === 'personal') router.push('/personal/profile')\n else if (key === 'settings') settingsOpen.value = true\n else if (key === 'module') router.push('/module')\n else if (key.startsWith('locale:')) onLocale(key.slice('locale:'.length))\n else if (key === 'clearCache') await onClearCache()\n else if (key === 'logout') await logout()\n}\nasync function onClearCache() {\n try {\n await clearClientCache()\n message.success(t('app.cacheCleared'))\n } catch (e) {\n message.error(translateError(e))\n }\n}\nasync function logout() {\n // 先断实时并标记自愿退出:logout API 会 Revoke 会话并推 force-logout,避免误弹「您已被强制下线」。\n await beginVoluntaryLogout()\n try {\n await authApi.logout()\n } catch (e) {\n message.error(translateError(e)) // 尽力而为,不阻断登出\n }\n resetRouter()\n auth.reset() // 内部会 clearTabs()\n user.clear()\n router.replace('/login')\n}\n</script>\n\n<template>\n <div class=\"bar\">\n <div class=\"left\">\n <n-button\n v-if=\"showCollapse\"\n quaternary\n circle\n :aria-label=\"t('app.collapse')\"\n @click=\"app.toggleCollapsed()\"\n >\n <Icon icon=\"ph:sidebar-simple\" :width=\"19\" />\n </n-button>\n <n-button-group size=\"small\" class=\"mobile-hide\">\n <n-button\n quaternary\n circle\n :disabled=\"!canBack\"\n :aria-label=\"t('app.back')\"\n @click=\"router.back()\"\n >\n <Icon icon=\"ph:caret-left\" :width=\"16\" />\n </n-button>\n <n-button\n quaternary\n circle\n :disabled=\"!canForward\"\n :aria-label=\"t('app.forward')\"\n @click=\"router.forward()\"\n >\n <Icon icon=\"ph:caret-right\" :width=\"16\" />\n </n-button>\n </n-button-group>\n <div v-if=\"showBrand\" class=\"brand\">\n <SmartLogo :size=\"26\" />\n <span class=\"brand-name mobile-hide\">{{ site.title }}</span>\n </div>\n <!-- 手机上面包屑收起,换成当前页标题,免得顶栏只剩一个 Logo、看不出自己在哪一页 -->\n <n-breadcrumb v-if=\"!isMobile && app.showBreadcrumb && crumbs.length\" class=\"crumb\">\n <n-breadcrumb-item v-for=\"(c, i) in crumbs\" :key=\"i\">{{ c }}</n-breadcrumb-item>\n </n-breadcrumb>\n <span v-else class=\"title\">{{ title }}</span>\n </div>\n\n <div v-if=\"topMenu\" class=\"center\">\n <n-menu\n v-if=\"topMenu === 'full'\"\n mode=\"horizontal\"\n responsive\n :options=\"menuOptions\"\n :value=\"activeKey\"\n @update:value=\"onSelect\"\n />\n <n-menu\n v-else-if=\"topMenu === 'l1'\"\n mode=\"horizontal\"\n responsive\n :options=\"l1Options\"\n :value=\"selectedL1\"\n @update:value=\"onSelectL1\"\n />\n <n-menu\n v-else\n mode=\"horizontal\"\n responsive\n :options=\"l2Options\"\n :value=\"activeKey\"\n @update:value=\"onSelect\"\n />\n </div>\n\n <!-- mobile-hide:窄屏(<768px)藏起来的次要项。顶栏总宽 > 屏宽时右端会被 layout 的 overflow:hidden 裁掉,\n 而全站唯一的登出入口就在最右边的用户下拉里 —— 手机上不能因为一排图标而退不出登录。\n 手机只留侧栏开关(default.vue 的 .hbg)/ 通知 / 头像;外观设置、切换应用、语言进头像菜单,\n 搜索有侧栏里的入口与 Ctrl+K,全屏在手机上无意义,主题模式在外观设置里。 -->\n <div class=\"right\">\n <n-tooltip v-if=\"showSearch\">\n <template #trigger>\n <n-button\n quaternary\n circle\n class=\"mobile-hide\"\n :aria-label=\"t('app.search')\"\n @click=\"emit('search')\"\n >\n <Icon icon=\"ph:magnifying-glass\" :width=\"19\" />\n </n-button>\n </template>\n {{ t('app.search') }} (Ctrl+K)\n </n-tooltip>\n\n <n-tooltip>\n <template #trigger>\n <n-button\n quaternary\n circle\n class=\"mobile-hide\"\n :aria-label=\"app.isDark ? t('app.dark') : t('app.light')\"\n @click=\"app.toggleDark()\"\n >\n <Icon :icon=\"app.isDark ? 'ph:moon' : 'ph:sun'\" :width=\"19\" />\n </n-button>\n </template>\n {{ app.isDark ? t('app.dark') : t('app.light') }}\n </n-tooltip>\n\n <n-tooltip v-if=\"fullscreenSupported\">\n <template #trigger>\n <n-button\n quaternary\n circle\n class=\"mobile-hide\"\n :aria-label=\"isFullscreen ? t('app.exitFullscreen') : t('app.fullscreen')\"\n @click=\"toggleFullscreen()\"\n >\n <Icon :icon=\"isFullscreen ? 'ph:corners-in' : 'ph:corners-out'\" :width=\"19\" />\n </n-button>\n </template>\n {{ isFullscreen ? t('app.exitFullscreen') : t('app.fullscreen') }}\n </n-tooltip>\n\n <n-dropdown :options=\"localeOptions\" @select=\"onLocale\">\n <n-button quaternary circle class=\"mobile-hide\" :aria-label=\"t('app.language')\">\n <Icon icon=\"ph:translate\" :width=\"19\" />\n </n-button>\n </n-dropdown>\n\n <!-- 扩展模块的入口:图标模式画成同款圆形按钮,组件模式整块交给它自己(自带角标/弹层时用) -->\n <template v-for=\"tool in headerTools\" :key=\"tool.key\">\n <component :is=\"tool.component\" v-if=\"tool.component\" />\n <n-tooltip v-else>\n <template #trigger>\n <n-button\n quaternary\n circle\n :class=\"{ 'mobile-hide': !tool.keepOnMobile }\"\n :aria-label=\"tool.label\"\n @click=\"tool.onClick()\"\n >\n <AppIcon :icon=\"tool.icon\" :size=\"19\" />\n </n-button>\n </template>\n {{ tool.label }}\n </n-tooltip>\n </template>\n\n <NoticeBell />\n\n <!-- 导航到应用选择页,而非下拉直切:应用一多下拉就难用,且\"设为默认\"只在选择页上。 -->\n <n-tooltip v-if=\"auth.modules.length > 1\">\n <template #trigger>\n <n-button\n quaternary\n circle\n class=\"mobile-hide\"\n :aria-label=\"t('app.switchModule')\"\n @click=\"router.push('/module')\"\n >\n <Icon icon=\"ph:squares-four\" :width=\"19\" />\n </n-button>\n </template>\n {{ t('app.switchModule') }}\n </n-tooltip>\n\n <n-dropdown :options=\"userOptions\" placement=\"bottom-end\" @select=\"onUser\">\n <div class=\"top-user\" tabindex=\"0\" role=\"button\" :aria-label=\"t('app.profile')\">\n <!-- 有头像用头像(profile 页可传),没有回落姓名首字,再没有回落原图标;头像来源见 stores/user.ts 的 avatar 注释 -->\n <n-avatar v-if=\"user.userInfo?.avatar\" round :size=\"28\" :src=\"user.userInfo.avatar\" />\n <n-avatar v-else-if=\"initial\" round :size=\"28\">{{ initial }}</n-avatar>\n <Icon v-else icon=\"ph:user-circle\" :width=\"24\" />\n <span class=\"top-user-name mobile-hide\">{{ displayName }}</span>\n <Icon icon=\"ph:caret-down\" :width=\"13\" class=\"caret mobile-hide\" />\n </div>\n </n-dropdown>\n </div>\n\n <SettingsDrawer v-model:show=\"settingsOpen\" />\n </div>\n</template>\n\n<style scoped>\n.bar {\n height: 100%;\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 0 14px 0 10px;\n}\n/* 可收缩(min-width:0 + overflow):右侧那组是刚需(含唯一的登出入口),要挤先挤左边的标题/面包屑。 */\n.left {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n overflow: hidden;\n}\n.brand {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--text-1);\n font-weight: 600;\n flex-shrink: 0;\n}\n.brand-name {\n font-size: 15px;\n letter-spacing: -0.02em;\n}\n.crumb {\n margin-left: 6px;\n font-size: 14px;\n min-width: 0;\n}\n.title {\n margin-left: 6px;\n font-size: 14px;\n font-weight: 500;\n color: var(--text-1);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.center {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n}\n.right {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-left: auto;\n flex-shrink: 0;\n}\n\n/* 头像胶囊:头像 + 姓名 + 下拉箭头,悬停 / 聚焦出淡底与发丝描边 */\n.top-user {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n height: 34px;\n padding: 0 8px 0 4px;\n margin-left: 4px;\n border: 1px solid transparent;\n border-radius: 999px;\n cursor: pointer;\n transition:\n background-color var(--transition-fast),\n border-color var(--transition-fast);\n}\n.top-user:hover,\n.top-user:focus-visible {\n background: var(--hover);\n border-color: var(--hairline);\n outline: none;\n}\n.top-user-name {\n font-size: 14px;\n font-weight: 500;\n white-space: nowrap;\n}\n.caret {\n color: var(--text-3);\n}\n@media (max-width: 1100px) {\n .top-user-name {\n display: none;\n }\n}\n\n/* 窄屏(断点与 layouts/default.vue 的 breakpointsTailwind.smaller('md') 一致):\n 只留侧栏开关 / 通知 / 头像,其余隐藏,保证最右的登出入口不被裁掉。 */\n@media (max-width: 767px) {\n .bar {\n gap: 8px;\n padding: 0 8px;\n }\n .top-user {\n padding: 0 4px;\n margin-left: 0;\n }\n .mobile-hide {\n display: none !important;\n }\n}\n</style>\n"],"names":["emit","__emit","app","useAppStore","site","useSite","user","useUserStore","auth","useAuthStore","route","useRoute","router","useRouter","message","useMessage","t","useI18n","isMobile","useBreakpoints","breakpointsTailwind","fullscreenSupported","isFullscreen","toggleFullscreen","useFullscreenToggle","menuOptions","l1Options","l2Options","activeKey","selectedL1","onSelect","onSelectL1","useLayoutMenu","flat","useMenuFlat","headerTools","useHeaderTools","settingsOpen","ref","title","computed","m","crumbs","_a","l","canBack","canForward","syncHistory","s","onMounted","stopHistoryHook","nextTick","onScopeDispose","localeOptions","onLocale","key","renderUserIcon","name","color","h","Icon","displayName","_b","initial","userOptions","list","o","onUser","onClearCache","logout","clearClientCache","e","translateError","beginVoluntaryLogout","authApi","resetRouter","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","__props","_createBlock","_unref","NButton","_cache","$event","_createVNode","NButtonGroup","_hoisted_3","SmartLogo","_hoisted_4","_toDisplayString","NBreadcrumb","_Fragment","_renderList","c","i","NBreadcrumbItem","_hoisted_5","_hoisted_6","NMenu","_hoisted_7","NTooltip","_createTextVNode","NDropdown","tool","_resolveDynamicComponent","_normalizeClass","AppIcon","NoticeBell","NAvatar","_hoisted_9","SettingsDrawer"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import o from "./NoticeBell2.vue.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import t from "../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
-
const
|
|
4
|
+
const m = /* @__PURE__ */ t(o, [["__scopeId", "data-v-3a2e9bdd"]]);
|
|
5
5
|
export {
|
|
6
|
-
|
|
6
|
+
m as default
|
|
7
7
|
};
|
|
8
8
|
//# sourceMappingURL=NoticeBell.vue.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NoticeBell2.vue.js","sources":["../../src/layouts/NoticeBell.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 顶栏消息通知铃铛。富面板(n-popover):无页签单列表 + 正文弹层。\n// 未读=圆点+加粗+淡主色底,已读=整行变淡;\"读没读\"是过滤器不是分类,不做成页签(筛选在个人通知页)。\n// 未读数每 30s 轮询;面板展开时拉取列表。\n// 通知带动作列表时,正文弹层底部渲染成按钮(useNoticeAction):铃铛里直接\"办\",不必先跳到目标页面找按钮。\nimport { ref } from 'vue'\nimport { useRouter } from 'vue-router'\nimport {\n NPopover,\n NBadge,\n NButton,\n NTag,\n NEllipsis,\n NScrollbar,\n NSpace,\n NText,\n NEmpty,\n NModal,\n NSpin,\n useMessage,\n} from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport { useIntervalFn } from '@vueuse/core'\nimport { useI18n } from 'vue-i18n'\nimport { noticeApi } from '#/api'\nimport { noticeBus } from '#/composables/useRealtime'\nimport { useNoticeAction } from '#/composables/useNoticeAction'\nimport { NoticeType, type NoticeAction, type NoticeMineItem } from '#/types/api'\nimport MarkdownView from '#/components/MarkdownEditor/MarkdownView.vue'\nimport { translateError } from '#/utils/error'\nimport { fmtDateTime } from '#/utils/format'\n\nconst { t } = useI18n()\nconst router = useRouter()\nconst message = useMessage()\nconst noticeAction = useNoticeAction()\n\nconst unread = ref(0)\nconst items = ref<NoticeMineItem[]>([])\nconst loading = ref(false)\nconst panelShow = ref(false)\n\nasync function fetchUnread() {\n try {\n unread.value = await noticeApi.unreadCount()\n } catch {\n /* 轮询失败静默,下次自愈 */\n }\n}\n// 无页签单列表:恒拉最近一页混排,未读靠条目样式强调;筛选能力在\"查看全部\"的个人通知页。\nasync function fetchList() {\n loading.value = true\n try {\n const { items: list } = await noticeApi.mine({ page: 1, pageSize: 10 })\n items.value = list\n } catch {\n items.value = []\n } finally {\n loading.value = false\n }\n}\nfunction onShow(show: boolean) {\n if (show) fetchList()\n}\n\n// 正文弹层:内容随列表取回,直接渲染(Markdown,不能纯文本直出);点条目即标记已读。\nconst showNotice = ref(false)\nconst viewNotice = ref<NoticeMineItem | null>(null)\nasync function markRead(item: NoticeMineItem) {\n if (item.isRead) return\n try {\n await noticeApi.markRead(item.id)\n item.isRead = true\n await fetchUnread()\n } catch (e) {\n message.error(translateError(e))\n }\n}\nasync function openNotice(item: NoticeMineItem) {\n viewNotice.value = item\n showNotice.value = true\n await markRead(item)\n}\n// 动作:成功后关掉弹层与面板(页面跳转时尤其要关,否则面板盖在新页面上)。\nconst running = ref<number | null>(null)\nasync function onAction(a: NoticeAction, index: number) {\n running.value = index\n try {\n if (await noticeAction.run(a)) {\n showNotice.value = false\n panelShow.value = false\n }\n } finally {\n running.value = null\n }\n}\nasync function markAllRead() {\n try {\n await noticeApi.markAllRead()\n await Promise.all([fetchUnread(), fetchList()])\n } catch (e) {\n message.error(translateError(e))\n }\n}\nfunction viewAll() {\n panelShow.value = false\n router.push('/personal/notice')\n}\n\n// 类型 → 标签色/文案。新增类型在此补一行即可。\nconst tagType = (ty: NoticeType) =>\n ty === NoticeType.Announcement ? 'warning' : ty === NoticeType.Message ? 'success' : 'info'\nconst typeLabel = (ty: NoticeType) =>\n ty === NoticeType.Announcement\n ? t('notice.typeAnnouncement')\n : ty === NoticeType.Message\n ? t('notice.typeMessage')\n : t('notice.typeNotice')\n\n// 正文摘要:去掉常见 Markdown 记号,压空白,截断。ponytail: 正则够用,要精准渲染再引 md 解析。\nfunction snippet(md?: string | null) {\n if (!md) return ''\n const s = md\n .replace(/!\\[[^\\]]*\\]\\([^)]*\\)/g, '') // 图片\n .replace(/\\[([^\\]]*)\\]\\([^)]*\\)/g, '$1') // 链接留文字\n .replace(/[#>*_`~-]/g, '') // 记号\n .replace(/\\s+/g, ' ')\n .trim()\n return s.length > 60 ? s.slice(0, 60) + '…' : s\n}\n\n// 双腿:实时推送到达即刷新未读(SignalR 开启时,即时);30s 轮询兜底(实时关闭/连接掉线时)。\n// VueUse 的 useEventBus.on 在组件卸载时自动退订。\nnoticeBus.on(() => {\n fetchUnread()\n})\nuseIntervalFn(fetchUnread, 30000)\nfetchUnread()\n</script>\n\n<template>\n <n-popover\n v-model:show=\"panelShow\"\n trigger=\"click\"\n placement=\"bottom-end\"\n :show-arrow=\"false\"\n style=\"padding: 0\"\n @update:show=\"onShow\"\n >\n <template #trigger>\n <n-badge :value=\"unread\" :max=\"99\" :show=\"unread > 0\">\n <n-button quaternary circle :aria-label=\"t('app.notice.title')\">\n <Icon icon=\"ph:bell\" :width=\"18\" />\n </n-button>\n </n-badge>\n </template>\n\n <div class=\"notice-panel\">\n <div class=\"notice-head\">\n <span class=\"notice-title\">{{ t('app.notice.title') }}</span>\n <n-button text size=\"tiny\" :disabled=\"unread === 0\" @click=\"markAllRead\">\n <template #icon><Icon icon=\"ph:checks\" :width=\"15\" /></template>\n {{ t('app.notice.markAllRead') }}\n </n-button>\n </div>\n\n <n-spin :show=\"loading\">\n <n-scrollbar style=\"max-height: 360px\">\n <div v-if=\"items.length === 0\" class=\"notice-empty\">\n <n-empty :description=\"t('app.notice.empty')\" size=\"small\" />\n </div>\n <ul v-else class=\"notice-list\">\n <li\n v-for=\"n in items\"\n :key=\"n.id\"\n :class=\"['notice-item', n.isRead ? 'read' : 'unread']\"\n @click=\"openNotice(n)\"\n >\n <span v-if=\"!n.isRead\" class=\"dot\" />\n <div class=\"notice-body\">\n <div class=\"line1\">\n <n-tag :type=\"tagType(n.type)\" size=\"tiny\" :bordered=\"false\" round>\n {{ typeLabel(n.type) }}\n </n-tag>\n <n-ellipsis class=\"item-title\" :class=\"{ unread: !n.isRead }\">\n {{ n.title }}\n </n-ellipsis>\n <Icon\n v-if=\"n.actions?.length\"\n icon=\"ph:lightning\"\n :width=\"13\"\n class=\"item-actions-mark\"\n />\n </div>\n <n-text v-if=\"snippet(n.content)\" depth=\"3\" class=\"item-snippet\">\n {{ snippet(n.content) }}\n </n-text>\n <n-text depth=\"3\" class=\"item-time\">\n {{ fmtDateTime(n.publishTime, { seconds: false }) }}\n </n-text>\n </div>\n </li>\n </ul>\n </n-scrollbar>\n </n-spin>\n\n <div class=\"notice-foot\">\n <n-button text size=\"small\" @click=\"viewAll\">\n {{ t('app.notice.viewAll') }}\n <template #icon><Icon icon=\"ph:arrow-right\" :width=\"14\" /></template>\n </n-button>\n </div>\n </div>\n </n-popover>\n\n <n-modal\n v-model:show=\"showNotice\"\n preset=\"card\"\n :title=\"viewNotice?.title || t('notice.detailTitle')\"\n style=\"width: 640px; max-width: 92vw\"\n >\n <MarkdownView :value=\"viewNotice?.content\" />\n <template v-if=\"viewNotice?.actions?.length\" #footer>\n <n-space justify=\"end\">\n <n-button\n v-for=\"(a, i) in viewNotice.actions\"\n :key=\"i\"\n size=\"small\"\n :type=\"noticeAction.buttonType(a)\"\n :loading=\"running === i\"\n :disabled=\"running !== null && running !== i\"\n @click=\"onAction(a, i)\"\n >\n {{ noticeAction.label(a) }}\n </n-button>\n </n-space>\n </template>\n </n-modal>\n</template>\n\n<style scoped>\n.notice-panel {\n width: 360px;\n max-width: 92vw;\n}\n.notice-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px 4px;\n}\n.notice-title {\n font-weight: 600;\n font-size: var(--font-size-md);\n}\n.notice-empty {\n padding: 32px 0;\n}\n.notice-list {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.notice-item {\n position: relative;\n display: flex;\n gap: 8px;\n padding: 12px 16px;\n cursor: pointer;\n border-top: 1px solid var(--n-divider-color, rgba(128, 128, 128, 0.15));\n transition: background-color 0.2s;\n}\n.notice-item:hover {\n background-color: rgba(128, 128, 128, 0.08);\n}\n/* 未读:整行淡主色底(明暗主题都成立);已读:整行变淡 */\n.notice-item.unread {\n background-color: color-mix(in srgb, var(--color-primary) 4%, transparent);\n}\n.notice-item.unread:hover {\n background-color: color-mix(in srgb, var(--color-primary) 9%, transparent);\n}\n.notice-item.read {\n opacity: 0.55;\n}\n.dot {\n position: absolute;\n left: 6px;\n top: 18px;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--color-primary, #d03050);\n}\n.notice-body {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.line1 {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n}\n.item-title {\n flex: 1;\n min-width: 0;\n font-size: var(--font-size-sm);\n}\n.item-title.unread {\n font-weight: 600;\n}\n.item-actions-mark {\n flex-shrink: 0;\n color: var(--color-primary, #d03050);\n}\n.item-snippet {\n font-size: 12px;\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n.item-time {\n font-size: 11px;\n}\n.notice-foot {\n display: flex;\n justify-content: center;\n padding: 8px;\n border-top: 1px solid var(--n-divider-color, rgba(128, 128, 128, 0.15));\n}\n</style>\n"],"names":["t","useI18n","router","useRouter","message","useMessage","noticeAction","useNoticeAction","unread","ref","items","loading","panelShow","fetchUnread","noticeApi","fetchList","list","onShow","show","showNotice","viewNotice","markRead","item","e","translateError","openNotice","running","onAction","a","index","markAllRead","viewAll","tagType","ty","NoticeType","typeLabel","snippet","md","s","noticeBus","useIntervalFn","_createVNode","_unref","NPopover","$event","NBadge","NButton","Icon","_createElementVNode","_hoisted_1","_hoisted_2","_hoisted_3","_toDisplayString","_createTextVNode","NSpin","NScrollbar","_openBlock","_createElementBlock","_hoisted_4","NEmpty","_hoisted_5","_Fragment","_renderList","n","_normalizeClass","_hoisted_7","_hoisted_8","_hoisted_9","NTag","NEllipsis","_a","_createBlock","NText","fmtDateTime","_hoisted_10","NModal","MarkdownView","_c","_b","NSpace","i"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"NoticeBell2.vue.js","sources":["../../src/layouts/NoticeBell.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 顶栏消息通知铃铛。富面板(n-popover):无页签单列表 + 正文弹层。\n// 未读=圆点+加粗+淡主色底,已读=整行变淡;\"读没读\"是过滤器不是分类,不做成页签(筛选在个人通知页)。\n// 未读数每 30s 轮询;面板展开时拉取列表。\n// 通知带动作列表时,正文弹层底部渲染成按钮(useNoticeAction):铃铛里直接\"办\",不必先跳到目标页面找按钮。\nimport { ref } from 'vue'\nimport { useRouter } from 'vue-router'\nimport {\n NPopover,\n NBadge,\n NButton,\n NTag,\n NEllipsis,\n NScrollbar,\n NSpace,\n NText,\n NEmpty,\n NModal,\n NSpin,\n useMessage,\n} from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport { useIntervalFn } from '@vueuse/core'\nimport { useI18n } from 'vue-i18n'\nimport { noticeApi } from '#/api'\nimport { noticeBus } from '#/composables/useRealtime'\nimport { useNoticeAction } from '#/composables/useNoticeAction'\nimport { NoticeType, type NoticeAction, type NoticeMineItem } from '#/types/api'\nimport MarkdownView from '#/components/MarkdownEditor/MarkdownView.vue'\nimport { translateError } from '#/utils/error'\nimport { fmtDateTime } from '#/utils/format'\n\nconst { t } = useI18n()\nconst router = useRouter()\nconst message = useMessage()\nconst noticeAction = useNoticeAction()\n\nconst unread = ref(0)\nconst items = ref<NoticeMineItem[]>([])\nconst loading = ref(false)\nconst panelShow = ref(false)\n\nasync function fetchUnread() {\n try {\n unread.value = await noticeApi.unreadCount()\n } catch {\n /* 轮询失败静默,下次自愈 */\n }\n}\n// 无页签单列表:恒拉最近一页混排,未读靠条目样式强调;筛选能力在\"查看全部\"的个人通知页。\nasync function fetchList() {\n loading.value = true\n try {\n const { items: list } = await noticeApi.mine({ page: 1, pageSize: 10 })\n items.value = list\n } catch {\n items.value = []\n } finally {\n loading.value = false\n }\n}\nfunction onShow(show: boolean) {\n if (show) fetchList()\n}\n\n// 正文弹层:内容随列表取回,直接渲染(Markdown,不能纯文本直出);点条目即标记已读。\nconst showNotice = ref(false)\nconst viewNotice = ref<NoticeMineItem | null>(null)\nasync function markRead(item: NoticeMineItem) {\n if (item.isRead) return\n try {\n await noticeApi.markRead(item.id)\n item.isRead = true\n await fetchUnread()\n } catch (e) {\n message.error(translateError(e))\n }\n}\nasync function openNotice(item: NoticeMineItem) {\n viewNotice.value = item\n showNotice.value = true\n await markRead(item)\n}\n// 动作:成功后关掉弹层与面板(页面跳转时尤其要关,否则面板盖在新页面上)。\nconst running = ref<number | null>(null)\nasync function onAction(a: NoticeAction, index: number) {\n running.value = index\n try {\n if (await noticeAction.run(a)) {\n showNotice.value = false\n panelShow.value = false\n }\n } finally {\n running.value = null\n }\n}\nasync function markAllRead() {\n try {\n await noticeApi.markAllRead()\n await Promise.all([fetchUnread(), fetchList()])\n } catch (e) {\n message.error(translateError(e))\n }\n}\nfunction viewAll() {\n panelShow.value = false\n router.push('/personal/notice')\n}\n\n// 类型 → 标签色/文案。新增类型在此补一行即可。\nconst tagType = (ty: NoticeType) =>\n ty === NoticeType.Announcement ? 'warning' : ty === NoticeType.Message ? 'success' : 'info'\nconst typeLabel = (ty: NoticeType) =>\n ty === NoticeType.Announcement\n ? t('notice.typeAnnouncement')\n : ty === NoticeType.Message\n ? t('notice.typeMessage')\n : t('notice.typeNotice')\n\n// 正文摘要:去掉常见 Markdown 记号,压空白,截断。ponytail: 正则够用,要精准渲染再引 md 解析。\nfunction snippet(md?: string | null) {\n if (!md) return ''\n const s = md\n .replace(/!\\[[^\\]]*\\]\\([^)]*\\)/g, '') // 图片\n .replace(/\\[([^\\]]*)\\]\\([^)]*\\)/g, '$1') // 链接留文字\n .replace(/[#>*_`~-]/g, '') // 记号\n .replace(/\\s+/g, ' ')\n .trim()\n return s.length > 60 ? s.slice(0, 60) + '…' : s\n}\n\n// 双腿:实时推送到达即刷新未读(SignalR 开启时,即时);30s 轮询兜底(实时关闭/连接掉线时)。\n// VueUse 的 useEventBus.on 在组件卸载时自动退订。\nnoticeBus.on(() => {\n fetchUnread()\n})\nuseIntervalFn(fetchUnread, 30000)\nfetchUnread()\n</script>\n\n<template>\n <n-popover\n v-model:show=\"panelShow\"\n trigger=\"click\"\n placement=\"bottom-end\"\n :show-arrow=\"false\"\n style=\"padding: 0\"\n @update:show=\"onShow\"\n >\n <template #trigger>\n <n-badge :value=\"unread\" :max=\"99\" :show=\"unread > 0\">\n <n-button quaternary circle :aria-label=\"t('app.notice.title')\">\n <Icon icon=\"ph:bell\" :width=\"19\" />\n </n-button>\n </n-badge>\n </template>\n\n <div class=\"notice-panel\">\n <div class=\"notice-head\">\n <span class=\"notice-title\">{{ t('app.notice.title') }}</span>\n <n-button text size=\"tiny\" :disabled=\"unread === 0\" @click=\"markAllRead\">\n <template #icon><Icon icon=\"ph:checks\" :width=\"15\" /></template>\n {{ t('app.notice.markAllRead') }}\n </n-button>\n </div>\n\n <n-spin :show=\"loading\">\n <n-scrollbar style=\"max-height: 360px\">\n <div v-if=\"items.length === 0\" class=\"notice-empty\">\n <n-empty :description=\"t('app.notice.empty')\" size=\"small\" />\n </div>\n <ul v-else class=\"notice-list\">\n <li\n v-for=\"n in items\"\n :key=\"n.id\"\n :class=\"['notice-item', n.isRead ? 'read' : 'unread']\"\n @click=\"openNotice(n)\"\n >\n <span v-if=\"!n.isRead\" class=\"dot\" />\n <div class=\"notice-body\">\n <div class=\"line1\">\n <n-tag :type=\"tagType(n.type)\" size=\"tiny\" :bordered=\"false\" round>\n {{ typeLabel(n.type) }}\n </n-tag>\n <n-ellipsis class=\"item-title\" :class=\"{ unread: !n.isRead }\">\n {{ n.title }}\n </n-ellipsis>\n <Icon\n v-if=\"n.actions?.length\"\n icon=\"ph:lightning\"\n :width=\"13\"\n class=\"item-actions-mark\"\n />\n </div>\n <n-text v-if=\"snippet(n.content)\" depth=\"3\" class=\"item-snippet\">\n {{ snippet(n.content) }}\n </n-text>\n <n-text depth=\"3\" class=\"item-time\">\n {{ fmtDateTime(n.publishTime, { seconds: false }) }}\n </n-text>\n </div>\n </li>\n </ul>\n </n-scrollbar>\n </n-spin>\n\n <div class=\"notice-foot\">\n <n-button text size=\"small\" @click=\"viewAll\">\n {{ t('app.notice.viewAll') }}\n <template #icon><Icon icon=\"ph:arrow-right\" :width=\"14\" /></template>\n </n-button>\n </div>\n </div>\n </n-popover>\n\n <n-modal\n v-model:show=\"showNotice\"\n preset=\"card\"\n :title=\"viewNotice?.title || t('notice.detailTitle')\"\n style=\"width: 640px; max-width: 92vw\"\n >\n <MarkdownView :value=\"viewNotice?.content\" />\n <template v-if=\"viewNotice?.actions?.length\" #footer>\n <n-space justify=\"end\">\n <n-button\n v-for=\"(a, i) in viewNotice.actions\"\n :key=\"i\"\n size=\"small\"\n :type=\"noticeAction.buttonType(a)\"\n :loading=\"running === i\"\n :disabled=\"running !== null && running !== i\"\n @click=\"onAction(a, i)\"\n >\n {{ noticeAction.label(a) }}\n </n-button>\n </n-space>\n </template>\n </n-modal>\n</template>\n\n<style scoped>\n.notice-panel {\n width: 360px;\n max-width: 92vw;\n}\n.notice-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px 4px;\n}\n.notice-title {\n font-weight: 600;\n font-size: 15px;\n}\n.notice-empty {\n padding: 32px 0;\n}\n.notice-list {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.notice-item {\n position: relative;\n display: flex;\n gap: 8px;\n padding: 12px 16px;\n cursor: pointer;\n border-top: 1px solid var(--separator);\n transition: background-color var(--transition-fast);\n}\n.notice-item:hover {\n background-color: var(--hover);\n}\n/* 未读:整行淡主色底(明暗主题都成立);已读:整行变淡 */\n.notice-item.unread {\n background-color: color-mix(in srgb, var(--signal) 5%, transparent);\n}\n.notice-item.unread:hover {\n background-color: color-mix(in srgb, var(--signal) 10%, transparent);\n}\n.notice-item.read {\n opacity: 0.55;\n}\n.dot {\n position: absolute;\n left: 6px;\n top: 18px;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--signal);\n}\n.notice-body {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.line1 {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n}\n.item-title {\n flex: 1;\n min-width: 0;\n font-size: 14px;\n}\n.item-title.unread {\n font-weight: 600;\n}\n.item-actions-mark {\n flex-shrink: 0;\n color: var(--signal);\n}\n.item-snippet {\n font-size: 13px;\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n.item-time {\n font-size: 12.5px;\n}\n.notice-foot {\n display: flex;\n justify-content: center;\n padding: 8px;\n border-top: 1px solid var(--separator);\n}\n</style>\n"],"names":["t","useI18n","router","useRouter","message","useMessage","noticeAction","useNoticeAction","unread","ref","items","loading","panelShow","fetchUnread","noticeApi","fetchList","list","onShow","show","showNotice","viewNotice","markRead","item","e","translateError","openNotice","running","onAction","a","index","markAllRead","viewAll","tagType","ty","NoticeType","typeLabel","snippet","md","s","noticeBus","useIntervalFn","_createVNode","_unref","NPopover","$event","NBadge","NButton","Icon","_createElementVNode","_hoisted_1","_hoisted_2","_hoisted_3","_toDisplayString","_createTextVNode","NSpin","NScrollbar","_openBlock","_createElementBlock","_hoisted_4","NEmpty","_hoisted_5","_Fragment","_renderList","n","_normalizeClass","_hoisted_7","_hoisted_8","_hoisted_9","NTag","NEllipsis","_a","_createBlock","NText","fmtDateTime","_hoisted_10","NModal","MarkdownView","_c","_b","NSpace","i"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import o from "./PersonalLayout2.vue.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import t from "../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
-
const
|
|
4
|
+
const p = /* @__PURE__ */ t(o, [["__scopeId", "data-v-6036bc95"]]);
|
|
5
5
|
export {
|
|
6
|
-
|
|
6
|
+
p as default
|
|
7
7
|
};
|
|
8
8
|
//# sourceMappingURL=PersonalLayout.vue.js.map
|
|
@@ -1,58 +1,80 @@
|
|
|
1
|
-
import { defineComponent as K, computed as
|
|
2
|
-
import { useRoute as
|
|
3
|
-
import { NMenu as
|
|
4
|
-
import {
|
|
5
|
-
import { useI18n as
|
|
6
|
-
import { useUserStore as
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class: "personal-sider"
|
|
10
|
-
}, S = { class: "personal-main" }, z = {
|
|
11
|
-
key: 0,
|
|
12
|
-
class: "personal-mobile-nav"
|
|
13
|
-
}, L = { class: "personal-content" }, F = /* @__PURE__ */ K({
|
|
1
|
+
import { defineComponent as K, computed as t, h as V, resolveComponent as B, openBlock as s, createElementBlock as k, normalizeClass as I, createBlock as p, unref as l, withCtx as c, createVNode as f, createCommentVNode as h, createElementVNode as b, Fragment as R, renderList as T, createTextVNode as M, toDisplayString as P } from "vue";
|
|
2
|
+
import { useRoute as S, useRouter as U } from "vue-router";
|
|
3
|
+
import { NCard as z, NMenu as A, NTabs as E, NTab as L } from "naive-ui";
|
|
4
|
+
import { Icon as O } from "@iconify/vue";
|
|
5
|
+
import { useI18n as D } from "vue-i18n";
|
|
6
|
+
import { useUserStore as F } from "../stores/user.js";
|
|
7
|
+
import { useShellBreakpoint as W } from "../composables/useShellBreakpoint.js";
|
|
8
|
+
const X = { class: "personal-main" }, j = { class: "personal-content" }, q = 760, ee = /* @__PURE__ */ K({
|
|
14
9
|
__name: "PersonalLayout",
|
|
15
|
-
setup(
|
|
16
|
-
const { t:
|
|
17
|
-
{ key: "/personal/profile", labelKey: "menu.profile" },
|
|
18
|
-
{ key: "/personal/password", labelKey: "menu.password" },
|
|
19
|
-
{ key: "/personal/security", labelKey: "menu.security" },
|
|
20
|
-
{ key: "/personal/sessions", labelKey: "menu.sessions" },
|
|
21
|
-
{ key: "/personal/bindings", labelKey: "menu.bindings" }
|
|
22
|
-
],
|
|
10
|
+
setup(x) {
|
|
11
|
+
const { t: _ } = D(), r = S(), C = U(), g = F(), { width: w } = W(), i = t(() => w.value < q), m = [
|
|
12
|
+
{ key: "/personal/profile", labelKey: "menu.profile", icon: "ph:user-circle" },
|
|
13
|
+
{ key: "/personal/password", labelKey: "menu.password", icon: "ph:key" },
|
|
14
|
+
{ key: "/personal/security", labelKey: "menu.security", icon: "ph:shield-check" },
|
|
15
|
+
{ key: "/personal/sessions", labelKey: "menu.sessions", icon: "ph:devices" },
|
|
16
|
+
{ key: "/personal/bindings", labelKey: "menu.bindings", icon: "ph:link-simple" }
|
|
17
|
+
], N = t(() => {
|
|
23
18
|
var e;
|
|
24
|
-
return !!((e =
|
|
25
|
-
}),
|
|
19
|
+
return !!((e = g.userInfo) != null && e.mustChangePassword);
|
|
20
|
+
}), u = t(() => (N.value ? m.filter((o) => o.key === "/personal/password") : [...m]).map((o) => ({ key: o.key, label: _(o.labelKey), icon: o.icon }))), d = t(() => {
|
|
26
21
|
var o;
|
|
27
|
-
const e =
|
|
28
|
-
return (e == null ? void 0 : e.key) ?? ((o =
|
|
29
|
-
}), y =
|
|
22
|
+
const e = u.value.find((a) => r.path === a.key || r.path.startsWith(a.key + "/"));
|
|
23
|
+
return (e == null ? void 0 : e.key) ?? ((o = u.value[0]) == null ? void 0 : o.key) ?? "/personal/profile";
|
|
24
|
+
}), y = t(
|
|
25
|
+
() => u.value.map((e) => ({
|
|
26
|
+
key: e.key,
|
|
27
|
+
label: e.label,
|
|
28
|
+
icon: () => V(O, { icon: e.icon, width: 18 })
|
|
29
|
+
}))
|
|
30
|
+
);
|
|
30
31
|
function v(e) {
|
|
31
|
-
e !==
|
|
32
|
+
e !== r.path && C.push(e);
|
|
32
33
|
}
|
|
33
34
|
return (e, o) => {
|
|
34
|
-
const
|
|
35
|
-
return
|
|
36
|
-
class:
|
|
35
|
+
const a = B("RouterView");
|
|
36
|
+
return s(), k("div", {
|
|
37
|
+
class: I(["personal-layout", { "is-compact": i.value }])
|
|
37
38
|
}, [
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
f("div", S, [
|
|
47
|
-
n(r) ? (u(), p("div", z, [
|
|
48
|
-
m(n(B), {
|
|
39
|
+
i.value ? h("", !0) : (s(), p(l(z), {
|
|
40
|
+
key: 0,
|
|
41
|
+
class: "personal-sider",
|
|
42
|
+
size: "small",
|
|
43
|
+
"content-style": "padding: 8px"
|
|
44
|
+
}, {
|
|
45
|
+
default: c(() => [
|
|
46
|
+
f(l(A), {
|
|
49
47
|
value: d.value,
|
|
50
|
-
options: y.value
|
|
51
|
-
|
|
48
|
+
options: y.value,
|
|
49
|
+
indent: 18,
|
|
50
|
+
"onUpdate:value": o[0] || (o[0] = (n) => v(n))
|
|
52
51
|
}, null, 8, ["value", "options"])
|
|
53
|
-
])
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
]),
|
|
53
|
+
_: 1
|
|
54
|
+
})),
|
|
55
|
+
b("div", X, [
|
|
56
|
+
i.value ? (s(), p(l(E), {
|
|
57
|
+
key: 0,
|
|
58
|
+
type: "segment",
|
|
59
|
+
class: "personal-tabs",
|
|
60
|
+
value: d.value,
|
|
61
|
+
"onUpdate:value": o[1] || (o[1] = (n) => v(n))
|
|
62
|
+
}, {
|
|
63
|
+
default: c(() => [
|
|
64
|
+
(s(!0), k(R, null, T(y.value, (n) => (s(), p(l(L), {
|
|
65
|
+
key: n.key,
|
|
66
|
+
name: n.key
|
|
67
|
+
}, {
|
|
68
|
+
default: c(() => [
|
|
69
|
+
M(P(n.label), 1)
|
|
70
|
+
]),
|
|
71
|
+
_: 2
|
|
72
|
+
}, 1032, ["name"]))), 128))
|
|
73
|
+
]),
|
|
74
|
+
_: 1
|
|
75
|
+
}, 8, ["value"])) : h("", !0),
|
|
76
|
+
b("div", j, [
|
|
77
|
+
f(a)
|
|
56
78
|
])
|
|
57
79
|
])
|
|
58
80
|
], 2);
|
|
@@ -60,6 +82,6 @@ const P = {
|
|
|
60
82
|
}
|
|
61
83
|
});
|
|
62
84
|
export {
|
|
63
|
-
|
|
85
|
+
ee as default
|
|
64
86
|
};
|
|
65
87
|
//# sourceMappingURL=PersonalLayout2.vue.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PersonalLayout2.vue.js","sources":["../../src/layouts/PersonalLayout.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 个人中心二级壳:主布局内容区内左侧子导航 + 右侧 RouterView。\n// 路径仍为 /personal/*;强制改密时只露出「修改密码」导航项。\nimport { computed } from 'vue'\nimport { useRoute, useRouter } from 'vue-router'\nimport { NMenu,
|
|
1
|
+
{"version":3,"file":"PersonalLayout2.vue.js","sources":["../../src/layouts/PersonalLayout.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 个人中心二级壳:主布局内容区内左侧子导航 + 右侧 RouterView。\n// 路径仍为 /personal/*;强制改密时只露出「修改密码」导航项。\n// 宽 / 中档子导航是左侧 200px 的卡片(n-menu);内容区 < 760 收成顶部横向分段控件(n-tabs segment)。\n// 按「内容区」宽度判而不是视口:侧栏展开 / 收起会改变可用宽度,和壳层三档同一个口径。\nimport { computed, h } from 'vue'\nimport { useRoute, useRouter } from 'vue-router'\nimport { NCard, NMenu, NTab, NTabs, type MenuOption } from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport { useI18n } from 'vue-i18n'\nimport { useUserStore } from '#/stores/user'\nimport { useShellBreakpoint } from '#/composables/useShellBreakpoint'\n\nconst { t } = useI18n()\nconst route = useRoute()\nconst router = useRouter()\nconst user = useUserStore()\nconst { width } = useShellBreakpoint()\n// 子导航收成分段控件的内容区宽度上界(不含)\nconst COMPACT_MAX = 760\nconst isCompact = computed(() => width.value < COMPACT_MAX)\n\nconst allNav = [\n { key: '/personal/profile', labelKey: 'menu.profile', icon: 'ph:user-circle' },\n { key: '/personal/password', labelKey: 'menu.password', icon: 'ph:key' },\n { key: '/personal/security', labelKey: 'menu.security', icon: 'ph:shield-check' },\n { key: '/personal/sessions', labelKey: 'menu.sessions', icon: 'ph:devices' },\n { key: '/personal/bindings', labelKey: 'menu.bindings', icon: 'ph:link-simple' },\n] as const\n\nconst mustChange = computed(() => !!user.userInfo?.mustChangePassword)\n\nconst navItems = computed(() => {\n const list = mustChange.value ? allNav.filter(x => x.key === '/personal/password') : [...allNav]\n return list.map(x => ({ key: x.key, label: t(x.labelKey), icon: x.icon }))\n})\n\nconst activeKey = computed(() => {\n const hit = navItems.value.find(x => route.path === x.key || route.path.startsWith(x.key + '/'))\n return hit?.key ?? navItems.value[0]?.key ?? '/personal/profile'\n})\n\n// 子导航每项带线条图标;分段控件(窄档)只放文字\nconst menuOptions = computed<MenuOption[]>(() =>\n navItems.value.map(x => ({\n key: x.key,\n label: x.label,\n icon: () => h(Icon, { icon: x.icon, width: 18 }),\n })),\n)\n\nfunction go(key: string) {\n if (key !== route.path) void router.push(key)\n}\n</script>\n\n<template>\n <div class=\"personal-layout\" :class=\"{ 'is-compact': isCompact }\">\n <n-card v-if=\"!isCompact\" class=\"personal-sider\" size=\"small\" content-style=\"padding: 8px\">\n <n-menu\n :value=\"activeKey\"\n :options=\"menuOptions\"\n :indent=\"18\"\n @update:value=\"(k: string) => go(k)\"\n />\n </n-card>\n <div class=\"personal-main\">\n <n-tabs\n v-if=\"isCompact\"\n type=\"segment\"\n class=\"personal-tabs\"\n :value=\"activeKey\"\n @update:value=\"(k: string) => go(k)\"\n >\n <n-tab v-for=\"o in menuOptions\" :key=\"o.key as string\" :name=\"o.key as string\">\n {{ o.label }}\n </n-tab>\n </n-tabs>\n <div class=\"personal-content\">\n <RouterView />\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.personal-layout {\n display: flex;\n gap: var(--gap-card);\n align-items: stretch;\n min-height: 100%;\n}\n.personal-sider {\n width: 200px;\n flex-shrink: 0;\n align-self: flex-start;\n}\n.personal-main {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: var(--gap-card);\n}\n.personal-tabs {\n flex-shrink: 0;\n}\n.personal-content {\n min-width: 0;\n}\n.personal-layout.is-compact {\n flex-direction: column;\n gap: var(--gap-card);\n}\n</style>\n"],"names":["COMPACT_MAX","t","useI18n","route","useRoute","router","useRouter","user","useUserStore","width","useShellBreakpoint","isCompact","computed","allNav","mustChange","_a","navItems","x","activeKey","hit","menuOptions","h","Icon","go","key","_createElementBlock","_normalizeClass","_createBlock","_unref","NCard","_createVNode","NMenu","_cache","k","_createElementVNode","_hoisted_1","NTabs","_Fragment","_renderList","o","NTab","_createTextVNode","_toDisplayString","_hoisted_2","_component_RouterView"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import t from "./SettingsDrawer2.vue.js";
|
|
2
2
|
/* empty css */
|
|
3
|
-
import
|
|
4
|
-
const
|
|
3
|
+
import a from "../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
+
const m = /* @__PURE__ */ a(t, [["__scopeId", "data-v-6325aaae"]]);
|
|
5
5
|
export {
|
|
6
|
-
|
|
6
|
+
m as default
|
|
7
7
|
};
|
|
8
8
|
//# sourceMappingURL=SettingsDrawer.vue.js.map
|