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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logoCrop.js","sources":["../../src/lib/logoCrop.ts"],"sourcesContent":["// Logo 裁剪的几何计算:图片以视口中心 + 偏移量摆放、按 scale 缩放,正方形取景框居中。\n// 与 DOM 无关,裁剪组件只负责把指针/滚轮事件换成 offset/scale,再用这里的结果画 canvas。\n\nexport interface CropState {\n /** 图片原始宽高 */\n width: number\n height: number\n /** 取景框边长(px,视口坐标) */\n frame: number\n /** 当前缩放(图片像素 → 视口像素) */\n scale: number\n /** 图片中心相对取景框中心的偏移(视口像素) */\n x: number\n y: number\n}\n\n/** 刚好铺满取景框的最小缩放:短边等于框边,不留空白。 */\nexport function coverScale(width: number, height: number, frame: number): number {\n return frame / Math.min(width, height)\n}\n\n// 可移范围为 0 时直接归零,避免 Math.max(-0, …) 产出 -0\nconst clamp = (v: number, max: number) => (max === 0 ? 0 : Math.min(max, Math.max(-max, v)))\n\n/** 把偏移收在\"图片始终盖满取景框\"的范围内。 */\nexport function clampOffset(s: CropState): { x: number; y: number } {\n const maxX = Math.max(0, (s.width * s.scale - s.frame) / 2)\n const maxY = Math.max(0, (s.height * s.scale - s.frame) / 2)\n return { x: clamp(s.x, maxX), y: clamp(s.y, maxY) }\n}\n\n/** 取景框在原图上的区域(原图像素),供 drawImage 取源矩形。 */\nexport function sourceRect(s: CropState): { sx: number; sy: number; size: number } {\n const size = s.frame / s.scale\n return {\n sx: s.width / 2 - s.x / s.scale - size / 2,\n sy: s.height / 2 - s.y / s.scale - size / 2,\n size,\n }\n}\n"],"names":["coverScale","width","height","frame","clamp","v","max","clampOffset","s","maxX","maxY","sourceRect","size"],"mappings":"AAiBO,SAASA,EAAWC,GAAeC,GAAgBC,GAAuB;AAC/E,SAAOA,IAAQ,KAAK,IAAIF,GAAOC,CAAM;AACvC;AAGA,MAAME,IAAQ,CAACC,GAAWC,MAAiBA,MAAQ,IAAI,IAAI,KAAK,IAAIA,GAAK,KAAK,IAAI,CAACA,GAAKD,CAAC,CAAC;AAGnF,SAASE,EAAYC,GAAwC;AAClE,QAAMC,IAAO,KAAK,IAAI,IAAID,EAAE,QAAQA,EAAE,QAAQA,EAAE,SAAS,CAAC,GACpDE,IAAO,KAAK,IAAI,IAAIF,EAAE,SAASA,EAAE,QAAQA,EAAE,SAAS,CAAC;AAC3D,SAAO,EAAE,GAAGJ,EAAMI,EAAE,GAAGC,CAAI,GAAG,GAAGL,EAAMI,EAAE,GAAGE,CAAI,EAAA;AAClD;AAGO,SAASC,EAAWH,GAAwD;AACjF,QAAMI,IAAOJ,EAAE,QAAQA,EAAE;AACzB,SAAO;AAAA,IACL,IAAIA,EAAE,QAAQ,IAAIA,EAAE,IAAIA,EAAE,QAAQI,IAAO;AAAA,IACzC,IAAIJ,EAAE,SAAS,IAAIA,EAAE,IAAIA,EAAE,QAAQI,IAAO;AAAA,IAC1C,MAAAA;AAAA,EAAA;AAEJ;"}
|
package/dist/lib/runtime.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ export interface BrandOptions {
|
|
|
5
5
|
title?: string;
|
|
6
6
|
/** 组件或图片地址;不传则用内置 SmartLogo 矢量标 */
|
|
7
7
|
logo?: Component | string;
|
|
8
|
+
/** 浏览器标签页图标跟随 sys.site.logo(配了 Logo 才换,清空即还原模板自带图标);默认 true */
|
|
9
|
+
faviconFromLogo?: boolean;
|
|
8
10
|
}
|
|
9
11
|
/**
|
|
10
12
|
* 运行期配置:由 createSmartAdmin 在挂载前写入,内核各处读这里而不读 import.meta.env ——
|
package/dist/lib/runtime.js
CHANGED
package/dist/lib/runtime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","sources":["../../src/lib/runtime.ts"],"sourcesContent":["import type { Component } from 'vue'\n\n/** 品牌默认值:sys.site.* 配置有值时以配置为准,为空时用这里。 */\nexport interface BrandOptions {\n /** 站点标题默认值;siteInfo 里 sys.site.title 有值时被覆盖 */\n title?: string\n /** 组件或图片地址;不传则用内置 SmartLogo 矢量标 */\n logo?: Component | string\n}\n\n/**\n * 运行期配置:由 createSmartAdmin 在挂载前写入,内核各处读这里而不读 import.meta.env ——\n * 库预编译时 import.meta.env 会被静态替换成库自己构建时的值,消费方改不了。\n */\nexport const runtime = {\n /** API 根地址;空串 = 同源(dev 由 Vite 代理,生产由反代或后端托管 dist) */\n apiBase: '',\n /** 登录页页脚展示的版本号;默认内核版本,消费方可覆盖为应用版本 */\n version: typeof __SMART_ADMIN_VERSION__ !== 'undefined' ? __SMART_ADMIN_VERSION__ : '',\n /** 开发态:登录页预填超管账号、设置抽屉显示「复制配置」 */\n dev: false,\n brand: {} as BrandOptions,\n}\n"],"names":["runtime"],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtime.js","sources":["../../src/lib/runtime.ts"],"sourcesContent":["import type { Component } from 'vue'\n\n/** 品牌默认值:sys.site.* 配置有值时以配置为准,为空时用这里。 */\nexport interface BrandOptions {\n /** 站点标题默认值;siteInfo 里 sys.site.title 有值时被覆盖 */\n title?: string\n /** 组件或图片地址;不传则用内置 SmartLogo 矢量标 */\n logo?: Component | string\n /** 浏览器标签页图标跟随 sys.site.logo(配了 Logo 才换,清空即还原模板自带图标);默认 true */\n faviconFromLogo?: boolean\n}\n\n/**\n * 运行期配置:由 createSmartAdmin 在挂载前写入,内核各处读这里而不读 import.meta.env ——\n * 库预编译时 import.meta.env 会被静态替换成库自己构建时的值,消费方改不了。\n */\nexport const runtime = {\n /** API 根地址;空串 = 同源(dev 由 Vite 代理,生产由反代或后端托管 dist) */\n apiBase: '',\n /** 登录页页脚展示的版本号;默认内核版本,消费方可覆盖为应用版本 */\n version: typeof __SMART_ADMIN_VERSION__ !== 'undefined' ? __SMART_ADMIN_VERSION__ : '',\n /** 开发态:登录页预填超管账号、设置抽屉显示「复制配置」 */\n dev: false,\n brand: {} as BrandOptions,\n}\n"],"names":["runtime"],"mappings":"AAgBO,MAAMA,IAAU;AAAA;AAAA,EAErB,SAAS;AAAA;AAAA,EAET,SAA0D;AAAA;AAAA,EAE1D,KAAK;AAAA,EACL,OAAO,CAAA;AACT;"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface RuleLine {
|
|
2
|
+
icon: string;
|
|
3
|
+
/** 关闭的规则灰显划线,仍列出来让人知道有这一项 */
|
|
4
|
+
on: boolean;
|
|
5
|
+
key: string;
|
|
6
|
+
params?: Record<string, string | number>;
|
|
7
|
+
}
|
|
8
|
+
export interface Duration {
|
|
9
|
+
key: 'config.preview.minutes' | 'config.preview.hours' | 'config.preview.days';
|
|
10
|
+
n: number;
|
|
11
|
+
}
|
|
12
|
+
/** 分钟数取最合适的单位,最多一位小数。 */
|
|
13
|
+
export declare function humanizeMinutes(minutes: number): Duration;
|
|
14
|
+
type Values = Record<string, string | undefined>;
|
|
15
|
+
/** 规则里嵌的短语由调用方按当前语言渲染。 */
|
|
16
|
+
export interface RuleFormatters {
|
|
17
|
+
duration: (d: Duration) => string;
|
|
18
|
+
/** upper / lower / digit / special */
|
|
19
|
+
requirement: (code: string) => string;
|
|
20
|
+
/** char / path / math */
|
|
21
|
+
captchaType: (code: string) => string;
|
|
22
|
+
/** 把若干短语连成一句("、" 或 ", ") */
|
|
23
|
+
join: (items: string[]) => string;
|
|
24
|
+
}
|
|
25
|
+
export declare function securityRules(v: Values, f: RuleFormatters): RuleLine[];
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
const u = (e) => Math.round(e * 10) / 10, i = (e) => `sys.security.${e}`;
|
|
2
|
+
function w(e) {
|
|
3
|
+
return e >= 1440 ? { key: "config.preview.days", n: u(e / 1440) } : e >= 60 ? { key: "config.preview.hours", n: u(e / 60) } : { key: "config.preview.minutes", n: e };
|
|
4
|
+
}
|
|
5
|
+
const r = (e, o, c) => {
|
|
6
|
+
const s = Number(e[o]);
|
|
7
|
+
return e[o] === void 0 || e[o] === "" || Number.isNaN(s) ? c : s;
|
|
8
|
+
}, n = (e, o) => e[o] === "true";
|
|
9
|
+
function f(e, o) {
|
|
10
|
+
const c = [
|
|
11
|
+
n(e, i("password.requireUpper")) && "upper",
|
|
12
|
+
n(e, i("password.requireLower")) && "lower",
|
|
13
|
+
n(e, i("password.requireDigit")) && "digit",
|
|
14
|
+
n(e, i("password.requireSpecial")) && "special"
|
|
15
|
+
].filter((h) => !!h), s = r(e, i("password.expireDays"), 0), t = r(e, i("password.historyCount"), 0), p = r(e, i("loginLock.maxFailCount"), 0), a = n(e, i("totp.enabled"));
|
|
16
|
+
return [
|
|
17
|
+
p > 0 ? {
|
|
18
|
+
icon: "ph:lock-key",
|
|
19
|
+
on: !0,
|
|
20
|
+
key: "config.preview.lock",
|
|
21
|
+
params: { count: p, minutes: r(e, i("loginLock.lockMinutes"), 1) }
|
|
22
|
+
} : { icon: "ph:lock-key", on: !1, key: "config.preview.lockOff" },
|
|
23
|
+
{
|
|
24
|
+
icon: "ph:textbox",
|
|
25
|
+
on: n(e, i("captcha.enabled")),
|
|
26
|
+
key: "config.preview.captcha",
|
|
27
|
+
params: { type: o.captchaType(e[i("captcha.type")] || "char") }
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
icon: "ph:device-mobile",
|
|
31
|
+
on: a,
|
|
32
|
+
key: a && n(e, i("totp.requireForSuperAdmin")) ? "config.preview.totpSuper" : "config.preview.totp"
|
|
33
|
+
},
|
|
34
|
+
{ icon: "ph:chat-circle-dots", on: n(e, i("mfa.enabled")), key: "config.preview.smsMfa" },
|
|
35
|
+
c.length ? {
|
|
36
|
+
icon: "ph:password",
|
|
37
|
+
on: !0,
|
|
38
|
+
key: "config.preview.password",
|
|
39
|
+
params: {
|
|
40
|
+
min: r(e, i("password.minLength"), 1),
|
|
41
|
+
reqs: o.join(c.map(o.requirement))
|
|
42
|
+
}
|
|
43
|
+
} : {
|
|
44
|
+
icon: "ph:password",
|
|
45
|
+
on: !0,
|
|
46
|
+
key: "config.preview.passwordMin",
|
|
47
|
+
params: { min: r(e, i("password.minLength"), 1) }
|
|
48
|
+
},
|
|
49
|
+
s > 0 ? {
|
|
50
|
+
icon: "ph:hourglass",
|
|
51
|
+
on: !0,
|
|
52
|
+
key: "config.preview.expire",
|
|
53
|
+
params: { days: s }
|
|
54
|
+
} : { icon: "ph:hourglass", on: !0, key: "config.preview.noExpire" },
|
|
55
|
+
t > 0 ? {
|
|
56
|
+
icon: "ph:clock-counter-clockwise",
|
|
57
|
+
on: !0,
|
|
58
|
+
key: "config.preview.history",
|
|
59
|
+
params: { n: t }
|
|
60
|
+
} : { icon: "ph:clock-counter-clockwise", on: !1, key: "config.preview.historyOff" },
|
|
61
|
+
n(e, i("password.forceChangeOnFirstLogin")) ? { icon: "ph:user-switch", on: !0, key: "config.preview.firstChange" } : { icon: "ph:user-switch", on: !1, key: "config.preview.firstChangeOff" },
|
|
62
|
+
{
|
|
63
|
+
icon: "ph:timer",
|
|
64
|
+
on: !0,
|
|
65
|
+
key: "config.preview.session",
|
|
66
|
+
params: {
|
|
67
|
+
access: o.duration(w(r(e, i("session.accessMinutes"), 30))),
|
|
68
|
+
refresh: o.duration(w(r(e, i("session.refreshMinutes"), 10080)))
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
icon: "ph:traffic-signal",
|
|
73
|
+
on: n(e, i("rateLimit.enabled")),
|
|
74
|
+
key: "config.preview.rateLimit",
|
|
75
|
+
params: {
|
|
76
|
+
seconds: r(e, i("rateLimit.windowSeconds"), 1),
|
|
77
|
+
permit: r(e, i("rateLimit.permitPerWindow"), 0)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
];
|
|
81
|
+
}
|
|
82
|
+
export {
|
|
83
|
+
w as humanizeMinutes,
|
|
84
|
+
f as securityRules
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=securityRules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"securityRules.js","sources":["../../src/lib/securityRules.ts"],"sourcesContent":["// 安全策略预览:把 sys.security.* 的草稿值翻成\"用户会遇到的规则\"。\n// 短信验证码登录是登录方式,不在这里(见配置中心「登录方式」页)。\n// 只产出 i18n 键 + 参数,文案在 locales 里;纯函数,便于单测。\n\nexport interface RuleLine {\n icon: string\n /** 关闭的规则灰显划线,仍列出来让人知道有这一项 */\n on: boolean\n key: string\n params?: Record<string, string | number>\n}\n\nexport interface Duration {\n key: 'config.preview.minutes' | 'config.preview.hours' | 'config.preview.days'\n n: number\n}\n\nconst round = (v: number) => Math.round(v * 10) / 10\nconst k = (s: string) => `sys.security.${s}`\n\n/** 分钟数取最合适的单位,最多一位小数。 */\nexport function humanizeMinutes(minutes: number): Duration {\n if (minutes >= 1440) return { key: 'config.preview.days', n: round(minutes / 1440) }\n if (minutes >= 60) return { key: 'config.preview.hours', n: round(minutes / 60) }\n return { key: 'config.preview.minutes', n: minutes }\n}\n\ntype Values = Record<string, string | undefined>\n\nconst num = (v: Values, key: string, fallback: number) => {\n const n = Number(v[key])\n return v[key] === undefined || v[key] === '' || Number.isNaN(n) ? fallback : n\n}\nconst on = (v: Values, key: string) => v[key] === 'true'\n\n/** 规则里嵌的短语由调用方按当前语言渲染。 */\nexport interface RuleFormatters {\n duration: (d: Duration) => string\n /** upper / lower / digit / special */\n requirement: (code: string) => string\n /** char / path / math */\n captchaType: (code: string) => string\n /** 把若干短语连成一句(\"、\" 或 \", \") */\n join: (items: string[]) => string\n}\n\nexport function securityRules(v: Values, f: RuleFormatters): RuleLine[] {\n const requirements = [\n on(v, k('password.requireUpper')) && 'upper',\n on(v, k('password.requireLower')) && 'lower',\n on(v, k('password.requireDigit')) && 'digit',\n on(v, k('password.requireSpecial')) && 'special',\n ].filter((r): r is string => !!r)\n const expireDays = num(v, k('password.expireDays'), 0)\n const history = num(v, k('password.historyCount'), 0)\n const maxFail = num(v, k('loginLock.maxFailCount'), 0)\n const totp = on(v, k('totp.enabled'))\n\n return [\n maxFail > 0\n ? {\n icon: 'ph:lock-key',\n on: true,\n key: 'config.preview.lock',\n params: { count: maxFail, minutes: num(v, k('loginLock.lockMinutes'), 1) },\n }\n : { icon: 'ph:lock-key', on: false, key: 'config.preview.lockOff' },\n {\n icon: 'ph:textbox',\n on: on(v, k('captcha.enabled')),\n key: 'config.preview.captcha',\n params: { type: f.captchaType(v[k('captcha.type')] || 'char') },\n },\n {\n icon: 'ph:device-mobile',\n on: totp,\n key:\n totp && on(v, k('totp.requireForSuperAdmin'))\n ? 'config.preview.totpSuper'\n : 'config.preview.totp',\n },\n { icon: 'ph:chat-circle-dots', on: on(v, k('mfa.enabled')), key: 'config.preview.smsMfa' },\n requirements.length\n ? {\n icon: 'ph:password',\n on: true,\n key: 'config.preview.password',\n params: {\n min: num(v, k('password.minLength'), 1),\n reqs: f.join(requirements.map(f.requirement)),\n },\n }\n : {\n icon: 'ph:password',\n on: true,\n key: 'config.preview.passwordMin',\n params: { min: num(v, k('password.minLength'), 1) },\n },\n expireDays > 0\n ? {\n icon: 'ph:hourglass',\n on: true,\n key: 'config.preview.expire',\n params: { days: expireDays },\n }\n : { icon: 'ph:hourglass', on: true, key: 'config.preview.noExpire' },\n history > 0\n ? {\n icon: 'ph:clock-counter-clockwise',\n on: true,\n key: 'config.preview.history',\n params: { n: history },\n }\n : { icon: 'ph:clock-counter-clockwise', on: false, key: 'config.preview.historyOff' },\n on(v, k('password.forceChangeOnFirstLogin'))\n ? { icon: 'ph:user-switch', on: true, key: 'config.preview.firstChange' }\n : { icon: 'ph:user-switch', on: false, key: 'config.preview.firstChangeOff' },\n {\n icon: 'ph:timer',\n on: true,\n key: 'config.preview.session',\n params: {\n access: f.duration(humanizeMinutes(num(v, k('session.accessMinutes'), 30))),\n refresh: f.duration(humanizeMinutes(num(v, k('session.refreshMinutes'), 10080))),\n },\n },\n {\n icon: 'ph:traffic-signal',\n on: on(v, k('rateLimit.enabled')),\n key: 'config.preview.rateLimit',\n params: {\n seconds: num(v, k('rateLimit.windowSeconds'), 1),\n permit: num(v, k('rateLimit.permitPerWindow'), 0),\n },\n },\n ]\n}\n"],"names":["round","v","k","s","humanizeMinutes","minutes","num","key","fallback","n","on","securityRules","f","requirements","r","expireDays","history","maxFail","totp"],"mappings":"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"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
export declare const WATERMARK_FIELDS: readonly ["name", "account", "org", "phone", "time", "text"];
|
|
2
|
+
export type WatermarkField = (typeof WATERMARK_FIELDS)[number];
|
|
3
|
+
export declare const WATERMARK_TIME_FORMATS: readonly ["YYYY-MM-DD", "YYYY-MM-DD HH:mm", "YYYY-MM-DD HH:mm:ss", "MM-DD HH:mm"];
|
|
4
|
+
export type WatermarkTimeFormat = (typeof WATERMARK_TIME_FORMATS)[number];
|
|
5
|
+
export type WatermarkLayout = 'single' | 'multi';
|
|
6
|
+
export type WatermarkDensity = 'sparse' | 'normal' | 'dense';
|
|
7
|
+
export interface WatermarkSettings {
|
|
8
|
+
enabled: boolean;
|
|
9
|
+
/** 已按 WATERMARK_FIELDS 的固定顺序排好 */
|
|
10
|
+
fields: WatermarkField[];
|
|
11
|
+
/** 内容项含 text 时才印 */
|
|
12
|
+
text: string;
|
|
13
|
+
timeFormat: WatermarkTimeFormat;
|
|
14
|
+
layout: WatermarkLayout;
|
|
15
|
+
/** px,12–28 */
|
|
16
|
+
fontSize: number;
|
|
17
|
+
/** 不透明度百分比,2–30 */
|
|
18
|
+
opacity: number;
|
|
19
|
+
/** 度,-45–45 */
|
|
20
|
+
rotate: number;
|
|
21
|
+
density: WatermarkDensity;
|
|
22
|
+
/** 相邻两行错开半格 */
|
|
23
|
+
cross: boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare const WATERMARK_LIMITS: {
|
|
26
|
+
readonly fontSize: {
|
|
27
|
+
readonly min: 12;
|
|
28
|
+
readonly max: 28;
|
|
29
|
+
};
|
|
30
|
+
readonly opacity: {
|
|
31
|
+
readonly min: 2;
|
|
32
|
+
readonly max: 30;
|
|
33
|
+
};
|
|
34
|
+
readonly rotate: {
|
|
35
|
+
readonly min: -45;
|
|
36
|
+
readonly max: 45;
|
|
37
|
+
};
|
|
38
|
+
readonly text: 40;
|
|
39
|
+
};
|
|
40
|
+
export declare const DEFAULT_WATERMARK: Readonly<WatermarkSettings>;
|
|
41
|
+
/** 配置键(与后端 ConfigSeed 的 WATERMARK_*_KEY 一一对应)。 */
|
|
42
|
+
export declare const WATERMARK_KEY: {
|
|
43
|
+
readonly enabled: "sys.watermark.enabled";
|
|
44
|
+
readonly fields: "sys.watermark.fields";
|
|
45
|
+
readonly text: "sys.watermark.text";
|
|
46
|
+
readonly timeFormat: "sys.watermark.timeFormat";
|
|
47
|
+
readonly layout: "sys.watermark.layout";
|
|
48
|
+
readonly fontSize: "sys.watermark.fontSize";
|
|
49
|
+
readonly opacity: "sys.watermark.opacity";
|
|
50
|
+
readonly rotate: "sys.watermark.rotate";
|
|
51
|
+
readonly density: "sys.watermark.density";
|
|
52
|
+
readonly cross: "sys.watermark.cross";
|
|
53
|
+
};
|
|
54
|
+
export declare const WATERMARK_KEYS: readonly string[];
|
|
55
|
+
/** 内容项:接受数组或逗号分隔串;丢掉未知项、去重、按固定顺序排。 */
|
|
56
|
+
export declare function normalizeWatermarkFields(raw: unknown): WatermarkField[];
|
|
57
|
+
/** 站点信息里的 watermark 节点(或任何半成品)→ 合法设置。 */
|
|
58
|
+
export declare function normalizeWatermark(raw?: Partial<Record<keyof WatermarkSettings, unknown>> | null): {
|
|
59
|
+
enabled: boolean;
|
|
60
|
+
fields: ("name" | "account" | "phone" | "org" | "time" | "text")[];
|
|
61
|
+
text: string;
|
|
62
|
+
timeFormat: "YYYY-MM-DD" | "YYYY-MM-DD HH:mm" | "YYYY-MM-DD HH:mm:ss" | "MM-DD HH:mm";
|
|
63
|
+
layout: WatermarkLayout;
|
|
64
|
+
fontSize: number;
|
|
65
|
+
opacity: number;
|
|
66
|
+
rotate: number;
|
|
67
|
+
density: WatermarkDensity;
|
|
68
|
+
cross: boolean;
|
|
69
|
+
};
|
|
70
|
+
/** 配置中心草稿(键值全是字符串)→ 合法设置。键不存在 = 沿用默认;空串的 fields = 一项都没勾。 */
|
|
71
|
+
export declare function watermarkFromValues(values: Record<string, string | undefined>): WatermarkSettings;
|
|
72
|
+
/** 用户自己的那部分内容;缺哪项那一项就不印。 */
|
|
73
|
+
export interface WatermarkWho {
|
|
74
|
+
name?: string | null;
|
|
75
|
+
account?: string | null;
|
|
76
|
+
org?: string | null;
|
|
77
|
+
/** 手机号后四位(整号不进浏览器存储) */
|
|
78
|
+
phoneTail?: string | null;
|
|
79
|
+
}
|
|
80
|
+
/** 按格式串格式化时间:只认 YYYY MM DD HH mm ss。 */
|
|
81
|
+
export declare function formatWatermarkTime(format: string, d: Date): string;
|
|
82
|
+
/** 内容项 → 要印出来的几段文字(按固定顺序;值为空的项跳过)。 */
|
|
83
|
+
export declare function watermarkParts(s: WatermarkSettings, who: WatermarkWho, now: Date): string[];
|
|
84
|
+
/** NWatermark 的入参子集。 */
|
|
85
|
+
export interface WatermarkProps {
|
|
86
|
+
content: string;
|
|
87
|
+
cross: boolean;
|
|
88
|
+
fontSize: number;
|
|
89
|
+
lineHeight: number;
|
|
90
|
+
rotate: number;
|
|
91
|
+
width: number;
|
|
92
|
+
height: number;
|
|
93
|
+
xGap: number;
|
|
94
|
+
yGap: number;
|
|
95
|
+
xOffset: number;
|
|
96
|
+
yOffset: number;
|
|
97
|
+
fontColor: string;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* 设置 + 当前用户 + 此刻 → NWatermark 入参;没启用、或没有任何可印的内容时返回 null。
|
|
101
|
+
*
|
|
102
|
+
* NWatermark 的画法是:一格画布 (width + xGap) × (height + yGap),**先把整个画布绕左上角旋转**,
|
|
103
|
+
* 再在旋转后的坐标系里从 (xOffset, yOffset) 起画字。所以倾斜后文字会冲出画布的上沿或左沿被裁掉
|
|
104
|
+
* (负角度向上冲、正角度向左冲),光加间距救不了,必须用 xOffset / yOffset 把旋转后的包围盒平移回画布内:
|
|
105
|
+
* 先算文字块 w × h 旋转后的包围盒,平移量取「让包围盒左上角落在 (0,0)」,再换算回旋转前的坐标系。
|
|
106
|
+
* 一格的大小 = 包围盒 + 疏密档位的间距。
|
|
107
|
+
*
|
|
108
|
+
* 文字块的宽按最长一行估算(汉字一个字号宽,其余 0.58,再放 6% 余量),高多留一点放下降部。
|
|
109
|
+
*/
|
|
110
|
+
export declare function buildWatermarkProps(s: WatermarkSettings, who: WatermarkWho, dark: boolean, now?: Date): WatermarkProps | null;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
const K = ["name", "account", "org", "phone", "time", "text"], _ = [
|
|
2
|
+
"YYYY-MM-DD",
|
|
3
|
+
"YYYY-MM-DD HH:mm",
|
|
4
|
+
"YYYY-MM-DD HH:mm:ss",
|
|
5
|
+
"MM-DD HH:mm"
|
|
6
|
+
], r = {
|
|
7
|
+
fontSize: { min: 12, max: 28 },
|
|
8
|
+
opacity: { min: 2, max: 30 },
|
|
9
|
+
rotate: { min: -45, max: 45 },
|
|
10
|
+
text: 40
|
|
11
|
+
}, F = Object.freeze({
|
|
12
|
+
enabled: !1,
|
|
13
|
+
fields: ["name", "account", "time"],
|
|
14
|
+
text: "",
|
|
15
|
+
timeFormat: "YYYY-MM-DD HH:mm",
|
|
16
|
+
layout: "single",
|
|
17
|
+
fontSize: 14,
|
|
18
|
+
opacity: 8,
|
|
19
|
+
rotate: -20,
|
|
20
|
+
density: "normal",
|
|
21
|
+
cross: !0
|
|
22
|
+
}), H = {
|
|
23
|
+
enabled: "sys.watermark.enabled",
|
|
24
|
+
fields: "sys.watermark.fields",
|
|
25
|
+
text: "sys.watermark.text",
|
|
26
|
+
timeFormat: "sys.watermark.timeFormat",
|
|
27
|
+
layout: "sys.watermark.layout",
|
|
28
|
+
fontSize: "sys.watermark.fontSize",
|
|
29
|
+
opacity: "sys.watermark.opacity",
|
|
30
|
+
rotate: "sys.watermark.rotate",
|
|
31
|
+
density: "sys.watermark.density",
|
|
32
|
+
cross: "sys.watermark.cross"
|
|
33
|
+
}, G = Object.values(H);
|
|
34
|
+
function d(t, e, n, o) {
|
|
35
|
+
const a = typeof t == "number" ? t : Number(t);
|
|
36
|
+
return t === "" || t === null || t === void 0 || !Number.isFinite(a) ? e : Math.min(o, Math.max(n, Math.trunc(a)));
|
|
37
|
+
}
|
|
38
|
+
const p = (t, e, n) => e.includes(t) ? t : n;
|
|
39
|
+
function I(t) {
|
|
40
|
+
const e = Array.isArray(t) ? t.map(String) : typeof t == "string" ? t.split(",").map((n) => n.trim()) : null;
|
|
41
|
+
return e ? K.filter((n) => e.includes(n)) : [...F.fields];
|
|
42
|
+
}
|
|
43
|
+
function O(t) {
|
|
44
|
+
const e = F, n = t ?? {}, o = typeof n.text == "string" ? n.text.trim() : "";
|
|
45
|
+
return {
|
|
46
|
+
enabled: n.enabled === !0,
|
|
47
|
+
fields: n.fields === void 0 ? [...e.fields] : I(n.fields),
|
|
48
|
+
text: o.slice(0, r.text),
|
|
49
|
+
timeFormat: p(n.timeFormat, _, e.timeFormat),
|
|
50
|
+
layout: p(n.layout, ["single", "multi"], e.layout),
|
|
51
|
+
fontSize: d(
|
|
52
|
+
n.fontSize,
|
|
53
|
+
e.fontSize,
|
|
54
|
+
r.fontSize.min,
|
|
55
|
+
r.fontSize.max
|
|
56
|
+
),
|
|
57
|
+
opacity: d(
|
|
58
|
+
n.opacity,
|
|
59
|
+
e.opacity,
|
|
60
|
+
r.opacity.min,
|
|
61
|
+
r.opacity.max
|
|
62
|
+
),
|
|
63
|
+
rotate: d(n.rotate, e.rotate, r.rotate.min, r.rotate.max),
|
|
64
|
+
density: p(n.density, ["sparse", "normal", "dense"], e.density),
|
|
65
|
+
cross: n.cross !== !1
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function L(t) {
|
|
69
|
+
const e = (n) => t[H[n]];
|
|
70
|
+
return O({
|
|
71
|
+
enabled: e("enabled") === "true",
|
|
72
|
+
fields: e("fields"),
|
|
73
|
+
text: e("text"),
|
|
74
|
+
timeFormat: e("timeFormat"),
|
|
75
|
+
layout: e("layout"),
|
|
76
|
+
fontSize: e("fontSize"),
|
|
77
|
+
opacity: e("opacity"),
|
|
78
|
+
rotate: e("rotate"),
|
|
79
|
+
density: e("density"),
|
|
80
|
+
cross: e("cross") !== "false"
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
const m = (t) => String(t).padStart(2, "0");
|
|
84
|
+
function j(t, e) {
|
|
85
|
+
const n = {
|
|
86
|
+
YYYY: String(e.getFullYear()),
|
|
87
|
+
MM: m(e.getMonth() + 1),
|
|
88
|
+
DD: m(e.getDate()),
|
|
89
|
+
HH: m(e.getHours()),
|
|
90
|
+
mm: m(e.getMinutes()),
|
|
91
|
+
ss: m(e.getSeconds())
|
|
92
|
+
};
|
|
93
|
+
return t.replace(/YYYY|MM|DD|HH|mm|ss/g, (o) => n[o]);
|
|
94
|
+
}
|
|
95
|
+
function v(t, e, n) {
|
|
96
|
+
const o = {
|
|
97
|
+
name: e.name,
|
|
98
|
+
account: e.account,
|
|
99
|
+
org: e.org,
|
|
100
|
+
phone: e.phoneTail ? `*${e.phoneTail}` : null,
|
|
101
|
+
time: j(t.timeFormat, n),
|
|
102
|
+
text: t.text
|
|
103
|
+
};
|
|
104
|
+
return t.fields.map((a) => {
|
|
105
|
+
var s;
|
|
106
|
+
return (s = o[a]) == null ? void 0 : s.trim();
|
|
107
|
+
}).filter((a) => !!a);
|
|
108
|
+
}
|
|
109
|
+
const P = { sparse: 120, normal: 64, dense: 24 };
|
|
110
|
+
function $(t, e, n, o = /* @__PURE__ */ new Date()) {
|
|
111
|
+
if (!t.enabled) return null;
|
|
112
|
+
const a = v(t, e, o);
|
|
113
|
+
if (!a.length) return null;
|
|
114
|
+
const s = t.layout === "multi" ? a : [a.join(" · ")], M = Math.round(t.fontSize * 1.4), R = (i) => [...i].reduce((y, E) => y + (E.charCodeAt(0) > 255 ? t.fontSize : t.fontSize * 0.58), 0), c = Math.ceil(Math.max(...s.map(R)) * 1.06), l = M * s.length + Math.ceil(t.fontSize * 0.3), x = t.rotate * Math.PI / 180, u = Math.cos(x), f = Math.sin(x), Y = [
|
|
115
|
+
[0, 0],
|
|
116
|
+
[c, 0],
|
|
117
|
+
[0, l],
|
|
118
|
+
[c, l]
|
|
119
|
+
].map(([i, y]) => [i * u - y * f, i * f + y * u]), h = Y.map((i) => i[0]), S = Y.map((i) => i[1]), g = Math.min(...h), z = Math.min(...S), T = Math.ceil(Math.max(...h) - g), W = Math.ceil(Math.max(...S) - z), b = -g, A = -z, D = P[t.density], k = t.opacity / 100;
|
|
120
|
+
return {
|
|
121
|
+
content: s.join(`
|
|
122
|
+
`),
|
|
123
|
+
cross: t.cross,
|
|
124
|
+
fontSize: t.fontSize,
|
|
125
|
+
lineHeight: M,
|
|
126
|
+
rotate: t.rotate,
|
|
127
|
+
width: c,
|
|
128
|
+
height: l,
|
|
129
|
+
xGap: T - c + D,
|
|
130
|
+
yGap: W - l + D,
|
|
131
|
+
xOffset: b * u + A * f + 0,
|
|
132
|
+
// + 0:不倾斜时把 -0 收成 0
|
|
133
|
+
yOffset: -b * f + A * u + 0,
|
|
134
|
+
fontColor: n ? `rgba(255,255,255,${k})` : `rgba(0,0,0,${k})`
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
export {
|
|
138
|
+
F as DEFAULT_WATERMARK,
|
|
139
|
+
K as WATERMARK_FIELDS,
|
|
140
|
+
H as WATERMARK_KEY,
|
|
141
|
+
G as WATERMARK_KEYS,
|
|
142
|
+
r as WATERMARK_LIMITS,
|
|
143
|
+
_ as WATERMARK_TIME_FORMATS,
|
|
144
|
+
$ as buildWatermarkProps,
|
|
145
|
+
j as formatWatermarkTime,
|
|
146
|
+
O as normalizeWatermark,
|
|
147
|
+
I as normalizeWatermarkFields,
|
|
148
|
+
L as watermarkFromValues,
|
|
149
|
+
v as watermarkParts
|
|
150
|
+
};
|
|
151
|
+
//# sourceMappingURL=watermark.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watermark.js","sources":["../../src/lib/watermark.ts"],"sourcesContent":["// 水印:配置(sys.watermark.*)→ 设置对象 → NWatermark 的入参。\n// 管理员只决定「印哪几项、长什么样」,每个人具体印什么由前端按登录用户拼,所以同一份设置在每台浏览器上内容不同。\n// 取值规则与后端 ConfigService.LoadWatermarkAsync 一致:任何一项缺失、写错或越界都收口成默认值 / 边界,\n// 这样配置中心的草稿预览(读键值表)和线上真水印(读站点信息)走同一套收口。\n\nexport const WATERMARK_FIELDS = ['name', 'account', 'org', 'phone', 'time', 'text'] as const\nexport type WatermarkField = (typeof WATERMARK_FIELDS)[number]\n\nexport const WATERMARK_TIME_FORMATS = [\n 'YYYY-MM-DD',\n 'YYYY-MM-DD HH:mm',\n 'YYYY-MM-DD HH:mm:ss',\n 'MM-DD HH:mm',\n] as const\nexport type WatermarkTimeFormat = (typeof WATERMARK_TIME_FORMATS)[number]\n\nexport type WatermarkLayout = 'single' | 'multi'\nexport type WatermarkDensity = 'sparse' | 'normal' | 'dense'\n\nexport interface WatermarkSettings {\n enabled: boolean\n /** 已按 WATERMARK_FIELDS 的固定顺序排好 */\n fields: WatermarkField[]\n /** 内容项含 text 时才印 */\n text: string\n timeFormat: WatermarkTimeFormat\n layout: WatermarkLayout\n /** px,12–28 */\n fontSize: number\n /** 不透明度百分比,2–30 */\n opacity: number\n /** 度,-45–45 */\n rotate: number\n density: WatermarkDensity\n /** 相邻两行错开半格 */\n cross: boolean\n}\n\nexport const WATERMARK_LIMITS = {\n fontSize: { min: 12, max: 28 },\n opacity: { min: 2, max: 30 },\n rotate: { min: -45, max: 45 },\n text: 40,\n} as const\n\nexport const DEFAULT_WATERMARK: Readonly<WatermarkSettings> = Object.freeze({\n enabled: false,\n fields: ['name', 'account', 'time'] as WatermarkField[],\n text: '',\n timeFormat: 'YYYY-MM-DD HH:mm',\n layout: 'single',\n fontSize: 14,\n opacity: 8,\n rotate: -20,\n density: 'normal',\n cross: true,\n})\n\n/** 配置键(与后端 ConfigSeed 的 WATERMARK_*_KEY 一一对应)。 */\nexport const WATERMARK_KEY = {\n enabled: 'sys.watermark.enabled',\n fields: 'sys.watermark.fields',\n text: 'sys.watermark.text',\n timeFormat: 'sys.watermark.timeFormat',\n layout: 'sys.watermark.layout',\n fontSize: 'sys.watermark.fontSize',\n opacity: 'sys.watermark.opacity',\n rotate: 'sys.watermark.rotate',\n density: 'sys.watermark.density',\n cross: 'sys.watermark.cross',\n} as const\nexport const WATERMARK_KEYS: readonly string[] = Object.values(WATERMARK_KEY)\n\nfunction clampInt(raw: unknown, fallback: number, min: number, max: number) {\n const n = typeof raw === 'number' ? raw : Number(raw)\n if (raw === '' || raw === null || raw === undefined || !Number.isFinite(n)) return fallback\n return Math.min(max, Math.max(min, Math.trunc(n)))\n}\n\nconst oneOf = <T extends string>(v: unknown, all: readonly T[], fallback: T): T =>\n all.includes(v as T) ? (v as T) : fallback\n\n/** 内容项:接受数组或逗号分隔串;丢掉未知项、去重、按固定顺序排。 */\nexport function normalizeWatermarkFields(raw: unknown): WatermarkField[] {\n const list = Array.isArray(raw)\n ? raw.map(String)\n : typeof raw === 'string'\n ? raw.split(',').map(s => s.trim())\n : null\n if (!list) return [...DEFAULT_WATERMARK.fields]\n return WATERMARK_FIELDS.filter(f => list.includes(f))\n}\n\n/** 站点信息里的 watermark 节点(或任何半成品)→ 合法设置。 */\nexport function normalizeWatermark(raw?: Partial<Record<keyof WatermarkSettings, unknown>> | null) {\n const d = DEFAULT_WATERMARK\n const r = raw ?? {}\n const text = typeof r.text === 'string' ? r.text.trim() : ''\n return {\n enabled: r.enabled === true,\n fields: r.fields === undefined ? [...d.fields] : normalizeWatermarkFields(r.fields),\n text: text.slice(0, WATERMARK_LIMITS.text),\n timeFormat: oneOf(r.timeFormat, WATERMARK_TIME_FORMATS, d.timeFormat),\n layout: oneOf(r.layout, ['single', 'multi'] as const, d.layout),\n fontSize: clampInt(\n r.fontSize,\n d.fontSize,\n WATERMARK_LIMITS.fontSize.min,\n WATERMARK_LIMITS.fontSize.max,\n ),\n opacity: clampInt(\n r.opacity,\n d.opacity,\n WATERMARK_LIMITS.opacity.min,\n WATERMARK_LIMITS.opacity.max,\n ),\n rotate: clampInt(r.rotate, d.rotate, WATERMARK_LIMITS.rotate.min, WATERMARK_LIMITS.rotate.max),\n density: oneOf(r.density, ['sparse', 'normal', 'dense'] as const, d.density),\n cross: r.cross !== false,\n } satisfies WatermarkSettings\n}\n\n/** 配置中心草稿(键值全是字符串)→ 合法设置。键不存在 = 沿用默认;空串的 fields = 一项都没勾。 */\nexport function watermarkFromValues(values: Record<string, string | undefined>): WatermarkSettings {\n const v = (k: keyof typeof WATERMARK_KEY) => values[WATERMARK_KEY[k]]\n return normalizeWatermark({\n enabled: v('enabled') === 'true',\n fields: v('fields'),\n text: v('text'),\n timeFormat: v('timeFormat'),\n layout: v('layout'),\n fontSize: v('fontSize'),\n opacity: v('opacity'),\n rotate: v('rotate'),\n density: v('density'),\n cross: v('cross') !== 'false',\n })\n}\n\n/** 用户自己的那部分内容;缺哪项那一项就不印。 */\nexport interface WatermarkWho {\n name?: string | null\n account?: string | null\n org?: string | null\n /** 手机号后四位(整号不进浏览器存储) */\n phoneTail?: string | null\n}\n\nconst pad = (n: number) => String(n).padStart(2, '0')\n\n/** 按格式串格式化时间:只认 YYYY MM DD HH mm ss。 */\nexport function formatWatermarkTime(format: string, d: Date): string {\n const map: Record<string, string> = {\n YYYY: String(d.getFullYear()),\n MM: pad(d.getMonth() + 1),\n DD: pad(d.getDate()),\n HH: pad(d.getHours()),\n mm: pad(d.getMinutes()),\n ss: pad(d.getSeconds()),\n }\n return format.replace(/YYYY|MM|DD|HH|mm|ss/g, t => map[t]!)\n}\n\n/** 内容项 → 要印出来的几段文字(按固定顺序;值为空的项跳过)。 */\nexport function watermarkParts(s: WatermarkSettings, who: WatermarkWho, now: Date): string[] {\n const value: Record<WatermarkField, string | null | undefined> = {\n name: who.name,\n account: who.account,\n org: who.org,\n phone: who.phoneTail ? `*${who.phoneTail}` : null,\n time: formatWatermarkTime(s.timeFormat, now),\n text: s.text,\n }\n return s.fields.map(f => value[f]?.trim()).filter((x): x is string => !!x)\n}\n\n/** NWatermark 的入参子集。 */\nexport interface WatermarkProps {\n content: string\n cross: boolean\n fontSize: number\n lineHeight: number\n rotate: number\n width: number\n height: number\n xGap: number\n yGap: number\n xOffset: number\n yOffset: number\n fontColor: string\n}\n\nconst GAP: Record<WatermarkDensity, number> = { sparse: 120, normal: 64, dense: 24 }\n\n/**\n * 设置 + 当前用户 + 此刻 → NWatermark 入参;没启用、或没有任何可印的内容时返回 null。\n *\n * NWatermark 的画法是:一格画布 (width + xGap) × (height + yGap),**先把整个画布绕左上角旋转**,\n * 再在旋转后的坐标系里从 (xOffset, yOffset) 起画字。所以倾斜后文字会冲出画布的上沿或左沿被裁掉\n * (负角度向上冲、正角度向左冲),光加间距救不了,必须用 xOffset / yOffset 把旋转后的包围盒平移回画布内:\n * 先算文字块 w × h 旋转后的包围盒,平移量取「让包围盒左上角落在 (0,0)」,再换算回旋转前的坐标系。\n * 一格的大小 = 包围盒 + 疏密档位的间距。\n *\n * 文字块的宽按最长一行估算(汉字一个字号宽,其余 0.58,再放 6% 余量),高多留一点放下降部。\n */\nexport function buildWatermarkProps(\n s: WatermarkSettings,\n who: WatermarkWho,\n dark: boolean,\n now: Date = new Date(),\n): WatermarkProps | null {\n if (!s.enabled) return null\n const parts = watermarkParts(s, who, now)\n if (!parts.length) return null\n const lines = s.layout === 'multi' ? parts : [parts.join(' · ')]\n const lineHeight = Math.round(s.fontSize * 1.4)\n const textWidth = (line: string) =>\n [...line].reduce((w, c) => w + (c.charCodeAt(0) > 255 ? s.fontSize : s.fontSize * 0.58), 0)\n const width = Math.ceil(Math.max(...lines.map(textWidth)) * 1.06)\n const height = lineHeight * lines.length + Math.ceil(s.fontSize * 0.3)\n\n const rad = (s.rotate * Math.PI) / 180\n const cos = Math.cos(rad)\n const sin = Math.sin(rad)\n const corners = [\n [0, 0],\n [width, 0],\n [0, height],\n [width, height],\n ].map(([x, y]) => [x! * cos - y! * sin, x! * sin + y! * cos] as const)\n const xs = corners.map(c => c[0])\n const ys = corners.map(c => c[1])\n const minX = Math.min(...xs)\n const minY = Math.min(...ys)\n const boxW = Math.ceil(Math.max(...xs) - minX)\n const boxH = Math.ceil(Math.max(...ys) - minY)\n // 画布坐标系里要平移 (-minX, -minY);画字用的偏移在旋转后的坐标系里,换算 R(-θ)·T\n const tx = -minX\n const ty = -minY\n const gap = GAP[s.density]\n const alpha = s.opacity / 100\n return {\n content: lines.join('\\n'),\n cross: s.cross,\n fontSize: s.fontSize,\n lineHeight,\n rotate: s.rotate,\n width,\n height,\n xGap: boxW - width + gap,\n yGap: boxH - height + gap,\n xOffset: tx * cos + ty * sin + 0, // + 0:不倾斜时把 -0 收成 0\n yOffset: -tx * sin + ty * cos + 0,\n fontColor: dark ? `rgba(255,255,255,${alpha})` : `rgba(0,0,0,${alpha})`,\n }\n}\n"],"names":["WATERMARK_FIELDS","WATERMARK_TIME_FORMATS","WATERMARK_LIMITS","DEFAULT_WATERMARK","WATERMARK_KEY","WATERMARK_KEYS","clampInt","raw","fallback","min","max","n","oneOf","v","all","normalizeWatermarkFields","list","s","f","normalizeWatermark","d","r","text","watermarkFromValues","values","k","pad","formatWatermarkTime","format","map","t","watermarkParts","who","now","value","_a","x","GAP","buildWatermarkProps","dark","parts","lines","lineHeight","textWidth","line","w","c","width","height","rad","cos","sin","corners","xs","ys","minX","minY","boxW","boxH","tx","ty","gap","alpha"],"mappings":"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"}
|