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":"index2.vue.js","sources":["../../../src/components/UserPicker/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, h, onMounted, reactive, ref, unref } from 'vue'\nimport { NButton, NEmpty, NInput, NTree, useMessage } from 'naive-ui'\nimport { SmartTable, type SmartTableColumn, type SmartTableInst } from 'smart-naive-table'\nimport { useI18n } from 'vue-i18n'\nimport AppIcon from '#/components/AppIcon.vue'\nimport FormContainer from '#/components/FormContainer/index.vue'\nimport { orgApi, userApi } from '#/api'\nimport { buildTree } from '#/utils/tree'\nimport { translateError } from '#/utils/error'\nimport type { SysOrg, UserItem } from '#/types/api'\n\nconst props = defineProps<{ excludeIds?: number[] }>()\nconst emit = defineEmits<{ (e: 'confirm', ids: number[]): void }>()\n\nconst { t } = useI18n()\nconst message = useMessage()\n\nconst show = ref(false)\nconst tableRef = ref<SmartTableInst<UserItem>>()\n\n// ── 机构树(左面板) ──\nconst orgFlat = ref<SysOrg[]>([])\nconst orgTree = computed(() => {\n const all = { id: 0, parentId: -1, name: t('common.all'), children: buildTree(orgFlat.value) }\n return [all]\n})\nconst selectedOrgKey = ref<number | null>(null)\nconst orgId = computed(() =>\n selectedOrgKey.value && selectedOrgKey.value !== 0 ? selectedOrgKey.value : undefined,\n)\n\nonMounted(async () => {\n try {\n orgFlat.value = await orgApi.list()\n } catch {\n /* 静默 */\n }\n})\n\nfunction onOrgSelect(keys: Array<string | number>) {\n selectedOrgKey.value = (keys[0] as number) ?? null\n tableRef.value?.refresh()\n}\n\n// ── 可选用户表(中间面板) ──\nconst checkedKeys = ref<(string | number)[]>([])\nconst excludeSet = computed(() => new Set(props.excludeIds ?? []))\n\nconst fetcher = (params: { page: number; pageSize: number; name?: string }) =>\n userApi.page({\n page: params.page,\n pageSize: params.pageSize,\n name: params.name,\n orgId: orgId.value,\n })\n\nconst columns: SmartTableColumn<UserItem>[] = [\n { type: 'selection' },\n { key: 'name', title: () => t('user.name'), width: 100 },\n { key: 'account', title: () => t('user.account'), width: 120, search: true },\n {\n key: 'op',\n title: () => t('common.operation'),\n width: 70,\n render: r => {\n const already = selectedSet.value.has(r.id) || excludeSet.value.has(r.id)\n return h(\n NButton,\n {\n size: 'tiny',\n type: 'primary',\n quaternary: true,\n disabled: already,\n onClick: () => addUsers([r]),\n },\n () => (already ? t('userPicker.added') : t('userPicker.add')),\n )\n },\n },\n]\n\n// ── 已选用户(右面板) ──\nconst selected = reactive<UserItem[]>([])\nconst selectedSet = computed(() => new Set(selected.map(u => u.id)))\nconst selectedSearch = ref('')\nconst filteredSelected = computed(() => {\n const q = selectedSearch.value.trim().toLowerCase()\n if (!q) return selected\n return selected.filter(\n u => u.name.toLowerCase().includes(q) || u.account.toLowerCase().includes(q),\n )\n})\n\nfunction addUsers(users: UserItem[]) {\n for (const u of users) {\n if (!selectedSet.value.has(u.id) && !excludeSet.value.has(u.id)) {\n selected.push(u)\n }\n }\n}\n\nfunction addChecked() {\n // SmartTable 只 expose rows,别改用未公开的 tableData —— 恒为 undefined。\n // unref 兼容类型声明的 Ref 与运行时 expose 解包两种形态。\n const rows = (unref(tableRef.value?.rows) ?? []).filter(r => checkedKeys.value.includes(r.id))\n addUsers(rows)\n checkedKeys.value = []\n}\n\nfunction removeUser(id: number) {\n const idx = selected.findIndex(u => u.id === id)\n if (idx >= 0) selected.splice(idx, 1)\n}\n\nfunction clearSelected() {\n selected.splice(0, selected.length)\n}\n\n// ── 公共 API ──\nasync function open(ids?: number[]) {\n selected.splice(0, selected.length)\n checkedKeys.value = []\n selectedSearch.value = ''\n selectedOrgKey.value = null\n show.value = true\n\n if (ids?.length) {\n try {\n // ponytail: 拉一页,靠 id 过滤。200 是内核 Api:MaxPageSize 的默认上限,再大后端直接回 48001。\n // 用户超过 200 个时,排在后面的 id 解析不出名字,走下面那条退回显示 id 的分支;\n // 真要支持更大规模的用户名单,再改成分页搜索。\n const { items } = await userApi.page({ page: 1, pageSize: 200 })\n const all = items.filter(u => ids.includes(u.id))\n // 没拉到的 id(翻页之外),退回只显示 id\n const found = new Set(all.map(u => u.id))\n for (const u of all) selected.push(u)\n for (const id of ids) {\n if (!found.has(id)) selected.push({ id, account: String(id), name: String(id) } as UserItem)\n }\n } catch {\n for (const id of ids) selected.push({ id, account: String(id), name: String(id) } as UserItem)\n }\n }\n}\n\nasync function handleConfirm() {\n const ids = selected.map(u => u.id)\n emit('confirm', ids)\n}\n\ndefineExpose({ open })\n</script>\n\n<template>\n <FormContainer\n v-model:show=\"show\"\n :title=\"t('userPicker.title')\"\n :width=\"1100\"\n :on-confirm=\"handleConfirm\"\n :confirm-text=\"t('common.confirm')\"\n >\n <div class=\"user-picker\">\n <!-- 左面板:机构树 -->\n <div class=\"picker-tree\">\n <div class=\"panel-header\">{{ t('org.title') }}</div>\n <n-tree\n :data=\"orgTree\"\n key-field=\"id\"\n label-field=\"name\"\n children-field=\"children\"\n selectable\n block-line\n default-expand-all\n :selected-keys=\"selectedOrgKey != null ? [selectedOrgKey] : []\"\n @update:selected-keys=\"onOrgSelect\"\n />\n </div>\n\n <!-- 中间面板:可选用户 -->\n <div class=\"picker-table\">\n <div class=\"panel-header\">\n <span>{{ t('userPicker.available') }}</span>\n <n-button\n size=\"tiny\"\n type=\"primary\"\n :disabled=\"checkedKeys.length === 0\"\n @click=\"addChecked\"\n >\n {{ t('userPicker.addChecked') }}({{ checkedKeys.length }})\n </n-button>\n </div>\n <SmartTable\n :default-page-size=\"100\"\n ref=\"tableRef\"\n :columns=\"columns\"\n :fetcher=\"fetcher\"\n :pagination=\"{ pageSize: 10 }\"\n size=\"small\"\n storage-key=\"user-picker\"\n :tool-button=\"false\"\n :checked-row-keys=\"checkedKeys\"\n @update:checked-row-keys=\"(keys: (string | number)[]) => (checkedKeys = keys)\"\n @error=\"e => message.error(translateError(e))\"\n />\n </div>\n\n <!-- 右面板:已选用户 -->\n <div class=\"picker-selected\">\n <div class=\"panel-header\">\n <span>{{ t('userPicker.selected') }}({{ selected.length }})</span>\n <n-button\n size=\"tiny\"\n quaternary\n type=\"error\"\n :disabled=\"selected.length === 0\"\n @click=\"clearSelected\"\n >\n {{ t('userPicker.clear') }}\n </n-button>\n </div>\n <n-input\n v-model:value=\"selectedSearch\"\n size=\"small\"\n clearable\n :placeholder=\"t('common.search')\"\n style=\"margin-bottom: 8px\"\n />\n <div class=\"selected-list\">\n <div v-for=\"u in filteredSelected\" :key=\"u.id\" class=\"selected-item\">\n <span class=\"selected-name\">\n {{ u.name }}\n <span class=\"selected-account\">({{ u.account }})</span>\n </span>\n <n-button size=\"tiny\" quaternary type=\"error\" @click=\"removeUser(u.id)\">\n <template #icon><AppIcon icon=\"ph:x\" :size=\"14\" /></template>\n </n-button>\n </div>\n <n-empty\n v-if=\"filteredSelected.length === 0\"\n :description=\"t('common.noData')\"\n style=\"padding: 24px 0\"\n />\n </div>\n </div>\n </div>\n </FormContainer>\n</template>\n\n<style scoped>\n.user-picker {\n display: flex;\n gap: 12px;\n min-height: 400px;\n}\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n font-size: 13px;\n font-weight: 600;\n padding: 0 0 8px;\n border-bottom: 1px solid var(--n-border-color, #e0e0e6);\n margin-bottom: 8px;\n}\n.picker-tree {\n width: 160px;\n flex-shrink: 0;\n overflow: auto;\n border-right: 1px solid var(--n-border-color, #e0e0e6);\n padding-right: 12px;\n}\n.picker-table {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n}\n.picker-selected {\n width: 200px;\n flex-shrink: 0;\n border-left: 1px solid var(--n-border-color, #e0e0e6);\n padding-left: 12px;\n display: flex;\n flex-direction: column;\n}\n.selected-list {\n flex: 1;\n overflow: auto;\n max-height: 380px;\n}\n.selected-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 4px 0;\n font-size: 13px;\n border-bottom: 1px solid var(--n-border-color, #e0e0e6);\n}\n.selected-item:last-child {\n border-bottom: none;\n}\n.selected-name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.selected-account {\n color: var(--n-text-color-disabled, #999);\n font-size: 12px;\n margin-left: 2px;\n}\n</style>\n"],"names":["props","__props","emit","__emit","t","useI18n","message","useMessage","show","ref","tableRef","orgFlat","orgTree","computed","buildTree","selectedOrgKey","orgId","onMounted","orgApi","onOrgSelect","keys","_a","checkedKeys","excludeSet","fetcher","params","userApi","columns","r","already","selectedSet","h","NButton","addUsers","selected","reactive","u","selectedSearch","filteredSelected","q","users","addChecked","rows","unref","removeUser","id","idx","clearSelected","open","ids","items","all","found","handleConfirm","__expose","_createBlock","FormContainer","$event","_unref","_createElementVNode","_hoisted_1","_hoisted_2","_hoisted_3","_toDisplayString","_createVNode","NTree","_hoisted_4","_hoisted_5","_createTextVNode","SmartTable","_cache","e","translateError","_hoisted_6","_hoisted_7","NInput","_hoisted_8","_createElementBlock","_Fragment","_renderList","_hoisted_9","_hoisted_10","AppIcon","NEmpty"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index2.vue.js","sources":["../../../src/components/UserPicker/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, h, onMounted, reactive, ref, unref } from 'vue'\nimport { NButton, NEmpty, NInput, NTab, NTabs, NTree, NTreeSelect, useMessage } from 'naive-ui'\nimport { SmartTable, type SmartTableColumn, type SmartTableInst } from 'smart-naive-table'\nimport { useI18n } from 'vue-i18n'\nimport { useWindowSize } from '@vueuse/core'\nimport AppIcon from '#/components/AppIcon.vue'\nimport FormContainer from '#/components/FormContainer/index.vue'\nimport { useShellBreakpoint } from '#/composables/useShellBreakpoint'\nimport { orgApi, userApi } from '#/api'\nimport { buildTree } from '#/utils/tree'\nimport { translateError } from '#/utils/error'\nimport { SEARCH_ACTIONS } from '#/utils/tableFilter'\nimport type { SysOrg, UserItem } from '#/types/api'\n\nconst props = defineProps<{ excludeIds?: number[] }>()\nconst emit = defineEmits<{ (e: 'confirm', ids: number[]): void }>()\n\nconst { t } = useI18n()\nconst message = useMessage()\n\nconst show = ref(false)\nconst tableRef = ref<SmartTableInst<UserItem>>()\n\n// 屏幕形态:\n// 宽 / 中档 = 居中弹窗里的三栏(机构树 | 可选用户 | 已选);\n// 窄档(壳层 < 600)= 底部抽屉,三栏收成「可选用户 / 已选」两页,机构树换成页内的树选择;\n// 内容区 < 900 但还不到窄档时仍是弹窗,三栏同样收成两页(1100 宽的三栏在这里放不下)。\n// 三栏选择器在抽屉里太局促,所以宽 / 中档固定用弹窗,不跟随「表单形态」全局偏好。\nconst { bp } = useShellBreakpoint()\nconst { width: winW } = useWindowSize()\nconst compact = computed(() => bp.value === 'narrow' || winW.value < 900)\nconst variant = computed(() => (bp.value === 'narrow' ? 'drawer' : 'modal'))\nconst tab = ref<'users' | 'selected'>('users')\nconst btnSize = computed(() => (compact.value ? 'large' : 'small'))\n\n// ── 机构树(左面板) ──\nconst orgFlat = ref<SysOrg[]>([])\nconst orgTree = computed(() => {\n const all = { id: 0, parentId: -1, name: t('common.all'), children: buildTree(orgFlat.value) }\n return [all]\n})\nconst selectedOrgKey = ref<number | null>(null)\nconst orgId = computed(() =>\n selectedOrgKey.value && selectedOrgKey.value !== 0 ? selectedOrgKey.value : undefined,\n)\n\nonMounted(async () => {\n try {\n orgFlat.value = await orgApi.list()\n } catch {\n /* 静默 */\n }\n})\n\nfunction onOrgSelect(keys: Array<string | number>) {\n selectedOrgKey.value = (keys[0] as number) ?? null\n tableRef.value?.refresh()\n}\n// 两页形态下机构树换成树选择:没有「再点一次取消」,选「全部」(id 0)即不限机构。\nfunction onOrgPick(key: number | null) {\n selectedOrgKey.value = key ?? null\n tableRef.value?.refresh()\n}\n\n// ── 可选用户表(中间面板) ──\nconst checkedKeys = ref<(string | number)[]>([])\nconst excludeSet = computed(() => new Set(props.excludeIds ?? []))\n\nconst fetcher = (params: { page: number; pageSize: number; account?: string }) =>\n userApi.page({\n page: params.page,\n pageSize: params.pageSize,\n account: params.account,\n orgId: orgId.value,\n })\n\nconst columns: SmartTableColumn<UserItem>[] = [\n { type: 'selection' },\n { key: 'name', title: () => t('user.name'), width: 100 },\n {\n key: 'account',\n title: () => t('user.account'),\n width: 120,\n search: { actions: SEARCH_ACTIONS.fuzzy },\n },\n {\n key: 'op',\n title: () => t('common.operation'),\n width: 70,\n render: r => {\n const already = selectedSet.value.has(r.id) || excludeSet.value.has(r.id)\n return h(\n NButton,\n {\n size: 'tiny',\n type: 'primary',\n quaternary: true,\n disabled: already,\n onClick: () => addUsers([r]),\n },\n () => (already ? t('userPicker.added') : t('userPicker.add')),\n )\n },\n },\n]\n\n// ── 已选用户(右面板) ──\nconst selected = reactive<UserItem[]>([])\nconst selectedSet = computed(() => new Set(selected.map(u => u.id)))\nconst selectedSearch = ref('')\nconst filteredSelected = computed(() => {\n const q = selectedSearch.value.trim().toLowerCase()\n if (!q) return selected\n return selected.filter(\n u => u.name.toLowerCase().includes(q) || u.account.toLowerCase().includes(q),\n )\n})\n\nfunction addUsers(users: UserItem[]) {\n for (const u of users) {\n if (!selectedSet.value.has(u.id) && !excludeSet.value.has(u.id)) {\n selected.push(u)\n }\n }\n}\n\nfunction addChecked() {\n // SmartTable 只 expose rows,别改用未公开的 tableData —— 恒为 undefined。\n // unref 兼容类型声明的 Ref 与运行时 expose 解包两种形态。\n const rows = (unref(tableRef.value?.rows) ?? []).filter(r => checkedKeys.value.includes(r.id))\n addUsers(rows)\n checkedKeys.value = []\n}\n\nfunction removeUser(id: number) {\n const idx = selected.findIndex(u => u.id === id)\n if (idx >= 0) selected.splice(idx, 1)\n}\n\nfunction clearSelected() {\n selected.splice(0, selected.length)\n}\n\n// ── 公共 API ──\nasync function open(ids?: number[]) {\n selected.splice(0, selected.length)\n checkedKeys.value = []\n selectedSearch.value = ''\n selectedOrgKey.value = null\n tab.value = 'users'\n show.value = true\n\n if (ids?.length) {\n try {\n // ponytail: 拉一页,靠 id 过滤。取 200 是为了在应用把 Api:MaxPageSize 调小时也不会被后端回 48001。\n // 用户超过 200 个时,排在后面的 id 解析不出名字,走下面那条退回显示 id 的分支;\n // 真要支持更大规模的用户名单,再改成分页搜索。\n const { items } = await userApi.page({ page: 1, pageSize: 200 })\n const all = items.filter(u => ids.includes(u.id))\n // 没拉到的 id(翻页之外),退回只显示 id\n const found = new Set(all.map(u => u.id))\n for (const u of all) selected.push(u)\n for (const id of ids) {\n if (!found.has(id)) selected.push({ id, account: String(id), name: String(id) } as UserItem)\n }\n } catch {\n for (const id of ids) selected.push({ id, account: String(id), name: String(id) } as UserItem)\n }\n }\n}\n\nasync function handleConfirm() {\n const ids = selected.map(u => u.id)\n emit('confirm', ids)\n}\n\ndefineExpose({ open })\n</script>\n\n<template>\n <FormContainer\n v-model:show=\"show\"\n :variant=\"variant\"\n :title=\"t('userPicker.title')\"\n :width=\"1100\"\n :on-confirm=\"handleConfirm\"\n :confirm-text=\"t('common.confirm')\"\n >\n <n-tabs v-if=\"compact\" v-model:value=\"tab\" type=\"segment\" animated class=\"picker-tabs\">\n <n-tab name=\"users\">{{ t('userPicker.available') }}</n-tab>\n <n-tab name=\"selected\">{{ t('userPicker.selected') }}({{ selected.length }})</n-tab>\n </n-tabs>\n <div class=\"user-picker\" :class=\"{ 'is-compact': compact }\">\n <!-- 左面板:机构树(两页形态下换成可选用户页顶部的树选择) -->\n <div v-if=\"!compact\" class=\"picker-tree\">\n <div class=\"panel-header\">{{ t('org.title') }}</div>\n <n-tree\n :data=\"orgTree\"\n key-field=\"id\"\n label-field=\"name\"\n children-field=\"children\"\n selectable\n block-line\n default-expand-all\n :selected-keys=\"selectedOrgKey != null ? [selectedOrgKey] : []\"\n @update:selected-keys=\"onOrgSelect\"\n />\n </div>\n\n <!-- 中间面板:可选用户 -->\n <div v-show=\"!compact || tab === 'users'\" class=\"picker-table\">\n <n-tree-select\n v-if=\"compact\"\n :value=\"selectedOrgKey ?? 0\"\n :options=\"orgTree\"\n key-field=\"id\"\n label-field=\"name\"\n children-field=\"children\"\n default-expand-all\n size=\"large\"\n class=\"picker-org-select\"\n @update:value=\"onOrgPick\"\n />\n <div class=\"panel-header\">\n <span>{{ t('userPicker.available') }}</span>\n <n-button\n :size=\"btnSize\"\n type=\"primary\"\n :disabled=\"checkedKeys.length === 0\"\n @click=\"addChecked\"\n >\n {{ t('userPicker.addChecked') }}({{ checkedKeys.length }})\n </n-button>\n </div>\n <SmartTable\n :default-page-size=\"100\"\n ref=\"tableRef\"\n :columns=\"columns\"\n :fetcher=\"fetcher\"\n :search=\"{ container: 'table' }\"\n :pagination=\"{ pageSize: 10 }\"\n size=\"small\"\n storage-key=\"user-picker\"\n :tool-button=\"false\"\n :checked-row-keys=\"checkedKeys\"\n @update:checked-row-keys=\"(keys: (string | number)[]) => (checkedKeys = keys)\"\n @error=\"e => message.error(translateError(e))\"\n />\n </div>\n\n <!-- 右面板:已选用户 -->\n <div v-show=\"!compact || tab === 'selected'\" class=\"picker-selected\">\n <div class=\"panel-header\">\n <span>{{ t('userPicker.selected') }}({{ selected.length }})</span>\n <n-button\n :size=\"btnSize\"\n quaternary\n type=\"error\"\n :disabled=\"selected.length === 0\"\n @click=\"clearSelected\"\n >\n {{ t('userPicker.clear') }}\n </n-button>\n </div>\n <n-input\n v-model:value=\"selectedSearch\"\n :size=\"compact ? 'large' : 'small'\"\n clearable\n :placeholder=\"t('common.search')\"\n style=\"margin-bottom: 8px\"\n />\n <div class=\"selected-list\">\n <div v-for=\"u in filteredSelected\" :key=\"u.id\" class=\"selected-item\">\n <span class=\"selected-name\">\n {{ u.name }}\n <span class=\"selected-account\">({{ u.account }})</span>\n </span>\n <n-button :size=\"btnSize\" quaternary type=\"error\" @click=\"removeUser(u.id)\">\n <template #icon><AppIcon icon=\"ph:x\" :size=\"14\" /></template>\n </n-button>\n </div>\n <n-empty\n v-if=\"filteredSelected.length === 0\"\n :description=\"t('common.noData')\"\n style=\"padding: 24px 0\"\n />\n </div>\n </div>\n </div>\n </FormContainer>\n</template>\n\n<style scoped>\n/* 选择器的尺寸、分隔线、字号。 */\n.user-picker {\n display: flex;\n gap: 12px;\n min-height: min(440px, calc(100vh - 250px));\n}\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 34px;\n font-size: 13.5px;\n font-weight: 600;\n padding: 0 0 8px;\n border-bottom: 1px solid var(--hairline);\n margin-bottom: 8px;\n}\n.picker-tree {\n width: 200px;\n flex-shrink: 0;\n overflow: auto;\n border-right: 1px solid var(--hairline);\n padding-right: 12px;\n}\n.picker-table {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n}\n.picker-org-select {\n margin-bottom: 8px;\n}\n.picker-selected {\n width: 220px;\n flex-shrink: 0;\n border-left: 1px solid var(--hairline);\n padding-left: 12px;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n.selected-list {\n flex: 1;\n min-height: 0;\n overflow: auto;\n max-height: 380px;\n}\n.selected-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 6px;\n padding: 2px 0;\n font-size: 13.5px;\n border-bottom: 1px solid var(--hairline);\n}\n.selected-item:last-child {\n border-bottom: none;\n}\n.selected-name {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.selected-account {\n color: var(--text-3);\n margin-left: 2px;\n}\n\n/* 两页形态:分段页签在上,当前页占满整行;已选页不再要左侧分隔线,条目行高放大到可点 */\n.picker-tabs {\n margin-bottom: 12px;\n}\n.user-picker.is-compact {\n min-height: 0;\n}\n.is-compact .picker-selected {\n width: auto;\n flex: 1;\n border-left: none;\n padding-left: 0;\n}\n.is-compact .selected-list {\n max-height: none;\n}\n.is-compact .selected-item {\n min-height: 44px;\n}\n</style>\n"],"names":["props","__props","emit","__emit","t","useI18n","message","useMessage","show","ref","tableRef","bp","useShellBreakpoint","winW","useWindowSize","compact","computed","variant","tab","btnSize","orgFlat","orgTree","buildTree","selectedOrgKey","orgId","onMounted","orgApi","onOrgSelect","keys","_a","onOrgPick","key","checkedKeys","excludeSet","fetcher","params","userApi","columns","SEARCH_ACTIONS","r","already","selectedSet","h","NButton","addUsers","selected","reactive","u","selectedSearch","filteredSelected","q","users","addChecked","rows","unref","removeUser","id","idx","clearSelected","open","ids","items","all","found","handleConfirm","__expose","_createBlock","FormContainer","$event","_unref","NTabs","_createVNode","NTab","_createTextVNode","_toDisplayString","_createElementVNode","_normalizeClass","_openBlock","_createElementBlock","_hoisted_1","_hoisted_2","NTree","_withDirectives","_hoisted_3","NTreeSelect","_hoisted_4","SmartTable","_cache","e","translateError","_vShow","_hoisted_5","_hoisted_6","NInput","_hoisted_7","_Fragment","_renderList","_hoisted_8","_hoisted_9","AppIcon","NEmpty"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAeA,UAAMA,IAAQC,GACRC,IAAOC,GAEP,EAAE,GAAAC,EAAA,IAAMC,GAAA,GACRC,IAAUC,GAAA,GAEVC,IAAOC,EAAI,EAAK,GAChBC,IAAWD,EAAA,GAOX,EAAE,IAAAE,EAAA,IAAOC,GAAA,GACT,EAAE,OAAOC,EAAA,IAASC,GAAA,GAClBC,IAAUC,EAAS,MAAML,EAAG,UAAU,YAAYE,EAAK,QAAQ,GAAG,GAClEI,IAAUD,EAAS,MAAOL,EAAG,UAAU,WAAW,WAAW,OAAQ,GACrEO,IAAMT,EAA0B,OAAO,GACvCU,IAAUH,EAAS,MAAOD,EAAQ,QAAQ,UAAU,OAAQ,GAG5DK,IAAUX,EAAc,EAAE,GAC1BY,IAAUL,EAAS,MAEhB,CADK,EAAE,IAAI,GAAG,UAAU,IAAI,MAAMZ,EAAE,YAAY,GAAG,UAAUkB,GAAUF,EAAQ,KAAK,EAAA,CAChF,CACZ,GACKG,IAAiBd,EAAmB,IAAI,GACxCe,IAAQR;AAAA,MAAS,MACrBO,EAAe,SAASA,EAAe,UAAU,IAAIA,EAAe,QAAQ;AAAA,IAAA;AAG9E,IAAAE,GAAU,YAAY;AACpB,UAAI;AACF,QAAAL,EAAQ,QAAQ,MAAMM,GAAO,KAAA;AAAA,MAC/B,QAAQ;AAAA,MAER;AAAA,IACF,CAAC;AAED,aAASC,EAAYC,GAA8B;;AACjD,MAAAL,EAAe,QAASK,EAAK,CAAC,KAAgB,OAC9CC,IAAAnB,EAAS,UAAT,QAAAmB,EAAgB;AAAA,IAClB;AAEA,aAASC,EAAUC,GAAoB;;AACrC,MAAAR,EAAe,QAAQQ,KAAO,OAC9BF,IAAAnB,EAAS,UAAT,QAAAmB,EAAgB;AAAA,IAClB;AAGA,UAAMG,IAAcvB,EAAyB,EAAE,GACzCwB,IAAajB,EAAS,MAAM,IAAI,IAAIhB,EAAM,cAAc,CAAA,CAAE,CAAC,GAE3DkC,IAAU,CAACC,MACfC,EAAQ,KAAK;AAAA,MACX,MAAMD,EAAO;AAAA,MACb,UAAUA,EAAO;AAAA,MACjB,SAASA,EAAO;AAAA,MAChB,OAAOX,EAAM;AAAA,IAAA,CACd,GAEGa,IAAwC;AAAA,MAC5C,EAAE,MAAM,YAAA;AAAA,MACR,EAAE,KAAK,QAAQ,OAAO,MAAMjC,EAAE,WAAW,GAAG,OAAO,IAAA;AAAA,MACnD;AAAA,QACE,KAAK;AAAA,QACL,OAAO,MAAMA,EAAE,cAAc;AAAA,QAC7B,OAAO;AAAA,QACP,QAAQ,EAAE,SAASkC,GAAe,MAAA;AAAA,MAAM;AAAA,MAE1C;AAAA,QACE,KAAK;AAAA,QACL,OAAO,MAAMlC,EAAE,kBAAkB;AAAA,QACjC,OAAO;AAAA,QACP,QAAQ,CAAAmC,MAAK;AACX,gBAAMC,IAAUC,EAAY,MAAM,IAAIF,EAAE,EAAE,KAAKN,EAAW,MAAM,IAAIM,EAAE,EAAE;AACxE,iBAAOG;AAAA,YACLC;AAAA,YACA;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,YAAY;AAAA,cACZ,UAAUH;AAAA,cACV,SAAS,MAAMI,EAAS,CAACL,CAAC,CAAC;AAAA,YAAA;AAAA,YAE7B,MAAiBnC,EAAVoC,IAAY,qBAAwB,gBAAN;AAAA,UAAsB;AAAA,QAE/D;AAAA,MAAA;AAAA,IACF,GAIIK,IAAWC,GAAqB,EAAE,GAClCL,IAAczB,EAAS,MAAM,IAAI,IAAI6B,EAAS,IAAI,CAAAE,MAAKA,EAAE,EAAE,CAAC,CAAC,GAC7DC,IAAiBvC,EAAI,EAAE,GACvBwC,IAAmBjC,EAAS,MAAM;AACtC,YAAMkC,IAAIF,EAAe,MAAM,KAAA,EAAO,YAAA;AACtC,aAAKE,IACEL,EAAS;AAAA,QACd,CAAAE,MAAKA,EAAE,KAAK,YAAA,EAAc,SAASG,CAAC,KAAKH,EAAE,QAAQ,YAAA,EAAc,SAASG,CAAC;AAAA,MAAA,IAF9DL;AAAA,IAIjB,CAAC;AAED,aAASD,EAASO,GAAmB;AACnC,iBAAWJ,KAAKI;AACd,QAAI,CAACV,EAAY,MAAM,IAAIM,EAAE,EAAE,KAAK,CAACd,EAAW,MAAM,IAAIc,EAAE,EAAE,KAC5DF,EAAS,KAAKE,CAAC;AAAA,IAGrB;AAEA,aAASK,IAAa;;AAGpB,YAAMC,KAAQC,GAAMzB,IAAAnB,EAAS,UAAT,gBAAAmB,EAAgB,IAAI,KAAK,CAAA,GAAI,OAAO,OAAKG,EAAY,MAAM,SAASO,EAAE,EAAE,CAAC;AAC7F,MAAAK,EAASS,CAAI,GACbrB,EAAY,QAAQ,CAAA;AAAA,IACtB;AAEA,aAASuB,EAAWC,GAAY;AAC9B,YAAMC,IAAMZ,EAAS,UAAU,CAAAE,MAAKA,EAAE,OAAOS,CAAE;AAC/C,MAAIC,KAAO,KAAGZ,EAAS,OAAOY,GAAK,CAAC;AAAA,IACtC;AAEA,aAASC,KAAgB;AACvB,MAAAb,EAAS,OAAO,GAAGA,EAAS,MAAM;AAAA,IACpC;AAGA,mBAAec,GAAKC,GAAgB;AAQlC,UAPAf,EAAS,OAAO,GAAGA,EAAS,MAAM,GAClCb,EAAY,QAAQ,CAAA,GACpBgB,EAAe,QAAQ,IACvBzB,EAAe,QAAQ,MACvBL,EAAI,QAAQ,SACZV,EAAK,QAAQ,IAEToD,KAAA,QAAAA,EAAK;AACP,YAAI;AAIF,gBAAM,EAAE,OAAAC,MAAU,MAAMzB,EAAQ,KAAK,EAAE,MAAM,GAAG,UAAU,KAAK,GACzD0B,IAAMD,EAAM,OAAO,CAAAd,MAAKa,EAAI,SAASb,EAAE,EAAE,CAAC,GAE1CgB,IAAQ,IAAI,IAAID,EAAI,IAAI,CAAAf,MAAKA,EAAE,EAAE,CAAC;AACxC,qBAAWA,KAAKe,EAAK,CAAAjB,EAAS,KAAKE,CAAC;AACpC,qBAAWS,KAAMI;AACf,YAAKG,EAAM,IAAIP,CAAE,OAAY,KAAK,EAAE,IAAAA,GAAI,SAAS,OAAOA,CAAE,GAAG,MAAM,OAAOA,CAAE,GAAe;AAAA,QAE/F,QAAQ;AACN,qBAAWA,KAAMI,EAAK,CAAAf,EAAS,KAAK,EAAE,IAAAW,GAAI,SAAS,OAAOA,CAAE,GAAG,MAAM,OAAOA,CAAE,GAAe;AAAA,QAC/F;AAAA,IAEJ;AAEA,mBAAeQ,KAAgB;AAC7B,YAAMJ,IAAMf,EAAS,IAAI,CAAAE,MAAKA,EAAE,EAAE;AAClC,MAAA7C,EAAK,WAAW0D,CAAG;AAAA,IACrB;AAEA,WAAAK,EAAa,EAAE,MAAAN,IAAM,mBAInBO,EA6GgBC,IAAA;AAAA,MA5GN,MAAM3D,EAAA;AAAA,8CAAAA,EAAI,QAAA4D;AAAA,MACjB,SAASnD,EAAA;AAAA,MACT,OAAOoD,EAAAjE,CAAA,EAAC,kBAAA;AAAA,MACR,OAAO;AAAA,MACP,cAAY4D;AAAA,MACZ,gBAAcK,EAAAjE,CAAA,EAAC,gBAAA;AAAA,IAAA;iBAEhB,MAGS;AAAA,QAHKW,EAAA,cAAdmD,EAGSG,EAAAC,EAAA,GAAA;AAAA;UAHsB,OAAOpD,EAAA;AAAA,mDAAAA,EAAG,QAAAkD;AAAA,UAAE,MAAK;AAAA,UAAU,UAAA;AAAA,UAAS,OAAM;AAAA,QAAA;qBACvE,MAA2D;AAAA,YAA3DG,EAA2DF,EAAAG,CAAA,GAAA,EAApD,MAAK,WAAO;AAAA,yBAAC,MAA+B;AAAA,oBAA5BH,EAAAjE,CAAA,EAAC,sBAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;YACxBmE,EAAoFF,EAAAG,CAAA,GAAA,EAA7E,MAAK,cAAU;AAAA,yBAAC,MAA8B;AAAA,gBAA3BC,EAAAC,EAAAL,EAAAjE,CAAA,4BAA2B,MAACsE,EAAG7B,EAAS,MAAM,IAAG,KAAC,CAAA;AAAA,cAAA;;;;;;QAE9E8B,EAgGM,OAAA;AAAA,UAhGD,OAAKC,GAAA,CAAC,eAAa,EAAA,cAAyB7D,EAAA,OAAO,CAAA;AAAA,QAAA;UAE1CA,EAAA,qBAAZ8D,KAAAC,EAaM,OAbNC,IAaM;AAAA,YAZJJ,EAAoD,OAApDK,IAAoDN,EAAvBL,EAAAjE,CAAA,EAAC,WAAA,CAAA,GAAA,CAAA;AAAA,YAC9BmE,EAUEF,EAAAY,EAAA,GAAA;AAAA,cATC,MAAM5D,EAAA;AAAA,cACP,aAAU;AAAA,cACV,eAAY;AAAA,cACZ,kBAAe;AAAA,cACf,YAAA;AAAA,cACA,cAAA;AAAA,cACA,sBAAA;AAAA,cACC,iBAAeE,EAAA,SAAc,OAAA,CAAYA,EAAA,KAAc,IAAA,CAAA;AAAA,cACvD,yBAAsBI;AAAA,YAAA;;UAK3BuD,EAAAP,EAsCM,OAtCNQ,IAsCM;AAAA,YApCIpE,EAAA,cADRmD,EAWEG,EAAAe,EAAA,GAAA;AAAA;cATC,OAAO7D,EAAA,SAAc;AAAA,cACrB,SAASF,EAAA;AAAA,cACV,aAAU;AAAA,cACV,eAAY;AAAA,cACZ,kBAAe;AAAA,cACf,sBAAA;AAAA,cACA,MAAK;AAAA,cACL,OAAM;AAAA,cACL,kBAAcS;AAAA,YAAA;YAEjB6C,EAUM,OAVNU,IAUM;AAAA,cATJV,EAA4C,gBAAnCN,EAAAjE,CAAA,EAAC,sBAAA,CAAA,GAAA,CAAA;AAAA,cACVmE,EAOWF,EAAA1B,CAAA,GAAA;AAAA,gBANR,MAAMxB,EAAA;AAAA,gBACP,MAAK;AAAA,gBACJ,UAAUa,EAAA,MAAY,WAAM;AAAA,gBAC5B,SAAOoB;AAAA,cAAA;2BAER,MAAgC;AAAA,kBAA7BqB,EAAAC,EAAAL,EAAAjE,CAAA,8BAA6B,MAACsE,EAAG1C,QAAY,MAAM,IAAG,MAC3D,CAAA;AAAA,gBAAA;;;;YAEFuC,EAaEF,EAAAiB,EAAA,GAAA;AAAA,cAZC,qBAAmB;AAAA,uBAChB;AAAA,cAAJ,KAAI5E;AAAA,cACH,SAAA2B;AAAA,cACA,SAAAH;AAAA,cACA,QAAQ,EAAA,WAAA,QAAA;AAAA,cACR,YAAY,EAAA,UAAA,GAAA;AAAA,cACb,MAAK;AAAA,cACL,eAAY;AAAA,cACX,eAAa;AAAA,cACb,oBAAkBF,EAAA;AAAA,cAClB,2BAAuBuD,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAG3D,MAA+BI,EAAA,QAAcJ;AAAA,cACvE,SAAK2D,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAE,CAAAC,MAAKnB,EAAA/D,CAAA,EAAQ,MAAM+D,EAAAoB,EAAA,EAAeD,CAAC,CAAA;AAAA,YAAA;;YApCjC,CAAAE,GAAA,CAAA3E,EAAA,SAAWG,EAAA,UAAG,OAAA;AAAA,UAAA;UAyC5BgE,EAAAP,EAoCM,OApCNgB,IAoCM;AAAA,YAnCJhB,EAWM,OAXNiB,IAWM;AAAA,cAVJjB,EAAkE,QAAA,MAAAD,EAAzDL,KAAC,qBAAA,CAAA,IAA0B,QAAIxB,EAAS,MAAM,IAAG,KAAC,CAAA;AAAA,cAC3D0B,EAQWF,EAAA1B,CAAA,GAAA;AAAA,gBAPR,MAAMxB,EAAA;AAAA,gBACP,YAAA;AAAA,gBACA,MAAK;AAAA,gBACJ,UAAU0B,EAAS,WAAM;AAAA,gBACzB,SAAOa;AAAA,cAAA;2BAER,MAA2B;AAAA,sBAAxBW,EAAAjE,CAAA,EAAC,kBAAA,CAAA,GAAA,CAAA;AAAA,gBAAA;;;;YAGRmE,EAMEF,EAAAwB,EAAA,GAAA;AAAA,cALQ,OAAO7C,EAAA;AAAA,uDAAAA,EAAc,QAAAoB;AAAA,cAC5B,MAAMrD,EAAA,QAAO,UAAA;AAAA,cACd,WAAA;AAAA,cACC,aAAasD,EAAAjE,CAAA,EAAC,eAAA;AAAA,cACf,OAAA,EAAA,iBAAA,MAAA;AAAA,YAAA;YAEFuE,EAeM,OAfNmB,IAeM;AAAA,sBAdJhB,EAQMiB,IAAA,MAAAC,GARW/C,EAAA,OAAgB,CAArBF,YAAZ+B,EAQM,OAAA;AAAA,gBAR8B,KAAK/B,EAAE;AAAA,gBAAI,OAAM;AAAA,cAAA;gBACnD4B,EAGO,QAHPsB,IAGO;AAAA,sBAFFlD,EAAE,IAAI,IAAG,KACZ,CAAA;AAAA,kBAAA4B,EAAuD,QAAvDuB,IAA+B,QAAInD,EAAE,OAAO,IAAG,KAAC,CAAA;AAAA,gBAAA;gBAElDwB,EAEWF,EAAA1B,CAAA,GAAA;AAAA,kBAFA,MAAMxB,EAAA;AAAA,kBAAS,YAAA;AAAA,kBAAW,MAAK;AAAA,kBAAS,SAAK,CAAAiD,MAAEb,EAAWR,EAAE,EAAE;AAAA,gBAAA;kBAC5D,QAAK,MAAkC;AAAA,oBAAlCwB,EAAkC4B,IAAA;AAAA,sBAAzB,MAAK;AAAA,sBAAQ,MAAM;AAAA,oBAAA;;;;;cAIxClD,EAAA,MAAiB,WAAM,UAD/BiB,EAIEG,EAAA+B,EAAA,GAAA;AAAA;gBAFC,aAAa/B,EAAAjE,CAAA,EAAC,eAAA;AAAA,gBACf,OAAA,EAAA,SAAA,SAAA;AAAA,cAAA;;;YAjCQ,CAAAsF,GAAA,CAAA3E,EAAA,SAAWG,EAAA,UAAG,UAAA;AAAA,UAAA;;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useBatchDelete.js","sources":["../../src/composables/useBatchDelete.ts"],"sourcesContent":["// 表格批量删除的样板收敛:维护勾选态 + 二次确认(挂起对话框防连点)+ 成功后清选并刷新。\n// 用在 SmartTable(经 $attrs 把 checked-row-keys 透传到内层 n-data-table)
|
|
1
|
+
{"version":3,"file":"useBatchDelete.js","sources":["../../src/composables/useBatchDelete.ts"],"sourcesContent":["// 表格批量删除的样板收敛:维护勾选态 + 二次确认(挂起对话框防连点)+ 成功后清选并刷新。\n// 用在 SmartTable(经 $attrs 把 checked-row-keys 透传到内层 n-data-table)。\n// 仅限 setup 中调用(内部用 useConfirm → useI18n/useDialog)。\n// SmartTable 3.0 用 #batch 批量栏承载按钮(勾选后才出现),不需要 hasSelection 控制禁用;\n// hasSelection 仍返回,给批量按钮不在 #batch 里的调用方用(如字典项的窄档抽屉,按钮在抽屉底栏)。\nimport { computed, ref } from 'vue'\nimport { useI18n } from 'vue-i18n'\nimport { useConfirm } from '#/composables/useConfirm'\n\nexport interface UseBatchDeleteOptions {\n /** 批量删除接口(收 number[] 主键)。 */\n remove: (ids: number[]) => Promise<unknown>\n /** 删除成功后刷新数据。 */\n refresh: () => void\n /** 成功 toast 文案;false = 不弹(另有提示)。缺省用 common.success。 */\n successMsg?: string | false\n /**\n * 自定义确认文案(可异步:删前要先查点东西才能把话说清楚时用,如\"这些角色关联了 N 个用户\")。\n * 缺省是按条数的通用文案。有此需求的页面若只给行内单删加警告,勾选+批量删就能绕过去。\n */\n content?: (ids: number[]) => string | Promise<string>\n}\n\nexport function useBatchDelete(opts: UseBatchDeleteOptions) {\n const { t } = useI18n()\n const { confirm } = useConfirm()\n /** 勾选的行主键(绑到表格的 checked-row-keys)。 */\n const checkedKeys = ref<Array<string | number>>([])\n const hasSelection = computed(() => checkedKeys.value.length > 0)\n\n async function run() {\n const ids = checkedKeys.value.map(Number)\n if (ids.length === 0) return\n const ok = await confirm({\n content: (await opts.content?.(ids)) ?? t('common.batchDeleteConfirm', { count: ids.length }),\n action: () => opts.remove(ids),\n successMsg: opts.successMsg,\n })\n if (ok) {\n checkedKeys.value = []\n opts.refresh()\n }\n }\n\n return { checkedKeys, hasSelection, run }\n}\n"],"names":["useBatchDelete","opts","t","useI18n","confirm","useConfirm","checkedKeys","ref","hasSelection","computed","run","ids","_a"],"mappings":";;;AAuBO,SAASA,EAAeC,GAA6B;AAC1D,QAAM,EAAE,GAAAC,EAAA,IAAMC,EAAA,GACR,EAAE,SAAAC,EAAA,IAAYC,EAAA,GAEdC,IAAcC,EAA4B,EAAE,GAC5CC,IAAeC,EAAS,MAAMH,EAAY,MAAM,SAAS,CAAC;AAEhE,iBAAeI,IAAM;;AACnB,UAAMC,IAAML,EAAY,MAAM,IAAI,MAAM;AACxC,QAAIK,EAAI,WAAW,EAAG;AAMtB,IALW,MAAMP,EAAQ;AAAA,MACvB,SAAU,QAAMQ,IAAAX,EAAK,YAAL,gBAAAW,EAAA,KAAAX,GAAeU,OAAST,EAAE,6BAA6B,EAAE,OAAOS,EAAI,OAAA,CAAQ;AAAA,MAC5F,QAAQ,MAAMV,EAAK,OAAOU,CAAG;AAAA,MAC7B,YAAYV,EAAK;AAAA,IAAA,CAClB,MAECK,EAAY,QAAQ,CAAA,GACpBL,EAAK,QAAA;AAAA,EAET;AAEA,SAAO,EAAE,aAAAK,GAAa,cAAAE,GAAc,KAAAE,EAAA;AACtC;"}
|
|
@@ -1,25 +1,26 @@
|
|
|
1
|
-
import { computed as l, ref as
|
|
2
|
-
import { NBadge as
|
|
3
|
-
import { createSharedComposable as
|
|
4
|
-
import
|
|
5
|
-
import { menuBadge as
|
|
1
|
+
import { computed as l, ref as I, watch as s, h } from "vue";
|
|
2
|
+
import { NBadge as M } from "naive-ui";
|
|
3
|
+
import { createSharedComposable as O } from "@vueuse/core";
|
|
4
|
+
import w from "../components/AppIcon.vue.js";
|
|
5
|
+
import { menuBadge as A } from "./useMenuBadge.js";
|
|
6
6
|
import { router as a } from "../router/index.js";
|
|
7
7
|
import { useAuthStore as K } from "../stores/auth.js";
|
|
8
8
|
import { useAppStore as T } from "../stores/app.js";
|
|
9
9
|
import { translateMenuTitle as m } from "../locales/menuTitle.js";
|
|
10
10
|
import { isHttpUrl as W, isFullscreenPath as _ } from "../utils/url.js";
|
|
11
|
+
import { lineIcon as C } from "../utils/menuIcon.js";
|
|
11
12
|
import { MenuType as p } from "../types/menu.js";
|
|
12
13
|
function d(r) {
|
|
13
14
|
return !W(r) && !_(r) ? !1 : (window.open(r, "_blank", "noopener,noreferrer"), !0);
|
|
14
15
|
}
|
|
15
|
-
function v(r, e = "ph:dot-outline
|
|
16
|
-
return () => h(
|
|
16
|
+
function v(r, e = "ph:dot-outline") {
|
|
17
|
+
return () => h(w, { icon: C(r) || e, size: 18 });
|
|
17
18
|
}
|
|
18
|
-
function
|
|
19
|
+
function R(r) {
|
|
19
20
|
if (r)
|
|
20
21
|
return () => {
|
|
21
|
-
const e =
|
|
22
|
-
return e == null || e === 0 || e === "" ? null : h(
|
|
22
|
+
const e = A(r);
|
|
23
|
+
return e == null || e === 0 || e === "" ? null : h(M, { value: e, max: 99 });
|
|
23
24
|
};
|
|
24
25
|
}
|
|
25
26
|
function y(r) {
|
|
@@ -29,7 +30,7 @@ function y(r) {
|
|
|
29
30
|
return n.length ? {
|
|
30
31
|
label: m(e.title, e.path),
|
|
31
32
|
key: `cat-${e.id}`,
|
|
32
|
-
icon: v(e.icon, "ph:folder
|
|
33
|
+
icon: v(e.icon, "ph:folder"),
|
|
33
34
|
children: n
|
|
34
35
|
} : null;
|
|
35
36
|
}
|
|
@@ -37,7 +38,7 @@ function y(r) {
|
|
|
37
38
|
label: m(e.title, e.path),
|
|
38
39
|
key: e.path ?? `menu-${e.id}`,
|
|
39
40
|
icon: v(e.icon),
|
|
40
|
-
extra:
|
|
41
|
+
extra: R(e.path)
|
|
41
42
|
};
|
|
42
43
|
}).filter((e) => e !== null);
|
|
43
44
|
}
|
|
@@ -51,10 +52,10 @@ function k(r) {
|
|
|
51
52
|
if (n) return n;
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
|
-
function
|
|
55
|
+
function $() {
|
|
55
56
|
const r = K(), e = T(), n = l(() => (e.locale, y(r.menuTree))), b = l(
|
|
56
57
|
() => n.value.map((t) => ({ label: t.label, key: t.key, icon: t.icon, extra: t.extra }))
|
|
57
|
-
), c = l(() => a.currentRoute.value.path), i =
|
|
58
|
+
), c = l(() => a.currentRoute.value.path), i = I();
|
|
58
59
|
function f(t) {
|
|
59
60
|
const o = n.value.find((u) => g(u, t));
|
|
60
61
|
return o ? String(o.key) : void 0;
|
|
@@ -86,8 +87,8 @@ function R() {
|
|
|
86
87
|
}
|
|
87
88
|
return { menuOptions: n, l1Options: b, l2Options: S, selectedL1: i, activeKey: c, onSelect: x, onSelectL1: L };
|
|
88
89
|
}
|
|
89
|
-
const
|
|
90
|
+
const Q = O($);
|
|
90
91
|
export {
|
|
91
|
-
|
|
92
|
+
Q as useLayoutMenu
|
|
92
93
|
};
|
|
93
94
|
//# sourceMappingURL=useLayoutMenu.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLayoutMenu.js","sources":["../../src/composables/useLayoutMenu.ts"],"sourcesContent":["// auth.menuTree → n-menu 的 MenuOption,外加混合布局下顶栏一级 / 侧栏二级的选中态联动。\n// 用法:default.vue 与 AppHeader 各自 useLayoutMenu(),createSharedComposable 保证它们共享同一份选中态。\n// 坑:off-menu 路由(如 /personal/*)命中不到任何一级,此时保留上一次的一级选中,别把顶栏清空。\nimport { computed, h, ref, watch } from 'vue'\nimport { NBadge, type MenuOption } from 'naive-ui'\nimport { createSharedComposable } from '@vueuse/core'\nimport AppIcon from '#/components/AppIcon.vue'\nimport { menuBadge } from '#/composables/useMenuBadge'\nimport { router } from '#/router'\nimport { useAuthStore } from '#/stores/auth'\nimport { useAppStore } from '#/stores/app'\nimport { translateMenuTitle } from '#/locales/menuTitle'\nimport { isFullscreenPath, isHttpUrl } from '#/utils/url'\nimport { MenuType, type MenuNode } from '#/types/menu'\n\n/**\n * 新标签页打开的两类 key → window.open;返回是否已处理。\n * - 外链菜单:path 为 http(s) URL。\n * - 站内整屏页:path 以 `/fullscreen/` 开头(大屏看板),站内静态路由,但必须脱离布局壳整屏显示。\n */\nfunction openIfExternal(key: string): boolean {\n if (!isHttpUrl(key) && !isFullscreenPath(key)) return false\n window.open(key, '_blank', 'noopener,noreferrer')\n return true\n}\n\n// 无图标兜底:rail/折叠态的 n-menu 只画图标,缺图标会渲染成空槽、整项像“消失”了,故永不返回 undefined。\n// 走 AppIcon 而非裸 Icon:菜单图标是库里配的,子集外的名字要由它懒加载整集兜底,否则渲染不出来。\nfunction renderIcon(name: string | undefined, fallback = 'ph:dot-outline
|
|
1
|
+
{"version":3,"file":"useLayoutMenu.js","sources":["../../src/composables/useLayoutMenu.ts"],"sourcesContent":["// auth.menuTree → n-menu 的 MenuOption,外加混合布局下顶栏一级 / 侧栏二级的选中态联动。\n// 用法:default.vue 与 AppHeader 各自 useLayoutMenu(),createSharedComposable 保证它们共享同一份选中态。\n// 坑:off-menu 路由(如 /personal/*)命中不到任何一级,此时保留上一次的一级选中,别把顶栏清空。\nimport { computed, h, ref, watch } from 'vue'\nimport { NBadge, type MenuOption } from 'naive-ui'\nimport { createSharedComposable } from '@vueuse/core'\nimport AppIcon from '#/components/AppIcon.vue'\nimport { menuBadge } from '#/composables/useMenuBadge'\nimport { router } from '#/router'\nimport { useAuthStore } from '#/stores/auth'\nimport { useAppStore } from '#/stores/app'\nimport { translateMenuTitle } from '#/locales/menuTitle'\nimport { isFullscreenPath, isHttpUrl } from '#/utils/url'\nimport { lineIcon } from '#/utils/menuIcon'\nimport { MenuType, type MenuNode } from '#/types/menu'\n\n/**\n * 新标签页打开的两类 key → window.open;返回是否已处理。\n * - 外链菜单:path 为 http(s) URL。\n * - 站内整屏页:path 以 `/fullscreen/` 开头(大屏看板),站内静态路由,但必须脱离布局壳整屏显示。\n */\nfunction openIfExternal(key: string): boolean {\n if (!isHttpUrl(key) && !isFullscreenPath(key)) return false\n window.open(key, '_blank', 'noopener,noreferrer')\n return true\n}\n\n// 无图标兜底:rail/折叠态的 n-menu 只画图标,缺图标会渲染成空槽、整项像“消失”了,故永不返回 undefined。\n// 走 AppIcon 而非裸 Icon:菜单图标是库里配的,子集外的名字要由它懒加载整集兜底,否则渲染不出来。\n// 全站统一线条款:库里存的 `-duotone` 名字在这里去掉后缀(见 utils/menuIcon),兜底图标本身也是线条款。\nfunction renderIcon(name: string | undefined, fallback = 'ph:dot-outline') {\n return () => h(AppIcon, { icon: lineIcon(name) || fallback, size: 18 })\n}\n\n// 角标(registerMenuBadge 登记的未读数/待办数)→ n-menu 的 extra 槽。\n// 读值在渲染函数里做,故登记的 ref 一变角标就变,不必重算整棵 options。\n// 折叠 / rail 态 n-menu 只画图标、不渲染 extra,角标随之隐藏——这是 n-menu 的行为,不另做补偿。\nfunction renderBadge(path: string | undefined) {\n if (!path) return undefined\n return () => {\n const value = menuBadge(path)\n if (value === null || value === undefined || value === 0 || value === '') return null\n return h(NBadge, { value, max: 99 })\n }\n}\n\n// 菜单树 → n-menu options:剥按钮、丢空目录、页面叶子 key=路由 path。目录/叶子各自兜底图标。\nfunction toOptions(nodes: MenuNode[]): MenuOption[] {\n return nodes\n .toSorted((a, b) => a.sort - b.sort)\n .filter(n => n.type !== MenuType.Button && n.visible !== false)\n .map<MenuOption | null>(n => {\n if (n.type === MenuType.Catalog) {\n const children = toOptions(n.children ?? [])\n if (!children.length) return null\n return {\n label: translateMenuTitle(n.title, n.path),\n key: `cat-${n.id}`,\n icon: renderIcon(n.icon, 'ph:folder'),\n children,\n }\n }\n return {\n label: translateMenuTitle(n.title, n.path),\n key: n.path ?? `menu-${n.id}`,\n icon: renderIcon(n.icon),\n extra: renderBadge(n.path),\n }\n })\n .filter((o): o is MenuOption => o !== null)\n}\n\nfunction containsKey(opt: MenuOption, path: string): boolean {\n if (opt.key === path) return true\n return ((opt.children as MenuOption[]) ?? []).some(c => containsKey(c, path))\n}\nfunction firstLeafKey(opt: MenuOption): string | undefined {\n if (typeof opt.key === 'string' && opt.key.startsWith('/')) return opt.key\n for (const c of (opt.children as MenuOption[]) ?? []) {\n const k = firstLeafKey(c)\n if (k) return k\n }\n return undefined\n}\n\n/**\n * 布局菜单派生 + 一/二级选中态联动(混合布局用)。\n * createSharedComposable → default.vue 与 AppHeader 共享同一份 selectedL1,不各自漂移。\n * 走 router.currentRoute(全局 ref),不依赖组件上下文的 useRoute。\n */\nfunction useLayoutMenuImpl() {\n const auth = useAuthStore()\n const app = useAppStore()\n\n // 工作台是每个应用菜单树里的一条(Sort=0 → 排第一项),跟着应用变,不用手工 prepend。\n const menuOptions = computed<MenuOption[]>(() => {\n void app.locale // 依赖:切换语言时 i18n key 标题重算\n return toOptions(auth.menuTree)\n })\n\n // 一级(剥 children → n-menu 渲染为可选普通项,无展开箭头)。\n const l1Options = computed<MenuOption[]>(() =>\n menuOptions.value.map(o => ({ label: o.label, key: o.key, icon: o.icon, extra: o.extra })),\n )\n\n const activeKey = computed(() => router.currentRoute.value.path)\n const selectedL1 = ref<string>()\n\n function findActiveL1(path: string): string | undefined {\n const top = menuOptions.value.find(o => containsKey(o, path))\n return top ? String(top.key) : undefined\n }\n\n // 路由 → 一级同步:命中才覆写(off-menu 路由如 /personal/* 保留上次);首次 seed 头一项。\n watch(\n () => router.currentRoute.value.path,\n path => {\n const l1 = findActiveL1(path)\n if (l1) selectedL1.value = l1\n else if (selectedL1.value === undefined)\n selectedL1.value = menuOptions.value[0]?.key as string | undefined\n },\n { immediate: true },\n )\n // 菜单可能晚于首个 watch 到达(F5 重建):补 seed / 修正失效选择。\n watch(menuOptions, opts => {\n if (selectedL1.value === undefined || !opts.some(o => o.key === selectedL1.value)) {\n selectedL1.value = findActiveL1(activeKey.value) ?? (opts[0]?.key as string | undefined)\n }\n })\n\n const l2Options = computed<MenuOption[]>(() => {\n const top = menuOptions.value.find(o => o.key === selectedL1.value)\n return (top?.children as MenuOption[]) ?? []\n })\n\n function onSelect(key: string) {\n if (openIfExternal(key)) return\n if (key.startsWith('/')) router.push(key)\n }\n function onSelectL1(key: string) {\n if (openIfExternal(key)) return\n selectedL1.value = key // 先设,L2 列立即刷新,不等导航\n const top = menuOptions.value.find(o => o.key === key)\n const target = key.startsWith('/') ? key : top ? firstLeafKey(top) : undefined\n if (target) router.push(target)\n }\n\n return { menuOptions, l1Options, l2Options, selectedL1, activeKey, onSelect, onSelectL1 }\n}\n\nexport const useLayoutMenu = createSharedComposable(useLayoutMenuImpl)\n"],"names":["openIfExternal","key","isHttpUrl","isFullscreenPath","renderIcon","name","fallback","AppIcon","lineIcon","renderBadge","path","value","menuBadge","NBadge","toOptions","nodes","a","b","n","MenuType","children","translateMenuTitle","o","containsKey","opt","c","firstLeafKey","k","useLayoutMenuImpl","auth","useAuthStore","app","useAppStore","menuOptions","computed","l1Options","activeKey","router","selectedL1","ref","findActiveL1","top","watch","l1","_a","opts","l2Options","onSelect","onSelectL1","target","useLayoutMenu","createSharedComposable"],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { computed as n } from "vue";
|
|
2
|
+
import { useI18n as t } from "vue-i18n";
|
|
3
|
+
import { resolveLoginHero as l } from "../lib/loginHero.js";
|
|
4
|
+
import { useSite as r } from "./useSite.js";
|
|
5
|
+
function f() {
|
|
6
|
+
const { t: e, locale: i } = t(), { site: o } = r();
|
|
7
|
+
return n(
|
|
8
|
+
() => l(
|
|
9
|
+
o.loginHero[i.value],
|
|
10
|
+
{
|
|
11
|
+
headline: `${e("login.headlinePre")}${e("login.headlineAccent")}${e("login.headlinePost")}`,
|
|
12
|
+
highlight: e("login.headlineAccent"),
|
|
13
|
+
features: [e("login.featRbac"), e("login.featScope"), e("login.featPortal")]
|
|
14
|
+
},
|
|
15
|
+
o.showFeatures
|
|
16
|
+
)
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
export {
|
|
20
|
+
f as useLoginHero
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=useLoginHero.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLoginHero.js","sources":["../../src/composables/useLoginHero.ts"],"sourcesContent":["import { computed } from 'vue'\nimport { useI18n } from 'vue-i18n'\nimport { resolveLoginHero } from '#/lib/loginHero'\nimport { useSite } from './useSite'\n\n/** 登录页 Hero 当前 locale 的生效文案:配置优先,空值逐字段回退内置 i18n。 */\nexport function useLoginHero() {\n const { t, locale } = useI18n()\n const { site } = useSite()\n\n return computed(() =>\n resolveLoginHero(\n site.loginHero[locale.value],\n {\n headline: `${t('login.headlinePre')}${t('login.headlineAccent')}${t('login.headlinePost')}`,\n highlight: t('login.headlineAccent'),\n features: [t('login.featRbac'), t('login.featScope'), t('login.featPortal')],\n },\n site.showFeatures,\n ),\n )\n}\n"],"names":["useLoginHero","t","locale","useI18n","site","useSite","computed","resolveLoginHero"],"mappings":";;;;AAMO,SAASA,IAAe;AAC7B,QAAM,EAAE,GAAAC,GAAG,QAAAC,EAAA,IAAWC,EAAA,GAChB,EAAE,MAAAC,EAAA,IAASC,EAAA;AAEjB,SAAOC;AAAA,IAAS,MACdC;AAAA,MACEH,EAAK,UAAUF,EAAO,KAAK;AAAA,MAC3B;AAAA,QACE,UAAU,GAAGD,EAAE,mBAAmB,CAAC,GAAGA,EAAE,sBAAsB,CAAC,GAAGA,EAAE,oBAAoB,CAAC;AAAA,QACzF,WAAWA,EAAE,sBAAsB;AAAA,QACnC,UAAU,CAACA,EAAE,gBAAgB,GAAGA,EAAE,iBAAiB,GAAGA,EAAE,kBAAkB,CAAC;AAAA,MAAA;AAAA,MAE7EG,EAAK;AAAA,IAAA;AAAA,EACP;AAEJ;"}
|
|
@@ -1,44 +1,54 @@
|
|
|
1
|
-
import { useAuthStore as
|
|
2
|
-
import { useTabsStore as
|
|
1
|
+
import { useAuthStore as I } from "../stores/auth.js";
|
|
2
|
+
import { useTabsStore as g } from "../stores/tabs.js";
|
|
3
3
|
import { useUserStore as f } from "../stores/user.js";
|
|
4
4
|
import { personalApi as s } from "../api/index.js";
|
|
5
|
-
import { buildRoutesForModule as
|
|
6
|
-
import { router as
|
|
7
|
-
let
|
|
8
|
-
async function
|
|
9
|
-
return await
|
|
5
|
+
import { buildRoutesForModule as M } from "./useAuthMenu.js";
|
|
6
|
+
import { router as S } from "../router/index.js";
|
|
7
|
+
let i = null;
|
|
8
|
+
async function n(r) {
|
|
9
|
+
return await M(r), { chooser: !1, moduleId: r };
|
|
10
10
|
}
|
|
11
|
-
function
|
|
12
|
-
const
|
|
13
|
-
function
|
|
14
|
-
return
|
|
15
|
-
|
|
16
|
-
})),
|
|
11
|
+
function b() {
|
|
12
|
+
const r = I();
|
|
13
|
+
function d() {
|
|
14
|
+
return i ?? (i = c().finally(() => {
|
|
15
|
+
i = null;
|
|
16
|
+
})), i;
|
|
17
17
|
}
|
|
18
18
|
async function c() {
|
|
19
|
-
const [{ modules:
|
|
19
|
+
const [{ modules: o, defaultModuleId: t }, m, a] = await Promise.all([
|
|
20
20
|
s.modules(),
|
|
21
|
-
s.permissions().then((
|
|
22
|
-
s.profile().then((
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
s.permissions().then((e) => ({ ok: !0, codes: e })).catch(() => ({ ok: !1, codes: [] })),
|
|
22
|
+
s.profile().then((e) => ({
|
|
23
|
+
sadm: e.isSuperAdmin,
|
|
24
|
+
avatar: e.avatar ?? null,
|
|
25
|
+
orgName: e.orgName ?? null,
|
|
26
|
+
phoneTail: e.phone ? e.phone.slice(-4) : null
|
|
27
|
+
})).catch(() => {
|
|
28
|
+
var e;
|
|
29
|
+
return {
|
|
30
|
+
sadm: ((e = f().userInfo) == null ? void 0 : e.isSuperAdmin) ?? !1,
|
|
31
|
+
avatar: null,
|
|
32
|
+
orgName: null,
|
|
33
|
+
phoneTail: null
|
|
34
|
+
};
|
|
25
35
|
})
|
|
26
36
|
]);
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
if (
|
|
30
|
-
const
|
|
31
|
-
return
|
|
37
|
+
r.modules = o, r.defaultModuleId = t ?? null, r.permissionCodes = m.codes, r.permissionsLoaded = m.ok, r.isSuperAdmin = a.sadm;
|
|
38
|
+
const u = f();
|
|
39
|
+
if (u.userInfo && (u.userInfo.avatar = a.avatar, u.userInfo.orgName = a.orgName, u.userInfo.phoneTail = a.phoneTail), o.length === 0) return { chooser: !0 };
|
|
40
|
+
const l = r.currentModuleId;
|
|
41
|
+
return l && o.some((e) => e.id === l) ? n(l) : o.length === 1 ? n(o[0].id) : t && o.some((e) => e.id === t) ? n(t) : { chooser: !0 };
|
|
32
42
|
}
|
|
33
|
-
async function p(
|
|
34
|
-
await o
|
|
43
|
+
async function p(o) {
|
|
44
|
+
await n(o), g().clearTabs(), S.replace(r.homePath);
|
|
35
45
|
}
|
|
36
|
-
async function h(
|
|
37
|
-
await s.setDefaultModule(
|
|
46
|
+
async function h(o) {
|
|
47
|
+
await s.setDefaultModule(o), r.defaultModuleId = o;
|
|
38
48
|
}
|
|
39
|
-
return { enter:
|
|
49
|
+
return { enter: n, enterInitial: d, switchModule: p, setDefault: h };
|
|
40
50
|
}
|
|
41
51
|
export {
|
|
42
|
-
|
|
52
|
+
b as useModule
|
|
43
53
|
};
|
|
44
54
|
//# sourceMappingURL=useModule.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useModule.js","sources":["../../src/composables/useModule.ts"],"sourcesContent":["// 多应用门户的进门/切换流程:登录后该直接进哪个应用、还是弹应用选择器,以及切换时清理旧应用的路由与标签。\n// enterInitial() 也是 F5/深链的恢复入口(动态路由只在内存里),路由守卫会调它。\n// 坑:权限码拉取失败时 permissionsLoaded 保持 false,v-auth 走 fail-closed 藏按钮 —— 宁可少显示,不谎报有权限。\nimport { useAuthStore } from '#/stores/auth'\nimport { useTabsStore } from '#/stores/tabs'\nimport { useUserStore } from '#/stores/user'\nimport { personalApi } from '#/api'\nimport { buildRoutesForModule } from './useAuthMenu'\nimport { router } from '#/router'\n\ntype EnterResult = { chooser: true } | { chooser: false; moduleId: number }\n\n// 进门单飞:F5/深链时守卫可能被并发导航各调一次 enterInitial,而 buildRoutesForModule 起手就 resetRouter()\n// —— 后一次会把前一次刚注册的动态路由整片摘掉,表现是偶发 404/白屏。模块级 promise 让并发合流成一次。\nlet entering: Promise<EnterResult> | null = null\n\n/** 进指定应用:重建它的动态路由。 */\nasync function enter(moduleId: number): Promise<EnterResult> {\n await buildRoutesForModule(moduleId)\n return { chooser: false, moduleId }\n}\n\n/** 门户:登录后决定直接进 / 进默认 / 弹选择器,以及切换应用。逻辑与 Naive 无关。 */\nexport function useModule() {\n const auth = useAuthStore()\n\n function enterInitial(): Promise<EnterResult> {\n entering ??= doEnterInitial().finally(() => {\n entering = null\n })\n return entering\n }\n\n async function doEnterInitial(): Promise<EnterResult> {\n // 并行拉模块 + 当前用户权限码。权限码喂 v-auth:成功(哪怕空集=超管)才标 loaded;\n // 失败不阻断进门户,但 permissionsLoaded 保持 false → v-auth fail-closed(藏按钮),不谎报\"有权限\"。\n // profile 拿超管标记喂 v-auth(只对超管 fail-open,普通用户空集则隐藏)+ 顺手回填顶栏头像;失败按普通用户处理(安全侧,不误放行)。\n const [{ modules, defaultModuleId }, perm, profile] = await Promise.all([\n personalApi.modules(),\n personalApi\n .permissions()\n .then(codes => ({ ok: true, codes }))\n .catch(() => ({ ok: false, codes: [] as string[] })),\n personalApi\n .profile()\n .then(p => ({
|
|
1
|
+
{"version":3,"file":"useModule.js","sources":["../../src/composables/useModule.ts"],"sourcesContent":["// 多应用门户的进门/切换流程:登录后该直接进哪个应用、还是弹应用选择器,以及切换时清理旧应用的路由与标签。\n// enterInitial() 也是 F5/深链的恢复入口(动态路由只在内存里),路由守卫会调它。\n// 坑:权限码拉取失败时 permissionsLoaded 保持 false,v-auth 走 fail-closed 藏按钮 —— 宁可少显示,不谎报有权限。\nimport { useAuthStore } from '#/stores/auth'\nimport { useTabsStore } from '#/stores/tabs'\nimport { useUserStore } from '#/stores/user'\nimport { personalApi } from '#/api'\nimport { buildRoutesForModule } from './useAuthMenu'\nimport { router } from '#/router'\n\ntype EnterResult = { chooser: true } | { chooser: false; moduleId: number }\n\n// 进门单飞:F5/深链时守卫可能被并发导航各调一次 enterInitial,而 buildRoutesForModule 起手就 resetRouter()\n// —— 后一次会把前一次刚注册的动态路由整片摘掉,表现是偶发 404/白屏。模块级 promise 让并发合流成一次。\nlet entering: Promise<EnterResult> | null = null\n\n/** 进指定应用:重建它的动态路由。 */\nasync function enter(moduleId: number): Promise<EnterResult> {\n await buildRoutesForModule(moduleId)\n return { chooser: false, moduleId }\n}\n\n/** 门户:登录后决定直接进 / 进默认 / 弹选择器,以及切换应用。逻辑与 Naive 无关。 */\nexport function useModule() {\n const auth = useAuthStore()\n\n function enterInitial(): Promise<EnterResult> {\n entering ??= doEnterInitial().finally(() => {\n entering = null\n })\n return entering\n }\n\n async function doEnterInitial(): Promise<EnterResult> {\n // 并行拉模块 + 当前用户权限码。权限码喂 v-auth:成功(哪怕空集=超管)才标 loaded;\n // 失败不阻断进门户,但 permissionsLoaded 保持 false → v-auth fail-closed(藏按钮),不谎报\"有权限\"。\n // profile 拿超管标记喂 v-auth(只对超管 fail-open,普通用户空集则隐藏)+ 顺手回填顶栏头像;失败按普通用户处理(安全侧,不误放行)。\n const [{ modules, defaultModuleId }, perm, profile] = await Promise.all([\n personalApi.modules(),\n personalApi\n .permissions()\n .then(codes => ({ ok: true, codes }))\n .catch(() => ({ ok: false, codes: [] as string[] })),\n personalApi\n .profile()\n .then(p => ({\n sadm: p.isSuperAdmin,\n avatar: p.avatar ?? null,\n orgName: p.orgName ?? null,\n phoneTail: p.phone ? p.phone.slice(-4) : null,\n }))\n .catch(() => ({\n sadm: useUserStore().userInfo?.isSuperAdmin ?? false,\n avatar: null,\n orgName: null,\n phoneTail: null,\n })),\n ])\n auth.modules = modules\n auth.defaultModuleId = defaultModuleId ?? null\n auth.permissionCodes = perm.codes\n auth.permissionsLoaded = perm.ok\n auth.isSuperAdmin = profile.sadm\n // 顶栏头像:登录出参不含 avatar,这里回填(取不到按无头像处理,顶栏回落图标)\n const user = useUserStore()\n if (user.userInfo) {\n user.userInfo.avatar = profile.avatar\n user.userInfo.orgName = profile.orgName // 水印要印机构和手机尾号,同样只有 profile 里有\n user.userInfo.phoneTail = profile.phoneTail\n }\n if (modules.length === 0) return { chooser: true } // 空态:选择器里提示未分配应用\n // F5/深链优先重建\"上次所在应用\"(持久化的 currentModuleId),让其动态路由复活,跨应用深链不落 404。\n const remembered = auth.currentModuleId\n if (remembered && modules.some(m => m.id === remembered)) return enter(remembered)\n if (modules.length === 1) return enter(modules[0]!.id)\n if (defaultModuleId && modules.some(m => m.id === defaultModuleId))\n return enter(defaultModuleId)\n return { chooser: true }\n }\n\n async function switchModule(moduleId: number): Promise<void> {\n await enter(moduleId)\n useTabsStore().clearTabs() // 切应用 → 标签归零(新应用路由已重建)\n router.replace(auth.homePath) // 落到新应用自己的首页\n }\n\n async function setDefault(moduleId: number): Promise<void> {\n await personalApi.setDefaultModule(moduleId)\n auth.defaultModuleId = moduleId // 本地同步,选择页角标立刻转移,不必重拉 /personal/modules\n }\n\n return { enter, enterInitial, switchModule, setDefault }\n}\n"],"names":["entering","enter","moduleId","buildRoutesForModule","useModule","auth","useAuthStore","enterInitial","doEnterInitial","modules","defaultModuleId","perm","profile","personalApi","codes","p","_a","useUserStore","user","remembered","m","switchModule","useTabsStore","router","setDefault"],"mappings":";;;;;;AAcA,IAAIA,IAAwC;AAG5C,eAAeC,EAAMC,GAAwC;AAC3D,eAAMC,EAAqBD,CAAQ,GAC5B,EAAE,SAAS,IAAO,UAAAA,EAAA;AAC3B;AAGO,SAASE,IAAY;AAC1B,QAAMC,IAAOC,EAAA;AAEb,WAASC,IAAqC;AAC5C,WAAAP,UAAaQ,IAAiB,QAAQ,MAAM;AAC1C,MAAAR,IAAW;AAAA,IACb,CAAC,IACMA;AAAA,EACT;AAEA,iBAAeQ,IAAuC;AAIpD,UAAM,CAAC,EAAE,SAAAC,GAAS,iBAAAC,EAAA,GAAmBC,GAAMC,CAAO,IAAI,MAAM,QAAQ,IAAI;AAAA,MACtEC,EAAY,QAAA;AAAA,MACZA,EACG,YAAA,EACA,KAAK,CAAAC,OAAU,EAAE,IAAI,IAAM,OAAAA,EAAA,EAAQ,EACnC,MAAM,OAAO,EAAE,IAAI,IAAO,OAAO,CAAA,IAAiB;AAAA,MACrDD,EACG,QAAA,EACA,KAAK,CAAAE,OAAM;AAAA,QACV,MAAMA,EAAE;AAAA,QACR,QAAQA,EAAE,UAAU;AAAA,QACpB,SAASA,EAAE,WAAW;AAAA,QACtB,WAAWA,EAAE,QAAQA,EAAE,MAAM,MAAM,EAAE,IAAI;AAAA,MAAA,EACzC,EACD,MAAM,MAAA;;AAAO;AAAA,UACZ,QAAMC,IAAAC,EAAA,EAAe,aAAf,gBAAAD,EAAyB,iBAAgB;AAAA,UAC/C,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,WAAW;AAAA,QAAA;AAAA,OACX;AAAA,IAAA,CACL;AACD,IAAAX,EAAK,UAAUI,GACfJ,EAAK,kBAAkBK,KAAmB,MAC1CL,EAAK,kBAAkBM,EAAK,OAC5BN,EAAK,oBAAoBM,EAAK,IAC9BN,EAAK,eAAeO,EAAQ;AAE5B,UAAMM,IAAOD,EAAA;AAMb,QALIC,EAAK,aACPA,EAAK,SAAS,SAASN,EAAQ,QAC/BM,EAAK,SAAS,UAAUN,EAAQ,SAChCM,EAAK,SAAS,YAAYN,EAAQ,YAEhCH,EAAQ,WAAW,EAAG,QAAO,EAAE,SAAS,GAAA;AAE5C,UAAMU,IAAad,EAAK;AACxB,WAAIc,KAAcV,EAAQ,KAAK,CAAAW,MAAKA,EAAE,OAAOD,CAAU,IAAUlB,EAAMkB,CAAU,IAC7EV,EAAQ,WAAW,IAAUR,EAAMQ,EAAQ,CAAC,EAAG,EAAE,IACjDC,KAAmBD,EAAQ,KAAK,CAAAW,MAAKA,EAAE,OAAOV,CAAe,IACxDT,EAAMS,CAAe,IACvB,EAAE,SAAS,GAAA;AAAA,EACpB;AAEA,iBAAeW,EAAanB,GAAiC;AAC3D,UAAMD,EAAMC,CAAQ,GACpBoB,EAAA,EAAe,UAAA,GACfC,EAAO,QAAQlB,EAAK,QAAQ;AAAA,EAC9B;AAEA,iBAAemB,EAAWtB,GAAiC;AACzD,UAAMW,EAAY,iBAAiBX,CAAQ,GAC3CG,EAAK,kBAAkBH;AAAA,EACzB;AAEA,SAAO,EAAE,OAAAD,GAAO,cAAAM,GAAc,cAAAc,GAAc,YAAAG,EAAA;AAC9C;"}
|
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
import { watchEffect as
|
|
1
|
+
import { watchEffect as i } from "vue";
|
|
2
2
|
import { useRoute as c } from "vue-router";
|
|
3
3
|
import { useAppStore as l } from "../stores/app.js";
|
|
4
|
-
import { useTabsStore as
|
|
5
|
-
import { useSite as
|
|
6
|
-
import { translateMenuTitle as
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
document.
|
|
15
|
-
})
|
|
4
|
+
import { useTabsStore as s } from "../stores/tabs.js";
|
|
5
|
+
import { useSite as f } from "./useSite.js";
|
|
6
|
+
import { translateMenuTitle as u } from "../locales/menuTitle.js";
|
|
7
|
+
import { applyFavicon as d } from "../lib/favicon.js";
|
|
8
|
+
import { runtime as g } from "../lib/runtime.js";
|
|
9
|
+
function E() {
|
|
10
|
+
const o = c(), r = l(), a = s(), { site: e } = f();
|
|
11
|
+
i(() => {
|
|
12
|
+
r.locale;
|
|
13
|
+
const t = a.tabs.find((p) => p.path === o.path), m = (t == null ? void 0 : t.titleFixed) && t.title || o.meta.title || "", n = m ? u(m, o.path) : "";
|
|
14
|
+
document.title = n ? `${n} · ${e.title}` : e.title;
|
|
15
|
+
}), i(() => {
|
|
16
|
+
document.documentElement.lang = r.locale;
|
|
17
|
+
}), g.brand.faviconFromLogo !== !1 && i(() => d(document, e.logo));
|
|
16
18
|
}
|
|
17
19
|
export {
|
|
18
|
-
|
|
20
|
+
E as usePageTitle
|
|
19
21
|
};
|
|
20
22
|
//# sourceMappingURL=usePageTitle.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePageTitle.js","sources":["../../src/composables/usePageTitle.ts"],"sourcesContent":["//
|
|
1
|
+
{"version":3,"file":"usePageTitle.js","sources":["../../src/composables/usePageTitle.ts"],"sourcesContent":["// 浏览器标题、标签页图标与文档语言。App.vue 调一次即可。\n//\n// 不这样动态维护的话,document.title 只会在启动时被站点名设一次,收藏夹/多窗口/历史记录里所有页面会长得一模一样;\n// <html lang> 也会硬编成 zh-CN,读屏器与浏览器翻译在英文界面下判错语言。\nimport { watchEffect } from 'vue'\nimport { useRoute } from 'vue-router'\nimport { useAppStore } from '#/stores/app'\nimport { useTabsStore } from '#/stores/tabs'\nimport { useSite } from '#/composables/useSite'\nimport { translateMenuTitle } from '#/locales/menuTitle'\nimport { applyFavicon } from '#/lib/favicon'\nimport { runtime } from '#/lib/runtime'\n\nexport function usePageTitle(): void {\n const route = useRoute()\n const app = useAppStore()\n const tabs = useTabsStore()\n const { site } = useSite()\n\n watchEffect(() => {\n void app.locale // 依赖:切语言后 i18n key 标题要重算\n // 详情页用 useTabTitle 设过动态标题(记录名)时以它为准 —— 静态 meta.title 是「详情」这种通名。\n const tab = tabs.tabs.find(x => x.path === route.path)\n const raw = (tab?.titleFixed && tab.title) || (route.meta.title as string | undefined) || ''\n const page = raw ? translateMenuTitle(raw, route.path) : ''\n document.title = page ? `${page} · ${site.title}` : site.title\n })\n\n watchEffect(() => {\n document.documentElement.lang = app.locale\n })\n\n // 标签页图标跟随站点 Logo(配置中心换 Logo 保存后 loadSite(true) 即时换掉);消费方可经 brand.faviconFromLogo 关掉\n if (runtime.brand.faviconFromLogo !== false) watchEffect(() => applyFavicon(document, site.logo))\n}\n"],"names":["usePageTitle","route","useRoute","app","useAppStore","tabs","useTabsStore","site","useSite","watchEffect","tab","x","raw","page","translateMenuTitle","runtime","applyFavicon"],"mappings":";;;;;;;;AAaO,SAASA,IAAqB;AACnC,QAAMC,IAAQC,EAAA,GACRC,IAAMC,EAAA,GACNC,IAAOC,EAAA,GACP,EAAE,MAAAC,EAAA,IAASC,EAAA;AAEjB,EAAAC,EAAY,MAAM;AAChB,IAAKN,EAAI;AAET,UAAMO,IAAML,EAAK,KAAK,KAAK,OAAKM,EAAE,SAASV,EAAM,IAAI,GAC/CW,KAAOF,KAAA,gBAAAA,EAAK,eAAcA,EAAI,SAAWT,EAAM,KAAK,SAAgC,IACpFY,IAAOD,IAAME,EAAmBF,GAAKX,EAAM,IAAI,IAAI;AACzD,aAAS,QAAQY,IAAO,GAAGA,CAAI,MAAMN,EAAK,KAAK,KAAKA,EAAK;AAAA,EAC3D,CAAC,GAEDE,EAAY,MAAM;AAChB,aAAS,gBAAgB,OAAON,EAAI;AAAA,EACtC,CAAC,GAGGY,EAAQ,MAAM,oBAAoB,MAAON,EAAY,MAAMO,EAAa,UAAUT,EAAK,IAAI,CAAC;AAClG;"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Ref } from 'vue';
|
|
2
|
+
export type ShellBreakpoint = 'wide' | 'mid' | 'narrow';
|
|
3
|
+
/** 壳层 narrow 的上界(不含)。与表格窄档 600 对齐,见文件头。 */
|
|
4
|
+
export declare const SHELL_NARROW_MAX = 600;
|
|
5
|
+
/** 壳层 wide 的下界(含)。 */
|
|
6
|
+
export declare const SHELL_WIDE_MIN = 1400;
|
|
7
|
+
/** 带左侧面板的页面:内容区窄于此值时面板收进抽屉。 */
|
|
8
|
+
export declare const SHELL_PANEL_DRAWER_MAX = 1000;
|
|
9
|
+
/** 纯判定,便于单测。 */
|
|
10
|
+
export declare function shellBreakpointOf(width: number): ShellBreakpoint;
|
|
11
|
+
export interface ShellBreakpointState {
|
|
12
|
+
/** 内容区(`.page` content box)宽度,px */
|
|
13
|
+
width: Ref<number>;
|
|
14
|
+
bp: Readonly<Ref<ShellBreakpoint>>;
|
|
15
|
+
}
|
|
16
|
+
/** 壳层调用:盯住 el 的 content box,把 { width, bp } 提供给后代。 */
|
|
17
|
+
export declare function provideShellBreakpoint(el: Ref<HTMLElement | undefined>): ShellBreakpointState;
|
|
18
|
+
/** 页面 / 组件调用:取壳层档位。壳层之外退回视口宽度(近似,够单测与独立挂载用)。 */
|
|
19
|
+
export declare function useShellBreakpoint(): ShellBreakpointState;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { inject as v, computed as c, ref as h, provide as w, watch as m, onScopeDispose as S } from "vue";
|
|
2
|
+
import { useWindowSize as b } from "@vueuse/core";
|
|
3
|
+
const R = 600, l = 1400;
|
|
4
|
+
function u(t) {
|
|
5
|
+
return t >= l ? "wide" : t >= R ? "mid" : "narrow";
|
|
6
|
+
}
|
|
7
|
+
const p = Symbol("shellBreakpoint");
|
|
8
|
+
function E(t) {
|
|
9
|
+
const n = h(l), d = c(() => u(n.value)), o = { width: n, bp: d };
|
|
10
|
+
w(p, o);
|
|
11
|
+
let e;
|
|
12
|
+
return m(
|
|
13
|
+
t,
|
|
14
|
+
(i, _, f) => {
|
|
15
|
+
!i || typeof ResizeObserver > "u" || (e = new ResizeObserver((a) => {
|
|
16
|
+
var s;
|
|
17
|
+
const r = (s = a[0]) == null ? void 0 : s.contentRect.width;
|
|
18
|
+
r !== void 0 && (n.value = r);
|
|
19
|
+
}), e.observe(i), f(() => e == null ? void 0 : e.disconnect()));
|
|
20
|
+
},
|
|
21
|
+
{ flush: "post" }
|
|
22
|
+
), S(() => e == null ? void 0 : e.disconnect()), o;
|
|
23
|
+
}
|
|
24
|
+
function L() {
|
|
25
|
+
const t = v(p, null);
|
|
26
|
+
if (t) return t;
|
|
27
|
+
const { width: n } = b();
|
|
28
|
+
return { width: n, bp: c(() => u(n.value)) };
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
R as SHELL_NARROW_MAX,
|
|
32
|
+
l as SHELL_WIDE_MIN,
|
|
33
|
+
E as provideShellBreakpoint,
|
|
34
|
+
u as shellBreakpointOf,
|
|
35
|
+
L as useShellBreakpoint
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=useShellBreakpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useShellBreakpoint.js","sources":["../../src/composables/useShellBreakpoint.ts"],"sourcesContent":["// 壳层档位:按「内容区」宽度判(不是视口),侧栏展开 / 收起、抽屉开合都会改变档位。\n//\n// wide ≥ 1400 统计卡等页面栅格铺开\n// mid 600–1399 栅格收窄;带左侧面板的页面在内容区 < 1000 时面板收进抽屉\n// narrow < 600 整页自然滚动,不锁一屏高度;统计卡两列;设置行上下排\n//\n// 阈值 600 = smart-naive-table 的窄档(表格根节点宽 < 600 换卡片)。壳层 narrow 必须和它对齐:\n// 壳层进入「整页自然滚动」时表格一定已是卡片列表;壳层不是 narrow 时表格一定仍是表格。\n// 两层阈值错开会出现一段宽度:页面不定高、表格却还在 fill-height,表体塌成最小高度。\n// 阈值直接取 600:量的是 `.page` 的 content box(ResizeObserver 的 contentRect 本身已扣掉内边距),\n// 留白不进数字,日后改 `.page` 的内边距不用回来改阈值。\n//\n// 用法:default.vue 调 provideShellBreakpoint(el) 绑定被量的元素;页面里调 useShellBreakpoint()\n// 取 { bp, width }(没有壳层时,如单测或独立挂载,退回按视口宽度估算)。\nimport {\n computed,\n inject,\n onScopeDispose,\n provide,\n ref,\n watch,\n type InjectionKey,\n type Ref,\n} from 'vue'\nimport { useWindowSize } from '@vueuse/core'\n\nexport type ShellBreakpoint = 'wide' | 'mid' | 'narrow'\n\n/** 壳层 narrow 的上界(不含)。与表格窄档 600 对齐,见文件头。 */\nexport const SHELL_NARROW_MAX = 600\n/** 壳层 wide 的下界(含)。 */\nexport const SHELL_WIDE_MIN = 1400\n/** 带左侧面板的页面:内容区窄于此值时面板收进抽屉。 */\nexport const SHELL_PANEL_DRAWER_MAX = 1000\n\n/** 纯判定,便于单测。 */\nexport function shellBreakpointOf(width: number): ShellBreakpoint {\n return width >= SHELL_WIDE_MIN ? 'wide' : width >= SHELL_NARROW_MAX ? 'mid' : 'narrow'\n}\n\nexport interface ShellBreakpointState {\n /** 内容区(`.page` content box)宽度,px */\n width: Ref<number>\n bp: Readonly<Ref<ShellBreakpoint>>\n}\n\nconst KEY: InjectionKey<ShellBreakpointState> = Symbol('shellBreakpoint')\n\n/** 壳层调用:盯住 el 的 content box,把 { width, bp } 提供给后代。 */\nexport function provideShellBreakpoint(el: Ref<HTMLElement | undefined>): ShellBreakpointState {\n const width = ref(SHELL_WIDE_MIN) // 首帧按宽档,避免挂载瞬间闪一下 narrow 的自然滚动布局\n const bp = computed(() => shellBreakpointOf(width.value))\n const state: ShellBreakpointState = { width, bp }\n provide(KEY, state)\n\n let ro: ResizeObserver | undefined\n watch(\n el,\n (node, _old, onCleanup) => {\n if (!node || typeof ResizeObserver === 'undefined') return\n ro = new ResizeObserver(entries => {\n const w = entries[0]?.contentRect.width\n if (w !== undefined) width.value = w\n })\n ro.observe(node)\n onCleanup(() => ro?.disconnect())\n },\n { flush: 'post' },\n )\n onScopeDispose(() => ro?.disconnect())\n return state\n}\n\n/** 页面 / 组件调用:取壳层档位。壳层之外退回视口宽度(近似,够单测与独立挂载用)。 */\nexport function useShellBreakpoint(): ShellBreakpointState {\n const injected = inject(KEY, null)\n if (injected) return injected\n const { width } = useWindowSize()\n return { width, bp: computed(() => shellBreakpointOf(width.value)) }\n}\n"],"names":["SHELL_NARROW_MAX","SHELL_WIDE_MIN","shellBreakpointOf","width","KEY","provideShellBreakpoint","el","ref","bp","computed","state","provide","ro","watch","node","_old","onCleanup","entries","w","_a","onScopeDispose","useShellBreakpoint","injected","inject","useWindowSize"],"mappings":";;AA6BO,MAAMA,IAAmB,KAEnBC,IAAiB;AAKvB,SAASC,EAAkBC,GAAgC;AAChE,SAAOA,KAASF,IAAiB,SAASE,KAASH,IAAmB,QAAQ;AAChF;AAQA,MAAMI,IAA0C,OAAO,iBAAiB;AAGjE,SAASC,EAAuBC,GAAwD;AAC7F,QAAMH,IAAQI,EAAIN,CAAc,GAC1BO,IAAKC,EAAS,MAAMP,EAAkBC,EAAM,KAAK,CAAC,GAClDO,IAA8B,EAAE,OAAAP,GAAO,IAAAK,EAAA;AAC7C,EAAAG,EAAQP,GAAKM,CAAK;AAElB,MAAIE;AACJ,SAAAC;AAAA,IACEP;AAAA,IACA,CAACQ,GAAMC,GAAMC,MAAc;AACzB,MAAI,CAACF,KAAQ,OAAO,iBAAmB,QACvCF,IAAK,IAAI,eAAe,CAAAK,MAAW;;AACjC,cAAMC,KAAIC,IAAAF,EAAQ,CAAC,MAAT,gBAAAE,EAAY,YAAY;AAClC,QAAID,MAAM,WAAWf,EAAM,QAAQe;AAAA,MACrC,CAAC,GACDN,EAAG,QAAQE,CAAI,GACfE,EAAU,MAAMJ,KAAA,gBAAAA,EAAI,YAAY;AAAA,IAClC;AAAA,IACA,EAAE,OAAO,OAAA;AAAA,EAAO,GAElBQ,EAAe,MAAMR,KAAA,gBAAAA,EAAI,YAAY,GAC9BF;AACT;AAGO,SAASW,IAA2C;AACzD,QAAMC,IAAWC,EAAOnB,GAAK,IAAI;AACjC,MAAIkB,EAAU,QAAOA;AACrB,QAAM,EAAE,OAAAnB,EAAA,IAAUqB,EAAA;AAClB,SAAO,EAAE,OAAArB,GAAO,IAAIM,EAAS,MAAMP,EAAkBC,EAAM,KAAK,CAAC,EAAA;AACnE;"}
|
|
@@ -1,11 +1,17 @@
|
|
|
1
|
+
import { LoginHeroCopy } from '../lib/loginHero';
|
|
2
|
+
import { WatermarkSettings } from '../lib/watermark';
|
|
1
3
|
export interface SiteInfo {
|
|
2
4
|
title: string;
|
|
3
5
|
subtitle: string;
|
|
4
6
|
copyright: string;
|
|
5
7
|
copyrightUrl: string;
|
|
6
8
|
logo: string;
|
|
9
|
+
loginHero: Record<string, LoginHeroCopy>;
|
|
10
|
+
showFeatures: boolean;
|
|
7
11
|
captchaEnabled: boolean;
|
|
8
12
|
smsLoginEnabled: boolean;
|
|
13
|
+
/** 登录后页面的水印设置(只有版式;每个人印什么由壳层按登录用户拼) */
|
|
14
|
+
watermark: WatermarkSettings;
|
|
9
15
|
}
|
|
10
16
|
export declare function loadSite(force?: boolean): Promise<void>;
|
|
11
17
|
/** 版本号不走后端配置:默认是内核版本(库构建期常量),消费方经 createSmartAdmin({ version }) 换成应用版本。 */
|
|
@@ -16,8 +22,22 @@ export declare function useSite(): {
|
|
|
16
22
|
copyright: string;
|
|
17
23
|
copyrightUrl: string;
|
|
18
24
|
logo: string;
|
|
25
|
+
loginHero: Record<string, LoginHeroCopy>;
|
|
26
|
+
showFeatures: boolean;
|
|
19
27
|
captchaEnabled: boolean;
|
|
20
28
|
smsLoginEnabled: boolean;
|
|
29
|
+
watermark: {
|
|
30
|
+
enabled: boolean;
|
|
31
|
+
fields: import('../lib/watermark').WatermarkField[];
|
|
32
|
+
text: string;
|
|
33
|
+
timeFormat: import('../lib/watermark').WatermarkTimeFormat;
|
|
34
|
+
layout: import('../lib/watermark').WatermarkLayout;
|
|
35
|
+
fontSize: number;
|
|
36
|
+
opacity: number;
|
|
37
|
+
rotate: number;
|
|
38
|
+
density: import('../lib/watermark').WatermarkDensity;
|
|
39
|
+
cross: boolean;
|
|
40
|
+
};
|
|
21
41
|
};
|
|
22
42
|
appVersion: string;
|
|
23
43
|
loadSite: typeof loadSite;
|