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":"LoginForm2.vue.js","sources":["../../../src/views/login/LoginForm.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { reactive, ref, computed, onMounted, onBeforeUnmount, h } from 'vue'\nimport { useRoute, useRouter } from 'vue-router'\nimport {\n NAlert,\n NForm,\n NFormItem,\n NInput,\n NCheckbox,\n NModal,\n NDropdown,\n useMessage,\n type DropdownOption,\n} from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport { useI18n } from 'vue-i18n'\nimport { authApi, externalAuthApi, ApiError } from '#/api'\nimport type { LoginOutput } from '#/types/api'\nimport { useUserStore } from '#/stores/user'\nimport { useAuthStore } from '#/stores/auth'\nimport { useAppStore } from '#/stores/app'\nimport { useSite } from '#/composables/useSite'\nimport { resetRouter } from '#/router'\nimport { btnGrad, glowSh } from '#/theme/mix'\nimport { translateError } from '#/utils/error'\nimport {\n splitLoginProviders,\n PREVIEW_ALL_SSO_BRANDS,\n previewAllBrandProviders,\n claimWeComAutoLogin,\n} from '#/utils/oauthBrand'\nimport SmartLogo from '#/components/SmartLogo.vue'\nimport { runtime } from '#/lib/runtime'\nimport BrandIcon from '#/components/oauth/BrandIcon.vue'\n\n// 皮肤外壳自带品牌栏时(如双栏),卡内不重复 logo/标题/页脚(showFooter=false 由外壳自绘版权)。\nwithDefaults(defineProps<{ showLogo?: boolean; showTitle?: boolean; showFooter?: boolean }>(), {\n showLogo: true,\n showTitle: true,\n showFooter: true,\n})\n\nconst router = useRouter()\nconst route = useRoute()\nconst message = useMessage()\nconst { t } = useI18n()\nconst user = useUserStore()\nconst auth = useAuthStore()\nconst app = useAppStore()\nconst { site, appVersion, loadSite } = useSite()\nconst year = new Date().getFullYear()\n\n/** 未绑定 SSO 后带回:登录成功后须确认再 claim(防静默抢绑) */\nconst pendingLink = computed(() =>\n typeof route.query.pendingLink === 'string' ? route.query.pendingLink : '',\n)\nconst pendingProvider = computed(() =>\n typeof route.query.provider === 'string' ? route.query.provider : '',\n)\nconst pendingDisplayName = computed(() =>\n typeof route.query.displayName === 'string' ? route.query.displayName : '',\n)\nconst pendingConfirmShow = ref(false)\nconst pendingClaimBusy = ref(false)\nconst pendingClaimToken = ref('')\n\n// 开发态(createSmartAdmin({ dev }))预填超管账号密码,免得每次手敲;生产留空。\n// SSO pending-link 场景故意不预填密码:解绑后 GitHub 会落到本页,预填+一点就 claim 看起来像「SSO 直接进了」。\nconst model = reactive(\n runtime.dev && !pendingLink.value\n ? { account: 'superAdmin', password: 'Aa123456', remember: true }\n : {\n account: runtime.dev ? 'superAdmin' : '',\n password: '',\n remember: true,\n },\n)\nconst loading = ref(false)\n\n// 登录形态:账号密码 / 短信免密 / 短信二次验证(40009) / TOTP 二次验证(40018)\n// 强制 MFA 未绑定(40020)用 Modal 引导,不切 mode,登录页默认也不常驻绑定链接\nconst mode = ref<'account' | 'sms' | 'mfa' | 'totp'>('account')\n\n// 短信免密登录\nconst smsModel = reactive({ phone: '', code: '' })\n// 二次验证挑战(40009 信令 args 下发)\nconst mfa = reactive({ challengeId: '', phoneMask: '', code: '' })\n// TOTP 挑战(40018)\nconst totp = reactive({ challengeId: '', code: '' })\n// 强制 MFA 但未绑定(40020):弹窗 + 带到 /mfa/bind 的账号\nconst bindRequiredShow = ref(false)\nconst bindAccount = ref('')\n\n// 发码/重发共用倒计时(同一时刻只有一个发码入口可见)\nconst countdown = ref(0)\nlet timer: number | undefined\nfunction startCountdown(s: number) {\n countdown.value = s\n window.clearInterval(timer)\n timer = window.setInterval(() => {\n countdown.value -= 1\n if (countdown.value <= 0) window.clearInterval(timer)\n }, 1000)\n}\nonBeforeUnmount(() => window.clearInterval(timer))\n\n// 验证码:是否启用由匿名站点信息(sys.security.captcha.enabled)运行时驱动;启用才拉取并展示。\n// 账号模式护登录,短信模式护发码(发码端点防脚本滥用)。\nconst captchaEnabled = ref(false)\nconst captchaId = ref('')\nconst captchaSvg = ref('')\nconst captchaCode = ref('')\nconst captchaType = ref('char')\n\n// math 类型需算出结果再输入,提示语不同;其余类型统一“请输入验证码”。\nconst captchaHint = computed(() =>\n captchaType.value === 'math' ? t('login.captchaMathPlaceholder') : t('login.captchaPlaceholder'),\n)\n\nasync function loadCaptcha() {\n try {\n const c = await authApi.captcha()\n captchaId.value = c.captchaId\n captchaSvg.value = c.svg\n captchaType.value = c.type || 'char'\n } catch {\n // 拉取失败不阻塞登录页渲染;点击图形可重试\n }\n}\n\n/** 验证码一次性消费:任何用掉票据的请求失败后必刷新,避免复用作废票据 */\nasync function refreshCaptchaAfterUse() {\n if (captchaEnabled.value) {\n captchaCode.value = ''\n await loadCaptcha()\n }\n}\n\nonMounted(async () => {\n // 站点信息全站共用(useSite 去重);验证码开关据此运行时驱动,启用才拉图。\n await loadSite()\n if (site.captchaEnabled) {\n captchaEnabled.value = true\n await loadCaptcha()\n }\n void loadSsoProviders()\n\n // SSO 回调带回的 TOTP 挑战:直接进入 totp 完成态\n const q = router.currentRoute.value.query\n const ch = typeof q.totpChallenge === 'string' ? q.totpChallenge : ''\n if (ch) {\n totp.challengeId = ch\n totp.code = ''\n mode.value = 'totp'\n }\n})\n\n// 英雄按钮:accent 派生渐变 + 发光(仅登录页/英雄区)。\nconst heroStyle = computed(() => ({\n background: btnGrad(app.accent),\n boxShadow: glowSh(app.accent),\n}))\n\n// 第三方登录:默认后端 providers 驱动;PREVIEW_ALL_SSO_BRANDS 时铺全品牌图(图标验收)。\nconst ssoProviders = ref<{ code: string; displayName: string; icon?: string | null }[]>([])\nconst pendingProviderLabel = computed(() => {\n const code = pendingProvider.value\n if (!code) return t('oauth.thirdParty')\n const hit = ssoProviders.value.find(p => p.code === code)\n return hit?.displayName || code\n})\nconst ssoDisplayList = computed(() =>\n PREVIEW_ALL_SSO_BRANDS ? previewAllBrandProviders() : ssoProviders.value,\n)\n// 预览全图标时不截断;正常模式 N=4 溢出\nconst ssoSplit = computed(() =>\n PREVIEW_ALL_SSO_BRANDS\n ? { visible: ssoDisplayList.value, overflow: [] as typeof ssoDisplayList.value }\n : splitLoginProviders(ssoDisplayList.value),\n)\nconst ssoOverflowOptions = computed<DropdownOption[]>(() =>\n ssoSplit.value.overflow.map(p => ({\n key: p.code,\n label: () =>\n h(\n 'span',\n {\n class: 'lf-sso-menu-item',\n style: { display: 'inline-flex', alignItems: 'center', gap: '8px' },\n },\n [h(BrandIcon, { code: p.code, icon: p.icon, size: 20 }), h('span', null, p.displayName)],\n ),\n })),\n)\nasync function loadSsoProviders() {\n try {\n ssoProviders.value = await externalAuthApi.providers()\n } catch {\n // 未配置外部登录或拉取失败:整段 SSO 区不显(预览全图标模式仍会显示)\n return\n }\n // 企业微信客户端里直接走企业微信登录;SSO 带回来的认领 / 二次验证要留在本页完成\n const q = route.query\n if (\n !q.pendingLink &&\n !q.totpChallenge &&\n claimWeComAutoLogin({\n userAgent: navigator.userAgent,\n providers: ssoProviders.value,\n storage: sessionStorage,\n })\n ) {\n window.location.href = ssoHref('wecom')\n }\n}\n/** 顶层跳 IdP(与 Gitee 一样用 <a href>)。预览假项仍给 authorize 链,未配后端会失败。 */\nfunction ssoHref(code: string) {\n return externalAuthApi.authorizeUrl(code)\n}\nfunction onSsoOverflow(key: string | number) {\n window.location.href = ssoHref(String(key))\n}\n\nasync function enterHome() {\n await router.replace('/')\n}\n\nasync function finishLogin(res: LoginOutput) {\n // 每次登录都清动态路由/授权态,否则上次会话的 routesReady=true 会跳过 enterInitial,\n // 菜单壳在、业务路由未重建 → 进系统后处处 404(绑定 MFA 后回登录再登最易踩中)。\n resetRouter()\n auth.reset()\n user.setSession(res)\n\n // 现场绑定:不静默 claim——须用户确认,并依赖服务端 binder cookie 同浏览器校验\n const link = pendingLink.value\n if (link) {\n pendingClaimToken.value = link\n pendingConfirmShow.value = true\n return\n }\n message.success(t('login.success'))\n await enterHome()\n}\n\nconst pendingConfirmIdentity = computed(() =>\n pendingDisplayName.value\n ? t('oauth.pendingLinkIdentity', { display: pendingDisplayName.value })\n : '',\n)\n\nasync function confirmPendingBind() {\n if (pendingClaimBusy.value) return\n pendingClaimBusy.value = true\n try {\n await externalAuthApi.claimPendingLink(pendingClaimToken.value)\n message.success(t('oauth.pendingLinkSuccess', { name: pendingProviderLabel.value }))\n } catch (e) {\n message.warning(translateError(e))\n } finally {\n pendingClaimBusy.value = false\n pendingConfirmShow.value = false\n pendingClaimToken.value = ''\n }\n await enterHome()\n}\n\nasync function skipPendingBind() {\n pendingConfirmShow.value = false\n pendingClaimToken.value = ''\n message.success(t('login.success'))\n await enterHome()\n}\n\nasync function onSubmit() {\n if (mode.value === 'mfa') return onMfaSubmit()\n if (mode.value === 'totp') return onTotpSubmit()\n if (mode.value === 'sms') return onSmsSubmit()\n\n if (!model.account || !model.password) {\n message.warning(t('login.required'))\n return\n }\n if (captchaEnabled.value && !captchaCode.value) {\n message.warning(t('login.captchaRequired'))\n return\n }\n loading.value = true\n try {\n const res = await authApi.login({\n account: model.account,\n password: model.password,\n ...(captchaEnabled.value\n ? { captchaId: captchaId.value, captchaCode: captchaCode.value }\n : {}),\n })\n await finishLogin(res)\n } catch (e) {\n // 40018 = 密码已过、需 TOTP 二次验证\n if (e instanceof ApiError && e.code === 40018 && e.args) {\n totp.challengeId = String(e.args.challengeId ?? '')\n totp.code = ''\n mode.value = 'totp'\n } else if (e instanceof ApiError && e.code === 40020) {\n // 40020 = 强制 MFA 未绑定 → Modal 引导自助设置(登录页默认不常驻链接)\n bindAccount.value = model.account.trim()\n bindRequiredShow.value = true\n } else if (e instanceof ApiError && e.code === 40009 && e.args) {\n // 40009 = 密码已过、需短信二次验证\n mfa.challengeId = String(e.args.challengeId ?? '')\n mfa.phoneMask = String(e.args.phoneMask ?? '')\n mfa.code = ''\n mode.value = 'mfa'\n startCountdown(Number(e.args.resendSeconds ?? 60))\n } else {\n message.error(translateError(e))\n }\n await refreshCaptchaAfterUse()\n } finally {\n loading.value = false\n }\n}\n\nfunction closeBindRequired() {\n bindRequiredShow.value = false\n}\n\nfunction goBindAuthenticator() {\n const account = bindAccount.value || model.account.trim()\n bindRequiredShow.value = false\n void router.push({ path: '/mfa/bind', query: account ? { account } : {} })\n}\n\nfunction goRecovery() {\n const account = model.account.trim() || bindAccount.value\n void router.push({\n path: '/mfa/bind',\n query: { ...(account ? { account } : {}), mode: 'recovery' },\n })\n}\n\nasync function onMfaSubmit() {\n if (!mfa.code) {\n message.warning(t('login.smsCodePlaceholder'))\n return\n }\n loading.value = true\n try {\n await finishLogin(\n await authApi.smsChallengeLogin({ challengeId: mfa.challengeId, code: mfa.code }),\n )\n } catch (e) {\n message.error(translateError(e))\n } finally {\n loading.value = false\n }\n}\n\nasync function onTotpSubmit() {\n if (!totp.code) {\n message.warning(t('login.totpPlaceholder'))\n return\n }\n loading.value = true\n try {\n await finishLogin(\n await authApi.totpChallengeLogin({ challengeId: totp.challengeId, code: totp.code }),\n )\n } catch (e) {\n message.error(translateError(e))\n } finally {\n loading.value = false\n }\n}\n\nasync function onMfaResend() {\n if (countdown.value > 0) return\n try {\n const r = await authApi.smsChallengeResend({ challengeId: mfa.challengeId })\n message.success(t('login.smsSent'))\n startCountdown(r.resendSeconds)\n } catch (e) {\n message.error(translateError(e))\n }\n}\n\nfunction backToAccount() {\n mode.value = 'account'\n mfa.challengeId = ''\n mfa.code = ''\n totp.challengeId = ''\n totp.code = ''\n}\n\nasync function onSendSmsCode() {\n if (countdown.value > 0) return\n if (!smsModel.phone) {\n message.warning(t('login.phonePlaceholder'))\n return\n }\n if (captchaEnabled.value && !captchaCode.value) {\n message.warning(t('login.captchaRequired'))\n return\n }\n try {\n const r = await authApi.smsLoginSend({\n phone: smsModel.phone,\n ...(captchaEnabled.value\n ? { captchaId: captchaId.value, captchaCode: captchaCode.value }\n : {}),\n })\n message.success(t('login.smsSent'))\n startCountdown(r.resendSeconds)\n } catch (e) {\n message.error(translateError(e))\n }\n await refreshCaptchaAfterUse()\n}\n\nasync function onSmsSubmit() {\n if (!smsModel.phone || !smsModel.code) {\n message.warning(t('login.smsRequired'))\n return\n }\n loading.value = true\n try {\n await finishLogin(await authApi.smsLogin({ phone: smsModel.phone, code: smsModel.code }))\n } catch (e) {\n message.error(translateError(e))\n } finally {\n loading.value = false\n }\n}\n</script>\n\n<template>\n <div class=\"login-form\">\n <div v-if=\"showLogo\" class=\"lf-brand\">\n <!-- 站点 logo 的取值顺序(配置 → brand 选项 → 内置矢量标)统一在 SmartLogo 里 -->\n <SmartLogo :size=\"34\" />\n <span class=\"lf-word\">{{ site.title }}</span>\n </div>\n\n <n-alert\n v-if=\"pendingLink\"\n type=\"info\"\n :bordered=\"false\"\n class=\"lf-pending-alert\"\n :title=\"t('oauth.pendingLinkTitle', { name: pendingProviderLabel })\"\n >\n {{ t('oauth.pendingLinkHint', { name: pendingProviderLabel }) }}\n </n-alert>\n\n <!-- 短信二次验证:密码已过,凭挑战 + 短信码完成登录 -->\n <template v-if=\"mode === 'mfa'\">\n <h2 v-if=\"showTitle\" class=\"lf-title\">{{ t('login.mfaTitle', { phone: mfa.phoneMask }) }}</h2>\n <p class=\"lf-hint-line\">{{ t('login.mfaSub') }}</p>\n <n-form @keyup.enter=\"onSubmit\">\n <n-form-item :label=\"t('login.smsCode')\" path=\"code\">\n <n-input\n v-model:value=\"mfa.code\"\n :placeholder=\"t('login.smsCodePlaceholder')\"\n size=\"large\"\n :maxlength=\"6\"\n >\n <template #prefix><Icon icon=\"ph:chat-circle-text\" /></template>\n </n-input>\n </n-form-item>\n <div class=\"row lf-between\">\n <a class=\"lf-link\" @click=\"backToAccount\">{{ t('login.backToPassword') }}</a>\n <a class=\"lf-link\" :class=\"{ 'lf-link-disabled': countdown > 0 }\" @click=\"onMfaResend\">\n {{ countdown > 0 ? t('login.resendAfter', { s: countdown }) : t('login.sendCode') }}\n </a>\n </div>\n <button\n class=\"hero-btn\"\n type=\"button\"\n :style=\"heroStyle\"\n :disabled=\"loading\"\n @click.prevent=\"onSubmit\"\n >\n {{ loading ? t('common.loading') : t('login.submit') }}\n </button>\n </n-form>\n </template>\n\n <!-- TOTP 二次验证:密码已过,凭 Authenticator 动态口令完成登录 -->\n <template v-else-if=\"mode === 'totp'\">\n <h2 v-if=\"showTitle\" class=\"lf-title\">{{ t('login.totpTitle') }}</h2>\n <p class=\"lf-hint-line\">{{ t('login.totpSub') }}</p>\n <n-form @keyup.enter=\"onSubmit\">\n <n-form-item :label=\"t('login.totpCode')\" path=\"code\">\n <n-input\n v-model:value=\"totp.code\"\n :placeholder=\"t('login.totpPlaceholder')\"\n size=\"large\"\n :maxlength=\"6\"\n >\n <template #prefix><Icon icon=\"ph:shield-check\" /></template>\n </n-input>\n </n-form-item>\n <div class=\"row lf-between\">\n <a class=\"lf-link\" @click=\"backToAccount\">{{ t('login.backToPassword') }}</a>\n <a class=\"lf-link\" @click=\"goRecovery\">{{ t('login.useRecovery') }}</a>\n </div>\n <button\n class=\"hero-btn\"\n type=\"button\"\n :style=\"heroStyle\"\n :disabled=\"loading\"\n @click.prevent=\"onSubmit\"\n >\n {{ loading ? t('common.loading') : t('login.submit') }}\n </button>\n </n-form>\n </template>\n\n <template v-else>\n <h2 v-if=\"showTitle\" class=\"lf-title\">{{ t('login.title') }}</h2>\n <n-form :model=\"mode === 'account' ? model : smsModel\" @keyup.enter=\"onSubmit\">\n <template v-if=\"mode === 'account'\">\n <n-form-item :label=\"t('login.account')\" path=\"account\">\n <n-input\n v-model:value=\"model.account\"\n :placeholder=\"t('login.accountPlaceholder')\"\n size=\"large\"\n >\n <template #prefix><Icon icon=\"ph:user\" /></template>\n </n-input>\n </n-form-item>\n <n-form-item :label=\"t('login.password')\" path=\"password\">\n <n-input\n v-model:value=\"model.password\"\n type=\"password\"\n show-password-on=\"click\"\n :placeholder=\"t('login.passwordPlaceholder')\"\n size=\"large\"\n >\n <template #prefix><Icon icon=\"ph:lock\" /></template>\n </n-input>\n </n-form-item>\n </template>\n <template v-else>\n <n-form-item :label=\"t('login.phone')\" path=\"phone\">\n <n-input\n v-model:value=\"smsModel.phone\"\n :placeholder=\"t('login.phonePlaceholder')\"\n size=\"large\"\n :maxlength=\"20\"\n >\n <template #prefix><Icon icon=\"ph:device-mobile\" /></template>\n </n-input>\n </n-form-item>\n </template>\n <n-form-item v-if=\"captchaEnabled\" :label=\"t('login.captcha')\" path=\"captcha\">\n <div class=\"lf-captcha\">\n <n-input\n v-model:value=\"captchaCode\"\n :placeholder=\"captchaHint\"\n size=\"large\"\n @keyup.enter=\"onSubmit\"\n >\n <template #prefix><Icon icon=\"ph:shield-check\" /></template>\n </n-input>\n <!-- SVG 来自本站后端;点击重取一张(一次性票据) -->\n <button\n type=\"button\"\n class=\"lf-captcha-img\"\n :title=\"t('login.captchaPlaceholder')\"\n @click=\"loadCaptcha\"\n v-html=\"captchaSvg\"\n />\n </div>\n </n-form-item>\n <n-form-item v-if=\"mode === 'sms'\" :label=\"t('login.smsCode')\" path=\"code\">\n <div class=\"lf-captcha\">\n <n-input\n v-model:value=\"smsModel.code\"\n :placeholder=\"t('login.smsCodePlaceholder')\"\n size=\"large\"\n :maxlength=\"6\"\n >\n <template #prefix><Icon icon=\"ph:chat-circle-text\" /></template>\n </n-input>\n <button\n type=\"button\"\n class=\"lf-send-btn\"\n :disabled=\"countdown > 0\"\n @click=\"onSendSmsCode\"\n >\n {{ countdown > 0 ? t('login.resendAfter', { s: countdown }) : t('login.sendCode') }}\n </button>\n </div>\n </n-form-item>\n <div class=\"row lf-between\">\n <n-checkbox v-if=\"mode === 'account'\" v-model:checked=\"model.remember\">\n {{ t('login.remember') }}\n </n-checkbox>\n <span v-else />\n <a\n v-if=\"site.smsLoginEnabled\"\n class=\"lf-link\"\n @click=\"mode = mode === 'account' ? 'sms' : 'account'\"\n >\n {{ mode === 'account' ? t('login.smsLogin') : t('login.accountLogin') }}\n </a>\n </div>\n <button\n class=\"hero-btn\"\n type=\"button\"\n :style=\"heroStyle\"\n :disabled=\"loading\"\n @click.prevent=\"onSubmit\"\n >\n {{ loading ? t('common.loading') : t('login.submit') }}\n </button>\n </n-form>\n\n <!-- 第三方登录:Gitee 风圆标;<a href>。PREVIEW_ALL_SSO_BRANDS 时展示全部品牌图。 -->\n <template v-if=\"ssoDisplayList.length\">\n <div class=\"lf-divider\">\n <span>{{ t('login.otherMethods') }}</span>\n </div>\n <div class=\"lf-sso\">\n <a\n v-for=\"p in ssoSplit.visible\"\n :key=\"p.code\"\n class=\"lf-sso-btn\"\n :href=\"ssoHref(p.code)\"\n :title=\"p.displayName\"\n :aria-label=\"p.displayName\"\n >\n <BrandIcon :code=\"p.code\" :icon=\"p.icon\" :size=\"32\" />\n </a>\n <n-dropdown\n v-if=\"ssoSplit.overflow.length\"\n trigger=\"click\"\n :options=\"ssoOverflowOptions\"\n @select=\"onSsoOverflow\"\n >\n <a\n class=\"lf-sso-btn lf-sso-more\"\n href=\"javascript:void(0)\"\n role=\"button\"\n :title=\"t('login.moreMethods')\"\n :aria-label=\"t('login.moreMethods')\"\n @click.prevent\n >\n <Icon icon=\"ph:dots-three-bold\" :width=\"18\" />\n </a>\n </n-dropdown>\n </div>\n </template>\n </template>\n\n <!-- 页脚:版权(可选链接)+ 构建期版本号。皮肤自绘页脚时(如双栏)传 :show-footer=\"false\" 关掉。 -->\n <footer v-if=\"showFooter\" class=\"lf-foot\">\n <span>\n © {{ year }}\n <a v-if=\"site.copyrightUrl\" :href=\"site.copyrightUrl\" target=\"_blank\" rel=\"noopener\">\n {{ site.copyright || site.title }}\n </a>\n <template v-else>{{ site.copyright || site.title }}</template>\n </span>\n <span v-if=\"appVersion\" class=\"lf-ver\">v{{ appVersion }}</span>\n </footer>\n\n <!-- 强制 MFA 未绑定(40020):遮罩 Modal,账密表单仍在底下;默认登录页不常驻绑定链接 -->\n <n-modal\n v-model:show=\"bindRequiredShow\"\n preset=\"dialog\"\n type=\"warning\"\n :title=\"t('login.totpBindTitle')\"\n :content=\"t('login.totpBindSub')\"\n :positive-text=\"t('login.setupAuthenticator')\"\n :negative-text=\"t('common.cancel')\"\n @positive-click=\"goBindAuthenticator\"\n @negative-click=\"closeBindRequired\"\n />\n <!-- pending-link:登录后显式确认绑定,防静默抢绑 -->\n <n-modal\n v-model:show=\"pendingConfirmShow\"\n preset=\"dialog\"\n type=\"info\"\n :title=\"t('oauth.pendingLinkConfirmTitle')\"\n :content=\"\n t('oauth.pendingLinkConfirmContent', {\n name: pendingProviderLabel,\n identity: pendingConfirmIdentity,\n account: user.userInfo?.account ?? '',\n })\n \"\n :positive-text=\"t('oauth.pendingLinkConfirmOk')\"\n :negative-text=\"t('oauth.pendingLinkConfirmSkip')\"\n :loading=\"pendingClaimBusy\"\n :closable=\"false\"\n :mask-closable=\"false\"\n @positive-click=\"confirmPendingBind\"\n @negative-click=\"skipPendingBind\"\n />\n </div>\n</template>\n\n<style scoped>\n/* 文字色默认跟随应用令牌;皮肤可通过 --lf-title / --lf-hint 覆盖(如极光深色皮肤强制浅色)。 */\n.login-form {\n width: 100%;\n}\n.lf-pending-alert {\n margin-bottom: 16px;\n border-radius: 10px;\n text-align: left;\n}\n.lf-brand {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 18px;\n}\n/* 后台配置的品牌 logo:限高与内置矢量 logo 齐平,宽度自适应不变形 */\n.lf-word {\n font-size: 22px;\n font-weight: 700;\n letter-spacing: 0.2px;\n color: var(--lf-title, var(--color-text-primary));\n}\n.lf-title {\n font-size: var(--font-size-lg);\n font-weight: 600;\n margin: 0 0 22px;\n color: var(--lf-title, var(--color-text-primary));\n}\n/* 二次验证副标题:标题下的弱化说明行 */\n.lf-hint-line {\n margin: -14px 0 18px;\n font-size: 13px;\n color: var(--lf-hint, var(--color-text-tertiary));\n}\n.row {\n margin: 4px 0 20px;\n}\n.lf-between {\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n/* 模式切换/重发:文字链接,复用主题色 */\n.lf-link {\n font-size: 13px;\n color: var(--color-primary);\n cursor: pointer;\n user-select: none;\n}\n.lf-link:hover {\n opacity: 0.85;\n}\n.lf-link-disabled {\n color: var(--lf-hint, var(--color-text-tertiary));\n cursor: default;\n pointer-events: none;\n}\n/* 验证码:输入框 + 可点击刷新的 SVG 图形(等高对齐) */\n.lf-captcha {\n display: flex;\n gap: 10px;\n width: 100%;\n align-items: stretch;\n}\n.lf-captcha-img {\n flex: 0 0 auto;\n height: 40px;\n min-width: 96px;\n padding: 0;\n border: 1px solid var(--lf-border, var(--color-border));\n border-radius: var(--radius-md);\n background: #fff;\n cursor: pointer;\n overflow: hidden;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.lf-captcha-img :deep(svg) {\n height: 100%;\n width: auto;\n}\n/* 发码按钮:与验证码图形同尺寸位,文字化 */\n.lf-send-btn {\n flex: 0 0 auto;\n height: 40px;\n min-width: 96px;\n padding: 0 12px;\n border: 1px solid var(--lf-border, var(--color-border));\n border-radius: var(--radius-md);\n background: var(--color-fill);\n font-size: 13px;\n color: var(--lf-title, var(--color-text-secondary));\n cursor: pointer;\n transition:\n border-color var(--transition-fast),\n color var(--transition-fast);\n}\n.lf-send-btn:hover:not(:disabled) {\n border-color: var(--color-primary);\n color: var(--color-primary);\n}\n.lf-send-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n.hero-btn {\n width: 100%;\n height: 48px;\n border: none;\n border-radius: var(--radius-md);\n color: #fff;\n font-size: var(--font-size-md);\n font-weight: 600;\n cursor: pointer;\n transition:\n transform var(--transition-fast),\n box-shadow var(--transition-fast);\n}\n.hero-btn:hover {\n transform: translateY(-2px);\n}\n.hero-btn:active {\n transform: translateY(0);\n}\n.hero-btn:disabled {\n opacity: 0.7;\n cursor: not-allowed;\n}\n/* 第三方登录:分隔线 + 等宽按钮(设计稿 §Variant A) */\n.lf-divider {\n display: flex;\n align-items: center;\n gap: 14px;\n margin: 24px 0 16px;\n}\n.lf-divider::before,\n.lf-divider::after {\n content: '';\n flex: 1;\n height: 1px;\n background: var(--lf-border, var(--color-border));\n}\n.lf-divider span {\n font-size: 12px;\n color: var(--lf-hint, var(--color-text-tertiary));\n}\n.lf-sso {\n display: flex;\n flex-wrap: wrap;\n justify-content: center;\n gap: 12px; /* 贴近 Gitee 一排小圆间距 */\n}\n/* Gitee 风:约 32px 圆标,比默认尺寸更紧凑 */\n.lf-sso-btn {\n width: 32px;\n height: 32px;\n padding: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n border-radius: 50%;\n background: transparent;\n color: inherit;\n text-decoration: none;\n cursor: pointer;\n overflow: hidden;\n box-sizing: border-box;\n flex-shrink: 0;\n}\n/* 不 hover 放大(Gitee 同款静态圆标) */\n.lf-sso-btn:hover {\n text-decoration: none;\n color: inherit;\n}\n.lf-sso-btn:focus-visible {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n}\n.lf-sso-more {\n width: 32px;\n height: 32px;\n border: 1px solid var(--lf-border, var(--color-border));\n background: var(--color-fill, #f5f5f5);\n color: var(--color-text-tertiary, #999);\n}\n/* 页脚:版权 + 版本号,弱化色,与 SSO 区留白 */\n.lf-foot {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n margin-top: 24px;\n font-size: 12px;\n color: var(--lf-hint, var(--color-text-tertiary));\n}\n.lf-foot a {\n color: inherit;\n text-decoration: none;\n}\n.lf-foot a:hover {\n color: var(--color-primary);\n}\n.lf-ver {\n opacity: 0.75;\n}\n</style>\n"],"names":["router","useRouter","route","useRoute","message","useMessage","useI18n","user","useUserStore","auth","useAuthStore","app","useAppStore","site","appVersion","loadSite","useSite","year","pendingLink","computed","pendingProvider","pendingDisplayName","pendingConfirmShow","ref","pendingClaimBusy","pendingClaimToken","model","reactive","runtime","loading","mode","smsModel","mfa","totp","bindRequiredShow","bindAccount","countdown","timer","startCountdown","s","onBeforeUnmount","captchaEnabled","captchaId","captchaSvg","captchaCode","captchaType","captchaHint","loadCaptcha","c","authApi","refreshCaptchaAfterUse","onMounted","loadSsoProviders","q","ch","heroStyle","btnGrad","glowSh","ssoProviders","pendingProviderLabel","code","hit","p","ssoDisplayList","ssoSplit","splitLoginProviders","ssoOverflowOptions","h","BrandIcon","externalAuthApi","claimWeComAutoLogin","ssoHref","onSsoOverflow","key","enterHome","finishLogin","res","resetRouter","link","pendingConfirmIdentity","confirmPendingBind","e","translateError","skipPendingBind","onSubmit","onMfaSubmit","onTotpSubmit","onSmsSubmit","ApiError","closeBindRequired","goBindAuthenticator","account","goRecovery","onMfaResend","r","backToAccount","onSendSmsCode","_openBlock","_createElementBlock","_hoisted_1","__props","_hoisted_2","_createVNode","SmartLogo","_createElementVNode","_hoisted_3","_toDisplayString","_unref","_createBlock","NAlert","_createTextVNode","_Fragment","_hoisted_4","_hoisted_5","NForm","NFormItem","NInput","_cache","$event","Icon","_hoisted_6","_normalizeClass","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_15","_hoisted_16","_hoisted_17","NCheckbox","_hoisted_18","_hoisted_19","_hoisted_20","_hoisted_21","_renderList","NDropdown","_hoisted_24","_hoisted_25","_hoisted_26","NModal"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LoginForm2.vue.js","sources":["../../../src/views/login/LoginForm.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { reactive, ref, computed, nextTick, onMounted, onBeforeUnmount, h } from 'vue'\nimport { useRoute, useRouter } from 'vue-router'\nimport {\n NAlert,\n NButton,\n NForm,\n NFormItem,\n NInput,\n NCheckbox,\n NModal,\n NDropdown,\n useMessage,\n type DropdownOption,\n} from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport { useI18n } from 'vue-i18n'\nimport { authApi, externalAuthApi, ApiError } from '#/api'\nimport type { LoginOutput } from '#/types/api'\nimport { useUserStore } from '#/stores/user'\nimport { useAuthStore } from '#/stores/auth'\nimport { useSite } from '#/composables/useSite'\nimport { resetRouter } from '#/router'\nimport { translateError } from '#/utils/error'\nimport {\n splitLoginProviders,\n PREVIEW_ALL_SSO_BRANDS,\n previewAllBrandProviders,\n claimWeComAutoLogin,\n} from '#/utils/oauthBrand'\nimport SmartLogo from '#/components/SmartLogo.vue'\nimport { runtime } from '#/lib/runtime'\nimport BrandIcon from '#/components/oauth/BrandIcon.vue'\n\n// 双栏布局下品牌区在左栏,卡内不重复 logo/标题,改用「欢迎回来」问候语(showGreeting);\n// 版权页脚由外壳画在卡外(showFooter=false)。单栏时全部默认:卡内顶部是 logo + 站点标题,再是「登录」标题。\nwithDefaults(\n defineProps<{\n showLogo?: boolean\n showTitle?: boolean\n showGreeting?: boolean\n showFooter?: boolean\n }>(),\n {\n showLogo: true,\n showTitle: true,\n showGreeting: false,\n showFooter: true,\n },\n)\n// 登录成功、即将跳转时通知外壳播退场动画(true);跳转没发生时撤销(false),免得页面停在淡出态\nconst emit = defineEmits<{ leave: [on: boolean] }>()\n\nconst router = useRouter()\nconst route = useRoute()\nconst message = useMessage()\nconst { t } = useI18n()\nconst user = useUserStore()\nconst auth = useAuthStore()\nconst { site, appVersion, loadSite } = useSite()\nconst year = new Date().getFullYear()\n\n/** 未绑定 SSO 后带回:登录成功后须确认再 claim(防静默抢绑) */\nconst pendingLink = computed(() =>\n typeof route.query.pendingLink === 'string' ? route.query.pendingLink : '',\n)\nconst pendingProvider = computed(() =>\n typeof route.query.provider === 'string' ? route.query.provider : '',\n)\nconst pendingDisplayName = computed(() =>\n typeof route.query.displayName === 'string' ? route.query.displayName : '',\n)\nconst pendingConfirmShow = ref(false)\nconst pendingClaimBusy = ref(false)\nconst pendingClaimToken = ref('')\n\n// 开发态(createSmartAdmin({ dev }))预填超管账号密码,免得每次手敲;生产留空。\n// SSO pending-link 场景故意不预填密码:解绑后 GitHub 会落到本页,预填+一点就 claim 看起来像「SSO 直接进了」。\nconst model = reactive(\n runtime.dev && !pendingLink.value\n ? { account: 'superAdmin', password: 'Aa123456', remember: true }\n : {\n account: runtime.dev ? 'superAdmin' : '',\n password: '',\n remember: true,\n },\n)\nconst loading = ref(false)\n\n// 登录形态:账号密码 / 短信免密 / 短信二次验证(40009) / TOTP 二次验证(40018)\n// 强制 MFA 未绑定(40020)用 Modal 引导,不切 mode,登录页默认也不常驻绑定链接\nconst mode = ref<'account' | 'sms' | 'mfa' | 'totp'>('account')\n\n// 短信免密登录\nconst smsModel = reactive({ phone: '', code: '' })\n// 二次验证挑战(40009 信令 args 下发)\nconst mfa = reactive({ challengeId: '', phoneMask: '', code: '' })\n// TOTP 挑战(40018)\nconst totp = reactive({ challengeId: '', code: '' })\n// 强制 MFA 但未绑定(40020):弹窗 + 带到 /mfa/bind 的账号\nconst bindRequiredShow = ref(false)\nconst bindAccount = ref('')\n\n// 发码/重发共用倒计时(同一时刻只有一个发码入口可见)\nconst countdown = ref(0)\nlet timer: number | undefined\nfunction startCountdown(s: number) {\n countdown.value = s\n window.clearInterval(timer)\n timer = window.setInterval(() => {\n countdown.value -= 1\n if (countdown.value <= 0) window.clearInterval(timer)\n }, 1000)\n}\nonBeforeUnmount(() => window.clearInterval(timer))\n\n// 验证码:是否启用由匿名站点信息(sys.security.captcha.enabled)运行时驱动;启用才拉取并展示。\n// 账号模式护登录,短信模式护发码(发码端点防脚本滥用)。\nconst captchaEnabled = ref(false)\nconst captchaId = ref('')\nconst captchaSvg = ref('')\nconst captchaCode = ref('')\nconst captchaType = ref('char')\n\n// math 类型需算出结果再输入,提示语不同;其余类型统一“请输入验证码”。\nconst captchaHint = computed(() =>\n captchaType.value === 'math' ? t('login.captchaMathPlaceholder') : t('login.captchaPlaceholder'),\n)\n\nasync function loadCaptcha() {\n try {\n const c = await authApi.captcha()\n captchaId.value = c.captchaId\n captchaSvg.value = c.svg\n captchaType.value = c.type || 'char'\n } catch {\n // 拉取失败不阻塞登录页渲染;点击图形可重试\n }\n}\n\n/** 验证码一次性消费:任何用掉票据的请求失败后必刷新,避免复用作废票据 */\nasync function refreshCaptchaAfterUse() {\n if (captchaEnabled.value) {\n captchaCode.value = ''\n await loadCaptcha()\n }\n}\n\nonMounted(async () => {\n // 站点信息全站共用(useSite 去重);验证码开关据此运行时驱动,启用才拉图。\n await loadSite()\n if (site.captchaEnabled) {\n captchaEnabled.value = true\n await loadCaptcha()\n }\n void loadSsoProviders()\n\n // SSO 回调带回的 TOTP 挑战:直接进入 totp 完成态\n const q = router.currentRoute.value.query\n const ch = typeof q.totpChallenge === 'string' ? q.totpChallenge : ''\n if (ch) {\n totp.challengeId = ch\n totp.code = ''\n mode.value = 'totp'\n }\n})\n\n// 第三方登录:默认后端 providers 驱动;PREVIEW_ALL_SSO_BRANDS 时铺全品牌图(图标验收)。\nconst ssoProviders = ref<{ code: string; displayName: string; icon?: string | null }[]>([])\nconst pendingProviderLabel = computed(() => {\n const code = pendingProvider.value\n if (!code) return t('oauth.thirdParty')\n const hit = ssoProviders.value.find(p => p.code === code)\n return hit?.displayName || code\n})\nconst ssoDisplayList = computed(() =>\n PREVIEW_ALL_SSO_BRANDS ? previewAllBrandProviders() : ssoProviders.value,\n)\n// 预览全图标时不截断;正常模式 N=4 溢出\nconst ssoSplit = computed(() =>\n PREVIEW_ALL_SSO_BRANDS\n ? { visible: ssoDisplayList.value, overflow: [] as typeof ssoDisplayList.value }\n : splitLoginProviders(ssoDisplayList.value),\n)\nconst ssoOverflowOptions = computed<DropdownOption[]>(() =>\n ssoSplit.value.overflow.map(p => ({\n key: p.code,\n label: () =>\n h(\n 'span',\n {\n class: 'lf-sso-menu-item',\n style: { display: 'inline-flex', alignItems: 'center', gap: '8px' },\n },\n [h(BrandIcon, { code: p.code, icon: p.icon, size: 20 }), h('span', null, p.displayName)],\n ),\n })),\n)\nasync function loadSsoProviders() {\n try {\n ssoProviders.value = await externalAuthApi.providers()\n } catch {\n // 未配置外部登录或拉取失败:整段 SSO 区不显(预览全图标模式仍会显示)\n return\n }\n // 企业微信客户端里直接走企业微信登录;SSO 带回来的认领 / 二次验证要留在本页完成\n const q = route.query\n if (\n !q.pendingLink &&\n !q.totpChallenge &&\n claimWeComAutoLogin({\n userAgent: navigator.userAgent,\n providers: ssoProviders.value,\n storage: sessionStorage,\n })\n ) {\n window.location.href = ssoHref('wecom')\n }\n}\n/** 顶层跳 IdP(与 Gitee 一样用 <a href>)。预览假项仍给 authorize 链,未配后端会失败。 */\nfunction ssoHref(code: string) {\n return externalAuthApi.authorizeUrl(code)\n}\nfunction onSsoOverflow(key: string | number) {\n window.location.href = ssoHref(String(key))\n}\n\nasync function enterHome() {\n await router.replace('/')\n}\n\n// 密码错 / 验证码错:表单左右抖一下(macOS 登录框的做法),比只弹 toast 更直接。\n// 先摘掉 class、等一帧再加,连续失败也能重播。\nconst shaking = ref(false)\nasync function shake() {\n shaking.value = false\n await nextTick()\n requestAnimationFrame(() => {\n shaking.value = true\n })\n}\n\n// 登录成功的收尾:先让页面淡出,再跳转。系统开了「减少动态效果」就不等。\nconst REDUCED_MOTION = '(prefers-reduced-motion: reduce)'\nasync function leaveThenEnter() {\n emit('leave', true)\n if (!window.matchMedia?.(REDUCED_MOTION).matches) {\n await new Promise<void>(resolve => setTimeout(resolve, 320))\n }\n await enterHome()\n emit('leave', false)\n}\n\nasync function finishLogin(res: LoginOutput) {\n // 每次登录都清动态路由/授权态,否则上次会话的 routesReady=true 会跳过 enterInitial,\n // 菜单壳在、业务路由未重建 → 进系统后处处 404(绑定 MFA 后回登录再登最易踩中)。\n resetRouter()\n auth.reset()\n user.setSession(res)\n\n // 现场绑定:不静默 claim——须用户确认,并依赖服务端 binder cookie 同浏览器校验\n const link = pendingLink.value\n if (link) {\n pendingClaimToken.value = link\n pendingConfirmShow.value = true\n return\n }\n message.success(t('login.success'))\n await leaveThenEnter()\n}\n\nconst pendingConfirmIdentity = computed(() =>\n pendingDisplayName.value\n ? t('oauth.pendingLinkIdentity', { display: pendingDisplayName.value })\n : '',\n)\n\nasync function confirmPendingBind() {\n if (pendingClaimBusy.value) return\n pendingClaimBusy.value = true\n try {\n await externalAuthApi.claimPendingLink(pendingClaimToken.value)\n message.success(t('oauth.pendingLinkSuccess', { name: pendingProviderLabel.value }))\n } catch (e) {\n message.warning(translateError(e))\n } finally {\n pendingClaimBusy.value = false\n pendingConfirmShow.value = false\n pendingClaimToken.value = ''\n }\n await enterHome()\n}\n\nasync function skipPendingBind() {\n pendingConfirmShow.value = false\n pendingClaimToken.value = ''\n message.success(t('login.success'))\n await enterHome()\n}\n\nasync function onSubmit() {\n if (mode.value === 'mfa') return onMfaSubmit()\n if (mode.value === 'totp') return onTotpSubmit()\n if (mode.value === 'sms') return onSmsSubmit()\n\n if (!model.account || !model.password) {\n message.warning(t('login.required'))\n return\n }\n if (captchaEnabled.value && !captchaCode.value) {\n message.warning(t('login.captchaRequired'))\n return\n }\n loading.value = true\n try {\n const res = await authApi.login({\n account: model.account,\n password: model.password,\n ...(captchaEnabled.value\n ? { captchaId: captchaId.value, captchaCode: captchaCode.value }\n : {}),\n })\n await finishLogin(res)\n } catch (e) {\n // 40018 = 密码已过、需 TOTP 二次验证\n if (e instanceof ApiError && e.code === 40018 && e.args) {\n totp.challengeId = String(e.args.challengeId ?? '')\n totp.code = ''\n mode.value = 'totp'\n } else if (e instanceof ApiError && e.code === 40020) {\n // 40020 = 强制 MFA 未绑定 → Modal 引导自助设置(登录页默认不常驻链接)\n bindAccount.value = model.account.trim()\n bindRequiredShow.value = true\n } else if (e instanceof ApiError && e.code === 40009 && e.args) {\n // 40009 = 密码已过、需短信二次验证\n mfa.challengeId = String(e.args.challengeId ?? '')\n mfa.phoneMask = String(e.args.phoneMask ?? '')\n mfa.code = ''\n mode.value = 'mfa'\n startCountdown(Number(e.args.resendSeconds ?? 60))\n } else {\n message.error(translateError(e))\n void shake()\n }\n await refreshCaptchaAfterUse()\n } finally {\n loading.value = false\n }\n}\n\nfunction closeBindRequired() {\n bindRequiredShow.value = false\n}\n\nfunction goBindAuthenticator() {\n const account = bindAccount.value || model.account.trim()\n bindRequiredShow.value = false\n void router.push({ path: '/mfa/bind', query: account ? { account } : {} })\n}\n\nfunction goRecovery() {\n const account = model.account.trim() || bindAccount.value\n void router.push({\n path: '/mfa/bind',\n query: { ...(account ? { account } : {}), mode: 'recovery' },\n })\n}\n\nasync function onMfaSubmit() {\n if (!mfa.code) {\n message.warning(t('login.smsCodePlaceholder'))\n return\n }\n loading.value = true\n try {\n await finishLogin(\n await authApi.smsChallengeLogin({ challengeId: mfa.challengeId, code: mfa.code }),\n )\n } catch (e) {\n message.error(translateError(e))\n void shake()\n } finally {\n loading.value = false\n }\n}\n\nasync function onTotpSubmit() {\n if (!totp.code) {\n message.warning(t('login.totpPlaceholder'))\n return\n }\n loading.value = true\n try {\n await finishLogin(\n await authApi.totpChallengeLogin({ challengeId: totp.challengeId, code: totp.code }),\n )\n } catch (e) {\n message.error(translateError(e))\n void shake()\n } finally {\n loading.value = false\n }\n}\n\nasync function onMfaResend() {\n if (countdown.value > 0) return\n try {\n const r = await authApi.smsChallengeResend({ challengeId: mfa.challengeId })\n message.success(t('login.smsSent'))\n startCountdown(r.resendSeconds)\n } catch (e) {\n message.error(translateError(e))\n }\n}\n\nfunction backToAccount() {\n mode.value = 'account'\n mfa.challengeId = ''\n mfa.code = ''\n totp.challengeId = ''\n totp.code = ''\n}\n\nasync function onSendSmsCode() {\n if (countdown.value > 0) return\n if (!smsModel.phone) {\n message.warning(t('login.phonePlaceholder'))\n return\n }\n if (captchaEnabled.value && !captchaCode.value) {\n message.warning(t('login.captchaRequired'))\n return\n }\n try {\n const r = await authApi.smsLoginSend({\n phone: smsModel.phone,\n ...(captchaEnabled.value\n ? { captchaId: captchaId.value, captchaCode: captchaCode.value }\n : {}),\n })\n message.success(t('login.smsSent'))\n startCountdown(r.resendSeconds)\n } catch (e) {\n message.error(translateError(e))\n }\n await refreshCaptchaAfterUse()\n}\n\nasync function onSmsSubmit() {\n if (!smsModel.phone || !smsModel.code) {\n message.warning(t('login.smsRequired'))\n return\n }\n loading.value = true\n try {\n await finishLogin(await authApi.smsLogin({ phone: smsModel.phone, code: smsModel.code }))\n } catch (e) {\n message.error(translateError(e))\n void shake()\n } finally {\n loading.value = false\n }\n}\n</script>\n\n<template>\n <div class=\"login-form\" :class=\"{ shake: shaking }\" @animationend.self=\"shaking = false\">\n <div v-if=\"showLogo\" class=\"lf-brand\">\n <!-- 站点 logo 的取值顺序(配置 → brand 选项 → 内置矢量标)统一在 SmartLogo 里 -->\n <SmartLogo :size=\"34\" />\n <span class=\"lf-word\">{{ site.title }}</span>\n </div>\n\n <n-alert\n v-if=\"pendingLink\"\n type=\"info\"\n :bordered=\"false\"\n class=\"lf-pending-alert\"\n :title=\"t('oauth.pendingLinkTitle', { name: pendingProviderLabel })\"\n >\n {{ t('oauth.pendingLinkHint', { name: pendingProviderLabel }) }}\n </n-alert>\n\n <!-- 登录方式切换:旧内容先淡出上移,新内容的逐项浮现由外壳(LoginDesk)的入场动画负责 -->\n <Transition name=\"lf-swap\" mode=\"out-in\">\n <div :key=\"mode\" class=\"lf-body\">\n <!-- 短信二次验证:密码已过,凭挑战 + 短信码完成登录 -->\n <template v-if=\"mode === 'mfa'\">\n <h2 v-if=\"showTitle || showGreeting\" class=\"lf-title\">\n {{ t('login.mfaTitle', { phone: mfa.phoneMask }) }}\n </h2>\n <p class=\"lf-hint-line\">{{ t('login.mfaSub') }}</p>\n <n-form :show-feedback=\"false\" @keyup.enter=\"onSubmit\">\n <n-form-item :label=\"t('login.smsCode')\" path=\"code\">\n <n-input\n v-model:value=\"mfa.code\"\n :placeholder=\"t('login.smsCodePlaceholder')\"\n size=\"large\"\n :maxlength=\"6\"\n >\n <template #prefix><Icon icon=\"ph:chat-circle-text\" /></template>\n </n-input>\n </n-form-item>\n <div class=\"row lf-between\">\n <n-button text type=\"primary\" @click=\"backToAccount\">\n {{ t('login.backToPassword') }}\n </n-button>\n <n-button\n text\n :type=\"countdown > 0 ? 'default' : 'primary'\"\n :disabled=\"countdown > 0\"\n @click=\"onMfaResend\"\n >\n {{ countdown > 0 ? t('login.resendAfter', { s: countdown }) : t('login.sendCode') }}\n </n-button>\n </div>\n <n-button\n class=\"hero-btn cta\"\n type=\"primary\"\n size=\"large\"\n block\n attr-type=\"button\"\n :loading=\"loading\"\n @click=\"onSubmit\"\n >\n {{ loading ? t('common.loading') : t('login.submit') }}\n </n-button>\n </n-form>\n </template>\n\n <!-- TOTP 二次验证:密码已过,凭 Authenticator 动态口令完成登录 -->\n <template v-else-if=\"mode === 'totp'\">\n <h2 v-if=\"showTitle || showGreeting\" class=\"lf-title\">{{ t('login.totpTitle') }}</h2>\n <p class=\"lf-hint-line\">{{ t('login.totpSub') }}</p>\n <n-form :show-feedback=\"false\" @keyup.enter=\"onSubmit\">\n <n-form-item :label=\"t('login.totpCode')\" path=\"code\">\n <n-input\n v-model:value=\"totp.code\"\n :placeholder=\"t('login.totpPlaceholder')\"\n size=\"large\"\n :maxlength=\"6\"\n >\n <template #prefix><Icon icon=\"ph:shield-check\" /></template>\n </n-input>\n </n-form-item>\n <div class=\"row lf-between\">\n <n-button text type=\"primary\" @click=\"backToAccount\">\n {{ t('login.backToPassword') }}\n </n-button>\n <n-button text type=\"primary\" @click=\"goRecovery\">\n {{ t('login.useRecovery') }}\n </n-button>\n </div>\n <n-button\n class=\"hero-btn cta\"\n type=\"primary\"\n size=\"large\"\n block\n attr-type=\"button\"\n :loading=\"loading\"\n @click=\"onSubmit\"\n >\n {{ loading ? t('common.loading') : t('login.submit') }}\n </n-button>\n </n-form>\n </template>\n\n <template v-else>\n <!-- 单栏:卡内标题「登录」;双栏:品牌在左栏,这里是问候语 -->\n <h2 v-if=\"showTitle\" class=\"lf-title\">{{ t('login.title') }}</h2>\n <div v-else-if=\"showGreeting\" class=\"lf-greet\">\n <h1>{{ t('login.welcome') }}</h1>\n <p>{{ t('login.welcomeSub') }}</p>\n </div>\n <n-form\n :model=\"mode === 'account' ? model : smsModel\"\n :show-feedback=\"false\"\n @keyup.enter=\"onSubmit\"\n >\n <template v-if=\"mode === 'account'\">\n <n-form-item :label=\"t('login.account')\" path=\"account\">\n <n-input\n v-model:value=\"model.account\"\n :placeholder=\"t('login.accountPlaceholder')\"\n size=\"large\"\n >\n <template #prefix><Icon icon=\"ph:user\" /></template>\n </n-input>\n </n-form-item>\n <n-form-item :label=\"t('login.password')\" path=\"password\">\n <n-input\n v-model:value=\"model.password\"\n type=\"password\"\n show-password-on=\"click\"\n :placeholder=\"t('login.passwordPlaceholder')\"\n size=\"large\"\n >\n <template #prefix><Icon icon=\"ph:lock\" /></template>\n </n-input>\n </n-form-item>\n </template>\n <template v-else>\n <n-form-item :label=\"t('login.phone')\" path=\"phone\">\n <n-input\n v-model:value=\"smsModel.phone\"\n :placeholder=\"t('login.phonePlaceholder')\"\n size=\"large\"\n :maxlength=\"20\"\n >\n <template #prefix><Icon icon=\"ph:device-mobile\" /></template>\n </n-input>\n </n-form-item>\n </template>\n <n-form-item v-if=\"captchaEnabled\" :label=\"t('login.captcha')\" path=\"captcha\">\n <div class=\"lf-captcha\">\n <n-input\n v-model:value=\"captchaCode\"\n :placeholder=\"captchaHint\"\n size=\"large\"\n @keyup.enter=\"onSubmit\"\n >\n <template #prefix><Icon icon=\"ph:shield-check\" /></template>\n </n-input>\n <!-- SVG 来自本站后端;点击重取一张(一次性票据);取图失败时图形位为空,点击重试 -->\n <button\n type=\"button\"\n class=\"lf-captcha-img\"\n :class=\"{ empty: !captchaSvg }\"\n :title=\"t('login.captchaPlaceholder')\"\n :aria-label=\"t('login.captchaPlaceholder')\"\n @click=\"loadCaptcha\"\n v-html=\"captchaSvg\"\n />\n </div>\n </n-form-item>\n <n-form-item v-if=\"mode === 'sms'\" :label=\"t('login.smsCode')\" path=\"code\">\n <div class=\"lf-captcha\">\n <n-input\n v-model:value=\"smsModel.code\"\n :placeholder=\"t('login.smsCodePlaceholder')\"\n size=\"large\"\n :maxlength=\"6\"\n >\n <template #prefix><Icon icon=\"ph:chat-circle-text\" /></template>\n </n-input>\n <n-button\n class=\"lf-send-btn\"\n secondary\n size=\"large\"\n attr-type=\"button\"\n :disabled=\"countdown > 0\"\n @click=\"onSendSmsCode\"\n >\n {{\n countdown > 0 ? t('login.resendAfter', { s: countdown }) : t('login.sendCode')\n }}\n </n-button>\n </div>\n </n-form-item>\n <div class=\"row lf-between\">\n <n-checkbox v-if=\"mode === 'account'\" v-model:checked=\"model.remember\">\n {{ t('login.remember') }}\n </n-checkbox>\n <span v-else />\n <n-button\n v-if=\"site.smsLoginEnabled\"\n text\n type=\"primary\"\n @click=\"mode = mode === 'account' ? 'sms' : 'account'\"\n >\n {{ mode === 'account' ? t('login.smsLogin') : t('login.accountLogin') }}\n </n-button>\n </div>\n <n-button\n class=\"hero-btn cta\"\n type=\"primary\"\n size=\"large\"\n block\n attr-type=\"button\"\n :loading=\"loading\"\n @click=\"onSubmit\"\n >\n {{ loading ? t('common.loading') : t('login.submit') }}\n </n-button>\n </n-form>\n\n <!-- 第三方登录:圆形品牌标;<a href>。PREVIEW_ALL_SSO_BRANDS 时展示全部品牌图。 -->\n <template v-if=\"ssoDisplayList.length\">\n <div class=\"lf-divider\">\n <span>{{ t('login.otherMethods') }}</span>\n </div>\n <div class=\"lf-sso\">\n <a\n v-for=\"p in ssoSplit.visible\"\n :key=\"p.code\"\n class=\"lf-sso-btn\"\n :href=\"ssoHref(p.code)\"\n :title=\"p.displayName\"\n :aria-label=\"p.displayName\"\n >\n <BrandIcon :code=\"p.code\" :icon=\"p.icon\" :size=\"28\" />\n </a>\n <n-dropdown\n v-if=\"ssoSplit.overflow.length\"\n trigger=\"click\"\n :options=\"ssoOverflowOptions\"\n @select=\"onSsoOverflow\"\n >\n <a\n class=\"lf-sso-btn lf-sso-more\"\n href=\"javascript:void(0)\"\n role=\"button\"\n :title=\"t('login.moreMethods')\"\n :aria-label=\"t('login.moreMethods')\"\n @click.prevent\n >\n <Icon icon=\"ph:dots-three\" :width=\"18\" />\n </a>\n </n-dropdown>\n </div>\n </template>\n </template>\n </div>\n </Transition>\n\n <!-- 页脚:版权(可选链接)+ 构建期版本号。双栏时外壳在卡外自绘页脚,传 :show-footer=\"false\" 关掉。 -->\n <footer v-if=\"showFooter\" class=\"lf-foot\">\n <span>\n © {{ year }}\n <a v-if=\"site.copyrightUrl\" :href=\"site.copyrightUrl\" target=\"_blank\" rel=\"noopener\">\n {{ site.copyright || site.title }}\n </a>\n <template v-else>{{ site.copyright || site.title }}</template>\n </span>\n <span v-if=\"appVersion\" class=\"lf-ver\">v{{ appVersion }}</span>\n </footer>\n\n <!-- 强制 MFA 未绑定(40020):遮罩 Modal,账密表单仍在底下;默认登录页不常驻绑定链接 -->\n <n-modal\n v-model:show=\"bindRequiredShow\"\n preset=\"dialog\"\n type=\"warning\"\n :title=\"t('login.totpBindTitle')\"\n :content=\"t('login.totpBindSub')\"\n :positive-text=\"t('login.setupAuthenticator')\"\n :negative-text=\"t('common.cancel')\"\n @positive-click=\"goBindAuthenticator\"\n @negative-click=\"closeBindRequired\"\n />\n <!-- pending-link:登录后显式确认绑定,防静默抢绑 -->\n <n-modal\n v-model:show=\"pendingConfirmShow\"\n preset=\"dialog\"\n type=\"info\"\n :title=\"t('oauth.pendingLinkConfirmTitle')\"\n :content=\"\n t('oauth.pendingLinkConfirmContent', {\n name: pendingProviderLabel,\n identity: pendingConfirmIdentity,\n account: user.userInfo?.account ?? '',\n })\n \"\n :positive-text=\"t('oauth.pendingLinkConfirmOk')\"\n :negative-text=\"t('oauth.pendingLinkConfirmSkip')\"\n :loading=\"pendingClaimBusy\"\n :closable=\"false\"\n :mask-closable=\"false\"\n @positive-click=\"confirmPendingBind\"\n @negative-click=\"skipPendingBind\"\n />\n </div>\n</template>\n\n<style scoped>\n.login-form {\n width: 100%;\n}\n/* 登录失败:左右抖一下并逐渐收住(macOS 登录框的做法),不回弹到别处 */\n.login-form.shake {\n animation: lf-shake 0.46s cubic-bezier(0.36, 0.07, 0.19, 0.97);\n}\n@keyframes lf-shake {\n 0%,\n 100% {\n transform: none;\n }\n 15% {\n transform: translate3d(-9px, 0, 0);\n }\n 30% {\n transform: translate3d(8px, 0, 0);\n }\n 45% {\n transform: translate3d(-6px, 0, 0);\n }\n 60% {\n transform: translate3d(4px, 0, 0);\n }\n 80% {\n transform: translate3d(-2px, 0, 0);\n }\n}\n/* 登录方式切换:旧内容淡出并轻微上移变虚 */\n.lf-swap-leave-active {\n transition:\n opacity 0.16s ease-in,\n transform 0.16s ease-in,\n filter 0.16s ease-in;\n}\n.lf-swap-leave-to {\n opacity: 0;\n transform: translate3d(0, -6px, 0);\n filter: blur(4px);\n}\n@media (prefers-reduced-motion: reduce) {\n .login-form.shake {\n animation: none;\n }\n}\n.lf-pending-alert {\n margin-bottom: 16px;\n border-radius: var(--radius-md);\n text-align: left;\n}\n/* 单栏卡内顶部:站点 logo + 标题。logo 取值顺序见 SmartLogo */\n.lf-brand {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 18px;\n}\n.lf-word {\n font-size: 22px;\n font-weight: 700;\n letter-spacing: -0.01em;\n color: var(--text-1);\n}\n.lf-title {\n font-size: 20px;\n font-weight: 600;\n letter-spacing: -0.02em;\n line-height: 1.3;\n margin: 0 0 16px;\n color: var(--text-1);\n}\n/* 双栏卡内问候语 */\n.lf-greet {\n text-align: center;\n margin: 2px 0 20px;\n}\n.lf-greet h1 {\n font-size: 26px;\n font-weight: 600;\n letter-spacing: -0.035em;\n margin: 0 0 4px;\n color: var(--text-1);\n}\n.lf-greet p {\n margin: 0;\n font-size: 13.5px;\n color: var(--text-3);\n}\n/* 二次验证副标题:标题下的弱化说明行 */\n.lf-hint-line {\n margin: -8px 0 18px;\n font-size: 13px;\n color: var(--text-3);\n}\n/* 表单项之间的间距(表单关了反馈行,没有校验规则要显示) */\n.login-form :deep(.n-form-item) {\n margin-bottom: 14px;\n}\n.row {\n margin: 2px 0 14px;\n min-height: 32px;\n}\n.lf-between {\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n.lf-between > :deep(.n-button) {\n height: 32px;\n padding: 0 2px;\n}\n/* 验证码:输入框 + 可点击刷新的 SVG 图形(等高对齐) */\n.lf-captcha {\n display: flex;\n gap: 10px;\n width: 100%;\n align-items: stretch;\n}\n.lf-captcha > :deep(.n-input) {\n flex: 1;\n min-width: 0;\n}\n.lf-captcha-img {\n flex: none;\n height: 42px;\n min-width: 100px;\n padding: 0;\n border: 1px solid var(--hairline);\n border-radius: var(--radius-md);\n background: #fff;\n cursor: pointer;\n overflow: hidden;\n display: grid;\n place-items: center;\n line-height: 0;\n}\n/* 取图失败时图形位为空:换成输入框同款底色,否则空白框像 bug;点击重试 */\n.lf-captcha-img.empty {\n background: var(--fill);\n}\n.lf-captcha-img:focus-visible {\n outline: 2px solid var(--signal);\n outline-offset: 2px;\n}\n.lf-captcha-img :deep(svg) {\n display: block;\n height: 40px;\n width: auto;\n}\n/* 发码按钮:与验证码图形同尺寸位 */\n.lf-send-btn {\n flex: none;\n min-width: 104px;\n}\n/* 第三方登录:分隔线 + 圆形品牌标 */\n.lf-divider {\n display: flex;\n align-items: center;\n gap: 14px;\n margin: 22px 0 14px;\n}\n.lf-divider::before,\n.lf-divider::after {\n content: '';\n flex: 1;\n height: 1px;\n background: var(--hairline);\n}\n.lf-divider span {\n font-size: 13px;\n color: var(--text-3);\n}\n.lf-sso {\n display: flex;\n flex-wrap: wrap;\n justify-content: center;\n gap: 12px;\n}\n/* 第三方登录:只露品牌标本身,不加灰底 / 描边 / 圆形裁切(会吃掉品牌标的轮廓);\n 40px 是点击热区,hover 才浮出一层极淡的圆角底,macOS 工具栏按钮的做法 */\n.lf-sso-btn {\n width: 40px;\n height: 40px;\n padding: 0;\n display: inline-grid;\n place-items: center;\n flex: none;\n border: none;\n border-radius: var(--radius-lg);\n background: transparent;\n color: var(--text-1);\n text-decoration: none;\n cursor: pointer;\n transition: background var(--transition-base);\n}\n.lf-sso-btn :deep(.oauth-brand-badge) {\n width: 28px;\n height: 28px;\n}\n.lf-sso-btn:hover {\n background: var(--hover);\n color: var(--text-1);\n text-decoration: none;\n}\n.lf-sso-btn:active {\n background: var(--pressed);\n}\n.lf-sso-btn:focus-visible {\n outline: 2px solid var(--signal);\n outline-offset: 2px;\n}\n/* 页脚:版权 + 版本号,弱化色 */\n.lf-foot {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n margin-top: 20px;\n font-size: 13px;\n color: var(--text-3);\n}\n.lf-foot a {\n color: inherit;\n text-decoration: none;\n}\n.lf-foot a:hover {\n color: var(--signal);\n}\n.lf-ver {\n opacity: 0.75;\n}\n@media (max-width: 480px) {\n .lf-captcha-img {\n min-width: 92px;\n }\n}\n</style>\n"],"names":["REDUCED_MOTION","emit","__emit","router","useRouter","route","useRoute","message","useMessage","t","useI18n","user","useUserStore","auth","useAuthStore","site","appVersion","loadSite","useSite","year","pendingLink","computed","pendingProvider","pendingDisplayName","pendingConfirmShow","ref","pendingClaimBusy","pendingClaimToken","model","reactive","runtime","loading","mode","smsModel","mfa","totp","bindRequiredShow","bindAccount","countdown","timer","startCountdown","s","onBeforeUnmount","captchaEnabled","captchaId","captchaSvg","captchaCode","captchaType","captchaHint","loadCaptcha","c","authApi","refreshCaptchaAfterUse","onMounted","loadSsoProviders","q","ch","ssoProviders","pendingProviderLabel","code","hit","p","ssoDisplayList","ssoSplit","splitLoginProviders","ssoOverflowOptions","h","BrandIcon","externalAuthApi","claimWeComAutoLogin","ssoHref","onSsoOverflow","key","enterHome","shaking","shake","nextTick","leaveThenEnter","_a","resolve","finishLogin","res","resetRouter","link","pendingConfirmIdentity","confirmPendingBind","e","translateError","skipPendingBind","onSubmit","onMfaSubmit","onTotpSubmit","onSmsSubmit","ApiError","closeBindRequired","goBindAuthenticator","account","goRecovery","onMfaResend","r","backToAccount","onSendSmsCode","_createElementBlock","_normalizeClass","__props","_openBlock","_hoisted_1","_createVNode","SmartLogo","_createElementVNode","_hoisted_2","_toDisplayString","_unref","_createBlock","NAlert","_createTextVNode","_Transition","_Fragment","_hoisted_3","_hoisted_4","NForm","NFormItem","NInput","_cache","$event","Icon","_hoisted_5","NButton","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_13","_hoisted_14","NCheckbox","_hoisted_15","_hoisted_16","_hoisted_17","_renderList","NDropdown","_hoisted_20","_hoisted_21","_hoisted_22","NModal"],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
/** 双栏:左栏渲染 brand 插槽,卡片宽度收到 384 */
|
|
3
|
+
split?: boolean;
|
|
4
|
+
/** 卡片宽度(px),窄屏被 max-width:100% 收住 */
|
|
5
|
+
width?: number;
|
|
6
|
+
/** NCard 内容区内边距 */
|
|
7
|
+
contentStyle?: string;
|
|
8
|
+
/** 退场:登录成功后由页面置真,整页淡出,等动画播完再跳转 */
|
|
9
|
+
leaving?: boolean;
|
|
10
|
+
};
|
|
11
|
+
declare var __VLS_1: {}, __VLS_3: {}, __VLS_26: {}, __VLS_34: {}, __VLS_36: {};
|
|
12
|
+
type __VLS_Slots = {} & {
|
|
13
|
+
brand?: (props: typeof __VLS_1) => any;
|
|
14
|
+
} & {
|
|
15
|
+
corner?: (props: typeof __VLS_3) => any;
|
|
16
|
+
} & {
|
|
17
|
+
above?: (props: typeof __VLS_26) => any;
|
|
18
|
+
} & {
|
|
19
|
+
default?: (props: typeof __VLS_34) => any;
|
|
20
|
+
} & {
|
|
21
|
+
after?: (props: typeof __VLS_36) => any;
|
|
22
|
+
};
|
|
23
|
+
declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
24
|
+
split: boolean;
|
|
25
|
+
width: number;
|
|
26
|
+
contentStyle: string;
|
|
27
|
+
leaving: boolean;
|
|
28
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
29
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
30
|
+
declare const _default: typeof __VLS_export;
|
|
31
|
+
export default _default;
|
|
32
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
33
|
+
new (): {
|
|
34
|
+
$slots: S;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import o from "./LoginDesk2.vue.js";
|
|
2
|
+
/* empty css */
|
|
3
|
+
/* empty css */
|
|
4
|
+
import t from "../../../_virtual/_plugin-vue_export-helper.js";
|
|
5
|
+
const e = /* @__PURE__ */ t(o, [["__scopeId", "data-v-2da0e5ac"]]);
|
|
6
|
+
export {
|
|
7
|
+
e as default
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=LoginDesk.vue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoginDesk.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { defineComponent as h, ref as w, onBeforeUnmount as b, openBlock as v, createElementBlock as g, normalizeClass as y, createElementVNode as o, renderSlot as l, createCommentVNode as $, createVNode as d, unref as e, withCtx as u, createTextVNode as x, toDisplayString as N, normalizeStyle as B } from "vue";
|
|
2
|
+
import { NTooltip as C, NButton as D, NCard as P } from "naive-ui";
|
|
3
|
+
import { Icon as S } from "@iconify/vue";
|
|
4
|
+
import { useI18n as F } from "vue-i18n";
|
|
5
|
+
import { useAppStore as A } from "../../../stores/app.js";
|
|
6
|
+
const V = {
|
|
7
|
+
key: 0,
|
|
8
|
+
class: "login-brand"
|
|
9
|
+
}, T = { class: "login-brand-inner" }, q = { class: "login-stage" }, z = { class: "login-corner" }, U = /* @__PURE__ */ h({
|
|
10
|
+
__name: "LoginDesk",
|
|
11
|
+
props: {
|
|
12
|
+
split: { type: Boolean, default: !1 },
|
|
13
|
+
width: { default: 400 },
|
|
14
|
+
contentStyle: { default: "padding: 26px 26px 22px" },
|
|
15
|
+
leaving: { type: Boolean, default: !1 }
|
|
16
|
+
},
|
|
17
|
+
setup(i) {
|
|
18
|
+
const r = A(), { t: a } = F(), p = w(null);
|
|
19
|
+
let c = 0;
|
|
20
|
+
function m(t, n) {
|
|
21
|
+
cancelAnimationFrame(c), c = requestAnimationFrame(() => {
|
|
22
|
+
var s, f;
|
|
23
|
+
(s = p.value) == null || s.style.setProperty("--px", t.toFixed(3)), (f = p.value) == null || f.style.setProperty("--py", n.toFixed(3));
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function k(t) {
|
|
27
|
+
t.pointerType === "mouse" && m(t.clientX / window.innerWidth * 2 - 1, t.clientY / window.innerHeight * 2 - 1);
|
|
28
|
+
}
|
|
29
|
+
return b(() => cancelAnimationFrame(c)), (t, n) => (v(), g("div", {
|
|
30
|
+
ref_key: "root",
|
|
31
|
+
ref: p,
|
|
32
|
+
class: y(["login desk-bg", { split: i.split, leaving: i.leaving }]),
|
|
33
|
+
onPointermove: k,
|
|
34
|
+
onPointerleave: n[1] || (n[1] = (s) => m(0, 0))
|
|
35
|
+
}, [
|
|
36
|
+
n[2] || (n[2] = o("div", {
|
|
37
|
+
class: "desk",
|
|
38
|
+
"aria-hidden": "true"
|
|
39
|
+
}, [
|
|
40
|
+
o("i"),
|
|
41
|
+
o("i"),
|
|
42
|
+
o("i"),
|
|
43
|
+
o("i")
|
|
44
|
+
], -1)),
|
|
45
|
+
i.split ? (v(), g("div", V, [
|
|
46
|
+
o("div", T, [
|
|
47
|
+
l(t.$slots, "brand", {}, void 0, !0)
|
|
48
|
+
])
|
|
49
|
+
])) : $("", !0),
|
|
50
|
+
o("div", q, [
|
|
51
|
+
o("div", z, [
|
|
52
|
+
l(t.$slots, "corner", {}, void 0, !0),
|
|
53
|
+
d(e(C), null, {
|
|
54
|
+
trigger: u(() => [
|
|
55
|
+
d(e(D), {
|
|
56
|
+
quaternary: "",
|
|
57
|
+
circle: "",
|
|
58
|
+
"aria-label": e(r).isDark ? e(a)("app.light") : e(a)("app.dark"),
|
|
59
|
+
onClick: n[0] || (n[0] = (s) => e(r).toggleDark())
|
|
60
|
+
}, {
|
|
61
|
+
icon: u(() => [
|
|
62
|
+
d(e(S), {
|
|
63
|
+
icon: e(r).isDark ? "ph:moon" : "ph:sun",
|
|
64
|
+
width: 18
|
|
65
|
+
}, null, 8, ["icon"])
|
|
66
|
+
]),
|
|
67
|
+
_: 1
|
|
68
|
+
}, 8, ["aria-label"])
|
|
69
|
+
]),
|
|
70
|
+
default: u(() => [
|
|
71
|
+
x(" " + N(e(r).isDark ? e(a)("app.light") : e(a)("app.dark")), 1)
|
|
72
|
+
]),
|
|
73
|
+
_: 1
|
|
74
|
+
})
|
|
75
|
+
]),
|
|
76
|
+
o("div", {
|
|
77
|
+
class: y(["login-card", { "on-desk": i.split }]),
|
|
78
|
+
style: B(i.split ? void 0 : { width: `${i.width}px` })
|
|
79
|
+
}, [
|
|
80
|
+
l(t.$slots, "above", {}, void 0, !0),
|
|
81
|
+
d(e(P), {
|
|
82
|
+
bordered: !0,
|
|
83
|
+
class: "desk-card",
|
|
84
|
+
"content-style": i.contentStyle
|
|
85
|
+
}, {
|
|
86
|
+
default: u(() => [
|
|
87
|
+
l(t.$slots, "default", {}, void 0, !0)
|
|
88
|
+
]),
|
|
89
|
+
_: 3
|
|
90
|
+
}, 8, ["content-style"]),
|
|
91
|
+
l(t.$slots, "after", {}, void 0, !0)
|
|
92
|
+
], 6)
|
|
93
|
+
])
|
|
94
|
+
], 34));
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
export {
|
|
98
|
+
U as default
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=LoginDesk2.vue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoginDesk2.vue.js","sources":["../../../../src/views/login/components/LoginDesk.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 入口类全屏页(登录 / 二次验证 / 第三方回调 / 门户加载失败)共用的外壳:macOS 锁屏语言。\n// 整页一张慢慢飘的柔光色场(.desk,颜色全由强调色推导,无网格)+ 浮在上面的毛玻璃卡,右上角是工具栏。\n// 单栏 = 居中一张卡;双栏(split)= 左栏品牌区(brand 插槽)压在色场上,右栏是这张卡。\n// 只管视觉外壳:卡里放什么、表单怎么提交都在各页自己手里。\n//\n// 动效(全部不回弹):入场按「卡 → 标题 → 字段 → 按钮」依次浮现(先模糊后清晰);\n// 色场与卡跟着指针做反向视差;leaving 为真时整页淡出放大一点(像 macOS 解锁),给登录成功收尾。\nimport { onBeforeUnmount, ref } from 'vue'\nimport { NButton, NCard, NTooltip } from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport { useI18n } from 'vue-i18n'\nimport { useAppStore } from '#/stores/app'\n\nwithDefaults(\n defineProps<{\n /** 双栏:左栏渲染 brand 插槽,卡片宽度收到 384 */\n split?: boolean\n /** 卡片宽度(px),窄屏被 max-width:100% 收住 */\n width?: number\n /** NCard 内容区内边距 */\n contentStyle?: string\n /** 退场:登录成功后由页面置真,整页淡出,等动画播完再跳转 */\n leaving?: boolean\n }>(),\n { split: false, width: 400, contentStyle: 'padding: 26px 26px 22px', leaving: false },\n)\n\nconst app = useAppStore()\nconst { t } = useI18n()\n\n// 指针视差:只认鼠标(触屏没有悬停位置),坐标归一到 -1..1 写成 CSS 变量,位移与过渡都在 CSS 里\nconst root = ref<HTMLElement | null>(null)\nlet raf = 0\nfunction setParallax(x: number, y: number) {\n cancelAnimationFrame(raf)\n raf = requestAnimationFrame(() => {\n root.value?.style.setProperty('--px', x.toFixed(3))\n root.value?.style.setProperty('--py', y.toFixed(3))\n })\n}\nfunction onPointerMove(e: PointerEvent) {\n if (e.pointerType !== 'mouse') return\n setParallax((e.clientX / window.innerWidth) * 2 - 1, (e.clientY / window.innerHeight) * 2 - 1)\n}\nonBeforeUnmount(() => cancelAnimationFrame(raf))\n</script>\n\n<template>\n <div\n ref=\"root\"\n class=\"login desk-bg\"\n :class=\"{ split, leaving }\"\n @pointermove=\"onPointerMove\"\n @pointerleave=\"setParallax(0, 0)\"\n >\n <div class=\"desk\" aria-hidden=\"true\">\n <i />\n <i />\n <i />\n <i />\n </div>\n\n <div v-if=\"split\" class=\"login-brand\">\n <div class=\"login-brand-inner\"><slot name=\"brand\" /></div>\n </div>\n\n <div class=\"login-stage\">\n <!-- 右上角工具栏:页面自己的按钮(布局切换、语言)在前,主题切换永远贴最右角 -->\n <div class=\"login-corner\">\n <slot name=\"corner\" />\n <n-tooltip>\n <template #trigger>\n <n-button\n quaternary\n circle\n :aria-label=\"app.isDark ? t('app.light') : t('app.dark')\"\n @click=\"app.toggleDark()\"\n >\n <template #icon>\n <Icon :icon=\"app.isDark ? 'ph:moon' : 'ph:sun'\" :width=\"18\" />\n </template>\n </n-button>\n </template>\n {{ app.isDark ? t('app.light') : t('app.dark') }}\n </n-tooltip>\n </div>\n\n <!-- margin-top 给右上角工具栏留位:窄屏内容比视口高时,顶部不会被工具栏盖住 -->\n <div\n class=\"login-card\"\n :class=\"{ 'on-desk': split }\"\n :style=\"split ? undefined : { width: `${width}px` }\"\n >\n <slot name=\"above\" />\n <n-card :bordered=\"true\" class=\"desk-card\" :content-style=\"contentStyle\">\n <slot />\n </n-card>\n <slot name=\"after\" />\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n/* 登录页(单栏 / 双栏都算)是 macOS 桌面那种纯色场:不要网格线,不要透视地面 */\n.login {\n /* 减速到底、不过冲:入场与视差共用这条曲线 */\n --rise: cubic-bezier(0.22, 1, 0.36, 1);\n min-height: 100dvh;\n background: var(--desk-base);\n position: relative;\n overflow: hidden;\n}\n.login.split {\n display: grid;\n grid-template-columns: minmax(340px, 46%) 1fr;\n}\n.login-stage {\n min-height: 100dvh;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 24px;\n position: relative;\n overflow: hidden;\n}\n\n/* 色场:四团 blur(70px) 的柔光球慢速漂移,颜色由强调色推导(--desk-1..4);\n 整体再按指针反向平移一点(用独立的 translate 属性,不和漂移动画的 transform 打架) */\n.desk {\n position: absolute;\n inset: -20%;\n pointer-events: none;\n z-index: 0;\n translate: calc(var(--px, 0) * -22px) calc(var(--py, 0) * -16px);\n transition: translate 1.4s var(--rise);\n}\n.desk i {\n position: absolute;\n display: block;\n border-radius: 50%;\n filter: blur(70px);\n opacity: var(--desk-op);\n}\n.desk i:nth-child(1) {\n left: 2%;\n top: 4%;\n width: 46%;\n height: 62%;\n background: var(--desk-1);\n animation: drift1 26s ease-in-out infinite alternate;\n}\n.desk i:nth-child(2) {\n left: 26%;\n top: 34%;\n width: 44%;\n height: 56%;\n background: var(--desk-2);\n animation: drift2 32s ease-in-out infinite alternate;\n}\n.desk i:nth-child(3) {\n left: 54%;\n top: -6%;\n width: 40%;\n height: 58%;\n background: var(--desk-3);\n animation: drift3 29s ease-in-out infinite alternate;\n}\n.desk i:nth-child(4) {\n left: 62%;\n top: 46%;\n width: 46%;\n height: 62%;\n background: var(--desk-4);\n animation: drift1 35s ease-in-out infinite alternate-reverse;\n}\n@keyframes drift1 {\n from {\n transform: none;\n }\n to {\n transform: translate3d(6%, -5%, 0) scale(1.12);\n }\n}\n@keyframes drift2 {\n from {\n transform: none;\n }\n to {\n transform: translate3d(-7%, 4%, 0) scale(1.08);\n }\n}\n@keyframes drift3 {\n from {\n transform: none;\n }\n to {\n transform: translate3d(4%, 7%, 0) scale(1.15);\n }\n}\n\n.login-corner {\n position: absolute;\n top: 16px;\n right: 16px;\n z-index: 3;\n display: flex;\n gap: 8px;\n animation: fadeIn 0.9s var(--rise) 0.7s both;\n}\n\n/* 双栏左栏:文字直接压在色场上(像 macOS 桌面上的字),不单独做一块彩色面板 */\n.login-brand {\n position: relative;\n z-index: 1;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n padding: 48px clamp(32px, 5vw, 76px);\n}\n.login-brand-inner {\n max-width: 440px;\n}\n\n.login-card {\n width: 400px;\n max-width: 100%;\n position: relative;\n z-index: 2;\n margin-top: 44px;\n}\n.login-card.on-desk {\n width: 384px;\n}\n\n/* 表单是一块浮在色场上的毛玻璃卡(macOS 的 vibrancy 材质),单栏双栏同一套 */\n.desk-card {\n border: 1px solid var(--glass-border) !important;\n border-radius: 22px !important;\n background: var(--glass-panel) !important;\n box-shadow: var(--glass-shadow) !important;\n backdrop-filter: blur(40px) saturate(180%);\n -webkit-backdrop-filter: blur(40px) saturate(180%);\n /* 反向视差:卡朝指针方向挪一点,色场反方向挪,拉出前后景深 */\n translate: calc(var(--px, 0) * 6px) calc(var(--py, 0) * 4px);\n transition:\n translate 1s var(--rise),\n background-color 0.3s,\n border-color 0.3s,\n box-shadow 0.3s;\n}\n.login-card :deep(.n-input) {\n border-radius: var(--radius-md);\n}\n/* 主按钮:强调色 → 第二色渐变,带一层强调色辉光;hover 只加深辉光并微提亮、不位移,按下轻轻收一下 */\n.login-card :deep(.n-button.cta) {\n background-image: linear-gradient(120deg, var(--signal), var(--login-accent-2));\n border-color: transparent;\n box-shadow: 0 10px 26px -10px var(--signal-glow);\n transition:\n box-shadow 0.22s var(--ease),\n transform 0.2s var(--ease),\n filter 0.2s var(--ease);\n}\n.login-card :deep(.n-button.cta:hover) {\n box-shadow: 0 16px 34px -10px var(--signal-glow);\n filter: brightness(1.04);\n}\n.login-card :deep(.n-button.cta:active:not(:disabled)) {\n transform: scale(0.985);\n filter: brightness(0.97);\n box-shadow: 0 6px 18px -10px var(--signal-glow);\n}\n\n/* ── 入场编排 ─────────────────────────────────────────────\n 动画必须挂在 .desk-card 自己身上,不能挂它的父级 .login-card:父级 opacity < 1 会让子元素的\n backdrop-filter 失去背景,动画期间卡是不模糊的,结束那一帧模糊才「啪」地打上去,看着就是生硬。\n 内容项(标题 / 字段 / 按钮 / 左栏文字)各自带延迟依次浮现,先模糊后清晰,不回弹。 */\n.desk-card {\n animation: cardIn 0.95s var(--rise) 0.08s both;\n}\n.login-card > :deep(:not(.desk-card)) {\n animation: fadeIn 0.9s var(--rise) 0.55s both;\n}\n\n/* 左栏:Logo → 标语 → 说明 → 亮点逐行 */\n.login-brand-inner :deep(.login-hero-panel > :not(.points)),\n.login-brand-inner :deep(.points li) {\n animation: riseIn 0.9s var(--rise) both;\n}\n.login-brand-inner :deep(.login-hero-panel > :nth-child(1)) {\n animation-delay: 0.1s;\n}\n.login-brand-inner :deep(.login-hero-panel > :nth-child(2)) {\n animation-delay: 0.18s;\n}\n.login-brand-inner :deep(.login-hero-panel > :nth-child(3)) {\n animation-delay: 0.26s;\n}\n.login-brand-inner :deep(.points li:nth-child(1)) {\n animation-delay: 0.36s;\n}\n.login-brand-inner :deep(.points li:nth-child(2)) {\n animation-delay: 0.43s;\n}\n.login-brand-inner :deep(.points li:nth-child(n + 3)) {\n animation-delay: 0.5s;\n}\n\n/* 卡内:LoginForm 的 .login-form > .lf-brand / .lf-body(标题、表单、第三方登录)和表单里的各行 */\n.login-card :deep(.login-form > .lf-brand),\n.login-card :deep(.login-form > .lf-pending-alert),\n.login-card :deep(.lf-body > :not(form)),\n.login-card :deep(.lf-body form > *) {\n animation: riseIn 0.8s var(--rise) both;\n}\n.login-card :deep(.login-form > .lf-brand),\n.login-card :deep(.login-form > .lf-pending-alert) {\n animation-delay: 0.18s;\n}\n.login-card :deep(.lf-body > :not(form)) {\n animation-delay: 0.22s;\n}\n.login-card :deep(.lf-body form > :nth-child(1)) {\n animation-delay: 0.28s;\n}\n.login-card :deep(.lf-body form > :nth-child(2)) {\n animation-delay: 0.34s;\n}\n.login-card :deep(.lf-body form > :nth-child(3)) {\n animation-delay: 0.4s;\n}\n.login-card :deep(.lf-body form > :nth-child(4)) {\n animation-delay: 0.46s;\n}\n.login-card :deep(.lf-body form > :nth-child(n + 5)) {\n animation-delay: 0.52s;\n}\n.login-card :deep(.lf-body > .lf-divider) {\n animation-delay: 0.56s;\n}\n.login-card :deep(.lf-body > .lf-sso) {\n animation-delay: 0.62s;\n}\n\n@keyframes cardIn {\n from {\n opacity: 0;\n transform: translate3d(0, 28px, 0) scale(0.965);\n }\n to {\n opacity: 1;\n transform: none;\n }\n}\n@keyframes riseIn {\n from {\n opacity: 0;\n transform: translate3d(0, 12px, 0);\n filter: blur(6px);\n }\n to {\n opacity: 1;\n transform: none;\n filter: none;\n }\n}\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n/* ── 退场:登录成功后整页淡出并微微放大(macOS 解锁的感觉),色场留着不动 ── */\n.login.leaving .desk-card {\n animation: cardOut 0.34s cubic-bezier(0.4, 0, 1, 1) both;\n}\n.login.leaving .login-brand-inner,\n.login.leaving .login-corner,\n.login.leaving .login-card > :deep(:not(.desk-card)) {\n animation: fadeOut 0.28s ease-in both;\n}\n@keyframes cardOut {\n to {\n opacity: 0;\n transform: translate3d(0, -8px, 0) scale(1.02);\n }\n}\n@keyframes fadeOut {\n to {\n opacity: 0;\n }\n}\n\n/* 减少动效:全局规则已把时长压到近零,这里再清掉延迟(否则 both 的起始态会把内容藏到延迟结束)并取消视差与漂移 */\n@media (prefers-reduced-motion: reduce) {\n .desk i {\n animation: none !important;\n }\n .desk,\n .desk-card {\n translate: none;\n }\n .login :deep(*),\n .login .desk-card,\n .login .login-corner {\n animation-delay: 0s !important;\n }\n}\n/* 窄屏收紧:卡片侧边留 16px,卡内边距随之压小(内联的 content-style 要靠 !important 盖住) */\n@media (max-width: 480px) {\n .login-stage {\n padding: 16px;\n }\n .desk-card :deep(.n-card__content) {\n padding: 22px 20px 18px !important;\n }\n}\n</style>\n\n<!-- View Transitions 的伪元素在文档根上,scoped 样式够不到,所以单独一块全局样式。\n 只在布局切换那一刻(.switching)给卡片命名:常驻的 view-transition-name 会让它多出独立图层。 -->\n<style>\n.login.switching .desk-card {\n view-transition-name: login-card;\n}\n::view-transition-group(login-card) {\n animation-duration: 0.62s;\n animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);\n}\n</style>\n"],"names":["app","useAppStore","t","useI18n","root","ref","raf","setParallax","x","y","_a","_b","onPointerMove","e","onBeforeUnmount","_createElementBlock","_normalizeClass","__props","_createElementVNode","_openBlock","_hoisted_1","_hoisted_2","_renderSlot","_ctx","_hoisted_3","_hoisted_4","_createVNode","_unref","NTooltip","NButton","_cache","$event","Icon","_createTextVNode","_normalizeStyle","NCard"],"mappings":";;;;;;;;;;;;;;;;;AA4BA,UAAMA,IAAMC,EAAA,GACN,EAAE,GAAAC,EAAA,IAAMC,EAAA,GAGRC,IAAOC,EAAwB,IAAI;AACzC,QAAIC,IAAM;AACV,aAASC,EAAYC,GAAWC,GAAW;AACzC,2BAAqBH,CAAG,GACxBA,IAAM,sBAAsB,MAAM;;AAChC,SAAAI,IAAAN,EAAK,UAAL,QAAAM,EAAY,MAAM,YAAY,QAAQF,EAAE,QAAQ,CAAC,KACjDG,IAAAP,EAAK,UAAL,QAAAO,EAAY,MAAM,YAAY,QAAQF,EAAE,QAAQ,CAAC;AAAA,MACnD,CAAC;AAAA,IACH;AACA,aAASG,EAAcC,GAAiB;AACtC,MAAIA,EAAE,gBAAgB,WACtBN,EAAaM,EAAE,UAAU,OAAO,aAAc,IAAI,GAAIA,EAAE,UAAU,OAAO,cAAe,IAAI,CAAC;AAAA,IAC/F;AACA,WAAAC,EAAgB,MAAM,qBAAqBR,CAAG,CAAC,mBAI7CS,EAoDM,OAAA;AAAA,eAnDA;AAAA,MAAJ,KAAIX;AAAA,MACJ,OAAKY,EAAA,CAAC,iBAAe,EAAA,OACXC,EAAA,gBAAOA,EAAA,QAAA,CAAO,CAAA;AAAA,MACvB,eAAaL;AAAA,MACb,uCAAcL,EAAW,GAAA,CAAA;AAAA,IAAA;sBAE1BW,EAKM,OAAA;AAAA,QALD,OAAM;AAAA,QAAO,eAAY;AAAA,MAAA;QAC5BA,EAAK,GAAA;AAAA,QACLA,EAAK,GAAA;AAAA,QACLA,EAAK,GAAA;AAAA,QACLA,EAAK,GAAA;AAAA,MAAA;MAGID,EAAA,SAAXE,EAAA,GAAAJ,EAEM,OAFNK,GAEM;AAAA,QADJF,EAA0D,OAA1DG,GAA0D;AAAA,UAA3BC,EAAqBC,EAAA,QAAA,SAAA,CAAA,GAAA,QAAA,EAAA;AAAA,QAAA;;MAGtDL,EAiCM,OAjCNM,GAiCM;AAAA,QA/BJN,EAiBM,OAjBNO,GAiBM;AAAA,UAhBJH,EAAsBC,EAAA,QAAA,UAAA,CAAA,GAAA,QAAA,EAAA;AAAA,UACtBG,EAcYC,EAAAC,CAAA,GAAA,MAAA;AAAA,YAbC,WACT,MASW;AAAA,cATXF,EASWC,EAAAE,CAAA,GAAA;AAAA,gBART,YAAA;AAAA,gBACA,QAAA;AAAA,gBACC,cAAYF,EAAA3B,CAAA,EAAI,SAAS2B,EAAAzB,CAAA,iBAAiByB,EAAAzB,CAAA,EAAC,UAAA;AAAA,gBAC3C,SAAK4B,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAAEJ,EAAA3B,CAAA,EAAI,WAAA;AAAA,cAAU;gBAEX,QACT,MAA8D;AAAA,kBAA9D0B,EAA8DC,EAAAK,CAAA,GAAA;AAAA,oBAAvD,MAAML,EAAA3B,CAAA,EAAI,SAAM,YAAA;AAAA,oBAA0B,OAAO;AAAA,kBAAA;;;;;uBAGnD,MACX;AAAA,cADWiC,EAAA,QACRN,EAAA3B,CAAA,EAAI,SAAS2B,EAAAzB,CAAA,iBAAiByB,EAAAzB,CAAA,EAAC,UAAA,CAAA,GAAA,CAAA;AAAA,YAAA;;;;QAKtCgB,EAUM,OAAA;AAAA,UATJ,OAAKF,EAAA,CAAC,cAAY,EAAA,WACGC,EAAA,MAAA,CAAK,CAAA;AAAA,UACzB,OAAKiB,EAAEjB,EAAA,QAAQ,qBAAwBA,EAAA,KAAK,KAAA,CAAA;AAAA,QAAA;UAE7CK,EAAqBC,EAAA,QAAA,SAAA,CAAA,GAAA,QAAA,EAAA;AAAA,UACrBG,EAESC,EAAAQ,CAAA,GAAA;AAAA,YAFA,UAAU;AAAA,YAAM,OAAM;AAAA,YAAa,iBAAelB,EAAA;AAAA,UAAA;uBACzD,MAAQ;AAAA,cAARK,EAAQC,EAAA,QAAA,WAAA,CAAA,GAAA,QAAA,EAAA;AAAA,YAAA;;;UAEVD,EAAqBC,EAAA,QAAA,SAAA,CAAA,GAAA,QAAA,EAAA;AAAA,QAAA;;;;;"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
headline: string;
|
|
3
|
+
highlight?: string;
|
|
4
|
+
subtitle?: string;
|
|
5
|
+
features?: string[];
|
|
6
|
+
/** 以下两项供配置中心预览未保存的草稿;不传则取当前站点信息 */
|
|
7
|
+
title?: string;
|
|
8
|
+
logo?: string;
|
|
9
|
+
};
|
|
10
|
+
declare const __VLS_export: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
11
|
+
title: string;
|
|
12
|
+
subtitle: string;
|
|
13
|
+
logo: string;
|
|
14
|
+
highlight: string;
|
|
15
|
+
features: string[];
|
|
16
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
17
|
+
declare const _default: typeof __VLS_export;
|
|
18
|
+
export default _default;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import o from "./LoginHeroPanel2.vue.js";
|
|
2
|
+
/* empty css */
|
|
3
|
+
import r from "../../../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
+
const m = /* @__PURE__ */ r(o, [["__scopeId", "data-v-85dbd38a"]]);
|
|
5
|
+
export {
|
|
6
|
+
m as default
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=LoginHeroPanel.vue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoginHeroPanel.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { defineComponent as k, computed as p, openBlock as l, createElementBlock as n, createElementVNode as a, createVNode as r, toDisplayString as s, unref as h, Fragment as u, renderList as d, normalizeClass as _, createCommentVNode as f, createTextVNode as v } from "vue";
|
|
2
|
+
import { Icon as y } from "@iconify/vue";
|
|
3
|
+
import { useSite as C } from "../../../composables/useSite.js";
|
|
4
|
+
import b from "../../../components/SmartLogo.vue.js";
|
|
5
|
+
const N = { class: "login-hero-panel" }, V = { class: "logo" }, L = { class: "headline" }, S = ["textContent"], z = {
|
|
6
|
+
key: 0,
|
|
7
|
+
class: "sub"
|
|
8
|
+
}, B = {
|
|
9
|
+
key: 1,
|
|
10
|
+
class: "points"
|
|
11
|
+
}, F = /* @__PURE__ */ k({
|
|
12
|
+
__name: "LoginHeroPanel",
|
|
13
|
+
props: {
|
|
14
|
+
headline: {},
|
|
15
|
+
highlight: { default: "" },
|
|
16
|
+
subtitle: { default: "" },
|
|
17
|
+
features: { default: () => [] },
|
|
18
|
+
title: { default: void 0 },
|
|
19
|
+
logo: { default: void 0 }
|
|
20
|
+
},
|
|
21
|
+
setup(t) {
|
|
22
|
+
const e = t, { site: g } = C(), m = p(() => {
|
|
23
|
+
const o = e.highlight ? e.headline.indexOf(e.highlight) : -1;
|
|
24
|
+
return o < 0 ? [{ text: e.headline, accent: !1 }] : [
|
|
25
|
+
{ text: e.headline.slice(0, o), accent: !1 },
|
|
26
|
+
{ text: e.highlight, accent: !0 },
|
|
27
|
+
{ text: e.headline.slice(o + e.highlight.length), accent: !1 }
|
|
28
|
+
].filter((c) => c.text);
|
|
29
|
+
});
|
|
30
|
+
return (o, c) => (l(), n("div", N, [
|
|
31
|
+
a("div", V, [
|
|
32
|
+
r(b, {
|
|
33
|
+
size: 46,
|
|
34
|
+
src: t.logo
|
|
35
|
+
}, null, 8, ["src"]),
|
|
36
|
+
a("span", null, s(t.title ?? h(g).title), 1)
|
|
37
|
+
]),
|
|
38
|
+
a("h2", L, [
|
|
39
|
+
(l(!0), n(u, null, d(m.value, (i, x) => (l(), n("span", {
|
|
40
|
+
key: x,
|
|
41
|
+
class: _({ hl: i.accent }),
|
|
42
|
+
textContent: s(i.text)
|
|
43
|
+
}, null, 10, S))), 128))
|
|
44
|
+
]),
|
|
45
|
+
t.subtitle ? (l(), n("p", z, s(t.subtitle), 1)) : f("", !0),
|
|
46
|
+
t.features.length ? (l(), n("ul", B, [
|
|
47
|
+
(l(!0), n(u, null, d(t.features, (i) => (l(), n("li", { key: i }, [
|
|
48
|
+
r(h(y), {
|
|
49
|
+
icon: "ph:check",
|
|
50
|
+
width: 15
|
|
51
|
+
}),
|
|
52
|
+
v(" " + s(i), 1)
|
|
53
|
+
]))), 128))
|
|
54
|
+
])) : f("", !0)
|
|
55
|
+
]));
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
export {
|
|
59
|
+
F as default
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=LoginHeroPanel2.vue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoginHeroPanel2.vue.js","sources":["../../../../src/views/login/components/LoginHeroPanel.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 登录页双栏左栏的品牌区(也是配置中心登录预览的左半边):文字直接压在柔光色场上,\n// Logo 锁定 + 大标语(强调词用强调色渐变高亮)+ 一行说明 + 单行勾选亮点。\nimport { computed } from 'vue'\nimport { Icon } from '@iconify/vue'\nimport { useSite } from '#/composables/useSite'\nimport SmartLogo from '#/components/SmartLogo.vue'\n\nconst props = withDefaults(\n defineProps<{\n headline: string\n highlight?: string\n subtitle?: string\n features?: string[]\n /** 以下两项供配置中心预览未保存的草稿;不传则取当前站点信息 */\n title?: string\n logo?: string\n }>(),\n {\n highlight: '',\n subtitle: '',\n features: () => [],\n title: undefined,\n logo: undefined,\n },\n)\n\nconst { site } = useSite()\n\n// 只做纯文本切片,不用 v-html;强调词只会成为一个普通 span。\nconst headlineParts = computed(() => {\n const index = props.highlight ? props.headline.indexOf(props.highlight) : -1\n if (index < 0) return [{ text: props.headline, accent: false }]\n return [\n { text: props.headline.slice(0, index), accent: false },\n { text: props.highlight, accent: true },\n { text: props.headline.slice(index + props.highlight.length), accent: false },\n ].filter(part => part.text)\n})\n</script>\n\n<template>\n <div class=\"login-hero-panel\">\n <div class=\"logo\">\n <SmartLogo :size=\"46\" :src=\"logo\" />\n <span>{{ title ?? site.title }}</span>\n </div>\n <h2 class=\"headline\">\n <span\n v-for=\"(part, index) in headlineParts\"\n :key=\"index\"\n :class=\"{ hl: part.accent }\"\n v-text=\"part.text\"\n />\n </h2>\n <p v-if=\"subtitle\" class=\"sub\">{{ subtitle }}</p>\n <ul v-if=\"features.length\" class=\"points\">\n <li v-for=\"feature in features\" :key=\"feature\">\n <Icon icon=\"ph:check\" :width=\"15\" />\n {{ feature }}\n </li>\n </ul>\n </div>\n</template>\n\n<style scoped>\n.login-hero-panel {\n min-width: 0;\n}\n.logo {\n display: flex;\n align-items: center;\n gap: 13px;\n margin-bottom: 30px;\n font-size: 22px;\n font-weight: 600;\n letter-spacing: -0.015em;\n color: var(--text-1);\n}\n.headline {\n margin: 0 0 14px;\n color: var(--text-1);\n font-size: clamp(30px, 2.5vw, 40px);\n font-weight: 600;\n letter-spacing: -0.04em;\n line-height: 1.18;\n}\n.headline .hl {\n background: linear-gradient(110deg, var(--signal), var(--login-accent-2));\n -webkit-background-clip: text;\n background-clip: text;\n color: transparent;\n}\n/* 色场上的正文一律用 --text-1:--text-2 是配白底卡片的,直接压在饱和色场上对比度不够 */\n.sub {\n margin: 0 0 34px;\n color: var(--text-1);\n font-size: 17px;\n line-height: 1.6;\n}\n.points {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n/* 字重 500 + 16px:同样是 --text-1,靠字重和字号把亮点和上面那句说明分开,不靠深浅 */\n.points li {\n display: flex;\n align-items: center;\n gap: 12px;\n color: var(--text-1);\n font-size: 16px;\n font-weight: 500;\n}\n.points li > :deep(svg) {\n flex-shrink: 0;\n box-sizing: content-box;\n width: 15px;\n height: 15px;\n padding: 5px;\n border-radius: 50%;\n color: var(--signal);\n background: var(--sel-bg);\n box-shadow: inset 0 0 0 1px var(--sel-ring);\n}\n</style>\n"],"names":["props","__props","site","useSite","headlineParts","computed","index","part","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_createVNode","SmartLogo","_toDisplayString","_unref","_hoisted_3","_Fragment","_renderList","_normalizeClass","_hoisted_5","_hoisted_6","feature","Icon","_createTextVNode"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAQA,UAAMA,IAAQC,GAmBR,EAAE,MAAAC,EAAA,IAASC,EAAA,GAGXC,IAAgBC,EAAS,MAAM;AACnC,YAAMC,IAAQN,EAAM,YAAYA,EAAM,SAAS,QAAQA,EAAM,SAAS,IAAI;AAC1E,aAAIM,IAAQ,IAAU,CAAC,EAAE,MAAMN,EAAM,UAAU,QAAQ,IAAO,IACvD;AAAA,QACL,EAAE,MAAMA,EAAM,SAAS,MAAM,GAAGM,CAAK,GAAG,QAAQ,GAAA;AAAA,QAChD,EAAE,MAAMN,EAAM,WAAW,QAAQ,GAAA;AAAA,QACjC,EAAE,MAAMA,EAAM,SAAS,MAAMM,IAAQN,EAAM,UAAU,MAAM,GAAG,QAAQ,GAAA;AAAA,MAAM,EAC5E,OAAO,CAAAO,MAAQA,EAAK,IAAI;AAAA,IAC5B,CAAC;sBAICC,EAAA,GAAAC,EAoBM,OApBNC,GAoBM;AAAA,MAnBJC,EAGM,OAHNC,GAGM;AAAA,QAFJC,EAAoCC,GAAA;AAAA,UAAxB,MAAM;AAAA,UAAK,KAAKb,EAAA;AAAA,QAAA;QAC5BU,EAAsC,QAAA,MAAAI,EAA7Bd,EAAA,SAASe,EAAAd,CAAA,EAAK,KAAK,GAAA,CAAA;AAAA,MAAA;MAE9BS,EAOK,MAPLM,GAOK;AAAA,SANHT,EAAA,EAAA,GAAAC,EAKES,GAAA,MAAAC,EAJwBf,EAAA,OAAa,CAA7BG,GAAMD,YADhBG,EAKE,QAAA;AAAA,UAHC,KAAKH;AAAA,UACL,OAAKc,EAAA,EAAA,IAAQb,EAAK,QAAM;AAAA,uBACzBQ,EAAkBR,EAAL,IAAI;AAAA,QAAA;;MAGZN,EAAA,iBAATQ,EAAiD,KAAjDY,GAAiDN,EAAfd,EAAA,QAAQ,GAAA,CAAA;MAChCA,EAAA,SAAS,UAAnBO,KAAAC,EAKK,MALLa,GAKK;AAAA,gBAJHb,EAGKS,GAAA,MAAAC,EAHiBlB,EAAA,UAAQ,CAAnBsB,YAAXd,EAGK,MAAA,EAH4B,KAAKc,KAAO;AAAA,UAC3CV,EAAoCG,EAAAQ,CAAA,GAAA;AAAA,YAA9B,MAAK;AAAA,YAAY,OAAO;AAAA,UAAA;UAAMC,EAAA,QACjCF,CAAO,GAAA,CAAA;AAAA,QAAA;;;;;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import o from "./index2.vue.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import t from "../../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
-
const m = /* @__PURE__ */ t(o, [["__scopeId", "data-v-
|
|
4
|
+
const m = /* @__PURE__ */ t(o, [["__scopeId", "data-v-34ea922a"]]);
|
|
5
5
|
export {
|
|
6
6
|
m as default
|
|
7
7
|
};
|