smart-admin-web 10.15.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 +1 -1
- package/dist/api/index.d.ts +4 -2
- package/dist/api/index.js +1 -1
- package/dist/api/index.js.map +1 -1
- package/dist/api/schema.d.ts +39 -5
- package/dist/assets/icons/ph-subset.json.js +5 -5
- package/dist/components/AppIcon.vue.js +9 -9
- package/dist/components/AppIcon.vue.js.map +1 -1
- package/dist/components/AppWatermark.vue.d.ts +14 -0
- package/dist/components/AppWatermark.vue.js +38 -0
- package/dist/components/AppWatermark.vue.js.map +1 -0
- package/dist/components/AppWatermark2.vue.js +5 -0
- package/dist/components/AppWatermark2.vue.js.map +1 -0
- package/dist/components/Chart/PieChart.vue.d.ts +1 -1
- package/dist/components/Chart/echarts.js +15 -20
- package/dist/components/Chart/echarts.js.map +1 -1
- package/dist/components/CronEditor/index.vue.js +1 -1
- package/dist/components/CronEditor/index2.vue.js +2 -1
- package/dist/components/CronEditor/index2.vue.js.map +1 -1
- package/dist/components/DetailPage/index.vue.js +2 -2
- package/dist/components/DetailPage/index2.vue.js.map +1 -1
- package/dist/components/DictTag/index.vue.js.map +1 -1
- package/dist/components/ErrorBoundary/index.vue.js +2 -2
- package/dist/components/ErrorBoundary/index2.vue.js +1 -1
- package/dist/components/ErrorBoundary/index2.vue.js.map +1 -1
- package/dist/components/FormContainer/index.vue.js +91 -56
- package/dist/components/FormContainer/index.vue.js.map +1 -1
- package/dist/components/ImportWizard/index.vue.js +1 -1
- package/dist/components/ImportWizard/index2.vue.js +44 -41
- package/dist/components/ImportWizard/index2.vue.js.map +1 -1
- package/dist/components/MenuSearch.vue.js +2 -2
- package/dist/components/MenuSearch2.vue.js +19 -18
- package/dist/components/MenuSearch2.vue.js.map +1 -1
- package/dist/components/PasswordStrength/index.vue.js +2 -2
- package/dist/components/PasswordStrength/index2.vue.js +20 -18
- package/dist/components/PasswordStrength/index2.vue.js.map +1 -1
- package/dist/components/TableTotal/index.vue.d.ts +6 -0
- package/dist/components/{SelectTable → TableTotal}/index.vue.js +1 -1
- package/dist/components/TableTotal/index2.vue.js +16 -0
- package/dist/components/TableTotal/index2.vue.js.map +1 -0
- package/dist/components/TableZoomButton/index.vue.js.map +1 -1
- package/dist/components/UserPicker/index.vue.js +2 -2
- package/dist/components/UserPicker/index2.vue.js +176 -117
- package/dist/components/UserPicker/index2.vue.js.map +1 -1
- package/dist/composables/useBatchDelete.js.map +1 -1
- package/dist/composables/useLayoutMenu.js +17 -16
- package/dist/composables/useLayoutMenu.js.map +1 -1
- package/dist/composables/useModule.js +39 -29
- package/dist/composables/useModule.js.map +1 -1
- package/dist/composables/useShellBreakpoint.d.ts +19 -0
- package/dist/composables/useShellBreakpoint.js +37 -0
- package/dist/composables/useShellBreakpoint.js.map +1 -0
- package/dist/composables/useSite.d.ts +15 -0
- package/dist/composables/useSite.js +16 -14
- package/dist/composables/useSite.js.map +1 -1
- package/dist/composables/useTabTitle.js.map +1 -1
- package/dist/composables/useTableTitle.d.ts +6 -0
- package/dist/composables/useTableTitle.js +11 -0
- package/dist/composables/useTableTitle.js.map +1 -0
- package/dist/composables/useTableZoom.d.ts +5 -0
- package/dist/composables/useTableZoom.js.map +1 -1
- package/dist/composables/useTheme.d.ts +2 -2
- package/dist/composables/useTheme.js +23 -20
- package/dist/composables/useTheme.js.map +1 -1
- package/dist/createSmartAdmin.d.ts +12 -2
- package/dist/createSmartAdmin.js +72 -60
- package/dist/createSmartAdmin.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +219 -205
- package/dist/index.js.map +1 -1
- package/dist/layouts/AccentPicker.vue.js +8 -0
- package/dist/layouts/AccentPicker.vue.js.map +1 -0
- package/dist/layouts/AccentPicker2.vue.js +131 -0
- package/dist/layouts/AccentPicker2.vue.js.map +1 -0
- package/dist/layouts/AppHeader.vue.d.ts +8 -1
- package/dist/layouts/AppHeader.vue.js +2 -2
- package/dist/layouts/AppHeader2.vue.js +317 -235
- package/dist/layouts/AppHeader2.vue.js.map +1 -1
- package/dist/layouts/NoticeBell.vue.js +2 -2
- package/dist/layouts/NoticeBell2.vue.js +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/loginHero.d.ts +2 -2
- package/dist/lib/loginHero.js.map +1 -1
- package/dist/lib/runtime.js +1 -1
- package/dist/lib/watermark.d.ts +110 -0
- package/dist/lib/watermark.js +151 -0
- package/dist/lib/watermark.js.map +1 -0
- package/dist/locales/en-US.d.ts +221 -15
- package/dist/locales/en-US.js +230 -21
- package/dist/locales/en-US.js.map +1 -1
- package/dist/locales/kernelMenuTitles.d.ts +1 -0
- package/dist/locales/kernelMenuTitles.js +128 -0
- package/dist/locales/kernelMenuTitles.js.map +1 -0
- package/dist/locales/menuTitle.d.ts +3 -0
- package/dist/locales/menuTitle.js +14 -12
- package/dist/locales/menuTitle.js.map +1 -1
- package/dist/locales/zh-CN.d.ts +221 -15
- package/dist/locales/zh-CN.js +238 -28
- package/dist/locales/zh-CN.js.map +1 -1
- package/dist/router/index.js +41 -32
- package/dist/router/index.js.map +1 -1
- package/dist/router/namedPage.d.ts +4 -0
- package/dist/router/namedPage.js +7 -7
- package/dist/router/namedPage.js.map +1 -1
- package/dist/router/viewRegistry.js +8 -8
- package/dist/router/viewRegistry.js.map +1 -1
- package/dist/stores/app.d.ts +0 -12
- package/dist/stores/app.js +11 -12
- package/dist/stores/app.js.map +1 -1
- package/dist/stores/tabs.js.map +1 -1
- package/dist/stores/user.d.ts +10 -0
- package/dist/stores/user.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/theme/accentTokens.d.ts +27 -0
- package/dist/theme/accentTokens.js +54 -0
- package/dist/theme/accentTokens.js.map +1 -0
- package/dist/theme/accents.d.ts +21 -1
- package/dist/theme/accents.js +11 -2
- package/dist/theme/accents.js.map +1 -1
- package/dist/theme/mix.d.ts +58 -7
- package/dist/theme/mix.js +115 -30
- package/dist/theme/mix.js.map +1 -1
- package/dist/theme/naive-theme.d.ts +5 -2
- package/dist/theme/naive-theme.js +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.js.map +1 -1
- package/dist/utils/tableFilter.d.ts +88 -0
- package/dist/utils/tableFilter.js +116 -0
- package/dist/utils/tableFilter.js.map +1 -0
- package/dist/utils/tableToolbar.d.ts +18 -0
- package/dist/utils/tableToolbar.js +11 -0
- package/dist/utils/tableToolbar.js.map +1 -0
- package/dist/utils/treeFilter.d.ts +20 -0
- package/dist/utils/treeFilter.js +24 -0
- package/dist/utils/treeFilter.js.map +1 -0
- package/dist/views/dashboard/ShortcutPicker.vue.js +1 -1
- package/dist/views/dashboard/ShortcutPicker2.vue.js +73 -48
- package/dist/views/dashboard/ShortcutPicker2.vue.js.map +1 -1
- package/dist/views/dashboard/biz.vue.js +1 -1
- package/dist/views/dashboard/biz2.vue.js +310 -257
- package/dist/views/dashboard/biz2.vue.js.map +1 -1
- package/dist/views/dashboard/workbench.vue.js +2 -2
- package/dist/views/dashboard/workbench2.vue.js +141 -155
- package/dist/views/dashboard/workbench2.vue.js.map +1 -1
- package/dist/views/embed/iframe.vue.js +2 -2
- package/dist/views/embed/iframe2.vue.js +22 -15
- package/dist/views/embed/iframe2.vue.js.map +1 -1
- package/dist/views/error/404.vue.js +2 -2
- package/dist/views/error/4042.vue.js +33 -24
- package/dist/views/error/4042.vue.js.map +1 -1
- package/dist/views/error/BootError.vue.js +1 -1
- package/dist/views/error/BootError2.vue.js +59 -48
- package/dist/views/error/BootError2.vue.js.map +1 -1
- package/dist/views/error/MissingRoute.vue.js +2 -2
- package/dist/views/error/MissingRoute2.vue.js +34 -15
- package/dist/views/error/MissingRoute2.vue.js.map +1 -1
- package/dist/views/login/LoginForm.vue.d.ts +7 -1
- package/dist/views/login/LoginForm.vue.js +2 -2
- package/dist/views/login/LoginForm2.vue.js +580 -488
- package/dist/views/login/LoginForm2.vue.js.map +1 -1
- package/dist/views/login/components/LoginDesk.vue.d.ts +36 -0
- package/dist/views/login/components/LoginDesk.vue.js +9 -0
- package/dist/views/login/components/LoginDesk.vue.js.map +1 -0
- package/dist/views/login/components/LoginDesk2.vue.js +100 -0
- package/dist/views/login/components/LoginDesk2.vue.js.map +1 -0
- package/dist/views/login/components/LoginHeroPanel.vue.js +3 -3
- package/dist/views/login/components/LoginHeroPanel2.vue.js +34 -39
- package/dist/views/login/components/LoginHeroPanel2.vue.js.map +1 -1
- package/dist/views/login/index.vue.js +1 -1
- package/dist/views/login/index2.vue.js +141 -71
- package/dist/views/login/index2.vue.js.map +1 -1
- package/dist/views/login/layout.d.ts +11 -0
- package/dist/views/login/layout.js +27 -0
- package/dist/views/login/layout.js.map +1 -0
- package/dist/views/mfa/index.vue.js +2 -2
- package/dist/views/mfa/index2.vue.js +367 -321
- package/dist/views/mfa/index2.vue.js.map +1 -1
- package/dist/views/module/index.vue.js +2 -2
- package/dist/views/module/index2.vue.js +132 -99
- package/dist/views/module/index2.vue.js.map +1 -1
- package/dist/views/oauth/callback.vue.js +2 -2
- package/dist/views/oauth/callback2.vue.js +65 -51
- package/dist/views/oauth/callback2.vue.js.map +1 -1
- package/dist/views/personal/bindings.vue.js +2 -2
- package/dist/views/personal/bindings2.vue.js +98 -94
- package/dist/views/personal/bindings2.vue.js.map +1 -1
- package/dist/views/personal/notice2.vue.js +103 -76
- package/dist/views/personal/notice2.vue.js.map +1 -1
- package/dist/views/personal/password2.vue.js +47 -40
- package/dist/views/personal/password2.vue.js.map +1 -1
- package/dist/views/personal/profile.vue.js +3 -3
- package/dist/views/personal/profile2.vue.js +24 -18
- package/dist/views/personal/profile2.vue.js.map +1 -1
- package/dist/views/personal/security.vue.js +2 -2
- package/dist/views/personal/security2.vue.js +65 -53
- package/dist/views/personal/security2.vue.js.map +1 -1
- package/dist/views/personal/sessions.vue.js +2 -2
- package/dist/views/personal/sessions2.vue.js +67 -62
- package/dist/views/personal/sessions2.vue.js.map +1 -1
- package/dist/views/system/ai-model/components/ProviderCard.vue.js +2 -2
- package/dist/views/system/ai-model/components/ProviderCard2.vue.js +142 -130
- package/dist/views/system/ai-model/components/ProviderCard2.vue.js.map +1 -1
- package/dist/views/system/ai-model/components/ProviderForm.vue.js +2 -2
- package/dist/views/system/ai-model/components/ProviderForm2.vue.js +71 -70
- package/dist/views/system/ai-model/components/ProviderForm2.vue.js.map +1 -1
- package/dist/views/system/ai-model/index.vue.js +2 -2
- package/dist/views/system/ai-model/index2.vue.js +99 -99
- package/dist/views/system/ai-model/index2.vue.js.map +1 -1
- package/dist/views/system/ai-model/presets.d.ts +1 -1
- package/dist/views/system/ai-model/presets.js +18 -18
- package/dist/views/system/ai-model/presets.js.map +1 -1
- package/dist/views/system/ai-usage/index.vue.js +2 -2
- package/dist/views/system/ai-usage/index2.vue.js +356 -258
- package/dist/views/system/ai-usage/index2.vue.js.map +1 -1
- package/dist/views/system/api-docs/index.vue.js +5 -2
- package/dist/views/system/api-docs/index.vue.js.map +1 -1
- package/dist/views/system/api-docs/index2.vue.js +92 -42
- package/dist/views/system/api-docs/index2.vue.js.map +1 -1
- package/dist/views/system/cache/index.vue.js +2 -2
- package/dist/views/system/cache/index2.vue.js +74 -80
- package/dist/views/system/cache/index2.vue.js.map +1 -1
- package/dist/views/system/config/components/AdminMock.vue.js +2 -2
- package/dist/views/system/config/components/AdminMock2.vue.js +60 -43
- package/dist/views/system/config/components/AdminMock2.vue.js.map +1 -1
- package/dist/views/system/config/components/AdvancedSection.vue.js +5 -2
- package/dist/views/system/config/components/AdvancedSection.vue.js.map +1 -1
- package/dist/views/system/config/components/AdvancedSection2.vue.js +98 -70
- package/dist/views/system/config/components/AdvancedSection2.vue.js.map +1 -1
- package/dist/views/system/config/components/BrandSection.vue.js +2 -2
- package/dist/views/system/config/components/BrandSection2.vue.js +121 -119
- package/dist/views/system/config/components/BrandSection2.vue.js.map +1 -1
- package/dist/views/system/config/components/CfgGroup.vue.js +3 -3
- package/dist/views/system/config/components/CfgGroup2.vue.js.map +1 -1
- package/dist/views/system/config/components/CfgRow.vue.js +1 -1
- package/dist/views/system/config/components/CfgRow2.vue.js +24 -23
- package/dist/views/system/config/components/CfgRow2.vue.js.map +1 -1
- package/dist/views/system/config/components/CfgSegment.vue.js +1 -1
- package/dist/views/system/config/components/CfgSegment2.vue.js +16 -15
- package/dist/views/system/config/components/CfgSegment2.vue.js.map +1 -1
- package/dist/views/system/config/components/ConfigFormModal.vue.js +2 -2
- package/dist/views/system/config/components/ConfigFormModal2.vue.js +35 -33
- package/dist/views/system/config/components/ConfigFormModal2.vue.js.map +1 -1
- package/dist/views/system/config/components/JobSection.vue.js +2 -2
- package/dist/views/system/config/components/JobSection2.vue.js +46 -44
- package/dist/views/system/config/components/JobSection2.vue.js.map +1 -1
- package/dist/views/system/config/components/LoginMock.vue.js +3 -3
- package/dist/views/system/config/components/LoginMock2.vue.js +83 -72
- package/dist/views/system/config/components/LoginMock2.vue.js.map +1 -1
- package/dist/views/system/config/components/LogoCropper.vue.js +1 -1
- package/dist/views/system/config/components/LogoCropper2.vue.js.map +1 -1
- package/dist/views/system/config/components/LogoEditor.vue.js +2 -2
- package/dist/views/system/config/components/LogoEditor2.vue.js +11 -13
- package/dist/views/system/config/components/LogoEditor2.vue.js.map +1 -1
- package/dist/views/system/config/components/ProviderSheet.vue.js +3 -3
- package/dist/views/system/config/components/ProviderSheet2.vue.js.map +1 -1
- package/dist/views/system/config/components/SectionLayout.vue.d.ts +4 -2
- package/dist/views/system/config/components/SectionLayout.vue.js +2 -2
- package/dist/views/system/config/components/SectionLayout2.vue.js +51 -27
- package/dist/views/system/config/components/SectionLayout2.vue.js.map +1 -1
- package/dist/views/system/config/components/SecuritySection.vue.js +2 -2
- package/dist/views/system/config/components/SecuritySection2.vue.js +207 -206
- package/dist/views/system/config/components/SecuritySection2.vue.js.map +1 -1
- package/dist/views/system/config/components/SensitiveSection.vue.js +2 -2
- package/dist/views/system/config/components/SensitiveSection2.vue.js +107 -102
- package/dist/views/system/config/components/SensitiveSection2.vue.js.map +1 -1
- package/dist/views/system/config/components/UploadSection.vue.js +2 -2
- package/dist/views/system/config/components/UploadSection2.vue.js +86 -77
- package/dist/views/system/config/components/UploadSection2.vue.js.map +1 -1
- package/dist/views/system/config/components/WatermarkSection.vue.js +8 -0
- package/dist/views/system/config/components/WatermarkSection.vue.js.map +1 -0
- package/dist/views/system/config/components/WatermarkSection2.vue.js +284 -0
- package/dist/views/system/config/components/WatermarkSection2.vue.js.map +1 -0
- package/dist/views/system/config/draft.d.ts +2 -2
- package/dist/views/system/config/draft.js.map +1 -1
- package/dist/views/system/config/groups.d.ts +4 -1
- package/dist/views/system/config/groups.js +54 -49
- package/dist/views/system/config/groups.js.map +1 -1
- package/dist/views/system/config/index.vue.js +3 -2
- package/dist/views/system/config/index.vue.js.map +1 -1
- package/dist/views/system/config/index2.vue.js +173 -148
- package/dist/views/system/config/index2.vue.js.map +1 -1
- package/dist/views/system/config/layoutMode.d.ts +23 -0
- package/dist/views/system/config/layoutMode.js +28 -0
- package/dist/views/system/config/layoutMode.js.map +1 -0
- package/dist/views/system/dict/index.vue.js +2 -2
- package/dist/views/system/dict/index2.vue.js +471 -366
- package/dist/views/system/dict/index2.vue.js.map +1 -1
- package/dist/views/system/file/index2.vue.js +91 -76
- package/dist/views/system/file/index2.vue.js.map +1 -1
- package/dist/views/system/job/index.vue.js +3 -3
- package/dist/views/system/job/index2.vue.js +897 -828
- package/dist/views/system/job/index2.vue.js.map +1 -1
- package/dist/views/system/job-log/components/AttemptTable.vue.d.ts +8 -0
- package/dist/views/system/job-log/components/AttemptTable.vue.js +5 -0
- package/dist/views/system/job-log/components/AttemptTable.vue.js.map +1 -0
- package/dist/views/system/job-log/components/AttemptTable2.vue.js +54 -0
- package/dist/views/system/job-log/components/AttemptTable2.vue.js.map +1 -0
- package/dist/views/system/job-log/index.vue.js +2 -2
- package/dist/views/system/job-log/index2.vue.js +193 -207
- package/dist/views/system/job-log/index2.vue.js.map +1 -1
- package/dist/views/system/job-log/runStatus.d.ts +13 -0
- package/dist/views/system/job-log/runStatus.js +26 -0
- package/dist/views/system/job-log/runStatus.js.map +1 -0
- package/dist/views/system/job-monitor/index.vue.js +2 -2
- package/dist/views/system/job-monitor/index2.vue.js +172 -180
- package/dist/views/system/job-monitor/index2.vue.js.map +1 -1
- package/dist/views/system/log/exception/index.vue.js +2 -2
- package/dist/views/system/log/exception/index2.vue.js +135 -96
- package/dist/views/system/log/exception/index2.vue.js.map +1 -1
- package/dist/views/system/log/login/index2.vue.js +62 -41
- package/dist/views/system/log/login/index2.vue.js.map +1 -1
- package/dist/views/system/log/op/index.vue.js +2 -2
- package/dist/views/system/log/op/index2.vue.js +200 -162
- package/dist/views/system/log/op/index2.vue.js.map +1 -1
- package/dist/views/system/menu/components/ButtonManager.vue.js +2 -2
- package/dist/views/system/menu/components/ButtonManager2.vue.js +206 -190
- package/dist/views/system/menu/components/ButtonManager2.vue.js.map +1 -1
- package/dist/views/system/menu/components/MenuFormModal.vue.js +2 -2
- package/dist/views/system/menu/components/MenuFormModal2.vue.js +127 -118
- package/dist/views/system/menu/components/MenuFormModal2.vue.js.map +1 -1
- package/dist/views/system/menu/index.vue.js +1 -1
- package/dist/views/system/menu/index2.vue.js +216 -183
- package/dist/views/system/menu/index2.vue.js.map +1 -1
- package/dist/views/system/module/index.vue.js +1 -1
- package/dist/views/system/module/index2.vue.js +177 -144
- package/dist/views/system/module/index2.vue.js.map +1 -1
- package/dist/views/system/monitor/index.vue.js +2 -2
- package/dist/views/system/monitor/index2.vue.js +134 -149
- package/dist/views/system/monitor/index2.vue.js.map +1 -1
- package/dist/views/system/notice/index.vue.js +1 -1
- package/dist/views/system/notice/index2.vue.js +209 -181
- package/dist/views/system/notice/index2.vue.js.map +1 -1
- package/dist/views/system/org/index.vue.js +1 -1
- package/dist/views/system/org/index2.vue.js +278 -248
- package/dist/views/system/org/index2.vue.js.map +1 -1
- package/dist/views/system/position/index.vue.js +5 -2
- package/dist/views/system/position/index.vue.js.map +1 -1
- package/dist/views/system/position/index2.vue.js +128 -92
- package/dist/views/system/position/index2.vue.js.map +1 -1
- package/dist/views/system/recycle/index.vue.js +2 -2
- package/dist/views/system/recycle/index2.vue.js +90 -67
- package/dist/views/system/recycle/index2.vue.js.map +1 -1
- package/dist/views/system/role/components/GrantMenuSheet.vue.d.ts +20 -0
- package/dist/views/system/role/components/GrantMenuSheet.vue.js +8 -0
- package/dist/views/system/role/components/GrantMenuSheet.vue.js.map +1 -0
- package/dist/views/system/role/components/GrantMenuSheet2.vue.js +117 -0
- package/dist/views/system/role/components/GrantMenuSheet2.vue.js.map +1 -0
- package/dist/views/system/role/components/GrantMenuTable.vue.d.ts +6 -4
- package/dist/views/system/role/components/GrantMenuTable.vue.js +2 -2
- package/dist/views/system/role/components/GrantMenuTable2.vue.js +279 -177
- package/dist/views/system/role/components/GrantMenuTable2.vue.js.map +1 -1
- package/dist/views/system/role/components/MatchText.vue.d.ts +7 -0
- package/dist/views/system/role/components/MatchText.vue.js +8 -0
- package/dist/views/system/role/components/MatchText.vue.js.map +1 -0
- package/dist/views/system/role/components/MatchText2.vue.js +29 -0
- package/dist/views/system/role/components/MatchText2.vue.js.map +1 -0
- package/dist/views/system/role/components/grantMenuGroups.d.ts +36 -0
- package/dist/views/system/role/components/grantMenuGroups.js +110 -48
- package/dist/views/system/role/components/grantMenuGroups.js.map +1 -1
- package/dist/views/system/role/index.vue.js +5 -2
- package/dist/views/system/role/index.vue.js.map +1 -1
- package/dist/views/system/role/index2.vue.js +181 -165
- package/dist/views/system/role/index2.vue.js.map +1 -1
- package/dist/views/system/session/index2.vue.js +75 -49
- package/dist/views/system/session/index2.vue.js.map +1 -1
- package/dist/views/system/user/components/ResetPasswordModal.vue.js +2 -2
- package/dist/views/system/user/components/ResetPasswordModal2.vue.js +2 -0
- package/dist/views/system/user/components/ResetPasswordModal2.vue.js.map +1 -1
- package/dist/views/system/user/components/UserFormModal.vue.js +2 -2
- package/dist/views/system/user/components/UserFormModal2.vue.js +77 -76
- package/dist/views/system/user/components/UserFormModal2.vue.js.map +1 -1
- package/dist/views/system/user/index.vue.js +2 -2
- package/dist/views/system/user/index2.vue.js +362 -275
- package/dist/views/system/user/index2.vue.js.map +1 -1
- package/package.json +3 -5
- package/dist/components/SelectTable/index.vue.d.ts +0 -76
- package/dist/components/SelectTable/index2.vue.js +0 -256
- package/dist/components/SelectTable/index2.vue.js.map +0 -1
- package/dist/composables/useTableRowSort.d.ts +0 -20
- package/dist/composables/useTableRowSort.js +0 -59
- package/dist/composables/useTableRowSort.js.map +0 -1
- package/dist/layouts/LayoutModeCards.vue.js +0 -8
- package/dist/layouts/LayoutModeCards.vue.js.map +0 -1
- package/dist/layouts/LayoutModeCards2.vue.js +0 -67
- package/dist/layouts/LayoutModeCards2.vue.js.map +0 -1
- package/dist/layouts/SettingRow.vue.d.ts +0 -16
- package/dist/layouts/SettingRow.vue.js +0 -8
- package/dist/layouts/SettingRow.vue.js.map +0 -1
- package/dist/layouts/SettingRow2.vue.js +0 -23
- package/dist/layouts/SettingRow2.vue.js.map +0 -1
- package/dist/views/login/skins/AuroraGlass.vue.js +0 -8
- package/dist/views/login/skins/AuroraGlass.vue.js.map +0 -1
- package/dist/views/login/skins/AuroraGlass2.vue.js +0 -80
- package/dist/views/login/skins/AuroraGlass2.vue.js.map +0 -1
- package/dist/views/login/skins/SplitPanel.vue.d.ts +0 -3
- package/dist/views/login/skins/SplitPanel.vue.js +0 -8
- package/dist/views/login/skins/SplitPanel.vue.js.map +0 -1
- package/dist/views/login/skins/SplitPanel2.vue.js +0 -65
- package/dist/views/login/skins/SplitPanel2.vue.js.map +0 -1
- package/dist/views/login/skins/Spotlight.vue.d.ts +0 -3
- package/dist/views/login/skins/Spotlight.vue.js +0 -8
- package/dist/views/login/skins/Spotlight.vue.js.map +0 -1
- package/dist/views/login/skins/Spotlight2.vue.js +0 -36
- package/dist/views/login/skins/Spotlight2.vue.js.map +0 -1
- package/dist/views/login/skins.d.ts +0 -8
- package/dist/views/login/skins.js +0 -13
- package/dist/views/login/skins.js.map +0 -1
- /package/dist/components/{SelectTable → TableTotal}/index.vue.js.map +0 -0
- /package/dist/layouts/{LayoutModeCards.vue.d.ts → AccentPicker.vue.d.ts} +0 -0
- /package/dist/views/{login/skins/AuroraGlass.vue.d.ts → system/config/components/WatermarkSection.vue.d.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index2.vue.js","sources":["../../../src/components/ImportWizard/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 四步导入向导:①上传 ②列映射 ③预览改错(裸 n-data-table)④结果。\n// API 由父级注入(用户导入走 userApi 六方法),组件对资源无感知,可复用到其他档案。\nimport { computed, h, ref, shallowRef, watch } from 'vue'\nimport {\n NModal,\n NSteps,\n NStep,\n NUpload,\n NUploadDragger,\n NText,\n NButton,\n NSpace,\n NSelect,\n NDataTable,\n NInput,\n NSwitch,\n NRadioGroup,\n NRadio,\n NAlert,\n NTooltip,\n NTag,\n useMessage,\n type DataTableColumns,\n type UploadFileInfo,\n} from 'naive-ui'\nimport { useI18n } from 'vue-i18n'\nimport AppIcon from '#/components/AppIcon.vue'\nimport DictSelect from '#/components/DictSelect/index.vue'\nimport { translateError } from '#/utils/error'\nimport { triggerBlobDownload } from '#/utils/download'\nimport { hardErrorsOf as hardErrors, isDuplicateOnly, isHardError } from '#/utils/importDup'\nimport type {\n CellError,\n DuplicateStrategy as DupStrategyNum,\n ImportColumn,\n ImportCommitResult,\n ImportPreview,\n ImportRow,\n} from '#/types/api'\nimport { DuplicateStrategy } from '#/types/api'\n\nexport interface ImportWizardApi {\n downloadTemplate: () => Promise<Blob>\n preview: (file: File, mapping?: Record<string, string>) => Promise<ImportPreview>\n validate: (rows: ImportRow[]) => Promise<ImportPreview>\n commit: (rows: ImportRow[], strategy: DupStrategyNum) => Promise<ImportCommitResult>\n errorReport: (rows: ImportRow[]) => Promise<Blob>\n}\n\nconst show = defineModel<boolean>('show', { default: false })\n\nconst props = defineProps<{\n api: ImportWizardApi\n /**\n * 弹窗标题。缺省是 `import.wizardTitle`(「导入用户」)——那是内核用户导入的文案,\n * 本组件被别的档案复用时必须传自己的标题,否则会顶着「导入用户」导别的东西。\n */\n title?: string\n /** 模板下载默认文件名 */\n templateFileName?: string\n /** 错误报告默认文件名 */\n errorReportFileName?: string\n /**\n * 可选的重复策略,按给定顺序渲染;缺省三种都给。\n * 用于档案本身不支持某种策略的场景 —— 例如条码储位只允许「跳过已存在」,\n * 覆盖会把条码挪到别的库位,不是导入该干的事。\n */\n strategies?: DupStrategyNum[]\n}>()\n\nconst emit = defineEmits<{\n /** 提交成功(含部分成功)后触发,父级通常 refresh 列表 */\n done: []\n}>()\n\nconst { t } = useI18n()\nconst message = useMessage()\n\n// ── 状态 ──\nconst step = ref(1) // n-steps 1-based\nconst loading = ref(false)\nconst file = ref<File | null>(null)\nconst fileList = ref<UploadFileInfo[]>([])\nconst headers = shallowRef<string[]>([])\n/** 表头 → 列 Key(空串 = 不映射) */\nconst mapping = ref<Record<string, string>>({})\nconst columns = shallowRef<ImportColumn[]>([])\n// rows 刻意保持深响应:setCell 是就地改 row.cells / row.errors(可编辑预览表),\n// 换成 shallowRef 后单元格改完不会重渲,红底也不会消 —— 要改得先把编辑改成不可变替换。\nconst rows = ref<ImportRow[]>([])\nconst columnErrors = ref<ImportPreview['columnErrors']>([])\nconst onlyErrors = ref(false)\nconst strategy = ref<DupStrategyNum>(DuplicateStrategy.Skip)\nconst commitResult = ref<ImportCommitResult | null>(null)\n\n/** 策略标签用函数形式,切换语言即时生效(与 SmartTable 列 title 同理)。 */\nconst strategyLabels: Record<DupStrategyNum, () => string> = {\n [DuplicateStrategy.Skip]: () => t('import.strategySkip'),\n [DuplicateStrategy.Overwrite]: () => t('import.strategyOverwrite'),\n [DuplicateStrategy.Error]: () => t('import.strategyError'),\n}\n/** 未指定 strategies 时三种都给。 */\nconst strategyOptions = computed(() =>\n (\n props.strategies ?? [\n DuplicateStrategy.Skip,\n DuplicateStrategy.Overwrite,\n DuplicateStrategy.Error,\n ]\n ).map(value => ({ value, label: strategyLabels[value] })),\n)\n\n// 「已存在」按策略呈现的判定见 utils/importDup(那里也记着与后端的镜像关系)\nconst isHard = (e: CellError) => isHardError(e, strategy.value)\nconst hardErrorsOf = (r: ImportRow) => hardErrors(r, strategy.value)\n/** 需要用户动手改的行数(不含「已存在」——那些按策略自动处理)。 */\nconst errorRows = computed(() => rows.value.filter(r => hardErrorsOf(r).length > 0).length)\n/** 只是「已存在」、会被策略正常处理的行数。 */\nconst duplicateRows = computed(\n () => rows.value.filter(r => isDuplicateOnly(r, strategy.value)).length,\n)\n\nfunction reset() {\n step.value = 1\n loading.value = false\n file.value = null\n fileList.value = []\n headers.value = []\n mapping.value = {}\n columns.value = []\n rows.value = []\n columnErrors.value = []\n onlyErrors.value = false\n // 默认选 Skip;调用方限制了可选策略且不含 Skip 时退到第一个可选项,避免选中一个没渲染的值。\n strategy.value = strategyOptions.value.some(o => o.value === DuplicateStrategy.Skip)\n ? DuplicateStrategy.Skip\n : (strategyOptions.value[0]?.value ?? DuplicateStrategy.Skip)\n commitResult.value = null\n}\n\nwatch(show, v => {\n if (v) reset()\n})\n\nfunction applyPreview(p: ImportPreview) {\n headers.value = [...p.headers]\n mapping.value = { ...p.mapping }\n columns.value = p.columns\n rows.value = p.rows.map(r => ({\n index: r.index,\n cells: { ...r.cells },\n errors: [...r.errors],\n }))\n columnErrors.value = p.columnErrors\n}\n\nasync function onDownloadTemplate() {\n loading.value = true\n try {\n const blob = await props.api.downloadTemplate()\n triggerBlobDownload(blob, props.templateFileName ?? 'import-template.xlsx')\n } catch (e) {\n message.error(translateError(e))\n } finally {\n loading.value = false\n }\n}\n\nfunction onFileChange(list: UploadFileInfo[]) {\n // 只保留最后选中的一个 xlsx\n fileList.value = list.slice(-1)\n const f = list[list.length - 1]?.file\n file.value = f instanceof File ? f : null\n}\n\nfunction onFileRemove() {\n fileList.value = []\n file.value = null\n}\n\n/** ①→②:带文件预览(mapping 空 = 服务端自动匹配) */\nasync function goMapping() {\n if (!file.value) {\n message.warning(t('import.needFile'))\n return\n }\n loading.value = true\n try {\n const p = await props.api.preview(file.value)\n applyPreview(p)\n // 确保每个表头在 mapping 里有键(未匹配的给空串,便于 n-select 显示「不映射」)\n for (const header of p.headers) {\n if (!(header in mapping.value)) mapping.value[header] = ''\n }\n step.value = 2\n } catch (e) {\n message.error(translateError(e))\n } finally {\n loading.value = false\n }\n}\n\n/** ②→③:按用户调整后的映射重新预览 */\nasync function goPreview() {\n if (!file.value) return\n // 去掉「不映射」空串,只传有效映射\n const map: Record<string, string> = {}\n for (const [header, key] of Object.entries(mapping.value)) {\n if (key) map[header] = key\n }\n loading.value = true\n try {\n const p = await props.api.preview(file.value, map)\n applyPreview(p)\n step.value = 3\n } catch (e) {\n message.error(translateError(e))\n } finally {\n loading.value = false\n }\n}\n\nconst targetColumnOptions = computed(() => [\n { label: t('import.unmap'), value: '' },\n ...columns.value.map(c => ({\n label: c.required ? `${c.title} *` : c.title,\n value: c.key,\n })),\n])\n\nfunction cellError(row: ImportRow, key: string) {\n return row.errors.find(e => e.columnKey === key)\n}\n\nfunction setCell(row: ImportRow, key: string, value: string | null) {\n row.cells[key] = value\n // 就地改后清该列旧错误,等重验;否则红底会误导\n row.errors = row.errors.filter(e => e.columnKey !== key)\n}\n\nconst displayRows = computed(() =>\n onlyErrors.value ? rows.value.filter(r => hardErrorsOf(r).length > 0) : rows.value,\n)\n\nconst previewColumns = computed<DataTableColumns<ImportRow>>(() => {\n const cols: DataTableColumns<ImportRow> = [\n {\n title: '#',\n key: '_index',\n width: 56,\n fixed: 'left',\n render: r => r.index,\n },\n ]\n for (const col of columns.value) {\n cols.push({\n title: () => (col.required ? `${col.title} *` : col.title),\n key: col.key,\n minWidth: 120,\n ellipsis: { tooltip: false },\n render: row => {\n const err = cellError(row, col.key)\n // 「已存在」在跳过/覆盖策略下不算错:走警示底色,输入框也不置 error 态\n const soft = err !== undefined && !isHard(err)\n const val = row.cells[col.key] ?? null\n const editor = col.dictTypeCode\n ? h(DictSelect, {\n typeCode: col.dictTypeCode,\n value: val,\n clearable: !col.required,\n size: 'small',\n // 弹层不跟随触发器宽度:向导的列很窄(minWidth 120,实测触发器约 66px),\n // 跟随会把「启用」「停用」截成「启..」「停..」。普通表单里下拉够宽,\n // 跟随反而更整齐 —— 所以只在向导关掉,不动共用的 DictSelect。\n consistentMenuWidth: false,\n style: { width: '100%' },\n status: err && !soft ? 'error' : undefined,\n 'onUpdate:value': (v: string | null) => setCell(row, col.key, v),\n })\n : h(NInput, {\n value: val ?? '',\n size: 'small',\n status: err && !soft ? 'error' : undefined,\n onUpdateValue: (v: string) => setCell(row, col.key, v),\n })\n const cell = h(\n 'div',\n {\n class: !err\n ? 'import-cell'\n : soft\n ? 'import-cell import-cell--dup'\n : 'import-cell import-cell--error',\n },\n [editor],\n )\n if (!err) return cell\n return h(\n NTooltip,\n { trigger: 'hover' },\n {\n trigger: () => cell,\n default: () =>\n soft ? t(`import.dupHint.${strategy.value}`) : translateError(err.code),\n },\n )\n },\n })\n }\n cols.push({\n title: () => t('import.errors'),\n key: '_errors',\n width: 160,\n fixed: 'right',\n render: r => {\n if (r.errors.length === 0)\n return h(NTag, { size: 'small', type: 'success', bordered: false }, () => t('import.ok'))\n const hard = hardErrorsOf(r)\n // 只剩「已存在」:不是要用户改的错,给警示标签 +「将按策略处理」而非红色错误数\n if (hard.length === 0) {\n return h(\n NTooltip,\n { trigger: 'hover' },\n {\n trigger: () =>\n h(NTag, { size: 'small', type: 'warning', bordered: false }, () =>\n t('import.dupTag'),\n ),\n default: () => t(`import.dupHint.${strategy.value}`),\n },\n )\n }\n return h(\n NTooltip,\n { trigger: 'hover' },\n {\n trigger: () =>\n h(NTag, { size: 'small', type: 'error', bordered: false }, () =>\n t('import.errorCount', { n: hard.length }),\n ),\n default: () => hard.map(e => `${e.columnKey}: ${translateError(e.code)}`).join('\\n'),\n },\n )\n },\n })\n return cols\n})\n\nasync function revalidate() {\n // 变异判据:请求必须带 rows;空数组也是明确失败路径(服务端会返回 0 行)\n loading.value = true\n try {\n const p = await props.api.validate(rows.value)\n // 保留当前列定义(重验不回传 headers/mapping;columns 仍有)\n rows.value = p.rows.map(r => ({\n index: r.index,\n cells: { ...r.cells },\n errors: [...r.errors],\n }))\n columns.value = p.columns.length ? p.columns : columns.value\n // 用本地按策略算出的硬错误数,不用 p.errorRows —— 后端不知道当前策略,会把「已存在」也计进去\n message.success(t('import.revalidated', { errors: errorRows.value, total: p.total }))\n } catch (e) {\n message.error(translateError(e))\n } finally {\n loading.value = false\n }\n}\n\nasync function doCommit() {\n loading.value = true\n try {\n const result = await props.api.commit(rows.value, strategy.value)\n commitResult.value = result\n step.value = 4\n if (result.inserted + result.updated > 0) emit('done')\n } catch (e) {\n message.error(translateError(e))\n } finally {\n loading.value = false\n }\n}\n\n/** ④ 失败行接回 ③ 继续改 */\nfunction backToEditFailures() {\n if (!commitResult.value) return\n rows.value = commitResult.value.failures.map(r => ({\n index: r.index,\n cells: { ...r.cells },\n errors: [...r.errors],\n }))\n onlyErrors.value = true\n commitResult.value = null\n step.value = 3\n}\n\nasync function downloadErrorReport() {\n const source =\n step.value === 4 && commitResult.value\n ? commitResult.value.failures\n : rows.value.filter(r => r.errors.length > 0)\n if (source.length === 0) {\n message.warning(t('import.noErrorRows'))\n return\n }\n loading.value = true\n try {\n const blob = await props.api.errorReport(source)\n triggerBlobDownload(blob, props.errorReportFileName ?? 'import-errors.xlsx')\n } catch (e) {\n message.error(translateError(e))\n } finally {\n loading.value = false\n }\n}\n\nfunction close() {\n show.value = false\n}\n</script>\n\n<template>\n <n-modal\n v-model:show=\"show\"\n preset=\"card\"\n :title=\"props.title ?? t('import.wizardTitle')\"\n :style=\"{ width: 'min(1100px, 96vw)' }\"\n :mask-closable=\"false\"\n :closable=\"!loading\"\n :close-on-esc=\"!loading\"\n >\n <n-steps :current=\"step\" size=\"small\" class=\"import-steps\">\n <n-step :title=\"t('import.stepUpload')\" />\n <n-step :title=\"t('import.stepMapping')\" />\n <n-step :title=\"t('import.stepPreview')\" />\n <n-step :title=\"t('import.stepResult')\" />\n </n-steps>\n\n <!-- ① 上传 -->\n <div v-show=\"step === 1\" class=\"import-pane\">\n <n-space vertical :size=\"12\">\n <n-button secondary :loading=\"loading\" @click=\"onDownloadTemplate\">\n <template #icon><AppIcon icon=\"ph:download-simple\" :size=\"16\" /></template>\n {{ t('import.downloadTemplate') }}\n </n-button>\n <n-upload\n :file-list=\"fileList\"\n :max=\"1\"\n accept=\".xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\"\n :default-upload=\"false\"\n @update:file-list=\"onFileChange\"\n @remove=\"onFileRemove\"\n >\n <n-upload-dragger>\n <div class=\"import-upload-icon\">\n <AppIcon icon=\"ph:file-xls\" :size=\"40\" />\n </div>\n <n-text style=\"font-size: 16px\">{{ t('import.dropHint') }}</n-text>\n <n-text depth=\"3\" style=\"display: block; margin-top: 8px\">\n {{ t('import.dropSub') }}\n </n-text>\n </n-upload-dragger>\n </n-upload>\n </n-space>\n </div>\n\n <!-- ② 列映射 -->\n <div v-show=\"step === 2\" class=\"import-pane\">\n <n-alert v-if=\"columnErrors.length\" type=\"warning\" style=\"margin-bottom: 12px\">\n {{ columnErrors.map(e => `${e.columnKey}: ${translateError(e.code)}`).join('; ') }}\n </n-alert>\n <n-text depth=\"3\" style=\"display: block; margin-bottom: 12px\">\n {{ t('import.mappingHint') }}\n </n-text>\n <div class=\"import-mapping\">\n <div class=\"import-mapping-head\">\n <span>{{ t('import.fileHeader') }}</span>\n <span>{{ t('import.targetColumn') }}</span>\n </div>\n <div v-for=\"hdr in headers\" :key=\"hdr\" class=\"import-mapping-row\">\n <span class=\"import-mapping-header\" :title=\"hdr\">{{ hdr }}</span>\n <n-select\n v-model:value=\"mapping[hdr]\"\n :options=\"targetColumnOptions\"\n :consistent-menu-width=\"false\"\n size=\"small\"\n />\n </div>\n </div>\n </div>\n\n <!-- ③ 预览改错(裸 n-data-table,不用 SmartTable) -->\n <div v-show=\"step === 3\" class=\"import-pane\">\n <n-space justify=\"space-between\" align=\"center\" style=\"margin-bottom: 12px\" wrap>\n <n-space align=\"center\">\n <n-text>\n {{ t('import.summary', { total: rows.length, errors: errorRows }) }}\n <template v-if=\"duplicateRows\">\n {{ t('import.summaryDup', { n: duplicateRows }) }}\n </template>\n </n-text>\n <n-switch v-model:value=\"onlyErrors\" size=\"small\">\n <template #checked>{{ t('import.onlyErrors') }}</template>\n <template #unchecked>{{ t('import.onlyErrors') }}</template>\n </n-switch>\n </n-space>\n <n-space>\n <n-button size=\"small\" :loading=\"loading\" @click=\"revalidate\">\n <template #icon><AppIcon icon=\"ph:arrows-clockwise\" :size=\"14\" /></template>\n {{ t('import.revalidate') }}\n </n-button>\n </n-space>\n </n-space>\n <n-data-table\n size=\"small\"\n :columns=\"previewColumns\"\n :data=\"displayRows\"\n :row-key=\"(r: ImportRow) => r.index\"\n :max-height=\"420\"\n :scroll-x=\"Math.max(800, columns.length * 140 + 220)\"\n />\n <div class=\"import-strategy\">\n <n-text strong style=\"margin-right: 12px\">{{ t('import.strategy') }}</n-text>\n <n-radio-group v-model:value=\"strategy\" name=\"dup-strategy\">\n <n-space>\n <n-radio v-for=\"option in strategyOptions\" :key=\"option.value\" :value=\"option.value\">\n {{ option.label() }}\n </n-radio>\n </n-space>\n </n-radio-group>\n </div>\n </div>\n\n <!-- ④ 结果 -->\n <div v-show=\"step === 4\" class=\"import-pane\">\n <n-alert\n v-if=\"commitResult\"\n :type=\"commitResult.failed > 0 ? 'warning' : 'success'\"\n :title=\"t('import.resultTitle')\"\n >\n <div>{{ t('import.resultTotal', { n: commitResult.total }) }}</div>\n <div>{{ t('import.resultInserted', { n: commitResult.inserted }) }}</div>\n <div>{{ t('import.resultUpdated', { n: commitResult.updated }) }}</div>\n <div>{{ t('import.resultSkipped', { n: commitResult.skipped }) }}</div>\n <div>{{ t('import.resultFailed', { n: commitResult.failed }) }}</div>\n </n-alert>\n <n-space style=\"margin-top: 16px\">\n <n-button\n v-if=\"commitResult && commitResult.failed > 0\"\n type=\"warning\"\n @click=\"backToEditFailures\"\n >\n {{ t('import.editFailures') }}\n </n-button>\n <n-button\n v-if=\"commitResult && commitResult.failed > 0\"\n secondary\n :loading=\"loading\"\n @click=\"downloadErrorReport\"\n >\n <template #icon><AppIcon icon=\"ph:download-simple\" :size=\"16\" /></template>\n {{ t('import.downloadErrorReport') }}\n </n-button>\n </n-space>\n </div>\n\n <template #footer>\n <n-space justify=\"end\">\n <n-button :disabled=\"loading\" @click=\"close\">\n {{ step === 4 ? t('common.close') : t('common.cancel') }}\n </n-button>\n <n-button v-if=\"step === 3\" secondary :disabled=\"loading\" @click=\"downloadErrorReport\">\n {{ t('import.downloadErrorReport') }}\n </n-button>\n <n-button v-if=\"step > 1 && step < 4\" :disabled=\"loading\" @click=\"step = step - 1\">\n {{ t('import.prev') }}\n </n-button>\n <n-button\n v-if=\"step === 1\"\n type=\"primary\"\n :loading=\"loading\"\n :disabled=\"!file\"\n @click=\"goMapping\"\n >\n {{ t('import.next') }}\n </n-button>\n <n-button v-if=\"step === 2\" type=\"primary\" :loading=\"loading\" @click=\"goPreview\">\n {{ t('import.next') }}\n </n-button>\n <n-button v-if=\"step === 3\" type=\"primary\" :loading=\"loading\" @click=\"doCommit\">\n {{ t('import.commit') }}\n </n-button>\n </n-space>\n </template>\n </n-modal>\n</template>\n\n<style scoped>\n.import-steps {\n margin-bottom: 20px;\n}\n.import-pane {\n min-height: 200px;\n}\n.import-upload-icon {\n margin-bottom: 12px;\n color: var(--n-text-color-3);\n}\n.import-mapping-head,\n.import-mapping-row {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 12px;\n align-items: center;\n}\n.import-mapping-head {\n font-weight: 600;\n font-size: 13px;\n margin-bottom: 8px;\n color: var(--n-text-color-2);\n}\n.import-mapping-row {\n margin-bottom: 8px;\n}\n.import-mapping-header {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 13px;\n}\n.import-strategy {\n margin-top: 16px;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n}\n:deep(.import-cell) {\n padding: 2px;\n border-radius: 4px;\n}\n:deep(.import-cell--error) {\n /* 用仓库自己的语义令牌(亮/暗都有定义)。别写 --n-error-color:那是 naive 组件内部的变量,\n 在这层普通 div 上未定义,整条 color-mix() 会被判无效丢弃 —— 红底静默不渲染,而 tsc/lint/build 全绿。 */\n background: var(--color-danger-bg);\n}\n:deep(.import-cell--dup) {\n /* 「库里已存在」在跳过/覆盖策略下会被正常处理,用警示色而非错误红——同上,只用语义令牌 */\n background: var(--color-warning-bg);\n}\n</style>\n"],"names":["show","_useModel","__props","props","emit","__emit","t","useI18n","message","useMessage","step","ref","loading","file","fileList","headers","shallowRef","mapping","columns","rows","columnErrors","onlyErrors","strategy","DuplicateStrategy","commitResult","strategyLabels","strategyOptions","computed","value","isHard","isHardError","hardErrorsOf","r","hardErrors","errorRows","duplicateRows","isDuplicateOnly","reset","o","_a","watch","v","applyPreview","p","onDownloadTemplate","blob","triggerBlobDownload","translateError","onFileChange","list","f","onFileRemove","goMapping","header","goPreview","map","key","e","targetColumnOptions","c","cellError","row","setCell","displayRows","previewColumns","cols","col","err","soft","val","editor","h","DictSelect","NInput","cell","NTooltip","NTag","hard","revalidate","doCommit","result","backToEditFailures","downloadErrorReport","source","close","_createBlock","_unref","NModal","$event","_createVNode","NSpace","NButton","_cache","NSteps","NStep","_withDirectives","_createElementVNode","_hoisted_1","AppIcon","_createTextVNode","NUpload","NUploadDragger","_hoisted_2","NText","_hoisted_3","NAlert","_toDisplayString","_hoisted_4","_hoisted_5","_createElementBlock","_Fragment","_renderList","hdr","_hoisted_6","NSelect","_hoisted_7","NSwitch","NDataTable","_hoisted_8","NRadioGroup","option","NRadio","_hoisted_9"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index2.vue.js","sources":["../../../src/components/ImportWizard/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 四步导入向导:①上传 ②列映射 ③预览改错(SmartTable 静态数据模式)④结果。\n// ③ 没用 SmartTable 的 `editable`(Excel 式草稿 + 批量保存):向导要的是「每个单元格始终是输入框 / 字典下拉、\n// 服务端按列返回的错误码实时标红并带悬浮提示、`已存在` 在跳过 / 覆盖策略下降级成警示底色、改完点『重新校验』走服务端」,\n// 而 `editable` 的草稿 / 保存模型没有这些;且写了 `render` 的列在 `editable` 下本来就不可编辑(README「editor」)。\n// 所以列仍用 `render` 画控件,表格本身(静态分页、固定列、横向滚动、空态)交给 SmartTable。\n// API 由父级注入(用户导入走 userApi 六方法),组件对资源无感知,可复用到其他档案。\nimport { computed, h, ref, shallowRef, watch } from 'vue'\nimport {\n NModal,\n NSteps,\n NStep,\n NUpload,\n NUploadDragger,\n NText,\n NButton,\n NSpace,\n NSelect,\n NInput,\n NSwitch,\n NRadioGroup,\n NRadio,\n NAlert,\n NTooltip,\n NTag,\n useMessage,\n type UploadFileInfo,\n} from 'naive-ui'\nimport { useI18n } from 'vue-i18n'\nimport { SmartTable, type SmartTableColumn } from 'smart-naive-table'\nimport AppIcon from '#/components/AppIcon.vue'\nimport DictSelect from '#/components/DictSelect/index.vue'\nimport { translateError } from '#/utils/error'\nimport { triggerBlobDownload } from '#/utils/download'\nimport { hardErrorsOf as hardErrors, isDuplicateOnly, isHardError } from '#/utils/importDup'\nimport type {\n CellError,\n DuplicateStrategy as DupStrategyNum,\n ImportColumn,\n ImportCommitResult,\n ImportPreview,\n ImportRow,\n} from '#/types/api'\nimport { DuplicateStrategy } from '#/types/api'\n\nexport interface ImportWizardApi {\n downloadTemplate: () => Promise<Blob>\n preview: (file: File, mapping?: Record<string, string>) => Promise<ImportPreview>\n validate: (rows: ImportRow[]) => Promise<ImportPreview>\n commit: (rows: ImportRow[], strategy: DupStrategyNum) => Promise<ImportCommitResult>\n errorReport: (rows: ImportRow[]) => Promise<Blob>\n}\n\nconst show = defineModel<boolean>('show', { default: false })\n\nconst props = defineProps<{\n api: ImportWizardApi\n /**\n * 弹窗标题。缺省是 `import.wizardTitle`(「导入用户」)——那是内核用户导入的文案,\n * 本组件被别的档案复用时必须传自己的标题,否则会顶着「导入用户」导别的东西。\n */\n title?: string\n /** 模板下载默认文件名 */\n templateFileName?: string\n /** 错误报告默认文件名 */\n errorReportFileName?: string\n /**\n * 可选的重复策略,按给定顺序渲染;缺省三种都给。\n * 用于档案本身不支持某种策略的场景 —— 例如条码储位只允许「跳过已存在」,\n * 覆盖会把条码挪到别的库位,不是导入该干的事。\n */\n strategies?: DupStrategyNum[]\n}>()\n\nconst emit = defineEmits<{\n /** 提交成功(含部分成功)后触发,父级通常 refresh 列表 */\n done: []\n}>()\n\nconst { t } = useI18n()\nconst message = useMessage()\n\n// ── 状态 ──\nconst step = ref(1) // n-steps 1-based\nconst loading = ref(false)\nconst file = ref<File | null>(null)\nconst fileList = ref<UploadFileInfo[]>([])\nconst headers = shallowRef<string[]>([])\n/** 表头 → 列 Key(空串 = 不映射) */\nconst mapping = ref<Record<string, string>>({})\nconst columns = shallowRef<ImportColumn[]>([])\n// rows 刻意保持深响应:setCell 是就地改 row.cells / row.errors(可编辑预览表),\n// 换成 shallowRef 后单元格改完不会重渲,红底也不会消 —— 要改得先把编辑改成不可变替换。\nconst rows = ref<ImportRow[]>([])\nconst columnErrors = ref<ImportPreview['columnErrors']>([])\nconst onlyErrors = ref(false)\nconst strategy = ref<DupStrategyNum>(DuplicateStrategy.Skip)\nconst commitResult = ref<ImportCommitResult | null>(null)\n\n/** 策略标签用函数形式,切换语言即时生效(与 SmartTable 列 title 同理)。 */\nconst strategyLabels: Record<DupStrategyNum, () => string> = {\n [DuplicateStrategy.Skip]: () => t('import.strategySkip'),\n [DuplicateStrategy.Overwrite]: () => t('import.strategyOverwrite'),\n [DuplicateStrategy.Error]: () => t('import.strategyError'),\n}\n/** 未指定 strategies 时三种都给。 */\nconst strategyOptions = computed(() =>\n (\n props.strategies ?? [\n DuplicateStrategy.Skip,\n DuplicateStrategy.Overwrite,\n DuplicateStrategy.Error,\n ]\n ).map(value => ({ value, label: strategyLabels[value] })),\n)\n\n// 「已存在」按策略呈现的判定见 utils/importDup(那里也记着与后端的镜像关系)\nconst isHard = (e: CellError) => isHardError(e, strategy.value)\nconst hardErrorsOf = (r: ImportRow) => hardErrors(r, strategy.value)\n/** 需要用户动手改的行数(不含「已存在」——那些按策略自动处理)。 */\nconst errorRows = computed(() => rows.value.filter(r => hardErrorsOf(r).length > 0).length)\n/** 只是「已存在」、会被策略正常处理的行数。 */\nconst duplicateRows = computed(\n () => rows.value.filter(r => isDuplicateOnly(r, strategy.value)).length,\n)\n\nfunction reset() {\n step.value = 1\n loading.value = false\n file.value = null\n fileList.value = []\n headers.value = []\n mapping.value = {}\n columns.value = []\n rows.value = []\n columnErrors.value = []\n onlyErrors.value = false\n // 默认选 Skip;调用方限制了可选策略且不含 Skip 时退到第一个可选项,避免选中一个没渲染的值。\n strategy.value = strategyOptions.value.some(o => o.value === DuplicateStrategy.Skip)\n ? DuplicateStrategy.Skip\n : (strategyOptions.value[0]?.value ?? DuplicateStrategy.Skip)\n commitResult.value = null\n}\n\nwatch(show, v => {\n if (v) reset()\n})\n\nfunction applyPreview(p: ImportPreview) {\n headers.value = [...p.headers]\n mapping.value = { ...p.mapping }\n columns.value = p.columns\n rows.value = p.rows.map(r => ({\n index: r.index,\n cells: { ...r.cells },\n errors: [...r.errors],\n }))\n columnErrors.value = p.columnErrors\n}\n\nasync function onDownloadTemplate() {\n loading.value = true\n try {\n const blob = await props.api.downloadTemplate()\n triggerBlobDownload(blob, props.templateFileName ?? 'import-template.xlsx')\n } catch (e) {\n message.error(translateError(e))\n } finally {\n loading.value = false\n }\n}\n\nfunction onFileChange(list: UploadFileInfo[]) {\n // 只保留最后选中的一个 xlsx\n fileList.value = list.slice(-1)\n const f = list[list.length - 1]?.file\n file.value = f instanceof File ? f : null\n}\n\nfunction onFileRemove() {\n fileList.value = []\n file.value = null\n}\n\n/** ①→②:带文件预览(mapping 空 = 服务端自动匹配) */\nasync function goMapping() {\n if (!file.value) {\n message.warning(t('import.needFile'))\n return\n }\n loading.value = true\n try {\n const p = await props.api.preview(file.value)\n applyPreview(p)\n // 确保每个表头在 mapping 里有键(未匹配的给空串,便于 n-select 显示「不映射」)\n for (const header of p.headers) {\n if (!(header in mapping.value)) mapping.value[header] = ''\n }\n step.value = 2\n } catch (e) {\n message.error(translateError(e))\n } finally {\n loading.value = false\n }\n}\n\n/** ②→③:按用户调整后的映射重新预览 */\nasync function goPreview() {\n if (!file.value) return\n // 去掉「不映射」空串,只传有效映射\n const map: Record<string, string> = {}\n for (const [header, key] of Object.entries(mapping.value)) {\n if (key) map[header] = key\n }\n loading.value = true\n try {\n const p = await props.api.preview(file.value, map)\n applyPreview(p)\n step.value = 3\n } catch (e) {\n message.error(translateError(e))\n } finally {\n loading.value = false\n }\n}\n\nconst targetColumnOptions = computed(() => [\n { label: t('import.unmap'), value: '' },\n ...columns.value.map(c => ({\n label: c.required ? `${c.title} *` : c.title,\n value: c.key,\n })),\n])\n\nfunction cellError(row: ImportRow, key: string) {\n return row.errors.find(e => e.columnKey === key)\n}\n\nfunction setCell(row: ImportRow, key: string, value: string | null) {\n row.cells[key] = value\n // 就地改后清该列旧错误,等重验;否则红底会误导\n row.errors = row.errors.filter(e => e.columnKey !== key)\n}\n\nconst displayRows = computed(() =>\n onlyErrors.value ? rows.value.filter(r => hardErrorsOf(r).length > 0) : rows.value,\n)\n\nconst previewColumns = computed<SmartTableColumn<ImportRow>[]>(() => {\n const cols: SmartTableColumn<ImportRow>[] = [\n {\n title: '#',\n key: '_index',\n width: 56,\n fixed: 'left',\n render: r => r.index,\n },\n ]\n for (const col of columns.value) {\n cols.push({\n title: () => (col.required ? `${col.title} *` : col.title),\n key: col.key,\n minWidth: 120,\n ellipsis: { tooltip: false },\n render: row => {\n const err = cellError(row, col.key)\n // 「已存在」在跳过/覆盖策略下不算错:走警示底色,输入框也不置 error 态\n const soft = err !== undefined && !isHard(err)\n const val = row.cells[col.key] ?? null\n const editor = col.dictTypeCode\n ? h(DictSelect, {\n typeCode: col.dictTypeCode,\n value: val,\n clearable: !col.required,\n size: 'small',\n // 弹层不跟随触发器宽度:向导的列很窄(minWidth 120,实测触发器约 66px),\n // 跟随会把「启用」「停用」截成「启..」「停..」。普通表单里下拉够宽,\n // 跟随反而更整齐 —— 所以只在向导关掉,不动共用的 DictSelect。\n consistentMenuWidth: false,\n style: { width: '100%' },\n status: err && !soft ? 'error' : undefined,\n 'onUpdate:value': (v: string | null) => setCell(row, col.key, v),\n })\n : h(NInput, {\n value: val ?? '',\n size: 'small',\n status: err && !soft ? 'error' : undefined,\n onUpdateValue: (v: string) => setCell(row, col.key, v),\n })\n const cell = h(\n 'div',\n {\n class: !err\n ? 'import-cell'\n : soft\n ? 'import-cell import-cell--dup'\n : 'import-cell import-cell--error',\n },\n [editor],\n )\n if (!err) return cell\n return h(\n NTooltip,\n { trigger: 'hover' },\n {\n trigger: () => cell,\n default: () =>\n soft ? t(`import.dupHint.${strategy.value}`) : translateError(err.code),\n },\n )\n },\n })\n }\n cols.push({\n title: () => t('import.errors'),\n key: '_errors',\n width: 160,\n fixed: 'right',\n render: r => {\n if (r.errors.length === 0)\n return h(NTag, { size: 'small', type: 'success', bordered: false }, () => t('import.ok'))\n const hard = hardErrorsOf(r)\n // 只剩「已存在」:不是要用户改的错,给警示标签 +「将按策略处理」而非红色错误数\n if (hard.length === 0) {\n return h(\n NTooltip,\n { trigger: 'hover' },\n {\n trigger: () =>\n h(NTag, { size: 'small', type: 'warning', bordered: false }, () =>\n t('import.dupTag'),\n ),\n default: () => t(`import.dupHint.${strategy.value}`),\n },\n )\n }\n return h(\n NTooltip,\n { trigger: 'hover' },\n {\n trigger: () =>\n h(NTag, { size: 'small', type: 'error', bordered: false }, () =>\n t('import.errorCount', { n: hard.length }),\n ),\n default: () => hard.map(e => `${e.columnKey}: ${translateError(e.code)}`).join('\\n'),\n },\n )\n },\n })\n return cols\n})\n\nasync function revalidate() {\n // 变异判据:请求必须带 rows;空数组也是明确失败路径(服务端会返回 0 行)\n loading.value = true\n try {\n const p = await props.api.validate(rows.value)\n // 保留当前列定义(重验不回传 headers/mapping;columns 仍有)\n rows.value = p.rows.map(r => ({\n index: r.index,\n cells: { ...r.cells },\n errors: [...r.errors],\n }))\n columns.value = p.columns.length ? p.columns : columns.value\n // 用本地按策略算出的硬错误数,不用 p.errorRows —— 后端不知道当前策略,会把「已存在」也计进去\n message.success(t('import.revalidated', { errors: errorRows.value, total: p.total }))\n } catch (e) {\n message.error(translateError(e))\n } finally {\n loading.value = false\n }\n}\n\nasync function doCommit() {\n loading.value = true\n try {\n const result = await props.api.commit(rows.value, strategy.value)\n commitResult.value = result\n step.value = 4\n if (result.inserted + result.updated > 0) emit('done')\n } catch (e) {\n message.error(translateError(e))\n } finally {\n loading.value = false\n }\n}\n\n/** ④ 失败行接回 ③ 继续改 */\nfunction backToEditFailures() {\n if (!commitResult.value) return\n rows.value = commitResult.value.failures.map(r => ({\n index: r.index,\n cells: { ...r.cells },\n errors: [...r.errors],\n }))\n onlyErrors.value = true\n commitResult.value = null\n step.value = 3\n}\n\nasync function downloadErrorReport() {\n const source =\n step.value === 4 && commitResult.value\n ? commitResult.value.failures\n : rows.value.filter(r => r.errors.length > 0)\n if (source.length === 0) {\n message.warning(t('import.noErrorRows'))\n return\n }\n loading.value = true\n try {\n const blob = await props.api.errorReport(source)\n triggerBlobDownload(blob, props.errorReportFileName ?? 'import-errors.xlsx')\n } catch (e) {\n message.error(translateError(e))\n } finally {\n loading.value = false\n }\n}\n\nfunction close() {\n show.value = false\n}\n</script>\n\n<template>\n <n-modal\n v-model:show=\"show\"\n preset=\"card\"\n :title=\"props.title ?? t('import.wizardTitle')\"\n :style=\"{ width: 'min(1100px, 96vw)' }\"\n :mask-closable=\"false\"\n :closable=\"!loading\"\n :close-on-esc=\"!loading\"\n >\n <n-steps :current=\"step\" size=\"small\" class=\"import-steps\">\n <n-step :title=\"t('import.stepUpload')\" />\n <n-step :title=\"t('import.stepMapping')\" />\n <n-step :title=\"t('import.stepPreview')\" />\n <n-step :title=\"t('import.stepResult')\" />\n </n-steps>\n\n <!-- ① 上传 -->\n <div v-show=\"step === 1\" class=\"import-pane\">\n <n-space vertical :size=\"12\">\n <n-button secondary :loading=\"loading\" @click=\"onDownloadTemplate\">\n <template #icon><AppIcon icon=\"ph:download-simple\" :size=\"16\" /></template>\n {{ t('import.downloadTemplate') }}\n </n-button>\n <n-upload\n :file-list=\"fileList\"\n :max=\"1\"\n accept=\".xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\"\n :default-upload=\"false\"\n @update:file-list=\"onFileChange\"\n @remove=\"onFileRemove\"\n >\n <n-upload-dragger>\n <div class=\"import-upload-icon\">\n <AppIcon icon=\"ph:file-xls\" :size=\"40\" />\n </div>\n <n-text style=\"font-size: 16px\">{{ t('import.dropHint') }}</n-text>\n <n-text depth=\"3\" style=\"display: block; margin-top: 8px\">\n {{ t('import.dropSub') }}\n </n-text>\n </n-upload-dragger>\n </n-upload>\n </n-space>\n </div>\n\n <!-- ② 列映射 -->\n <div v-show=\"step === 2\" class=\"import-pane\">\n <n-alert v-if=\"columnErrors.length\" type=\"warning\" style=\"margin-bottom: 12px\">\n {{ columnErrors.map(e => `${e.columnKey}: ${translateError(e.code)}`).join('; ') }}\n </n-alert>\n <n-text depth=\"3\" style=\"display: block; margin-bottom: 12px\">\n {{ t('import.mappingHint') }}\n </n-text>\n <div class=\"import-mapping\">\n <div class=\"import-mapping-head\">\n <span>{{ t('import.fileHeader') }}</span>\n <span>{{ t('import.targetColumn') }}</span>\n </div>\n <div v-for=\"hdr in headers\" :key=\"hdr\" class=\"import-mapping-row\">\n <span class=\"import-mapping-header\" :title=\"hdr\">{{ hdr }}</span>\n <n-select\n v-model:value=\"mapping[hdr]\"\n :options=\"targetColumnOptions\"\n :consistent-menu-width=\"false\"\n size=\"small\"\n />\n </div>\n </div>\n </div>\n\n <!-- ③ 预览改错(SmartTable 静态数据模式;嵌在向导弹窗里,不套整页列表的工具栏 / 条件构造器标准) -->\n <div v-show=\"step === 3\" class=\"import-pane\">\n <n-space justify=\"space-between\" align=\"center\" style=\"margin-bottom: 12px\" wrap>\n <n-space align=\"center\">\n <n-text>\n {{ t('import.summary', { total: rows.length, errors: errorRows }) }}\n <template v-if=\"duplicateRows\">\n {{ t('import.summaryDup', { n: duplicateRows }) }}\n </template>\n </n-text>\n <n-switch v-model:value=\"onlyErrors\" size=\"small\">\n <template #checked>{{ t('import.onlyErrors') }}</template>\n <template #unchecked>{{ t('import.onlyErrors') }}</template>\n </n-switch>\n </n-space>\n <n-space>\n <n-button size=\"small\" :loading=\"loading\" @click=\"revalidate\">\n <template #icon><AppIcon icon=\"ph:arrows-clockwise\" :size=\"14\" /></template>\n {{ t('import.revalidate') }}\n </n-button>\n </n-space>\n </n-space>\n <SmartTable\n size=\"small\"\n :columns=\"previewColumns\"\n :data=\"displayRows\"\n :row-key=\"(r: ImportRow) => r.index\"\n :toolbar=\"false\"\n :max-height=\"420\"\n :scroll-x=\"Math.max(800, columns.length * 140 + 220)\"\n storage-key=\"import-preview\"\n />\n <div class=\"import-strategy\">\n <n-text strong style=\"margin-right: 12px\">{{ t('import.strategy') }}</n-text>\n <n-radio-group v-model:value=\"strategy\" name=\"dup-strategy\">\n <n-space>\n <n-radio v-for=\"option in strategyOptions\" :key=\"option.value\" :value=\"option.value\">\n {{ option.label() }}\n </n-radio>\n </n-space>\n </n-radio-group>\n </div>\n </div>\n\n <!-- ④ 结果 -->\n <div v-show=\"step === 4\" class=\"import-pane\">\n <n-alert\n v-if=\"commitResult\"\n :type=\"commitResult.failed > 0 ? 'warning' : 'success'\"\n :title=\"t('import.resultTitle')\"\n >\n <div>{{ t('import.resultTotal', { n: commitResult.total }) }}</div>\n <div>{{ t('import.resultInserted', { n: commitResult.inserted }) }}</div>\n <div>{{ t('import.resultUpdated', { n: commitResult.updated }) }}</div>\n <div>{{ t('import.resultSkipped', { n: commitResult.skipped }) }}</div>\n <div>{{ t('import.resultFailed', { n: commitResult.failed }) }}</div>\n </n-alert>\n <n-space style=\"margin-top: 16px\">\n <n-button\n v-if=\"commitResult && commitResult.failed > 0\"\n type=\"warning\"\n @click=\"backToEditFailures\"\n >\n {{ t('import.editFailures') }}\n </n-button>\n <n-button\n v-if=\"commitResult && commitResult.failed > 0\"\n secondary\n :loading=\"loading\"\n @click=\"downloadErrorReport\"\n >\n <template #icon><AppIcon icon=\"ph:download-simple\" :size=\"16\" /></template>\n {{ t('import.downloadErrorReport') }}\n </n-button>\n </n-space>\n </div>\n\n <template #footer>\n <n-space justify=\"end\">\n <n-button :disabled=\"loading\" @click=\"close\">\n {{ step === 4 ? t('common.close') : t('common.cancel') }}\n </n-button>\n <n-button v-if=\"step === 3\" secondary :disabled=\"loading\" @click=\"downloadErrorReport\">\n {{ t('import.downloadErrorReport') }}\n </n-button>\n <n-button v-if=\"step > 1 && step < 4\" :disabled=\"loading\" @click=\"step = step - 1\">\n {{ t('import.prev') }}\n </n-button>\n <n-button\n v-if=\"step === 1\"\n type=\"primary\"\n :loading=\"loading\"\n :disabled=\"!file\"\n @click=\"goMapping\"\n >\n {{ t('import.next') }}\n </n-button>\n <n-button v-if=\"step === 2\" type=\"primary\" :loading=\"loading\" @click=\"goPreview\">\n {{ t('import.next') }}\n </n-button>\n <n-button v-if=\"step === 3\" type=\"primary\" :loading=\"loading\" @click=\"doCommit\">\n {{ t('import.commit') }}\n </n-button>\n </n-space>\n </template>\n </n-modal>\n</template>\n\n<style scoped>\n.import-steps {\n margin-bottom: 20px;\n}\n.import-pane {\n min-height: 200px;\n}\n.import-upload-icon {\n margin-bottom: 12px;\n color: var(--n-text-color-3);\n}\n.import-mapping-head,\n.import-mapping-row {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 12px;\n align-items: center;\n}\n.import-mapping-head {\n font-weight: 600;\n font-size: 13px;\n margin-bottom: 8px;\n color: var(--n-text-color-2);\n}\n.import-mapping-row {\n margin-bottom: 8px;\n}\n.import-mapping-header {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 13px;\n}\n.import-strategy {\n margin-top: 16px;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n}\n:deep(.import-cell) {\n padding: 2px;\n border-radius: 4px;\n}\n:deep(.import-cell--error) {\n /* 用仓库自己的语义令牌(亮/暗都有定义)。别写 --n-error-color:那是 naive 组件内部的变量,\n 在这层普通 div 上未定义,整条 color-mix() 会被判无效丢弃 —— 红底静默不渲染,而 tsc/lint/build 全绿。 */\n background: var(--color-danger-bg);\n}\n:deep(.import-cell--dup) {\n /* 「库里已存在」在跳过/覆盖策略下会被正常处理,用警示色而非错误红——同上,只用语义令牌 */\n background: var(--color-warning-bg);\n}\n</style>\n"],"names":["show","_useModel","__props","props","emit","__emit","t","useI18n","message","useMessage","step","ref","loading","file","fileList","headers","shallowRef","mapping","columns","rows","columnErrors","onlyErrors","strategy","DuplicateStrategy","commitResult","strategyLabels","strategyOptions","computed","value","isHard","isHardError","hardErrorsOf","r","hardErrors","errorRows","duplicateRows","isDuplicateOnly","reset","o","_a","watch","v","applyPreview","p","onDownloadTemplate","blob","triggerBlobDownload","translateError","onFileChange","list","f","onFileRemove","goMapping","header","goPreview","map","key","e","targetColumnOptions","c","cellError","row","setCell","displayRows","previewColumns","cols","col","err","soft","val","editor","h","DictSelect","NInput","cell","NTooltip","NTag","hard","revalidate","doCommit","result","backToEditFailures","downloadErrorReport","source","close","_createBlock","_unref","NModal","$event","_createVNode","NSpace","NButton","_cache","NSteps","NStep","_withDirectives","_createElementVNode","_hoisted_1","AppIcon","_createTextVNode","NUpload","NUploadDragger","_hoisted_2","NText","_hoisted_3","NAlert","_toDisplayString","_hoisted_4","_hoisted_5","_createElementBlock","_Fragment","_renderList","hdr","_hoisted_6","NSelect","_hoisted_7","NSwitch","SmartTable","_hoisted_8","NRadioGroup","option","NRadio","_hoisted_9"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAqDA,UAAMA,IAAOC,GAAoBC,GAAC,MAA0B,GAEtDC,IAAQD,GAmBRE,KAAOC,IAKP,EAAE,GAAAC,EAAA,IAAMC,GAAA,GACRC,IAAUC,GAAA,GAGVC,IAAOC,EAAI,CAAC,GACZC,IAAUD,EAAI,EAAK,GACnBE,IAAOF,EAAiB,IAAI,GAC5BG,IAAWH,EAAsB,EAAE,GACnCI,IAAUC,GAAqB,EAAE,GAEjCC,IAAUN,EAA4B,EAAE,GACxCO,IAAUF,GAA2B,EAAE,GAGvCG,IAAOR,EAAiB,EAAE,GAC1BS,IAAeT,EAAmC,EAAE,GACpDU,IAAaV,EAAI,EAAK,GACtBW,IAAWX,EAAoBY,EAAkB,IAAI,GACrDC,IAAeb,EAA+B,IAAI,GAGlDc,KAAuD;AAAA,MAC3D,CAACF,EAAkB,IAAI,GAAG,MAAMjB,EAAE,qBAAqB;AAAA,MACvD,CAACiB,EAAkB,SAAS,GAAG,MAAMjB,EAAE,0BAA0B;AAAA,MACjE,CAACiB,EAAkB,KAAK,GAAG,MAAMjB,EAAE,sBAAsB;AAAA,IAAA,GAGrDoB,IAAkBC;AAAA,MAAS,OAE7BxB,EAAM,cAAc;AAAA,QAClBoB,EAAkB;AAAA,QAClBA,EAAkB;AAAA,QAClBA,EAAkB;AAAA,MAAA,GAEpB,IAAI,CAAAK,OAAU,EAAE,OAAAA,GAAO,OAAOH,GAAeG,CAAK,IAAI;AAAA,IAAA,GAIpDC,KAAS,CAAC,MAAiBC,GAAY,GAAGR,EAAS,KAAK,GACxDS,IAAe,CAACC,MAAiBC,GAAWD,GAAGV,EAAS,KAAK,GAE7DY,IAAYP,EAAS,MAAMR,EAAK,MAAM,OAAO,CAAAa,MAAKD,EAAaC,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,GAEpFG,IAAgBR;AAAA,MACpB,MAAMR,EAAK,MAAM,OAAO,CAAAa,MAAKI,GAAgBJ,GAAGV,EAAS,KAAK,CAAC,EAAE;AAAA,IAAA;AAGnE,aAASe,KAAQ;;AACf,MAAA3B,EAAK,QAAQ,GACbE,EAAQ,QAAQ,IAChBC,EAAK,QAAQ,MACbC,EAAS,QAAQ,CAAA,GACjBC,EAAQ,QAAQ,CAAA,GAChBE,EAAQ,QAAQ,CAAA,GAChBC,EAAQ,QAAQ,CAAA,GAChBC,EAAK,QAAQ,CAAA,GACbC,EAAa,QAAQ,CAAA,GACrBC,EAAW,QAAQ,IAEnBC,EAAS,QAAQI,EAAgB,MAAM,KAAK,CAAAY,MAAKA,EAAE,UAAUf,EAAkB,IAAI,IAC/EA,EAAkB,SACjBgB,IAAAb,EAAgB,MAAM,CAAC,MAAvB,gBAAAa,EAA0B,UAAShB,EAAkB,MAC1DC,EAAa,QAAQ;AAAA,IACvB;AAEA,IAAAgB,GAAMxC,GAAM,CAAAyC,MAAK;AACf,MAAIA,KAAGJ,GAAA;AAAA,IACT,CAAC;AAED,aAASK,EAAaC,GAAkB;AACtC,MAAA5B,EAAQ,QAAQ,CAAC,GAAG4B,EAAE,OAAO,GAC7B1B,EAAQ,QAAQ,EAAE,GAAG0B,EAAE,QAAA,GACvBzB,EAAQ,QAAQyB,EAAE,SAClBxB,EAAK,QAAQwB,EAAE,KAAK,IAAI,CAAAX,OAAM;AAAA,QAC5B,OAAOA,EAAE;AAAA,QACT,OAAO,EAAE,GAAGA,EAAE,MAAA;AAAA,QACd,QAAQ,CAAC,GAAGA,EAAE,MAAM;AAAA,MAAA,EACpB,GACFZ,EAAa,QAAQuB,EAAE;AAAA,IACzB;AAEA,mBAAeC,KAAqB;AAClC,MAAAhC,EAAQ,QAAQ;AAChB,UAAI;AACF,cAAMiC,IAAO,MAAM1C,EAAM,IAAI,iBAAA;AAC7B,QAAA2C,GAAoBD,GAAM1C,EAAM,oBAAoB,sBAAsB;AAAA,MAC5E,SAAS,GAAG;AACV,QAAAK,EAAQ,MAAMuC,EAAe,CAAC,CAAC;AAAA,MACjC,UAAA;AACE,QAAAnC,EAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;AAEA,aAASoC,GAAaC,GAAwB;;AAE5C,MAAAnC,EAAS,QAAQmC,EAAK,MAAM,EAAE;AAC9B,YAAMC,KAAIX,IAAAU,EAAKA,EAAK,SAAS,CAAC,MAApB,gBAAAV,EAAuB;AACjC,MAAA1B,EAAK,QAAQqC,aAAa,OAAOA,IAAI;AAAA,IACvC;AAEA,aAASC,KAAe;AACtB,MAAArC,EAAS,QAAQ,CAAA,GACjBD,EAAK,QAAQ;AAAA,IACf;AAGA,mBAAeuC,KAAY;AACzB,UAAI,CAACvC,EAAK,OAAO;AACf,QAAAL,EAAQ,QAAQF,EAAE,iBAAiB,CAAC;AACpC;AAAA,MACF;AACA,MAAAM,EAAQ,QAAQ;AAChB,UAAI;AACF,cAAM+B,IAAI,MAAMxC,EAAM,IAAI,QAAQU,EAAK,KAAK;AAC5C,QAAA6B,EAAaC,CAAC;AAEd,mBAAWU,KAAUV,EAAE;AACrB,UAAMU,KAAUpC,EAAQ,UAAQA,EAAQ,MAAMoC,CAAM,IAAI;AAE1D,QAAA3C,EAAK,QAAQ;AAAA,MACf,SAAS,GAAG;AACV,QAAAF,EAAQ,MAAMuC,EAAe,CAAC,CAAC;AAAA,MACjC,UAAA;AACE,QAAAnC,EAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;AAGA,mBAAe0C,KAAY;AACzB,UAAI,CAACzC,EAAK,MAAO;AAEjB,YAAM0C,IAA8B,CAAA;AACpC,iBAAW,CAACF,GAAQG,CAAG,KAAK,OAAO,QAAQvC,EAAQ,KAAK;AACtD,QAAIuC,MAAKD,EAAIF,CAAM,IAAIG;AAEzB,MAAA5C,EAAQ,QAAQ;AAChB,UAAI;AACF,cAAM+B,IAAI,MAAMxC,EAAM,IAAI,QAAQU,EAAK,OAAO0C,CAAG;AACjD,QAAAb,EAAaC,CAAC,GACdjC,EAAK,QAAQ;AAAA,MACf,SAAS+C,GAAG;AACV,QAAAjD,EAAQ,MAAMuC,EAAeU,CAAC,CAAC;AAAA,MACjC,UAAA;AACE,QAAA7C,EAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;AAEA,UAAM8C,KAAsB/B,EAAS,MAAM;AAAA,MACzC,EAAE,OAAOrB,EAAE,cAAc,GAAG,OAAO,GAAA;AAAA,MACnC,GAAGY,EAAQ,MAAM,IAAI,CAAAyC,OAAM;AAAA,QACzB,OAAOA,EAAE,WAAW,GAAGA,EAAE,KAAK,OAAOA,EAAE;AAAA,QACvC,OAAOA,EAAE;AAAA,MAAA,EACT;AAAA,IAAA,CACH;AAED,aAASC,GAAUC,GAAgBL,GAAa;AAC9C,aAAOK,EAAI,OAAO,KAAK,CAAAJ,MAAKA,EAAE,cAAcD,CAAG;AAAA,IACjD;AAEA,aAASM,EAAQD,GAAgBL,GAAa5B,GAAsB;AAClE,MAAAiC,EAAI,MAAML,CAAG,IAAI5B,GAEjBiC,EAAI,SAASA,EAAI,OAAO,OAAO,CAAAJ,MAAKA,EAAE,cAAcD,CAAG;AAAA,IACzD;AAEA,UAAMO,KAAcpC;AAAA,MAAS,MAC3BN,EAAW,QAAQF,EAAK,MAAM,OAAO,CAAAa,MAAKD,EAAaC,CAAC,EAAE,SAAS,CAAC,IAAIb,EAAK;AAAA,IAAA,GAGzE6C,KAAiBrC,EAAwC,MAAM;AACnE,YAAMsC,IAAsC;AAAA,QAC1C;AAAA,UACE,OAAO;AAAA,UACP,KAAK;AAAA,UACL,OAAO;AAAA,UACP,OAAO;AAAA,UACP,QAAQ,OAAKjC,EAAE;AAAA,QAAA;AAAA,MACjB;AAEF,iBAAWkC,KAAOhD,EAAQ;AACxB,QAAA+C,EAAK,KAAK;AAAA,UACR,OAAO,MAAOC,EAAI,WAAW,GAAGA,EAAI,KAAK,OAAOA,EAAI;AAAA,UACpD,KAAKA,EAAI;AAAA,UACT,UAAU;AAAA,UACV,UAAU,EAAE,SAAS,GAAA;AAAA,UACrB,QAAQ,CAAAL,MAAO;AACb,kBAAMM,IAAMP,GAAUC,GAAKK,EAAI,GAAG,GAE5BE,IAAOD,MAAQ,UAAa,CAACtC,GAAOsC,CAAG,GACvCE,KAAMR,EAAI,MAAMK,EAAI,GAAG,KAAK,MAC5BI,KAASJ,EAAI,eACfK,EAAEC,IAAY;AAAA,cACZ,UAAUN,EAAI;AAAA,cACd,OAAOG;AAAA,cACP,WAAW,CAACH,EAAI;AAAA,cAChB,MAAM;AAAA;AAAA;AAAA;AAAA,cAIN,qBAAqB;AAAA,cACrB,OAAO,EAAE,OAAO,OAAA;AAAA,cAChB,QAAQC,KAAO,CAACC,IAAO,UAAU;AAAA,cACjC,kBAAkB,CAAC3B,MAAqBqB,EAAQD,GAAKK,EAAI,KAAKzB,CAAC;AAAA,YAAA,CAChE,IACD8B,EAAEE,IAAQ;AAAA,cACR,OAAOJ,MAAO;AAAA,cACd,MAAM;AAAA,cACN,QAAQF,KAAO,CAACC,IAAO,UAAU;AAAA,cACjC,eAAe,CAAC3B,MAAcqB,EAAQD,GAAKK,EAAI,KAAKzB,CAAC;AAAA,YAAA,CACtD,GACCiC,KAAOH;AAAA,cACX;AAAA,cACA;AAAA,gBACE,OAAQJ,IAEJC,IACE,iCACA,mCAHF;AAAA,cAGE;AAAA,cAER,CAACE,EAAM;AAAA,YAAA;AAET,mBAAKH,IACEI;AAAA,cACLI;AAAA,cACA,EAAE,SAAS,QAAA;AAAA,cACX;AAAA,gBACE,SAAS,MAAMD;AAAA,gBACf,SAAS,MACPN,IAAO9D,EAAE,kBAAkBgB,EAAS,KAAK,EAAE,IAAIyB,EAAeoB,EAAI,IAAI;AAAA,cAAA;AAAA,YAC1E,IAReO;AAAA,UAUnB;AAAA,QAAA,CACD;AAEH,aAAAT,EAAK,KAAK;AAAA,QACR,OAAO,MAAM3D,EAAE,eAAe;AAAA,QAC9B,KAAK;AAAA,QACL,OAAO;AAAA,QACP,OAAO;AAAA,QACP,QAAQ,CAAA0B,MAAK;AACX,cAAIA,EAAE,OAAO,WAAW;AACtB,mBAAOuC,EAAEK,GAAM,EAAE,MAAM,SAAS,MAAM,WAAW,UAAU,GAAA,GAAS,MAAMtE,EAAE,WAAW,CAAC;AAC1F,gBAAMuE,IAAO9C,EAAaC,CAAC;AAE3B,iBAAI6C,EAAK,WAAW,IACXN;AAAA,YACLI;AAAA,YACA,EAAE,SAAS,QAAA;AAAA,YACX;AAAA,cACE,SAAS,MACPJ;AAAA,gBAAEK;AAAA,gBAAM,EAAE,MAAM,SAAS,MAAM,WAAW,UAAU,GAAA;AAAA,gBAAS,MAC3DtE,EAAE,eAAe;AAAA,cAAA;AAAA,cAErB,SAAS,MAAMA,EAAE,kBAAkBgB,EAAS,KAAK,EAAE;AAAA,YAAA;AAAA,UACrD,IAGGiD;AAAA,YACLI;AAAA,YACA,EAAE,SAAS,QAAA;AAAA,YACX;AAAA,cACE,SAAS,MACPJ;AAAA,gBAAEK;AAAA,gBAAM,EAAE,MAAM,SAAS,MAAM,SAAS,UAAU,GAAA;AAAA,gBAAS,MACzDtE,EAAE,qBAAqB,EAAE,GAAGuE,EAAK,QAAQ;AAAA,cAAA;AAAA,cAE7C,SAAS,MAAMA,EAAK,IAAI,CAAApB,MAAK,GAAGA,EAAE,SAAS,KAAKV,EAAeU,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK;AAAA,CAAI;AAAA,YAAA;AAAA,UACrF;AAAA,QAEJ;AAAA,MAAA,CACD,GACMQ;AAAA,IACT,CAAC;AAED,mBAAea,KAAa;AAE1B,MAAAlE,EAAQ,QAAQ;AAChB,UAAI;AACF,cAAM+B,IAAI,MAAMxC,EAAM,IAAI,SAASgB,EAAK,KAAK;AAE7C,QAAAA,EAAK,QAAQwB,EAAE,KAAK,IAAI,CAAAX,OAAM;AAAA,UAC5B,OAAOA,EAAE;AAAA,UACT,OAAO,EAAE,GAAGA,EAAE,MAAA;AAAA,UACd,QAAQ,CAAC,GAAGA,EAAE,MAAM;AAAA,QAAA,EACpB,GACFd,EAAQ,QAAQyB,EAAE,QAAQ,SAASA,EAAE,UAAUzB,EAAQ,OAEvDV,EAAQ,QAAQF,EAAE,sBAAsB,EAAE,QAAQ4B,EAAU,OAAO,OAAOS,EAAE,MAAA,CAAO,CAAC;AAAA,MACtF,SAAS,GAAG;AACV,QAAAnC,EAAQ,MAAMuC,EAAe,CAAC,CAAC;AAAA,MACjC,UAAA;AACE,QAAAnC,EAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;AAEA,mBAAemE,KAAW;AACxB,MAAAnE,EAAQ,QAAQ;AAChB,UAAI;AACF,cAAMoE,IAAS,MAAM7E,EAAM,IAAI,OAAOgB,EAAK,OAAOG,EAAS,KAAK;AAChE,QAAAE,EAAa,QAAQwD,GACrBtE,EAAK,QAAQ,GACTsE,EAAO,WAAWA,EAAO,UAAU,QAAQ,MAAM;AAAA,MACvD,SAAS,GAAG;AACV,QAAAxE,EAAQ,MAAMuC,EAAe,CAAC,CAAC;AAAA,MACjC,UAAA;AACE,QAAAnC,EAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;AAGA,aAASqE,KAAqB;AAC5B,MAAKzD,EAAa,UAClBL,EAAK,QAAQK,EAAa,MAAM,SAAS,IAAI,CAAAQ,OAAM;AAAA,QACjD,OAAOA,EAAE;AAAA,QACT,OAAO,EAAE,GAAGA,EAAE,MAAA;AAAA,QACd,QAAQ,CAAC,GAAGA,EAAE,MAAM;AAAA,MAAA,EACpB,GACFX,EAAW,QAAQ,IACnBG,EAAa,QAAQ,MACrBd,EAAK,QAAQ;AAAA,IACf;AAEA,mBAAewE,KAAsB;AACnC,YAAMC,IACJzE,EAAK,UAAU,KAAKc,EAAa,QAC7BA,EAAa,MAAM,WACnBL,EAAK,MAAM,OAAO,CAAAa,MAAKA,EAAE,OAAO,SAAS,CAAC;AAChD,UAAImD,EAAO,WAAW,GAAG;AACvB,QAAA3E,EAAQ,QAAQF,EAAE,oBAAoB,CAAC;AACvC;AAAA,MACF;AACA,MAAAM,EAAQ,QAAQ;AAChB,UAAI;AACF,cAAMiC,IAAO,MAAM1C,EAAM,IAAI,YAAYgF,CAAM;AAC/C,QAAArC,GAAoBD,GAAM1C,EAAM,uBAAuB,oBAAoB;AAAA,MAC7E,SAASsD,GAAG;AACV,QAAAjD,EAAQ,MAAMuC,EAAeU,CAAC,CAAC;AAAA,MACjC,UAAA;AACE,QAAA7C,EAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;AAEA,aAASwE,KAAQ;AACf,MAAApF,EAAK,QAAQ;AAAA,IACf;2BAIEqF,EA8KUC,EAAAC,EAAA,GAAA;AAAA,MA7KA,MAAMvF,EAAA;AAAA,8CAAAA,EAAI,QAAAwF;AAAA,MAClB,QAAO;AAAA,MACN,OAAOrF,EAAM,SAASmF,EAAAhF,CAAA,EAAC,oBAAA;AAAA,MACvB,OAAO,EAAA,OAAA,oBAAA;AAAA,MACP,iBAAe;AAAA,MACf,WAAWM,EAAA;AAAA,MACX,iBAAeA,EAAA;AAAA,IAAA;MA2IL,UACT,MAyBU;AAAA,QAzBV6E,EAyBUH,EAAAI,CAAA,GAAA,EAzBD,SAAQ,SAAK;AAAA,qBACpB,MAEW;AAAA,YAFXD,EAEWH,EAAAK,CAAA,GAAA;AAAA,cAFA,UAAU/E,EAAA;AAAA,cAAU,SAAOwE;AAAA,YAAA;yBACpC,MAAyD;AAAA,oBAAtD1E,EAAA,UAAI,IAAS4E,EAAAhF,CAAA,EAAC,cAAA,IAAmBgF,EAAAhF,CAAA,EAAC,eAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;YAEvBI,EAAA,UAAI,UAApB2E,EAEWC,EAAAK,CAAA,GAAA;AAAA;cAFiB,WAAA;AAAA,cAAW,UAAU/E,EAAA;AAAA,cAAU,SAAOsE;AAAA,YAAA;yBAChE,MAAqC;AAAA,oBAAlCI,EAAAhF,CAAA,EAAC,4BAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;YAEUI,EAAA,aAAYA,EAAA,QAAI,UAAhC2E,EAEWC,EAAAK,CAAA,GAAA;AAAA;cAF4B,UAAU/E,EAAA;AAAA,cAAU,SAAKgF,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAJ,MAAE9E,EAAA,QAAOA,EAAA,QAAI;AAAA,YAAA;yBAC3E,MAAsB;AAAA,oBAAnB4E,EAAAhF,CAAA,EAAC,aAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;YAGEI,EAAA,UAAI,UADZ2E,EAQWC,EAAAK,CAAA,GAAA;AAAA;cANT,MAAK;AAAA,cACJ,SAAS/E,EAAA;AAAA,cACT,WAAWC,EAAA;AAAA,cACX,SAAOuC;AAAA,YAAA;yBAER,MAAsB;AAAA,oBAAnBkC,EAAAhF,CAAA,EAAC,aAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;YAEUI,EAAA,UAAI,UAApB2E,EAEWC,EAAAK,CAAA,GAAA;AAAA;cAFiB,MAAK;AAAA,cAAW,SAAS/E,EAAA;AAAA,cAAU,SAAO0C;AAAA,YAAA;yBACpE,MAAsB;AAAA,oBAAnBgC,EAAAhF,CAAA,EAAC,aAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;YAEUI,EAAA,UAAI,UAApB2E,EAEWC,EAAAK,CAAA,GAAA;AAAA;cAFiB,MAAK;AAAA,cAAW,SAAS/E,EAAA;AAAA,cAAU,SAAOmE;AAAA,YAAA;yBACpE,MAAwB;AAAA,oBAArBO,EAAAhF,CAAA,EAAC,eAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;;;;;iBAjKV,MAKU;AAAA,QALVmF,EAKUH,EAAAO,EAAA,GAAA;AAAA,UALA,SAASnF,EAAA;AAAA,UAAM,MAAK;AAAA,UAAQ,OAAM;AAAA,QAAA;qBAC1C,MAA0C;AAAA,YAA1C+E,EAA0CH,EAAAQ,CAAA,GAAA;AAAA,cAAjC,OAAOR,EAAAhF,CAAA,EAAC,mBAAA;AAAA,YAAA;YACjBmF,EAA2CH,EAAAQ,CAAA,GAAA;AAAA,cAAlC,OAAOR,EAAAhF,CAAA,EAAC,oBAAA;AAAA,YAAA;YACjBmF,EAA2CH,EAAAQ,CAAA,GAAA;AAAA,cAAlC,OAAOR,EAAAhF,CAAA,EAAC,oBAAA;AAAA,YAAA;YACjBmF,EAA0CH,EAAAQ,CAAA,GAAA;AAAA,cAAjC,OAAOR,EAAAhF,CAAA,EAAC,mBAAA;AAAA,YAAA;;;;QAInByF,EAAAC,EAyBM,OAzBNC,IAyBM;AAAA,UAxBJR,EAuBUH,EAAAI,CAAA,GAAA;AAAA,YAvBD,UAAA;AAAA,YAAU,MAAM;AAAA,UAAA;uBACvB,MAGW;AAAA,cAHXD,EAGWH,EAAAK,CAAA,GAAA;AAAA,gBAHD,WAAA;AAAA,gBAAW,SAAS/E,EAAA;AAAA,gBAAU,SAAOgC;AAAA,cAAA;gBAClC,QAAK,MAAgD;AAAA,kBAAhD6C,EAAgDS,GAAA;AAAA,oBAAvC,MAAK;AAAA,oBAAsB,MAAM;AAAA,kBAAA;;2BAAiB,MAC3E;AAAA,kBAD2EC,EAAA,QACxEb,EAAAhF,CAAA,EAAC,yBAAA,CAAA,GAAA,CAAA;AAAA,gBAAA;;;cAENmF,EAiBWH,EAAAc,EAAA,GAAA;AAAA,gBAhBR,aAAWtF,EAAA;AAAA,gBACX,KAAK;AAAA,gBACN,QAAO;AAAA,gBACN,kBAAgB;AAAA,gBAChB,qBAAkBkC;AAAA,gBAClB,UAAQG;AAAA,cAAA;2BAET,MAQmB;AAAA,kBARnBsC,EAQmBH,EAAAe,EAAA,GAAA,MAAA;AAAA,+BAPjB,MAEM;AAAA,sBAFNL,EAEM,OAFNM,IAEM;AAAA,wBADJb,EAAyCS,GAAA;AAAA,0BAAhC,MAAK;AAAA,0BAAe,MAAM;AAAA,wBAAA;;sBAErCT,EAAmEH,EAAAiB,CAAA,GAAA,EAA3D,OAAA,EAAA,aAAA,OAAA,KAAuB;AAAA,mCAAC,MAA0B;AAAA,8BAAvBjB,EAAAhF,CAAA,EAAC,iBAAA,CAAA,GAAA,CAAA;AAAA,wBAAA;;;sBACpCmF,EAESH,EAAAiB,CAAA,GAAA;AAAA,wBAFD,OAAM;AAAA,wBAAI,OAAA,EAAA,SAAA,SAAA,cAAA,MAAA;AAAA,sBAAA;mCAChB,MAAyB;AAAA,8BAAtBjB,EAAAhF,CAAA,EAAC,gBAAA,CAAA,GAAA,CAAA;AAAA,wBAAA;;;;;;;;;;;;;cApBDI,EAAA,UAAI,CAAA;AAAA,QAAA;QA4BjBqF,EAAAC,EAsBM,OAtBNQ,IAsBM;AAAA,UArBWpF,EAAA,MAAa,eAA5BiE,EAEUC,EAAAmB,EAAA,GAAA;AAAA;YAF0B,MAAK;AAAA,YAAU,OAAA,EAAA,iBAAA,OAAA;AAAA,UAAA;uBACjD,MAAmF;AAAA,cAAhFN,EAAAO,EAAAtF,EAAA,MAAa,IAAI,CAAAqC,SAAQA,EAAE,SAAS,KAAK6B,KAAe7B,EAAE,IAAI,KAAK,KAAI,IAAA,CAAA,GAAA,CAAA;AAAA,YAAA;;;UAE5EgC,EAESH,EAAAiB,CAAA,GAAA;AAAA,YAFD,OAAM;AAAA,YAAI,OAAA,EAAA,SAAA,SAAA,iBAAA,OAAA;AAAA,UAAA;uBAChB,MAA6B;AAAA,kBAA1BjB,EAAAhF,CAAA,EAAC,oBAAA,CAAA,GAAA,CAAA;AAAA,YAAA;;;UAEN0F,EAcM,OAdNW,IAcM;AAAA,YAbJX,EAGM,OAHNY,IAGM;AAAA,cAFJZ,EAAyC,gBAAhCV,EAAAhF,CAAA,EAAC,mBAAA,CAAA,GAAA,CAAA;AAAA,cACV0F,EAA2C,gBAAlCV,EAAAhF,CAAA,EAAC,qBAAA,CAAA,GAAA,CAAA;AAAA,YAAA;oBAEZuG,EAQMC,GAAA,MAAAC,GARahG,EAAA,OAAO,CAAdiG,YAAZH,EAQM,OAAA;AAAA,cARuB,KAAKG;AAAA,cAAK,OAAM;AAAA,YAAA;cAC3ChB,EAAiE,QAAA;AAAA,gBAA3D,OAAM;AAAA,gBAAyB,OAAOgB;AAAA,cAAA,KAAQA,CAAG,GAAA,GAAAC,EAAA;AAAA,cACvDxB,EAKEH,EAAA4B,EAAA,GAAA;AAAA,gBAJQ,OAAOjG,EAAA,MAAQ+F,CAAG;AAAA,gBAAX,kBAAA,CAAAxB,MAAAvE,EAAA,MAAQ+F,CAAG,IAAAxB;AAAA,gBACzB,SAAS9B,GAAA;AAAA,gBACT,yBAAuB;AAAA,gBACxB,MAAK;AAAA,cAAA;;;;cAlBAhD,EAAA,UAAI,CAAA;AAAA,QAAA;QAyBjBqF,EAAAC,EAyCM,OAzCNmB,IAyCM;AAAA,UAxCJ1B,EAmBUH,EAAAI,CAAA,GAAA;AAAA,YAnBD,SAAQ;AAAA,YAAgB,OAAM;AAAA,YAAS,OAAA,EAAA,iBAAA,OAAA;AAAA,YAA4B,MAAA;AAAA,UAAA;uBAC1E,MAWU;AAAA,cAXVD,EAWUH,EAAAI,CAAA,GAAA,EAXD,OAAM,YAAQ;AAAA,2BACrB,MAKS;AAAA,kBALTD,EAKSH,EAAAiB,CAAA,GAAA,MAAA;AAAA,+BAJP,MAAoE;AAAA,sBAAjEJ,EAAAO,EAAApB,EAAAhF,CAAA,6BAA6Ba,EAAA,MAAK,QAAM,QAAUe,EAAA,MAAA,MAAe,KACpE,CAAA;AAAA,sBAAgBC,EAAA,cAAhB0E,EAEWC,GAAA,EAAA,KAAA,KAAA;AAAA,wBADNX,EAAAO,EAAApB,EAAAhF,CAAA,4BAA4B6B,EAAA,MAAA,CAAa,CAAA,GAAA,CAAA;AAAA,sBAAA;;;;kBAGhDsD,EAGWH,EAAA8B,EAAA,GAAA;AAAA,oBAHO,OAAO/F,EAAA;AAAA,6DAAAA,EAAU,QAAAmE;AAAA,oBAAE,MAAK;AAAA,kBAAA;oBAC7B,WAAQ,MAA4B;AAAA,0BAAzBF,EAAAhF,CAAA,EAAC,mBAAA,CAAA,GAAA,CAAA;AAAA,oBAAA;oBACZ,aAAU,MAA4B;AAAA,0BAAzBgF,EAAAhF,CAAA,EAAC,mBAAA,CAAA,GAAA,CAAA;AAAA,oBAAA;;;;;;cAG7BmF,EAKUH,EAAAI,CAAA,GAAA,MAAA;AAAA,2BAJR,MAGW;AAAA,kBAHXD,EAGWH,EAAAK,CAAA,GAAA;AAAA,oBAHD,MAAK;AAAA,oBAAS,SAAS/E,EAAA;AAAA,oBAAU,SAAOkE;AAAA,kBAAA;oBACrC,QAAK,MAAiD;AAAA,sBAAjDW,EAAiDS,GAAA;AAAA,wBAAxC,MAAK;AAAA,wBAAuB,MAAM;AAAA,sBAAA;;+BAAiB,MAC5E;AAAA,sBAD4EC,EAAA,QACzEb,EAAAhF,CAAA,EAAC,mBAAA,CAAA,GAAA,CAAA;AAAA,oBAAA;;;;;;;;;UAIVmF,EASEH,EAAA+B,EAAA,GAAA;AAAA,YARA,MAAK;AAAA,YACJ,SAASrD,GAAA;AAAA,YACT,MAAMD,GAAA;AAAA,YACN,WAAO,CAAG,MAAiB,EAAE;AAAA,YAC7B,SAAS;AAAA,YACT,cAAY;AAAA,YACZ,YAAU,KAAK,IAAG,KAAM7C,EAAA,MAAQ,SAAM,MAAA,GAAA;AAAA,YACvC,eAAY;AAAA,UAAA;UAEd8E,EASM,OATNsB,IASM;AAAA,YARJ7B,EAA6EH,EAAAiB,CAAA,GAAA;AAAA,cAArE,QAAA;AAAA,cAAO,OAAA,EAAA,gBAAA,OAAA;AAAA,YAAA;yBAA2B,MAA0B;AAAA,oBAAvBjB,EAAAhF,CAAA,EAAC,iBAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;YAC9CmF,EAMgBH,EAAAiC,EAAA,GAAA;AAAA,cANO,OAAOjG,EAAA;AAAA,uDAAAA,EAAQ,QAAAkE;AAAA,cAAE,MAAK;AAAA,YAAA;yBAC3C,MAIU;AAAA,gBAJVC,EAIUH,EAAAI,CAAA,GAAA,MAAA;AAAA,6BAHC,MAAiC;AAAA,4BAA1CmB,EAEUC,GAAA,MAAAC,GAFgBrF,EAAA,OAAe,CAAzB8F,YAAhBnC,EAEUC,EAAAmC,EAAA,GAAA;AAAA,sBAFkC,KAAKD,EAAO;AAAA,sBAAQ,OAAOA,EAAO;AAAA,oBAAA;iCAC5E,MAAoB;AAAA,wBAAjBrB,EAAAO,EAAAc,EAAO,MAAA,CAAK,GAAA,CAAA;AAAA,sBAAA;;;;;;;;;;;cApCZ9G,EAAA,UAAI,CAAA;AAAA,QAAA;QA4CjBqF,EAAAC,EA8BM,OA9BN0B,IA8BM;AAAA,UA5BIlG,EAAA,cADR6D,EAUUC,EAAAmB,EAAA,GAAA;AAAA;YARP,MAAMjF,EAAA,MAAa,SAAM,IAAA,YAAA;AAAA,YACzB,OAAO8D,EAAAhF,CAAA,EAAC,oBAAA;AAAA,UAAA;uBAET,MAAmE;AAAA,cAAnE0F,EAAmE,OAAA,MAAAU,EAA3DpB,EAAAhF,CAAA,EAAC,sBAAA,EAAA,GAA4BkB,EAAA,MAAa,MAAA,CAAK,CAAA,GAAA,CAAA;AAAA,cACvDwE,EAAyE,OAAA,MAAAU,EAAjEpB,EAAAhF,CAAA,EAAC,yBAAA,EAAA,GAA+BkB,EAAA,MAAa,SAAA,CAAQ,CAAA,GAAA,CAAA;AAAA,cAC7DwE,EAAuE,OAAA,MAAAU,EAA/DpB,EAAAhF,CAAA,EAAC,wBAAA,EAAA,GAA8BkB,EAAA,MAAa,QAAA,CAAO,CAAA,GAAA,CAAA;AAAA,cAC3DwE,EAAuE,OAAA,MAAAU,EAA/DpB,EAAAhF,CAAA,EAAC,wBAAA,EAAA,GAA8BkB,EAAA,MAAa,QAAA,CAAO,CAAA,GAAA,CAAA;AAAA,cAC3DwE,EAAqE,OAAA,MAAAU,EAA7DpB,EAAAhF,CAAA,EAAC,uBAAA,EAAA,GAA6BkB,EAAA,MAAa,OAAA,CAAM,CAAA,GAAA,CAAA;AAAA,YAAA;;;UAE3DiE,EAiBUH,EAAAI,CAAA,GAAA,EAjBD,OAAA,EAAA,cAAA,OAAA,KAAwB;AAAA,uBAC/B,MAMW;AAAA,cALHlE,EAAA,SAAgBA,EAAA,MAAa,SAAM,UAD3C6D,EAMWC,EAAAK,CAAA,GAAA;AAAA;gBAJT,MAAK;AAAA,gBACJ,SAAOV;AAAA,cAAA;2BAER,MAA8B;AAAA,sBAA3BK,EAAAhF,CAAA,EAAC,qBAAA,CAAA,GAAA,CAAA;AAAA,gBAAA;;;cAGEkB,EAAA,SAAgBA,EAAA,MAAa,SAAM,UAD3C6D,EAQWC,EAAAK,CAAA,GAAA;AAAA;gBANT,WAAA;AAAA,gBACC,SAAS/E,EAAA;AAAA,gBACT,SAAOsE;AAAA,cAAA;gBAEG,QAAK,MAAgD;AAAA,kBAAhDO,EAAgDS,GAAA;AAAA,oBAAvC,MAAK;AAAA,oBAAsB,MAAM;AAAA,kBAAA;;2BAAiB,MAC3E;AAAA,kBAD2EC,EAAA,QACxEb,EAAAhF,CAAA,EAAC,4BAAA,CAAA,GAAA,CAAA;AAAA,gBAAA;;;;;;;cA3BGI,EAAA,UAAI,CAAA;AAAA,QAAA;;;;;;"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import o from "./MenuSearch2.vue.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import r from "../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
-
const
|
|
4
|
+
const m = /* @__PURE__ */ r(o, [["__scopeId", "data-v-18182547"]]);
|
|
5
5
|
export {
|
|
6
|
-
|
|
6
|
+
m as default
|
|
7
7
|
};
|
|
8
8
|
//# sourceMappingURL=MenuSearch.vue.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { defineComponent as E, useModel as B, ref as v, computed as H, watch as y, nextTick as
|
|
2
|
-
import { useRouter as
|
|
1
|
+
import { defineComponent as E, useModel as B, ref as v, computed as H, watch as y, nextTick as I, openBlock as i, createBlock as d, unref as s, withCtx as M, createElementVNode as p, createVNode as m, createElementBlock as w, Fragment as S, renderList as T, normalizeClass as U, createCommentVNode as z, toDisplayString as C } from "vue";
|
|
2
|
+
import { useRouter as F } from "vue-router";
|
|
3
3
|
import { NModal as K, NInput as R, NScrollbar as V, NEmpty as $ } from "naive-ui";
|
|
4
4
|
import { Icon as q } from "@iconify/vue";
|
|
5
5
|
import A from "./AppIcon.vue.js";
|
|
@@ -8,10 +8,11 @@ import { useI18n as P } from "vue-i18n";
|
|
|
8
8
|
import { useMenuFlat as j } from "../composables/useMenuFlat.js";
|
|
9
9
|
import { translateMenuTitle as O } from "../locales/menuTitle.js";
|
|
10
10
|
import { isHttpUrl as G, isFullscreenPath as J } from "../utils/url.js";
|
|
11
|
-
|
|
11
|
+
import { lineIcon as Q } from "../utils/menuIcon.js";
|
|
12
|
+
const W = { class: "palette" }, X = { class: "search" }, Y = {
|
|
12
13
|
key: 0,
|
|
13
14
|
class: "list"
|
|
14
|
-
},
|
|
15
|
+
}, Z = ["onClick", "onMouseenter"], ee = ["innerHTML"], te = { class: "ipath" }, oe = { class: "hint" }, ve = /* @__PURE__ */ E({
|
|
15
16
|
__name: "MenuSearch",
|
|
16
17
|
props: {
|
|
17
18
|
show: { type: Boolean, default: !1 },
|
|
@@ -19,7 +20,7 @@ const Q = { class: "palette" }, W = { class: "search" }, X = {
|
|
|
19
20
|
},
|
|
20
21
|
emits: ["update:show"],
|
|
21
22
|
setup(L) {
|
|
22
|
-
const n = B(L, "show"), x =
|
|
23
|
+
const n = B(L, "show"), x = F(), { t: h } = P(), N = j(), u = v(""), r = v(0), _ = v();
|
|
23
24
|
function b(e) {
|
|
24
25
|
return O(e.title);
|
|
25
26
|
}
|
|
@@ -28,7 +29,7 @@ const Q = { class: "palette" }, W = { class: "search" }, X = {
|
|
|
28
29
|
return o ? e.filter((t) => t.display.toLowerCase().includes(o) || t.path.toLowerCase().includes(o)) : e;
|
|
29
30
|
});
|
|
30
31
|
y(c, () => r.value = 0), y(n, (e) => {
|
|
31
|
-
e && (u.value = "", r.value = 0,
|
|
32
|
+
e && (u.value = "", r.value = 0, I(() => {
|
|
32
33
|
var o;
|
|
33
34
|
return (o = _.value) == null ? void 0 : o.focus();
|
|
34
35
|
}));
|
|
@@ -62,8 +63,8 @@ const Q = { class: "palette" }, W = { class: "search" }, X = {
|
|
|
62
63
|
"transform-origin": "center"
|
|
63
64
|
}, {
|
|
64
65
|
default: M(() => [
|
|
65
|
-
p("div",
|
|
66
|
-
p("div",
|
|
66
|
+
p("div", W, [
|
|
67
|
+
p("div", X, [
|
|
67
68
|
m(s(q), {
|
|
68
69
|
icon: "ph:magnifying-glass",
|
|
69
70
|
width: 18,
|
|
@@ -81,25 +82,25 @@ const Q = { class: "palette" }, W = { class: "search" }, X = {
|
|
|
81
82
|
]),
|
|
82
83
|
m(s(V), { style: { "max-height": "52vh" } }, {
|
|
83
84
|
default: M(() => [
|
|
84
|
-
c.value.length ? (i(), w("div",
|
|
85
|
-
(i(!0), w(
|
|
85
|
+
c.value.length ? (i(), w("div", Y, [
|
|
86
|
+
(i(!0), w(S, null, T(c.value, (t, l) => (i(), w("div", {
|
|
86
87
|
key: t.path,
|
|
87
|
-
class:
|
|
88
|
+
class: U(["item", { active: l === r.value }]),
|
|
88
89
|
onClick: (a) => g(t),
|
|
89
90
|
onMouseenter: (a) => r.value = l
|
|
90
91
|
}, [
|
|
91
92
|
t.icon ? (i(), d(A, {
|
|
92
93
|
key: 0,
|
|
93
|
-
icon: t.icon,
|
|
94
|
+
icon: s(Q)(t.icon),
|
|
94
95
|
size: 18,
|
|
95
96
|
class: "iicon"
|
|
96
|
-
}, null, 8, ["icon"])) :
|
|
97
|
+
}, null, 8, ["icon"])) : z("", !0),
|
|
97
98
|
p("span", {
|
|
98
99
|
class: "ititle",
|
|
99
100
|
innerHTML: D(t.display)
|
|
100
|
-
}, null, 8,
|
|
101
|
-
p("span",
|
|
102
|
-
], 42,
|
|
101
|
+
}, null, 8, ee),
|
|
102
|
+
p("span", te, C(t.breadcrumb.join(" / ")), 1)
|
|
103
|
+
], 42, Z))), 128))
|
|
103
104
|
])) : (i(), d(s($), {
|
|
104
105
|
key: 1,
|
|
105
106
|
description: s(h)("settings.searchEmpty"),
|
|
@@ -108,7 +109,7 @@ const Q = { class: "palette" }, W = { class: "search" }, X = {
|
|
|
108
109
|
]),
|
|
109
110
|
_: 1
|
|
110
111
|
}),
|
|
111
|
-
p("div",
|
|
112
|
+
p("div", oe, C(s(h)("settings.searchHint")), 1)
|
|
112
113
|
])
|
|
113
114
|
]),
|
|
114
115
|
_: 1
|
|
@@ -116,6 +117,6 @@ const Q = { class: "palette" }, W = { class: "search" }, X = {
|
|
|
116
117
|
}
|
|
117
118
|
});
|
|
118
119
|
export {
|
|
119
|
-
|
|
120
|
+
ve as default
|
|
120
121
|
};
|
|
121
122
|
//# sourceMappingURL=MenuSearch2.vue.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MenuSearch2.vue.js","sources":["../../src/components/MenuSearch.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, nextTick, ref, watch } from 'vue'\nimport { useRouter } from 'vue-router'\nimport { NModal, NInput, NScrollbar, NEmpty } from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport AppIcon from '#/components/AppIcon.vue'\nimport { onKeyStroke } from '@vueuse/core'\nimport { useI18n } from 'vue-i18n'\nimport { useMenuFlat, type MenuLeaf } from '#/composables/useMenuFlat'\nimport { translateMenuTitle } from '#/locales/menuTitle'\nimport { isFullscreenPath, isHttpUrl } from '#/utils/url'\n\ntype Hit = MenuLeaf & { display: string }\n\nconst show = defineModel<boolean>('show', { default: false })\nconst router = useRouter()\nconst { t } = useI18n()\nconst leaves = useMenuFlat()\n\nconst q = ref('')\nconst cursor = ref(0)\nconst inputRef = ref<InstanceType<typeof NInput>>()\n\n// 标题翻译走单源(locales/menuTitle):侧栏 / 面包屑 / 多标签 / 浏览器标题必须同一条规则。\nfunction label(item: MenuLeaf) {\n return translateMenuTitle(item.title)\n}\n\nconst results = computed<Hit[]>(() => {\n const list: Hit[] = leaves.value.map(l => ({ ...l, display: label(l) }))\n const kw = q.value.trim().toLowerCase()\n if (!kw) return list\n return list.filter(l => l.display.toLowerCase().includes(kw) || l.path.toLowerCase().includes(kw))\n})\n\nwatch(results, () => (cursor.value = 0))\nwatch(show, v => {\n if (v) {\n q.value = ''\n cursor.value = 0\n nextTick(() => inputRef.value?.focus())\n }\n})\n\nfunction go(item?: Hit) {\n if (item) {\n // 外链与站内整屏页(/fullscreen/*,如大屏看板)一律新标签打开,与侧栏点击行为一致\n if (isHttpUrl(item.path) || isFullscreenPath(item.path))\n window.open(item.path, '_blank', 'noopener,noreferrer')\n else router.push(item.path)\n }\n show.value = false\n}\n\n// esc/highlight 产物走模板 v-html:必须先转义原文、再插 <mark>,顺序颠倒即 XSS。\nfunction esc(s: string) {\n return s.replace(\n /[&<>\"]/g,\n c => ({ '&': '&', '<': '<', '>': '>', '\"': '"' })[c] ?? c,\n )\n}\nfunction highlight(text: string) {\n const kw = q.value.trim()\n const safe = esc(text)\n if (!kw) return safe\n const k = esc(kw)\n const i = safe.toLowerCase().indexOf(k.toLowerCase())\n if (i === -1) return safe\n return (\n safe.slice(0, i) + '<mark>' + safe.slice(i, i + k.length) + '</mark>' + safe.slice(i + k.length)\n )\n}\n\n// 全局热键 Ctrl/Cmd+K 开关面板\nonKeyStroke('k', e => {\n if (e.ctrlKey || e.metaKey) {\n e.preventDefault()\n show.value = !show.value\n }\n})\nonKeyStroke('ArrowDown', e => {\n if (!show.value) return\n e.preventDefault()\n cursor.value = Math.min(cursor.value + 1, results.value.length - 1)\n})\nonKeyStroke('ArrowUp', e => {\n if (!show.value) return\n e.preventDefault()\n cursor.value = Math.max(cursor.value - 1, 0)\n})\nonKeyStroke('Enter', e => {\n if (!show.value) return\n e.preventDefault()\n go(results.value[cursor.value])\n})\n</script>\n\n<template>\n <n-modal v-model:show=\"show\" transform-origin=\"center\">\n <div class=\"palette\">\n <div class=\"search\">\n <Icon icon=\"ph:magnifying-glass\" :width=\"18\" class=\"sicon\" />\n <n-input\n ref=\"inputRef\"\n v-model:value=\"q\"\n :placeholder=\"t('settings.searchPlaceholder')\"\n :bordered=\"false\"\n size=\"large\"\n />\n </div>\n <n-scrollbar style=\"max-height: 52vh\">\n <div v-if=\"results.length\" class=\"list\">\n <div\n v-for=\"(item, i) in results\"\n :key=\"item.path\"\n class=\"item\"\n :class=\"{ active: i === cursor }\"\n @click=\"go(item)\"\n @mouseenter=\"cursor = i\"\n >\n <!-- 菜单图标来自库里配的名字,可能不在离线子集内 → 走 AppIcon 的懒加载兜底 -->\n <AppIcon v-if=\"item.icon\" :icon=\"item.icon\" :size=\"18\" class=\"iicon\" />\n <span class=\"ititle\" v-html=\"highlight(item.display)\" />\n <span class=\"ipath\">{{ item.breadcrumb.join(' / ') }}</span>\n </div>\n </div>\n <n-empty v-else :description=\"t('settings.searchEmpty')\" class=\"empty\" />\n </n-scrollbar>\n <div class=\"hint\">{{ t('settings.searchHint') }}</div>\n </div>\n </n-modal>\n</template>\n\n<style scoped>\n.palette {\n width: 560px;\n max-width: 92vw;\n background: var(--color-bg-container);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n box-shadow: var(--shadow-3);\n overflow: hidden;\n}\n.search {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 16px;\n border-bottom: 1px solid var(--color-border);\n}\n.sicon {\n color: var(--color-text-tertiary);\n flex-shrink: 0;\n}\n.list {\n padding: 8px;\n}\n.item {\n display: flex;\n align-items: center;\n gap: 10px;\n height: 44px;\n padding: 0 12px;\n border-radius: var(--radius-md);\n cursor: pointer;\n color: var(--color-text-primary);\n}\n.item.active {\n background: var(--color-primary-light);\n color: var(--color-primary);\n}\n.iicon {\n flex-shrink: 0;\n}\n.ititle {\n font-size: var(--font-size-md);\n}\n.ititle :deep(mark) {\n background: transparent;\n color: var(--color-primary);\n font-weight: 600;\n}\n.ipath {\n margin-left: auto;\n font-size: var(--font-size-sm);\n color: var(--color-text-tertiary);\n}\n.empty {\n padding: 32px 0;\n}\n.hint {\n padding: 8px 16px;\n border-top: 1px solid var(--color-border);\n font-size: var(--font-size-sm);\n color: var(--color-text-tertiary);\n}\n</style>\n"],"names":["show","_useModel","__props","router","useRouter","t","useI18n","leaves","useMenuFlat","q","ref","cursor","inputRef","label","item","translateMenuTitle","results","computed","list","l","kw","watch","v","nextTick","_a","go","isHttpUrl","isFullscreenPath","esc","s","c","highlight","text","safe","k","i","onKeyStroke","_createBlock","_unref","NModal","$event","_createElementVNode","_hoisted_1","_hoisted_2","_createVNode","Icon","NInput","NScrollbar","_openBlock","_createElementBlock","_hoisted_3","_Fragment","_renderList","_normalizeClass","AppIcon","_hoisted_6","_toDisplayString","NEmpty","_hoisted_7"],"mappings":"
|
|
1
|
+
{"version":3,"file":"MenuSearch2.vue.js","sources":["../../src/components/MenuSearch.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, nextTick, ref, watch } from 'vue'\nimport { useRouter } from 'vue-router'\nimport { NModal, NInput, NScrollbar, NEmpty } from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport AppIcon from '#/components/AppIcon.vue'\nimport { onKeyStroke } from '@vueuse/core'\nimport { useI18n } from 'vue-i18n'\nimport { useMenuFlat, type MenuLeaf } from '#/composables/useMenuFlat'\nimport { translateMenuTitle } from '#/locales/menuTitle'\nimport { isFullscreenPath, isHttpUrl } from '#/utils/url'\n\nimport { lineIcon } from '#/utils/menuIcon'\ntype Hit = MenuLeaf & { display: string }\n\nconst show = defineModel<boolean>('show', { default: false })\nconst router = useRouter()\nconst { t } = useI18n()\nconst leaves = useMenuFlat()\n\nconst q = ref('')\nconst cursor = ref(0)\nconst inputRef = ref<InstanceType<typeof NInput>>()\n\n// 标题翻译走单源(locales/menuTitle):侧栏 / 面包屑 / 多标签 / 浏览器标题必须同一条规则。\nfunction label(item: MenuLeaf) {\n return translateMenuTitle(item.title)\n}\n\nconst results = computed<Hit[]>(() => {\n const list: Hit[] = leaves.value.map(l => ({ ...l, display: label(l) }))\n const kw = q.value.trim().toLowerCase()\n if (!kw) return list\n return list.filter(l => l.display.toLowerCase().includes(kw) || l.path.toLowerCase().includes(kw))\n})\n\nwatch(results, () => (cursor.value = 0))\nwatch(show, v => {\n if (v) {\n q.value = ''\n cursor.value = 0\n nextTick(() => inputRef.value?.focus())\n }\n})\n\nfunction go(item?: Hit) {\n if (item) {\n // 外链与站内整屏页(/fullscreen/*,如大屏看板)一律新标签打开,与侧栏点击行为一致\n if (isHttpUrl(item.path) || isFullscreenPath(item.path))\n window.open(item.path, '_blank', 'noopener,noreferrer')\n else router.push(item.path)\n }\n show.value = false\n}\n\n// esc/highlight 产物走模板 v-html:必须先转义原文、再插 <mark>,顺序颠倒即 XSS。\nfunction esc(s: string) {\n return s.replace(\n /[&<>\"]/g,\n c => ({ '&': '&', '<': '<', '>': '>', '\"': '"' })[c] ?? c,\n )\n}\nfunction highlight(text: string) {\n const kw = q.value.trim()\n const safe = esc(text)\n if (!kw) return safe\n const k = esc(kw)\n const i = safe.toLowerCase().indexOf(k.toLowerCase())\n if (i === -1) return safe\n return (\n safe.slice(0, i) + '<mark>' + safe.slice(i, i + k.length) + '</mark>' + safe.slice(i + k.length)\n )\n}\n\n// 全局热键 Ctrl/Cmd+K 开关面板\nonKeyStroke('k', e => {\n if (e.ctrlKey || e.metaKey) {\n e.preventDefault()\n show.value = !show.value\n }\n})\nonKeyStroke('ArrowDown', e => {\n if (!show.value) return\n e.preventDefault()\n cursor.value = Math.min(cursor.value + 1, results.value.length - 1)\n})\nonKeyStroke('ArrowUp', e => {\n if (!show.value) return\n e.preventDefault()\n cursor.value = Math.max(cursor.value - 1, 0)\n})\nonKeyStroke('Enter', e => {\n if (!show.value) return\n e.preventDefault()\n go(results.value[cursor.value])\n})\n</script>\n\n<template>\n <n-modal v-model:show=\"show\" transform-origin=\"center\">\n <div class=\"palette\">\n <div class=\"search\">\n <Icon icon=\"ph:magnifying-glass\" :width=\"18\" class=\"sicon\" />\n <n-input\n ref=\"inputRef\"\n v-model:value=\"q\"\n :placeholder=\"t('settings.searchPlaceholder')\"\n :bordered=\"false\"\n size=\"large\"\n />\n </div>\n <n-scrollbar style=\"max-height: 52vh\">\n <div v-if=\"results.length\" class=\"list\">\n <div\n v-for=\"(item, i) in results\"\n :key=\"item.path\"\n class=\"item\"\n :class=\"{ active: i === cursor }\"\n @click=\"go(item)\"\n @mouseenter=\"cursor = i\"\n >\n <!-- 菜单图标来自库里配的名字,可能不在离线子集内 → 走 AppIcon 的懒加载兜底 -->\n <AppIcon v-if=\"item.icon\" :icon=\"lineIcon(item.icon)\" :size=\"18\" class=\"iicon\" />\n <span class=\"ititle\" v-html=\"highlight(item.display)\" />\n <span class=\"ipath\">{{ item.breadcrumb.join(' / ') }}</span>\n </div>\n </div>\n <n-empty v-else :description=\"t('settings.searchEmpty')\" class=\"empty\" />\n </n-scrollbar>\n <div class=\"hint\">{{ t('settings.searchHint') }}</div>\n </div>\n </n-modal>\n</template>\n\n<style scoped>\n.palette {\n width: 560px;\n max-width: 92vw;\n background: var(--color-bg-container);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n box-shadow: var(--shadow-3);\n overflow: hidden;\n}\n.search {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 16px;\n border-bottom: 1px solid var(--color-border);\n}\n.sicon {\n color: var(--color-text-tertiary);\n flex-shrink: 0;\n}\n.list {\n padding: 8px;\n}\n.item {\n display: flex;\n align-items: center;\n gap: 10px;\n height: 44px;\n padding: 0 12px;\n border-radius: var(--radius-md);\n cursor: pointer;\n color: var(--color-text-primary);\n}\n.item.active {\n background: var(--color-primary-light);\n color: var(--color-primary);\n}\n.iicon {\n flex-shrink: 0;\n}\n.ititle {\n font-size: var(--font-size-md);\n}\n.ititle :deep(mark) {\n background: transparent;\n color: var(--color-primary);\n font-weight: 600;\n}\n.ipath {\n margin-left: auto;\n font-size: var(--font-size-sm);\n color: var(--color-text-tertiary);\n}\n.empty {\n padding: 32px 0;\n}\n.hint {\n padding: 8px 16px;\n border-top: 1px solid var(--color-border);\n font-size: var(--font-size-sm);\n color: var(--color-text-tertiary);\n}\n</style>\n"],"names":["show","_useModel","__props","router","useRouter","t","useI18n","leaves","useMenuFlat","q","ref","cursor","inputRef","label","item","translateMenuTitle","results","computed","list","l","kw","watch","v","nextTick","_a","go","isHttpUrl","isFullscreenPath","esc","s","c","highlight","text","safe","k","i","onKeyStroke","_createBlock","_unref","NModal","$event","_createElementVNode","_hoisted_1","_hoisted_2","_createVNode","Icon","NInput","NScrollbar","_openBlock","_createElementBlock","_hoisted_3","_Fragment","_renderList","_normalizeClass","AppIcon","lineIcon","_hoisted_6","_toDisplayString","NEmpty","_hoisted_7"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
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
|
|
4
|
+
const e = /* @__PURE__ */ t(o, [["__scopeId", "data-v-403d0e3f"]]);
|
|
5
5
|
export {
|
|
6
|
-
|
|
6
|
+
e as default
|
|
7
7
|
};
|
|
8
8
|
//# sourceMappingURL=index.vue.js.map
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import { defineComponent as y, ref as L, onMounted as _, computed as n, openBlock as o, createElementBlock as a, createElementVNode as l, Fragment as m, renderList as w, normalizeStyle as
|
|
2
|
-
import { useI18n as
|
|
3
|
-
import
|
|
4
|
-
import { configApi as
|
|
5
|
-
const
|
|
1
|
+
import { defineComponent as y, ref as L, onMounted as _, computed as n, openBlock as o, createElementBlock as a, createElementVNode as l, Fragment as m, renderList as w, normalizeStyle as v, toDisplayString as u, unref as x, normalizeClass as P, createVNode as q, createTextVNode as z, createCommentVNode as C } from "vue";
|
|
2
|
+
import { useI18n as N } from "vue-i18n";
|
|
3
|
+
import S from "../AppIcon.vue.js";
|
|
4
|
+
import { configApi as V } from "../../api/index.js";
|
|
5
|
+
const b = {
|
|
6
6
|
key: 0,
|
|
7
|
-
class: "pw-meter"
|
|
7
|
+
class: "pw-meter",
|
|
8
|
+
"aria-live": "polite"
|
|
8
9
|
}, A = { class: "pw-bar" }, B = { class: "pw-rules" }, Z = /* @__PURE__ */ y({
|
|
9
10
|
__name: "index",
|
|
10
11
|
props: {
|
|
11
12
|
value: {}
|
|
12
13
|
},
|
|
13
14
|
setup(p) {
|
|
14
|
-
const h = p, { t: s } =
|
|
15
|
+
const h = p, { t: s } = N(), i = L({
|
|
15
16
|
minLength: 8,
|
|
16
17
|
requireUpper: !0,
|
|
17
18
|
requireLower: !0,
|
|
@@ -20,7 +21,7 @@ const V = {
|
|
|
20
21
|
});
|
|
21
22
|
_(async () => {
|
|
22
23
|
try {
|
|
23
|
-
i.value = await
|
|
24
|
+
i.value = await V.passwordPolicy();
|
|
24
25
|
} catch {
|
|
25
26
|
}
|
|
26
27
|
});
|
|
@@ -38,14 +39,14 @@ const V = {
|
|
|
38
39
|
if (!t) return 0;
|
|
39
40
|
const r = g.value, e = [r.upper, r.lower, r.digit, r.special].filter(Boolean).length;
|
|
40
41
|
return !r.minLength || e <= 1 ? 1 : e === 2 || t.length < 12 ? 2 : 3;
|
|
41
|
-
}),
|
|
42
|
+
}), k = n(
|
|
42
43
|
() => [
|
|
43
44
|
"",
|
|
44
45
|
s("changePassword.strength.weak"),
|
|
45
46
|
s("changePassword.strength.fair"),
|
|
46
47
|
s("changePassword.strength.strong")
|
|
47
48
|
][c.value]
|
|
48
|
-
), d = n(() => ["", "
|
|
49
|
+
), d = n(() => ["", "var(--err)", "var(--warn)", "var(--ok)"][c.value]), f = n(() => {
|
|
49
50
|
const t = i.value, r = g.value, e = [
|
|
50
51
|
{
|
|
51
52
|
key: "minLength",
|
|
@@ -59,30 +60,31 @@ const V = {
|
|
|
59
60
|
text: t.requireSpecial ? s("changePassword.rules.special") : s("changePassword.rules.specialOptional")
|
|
60
61
|
}), e;
|
|
61
62
|
});
|
|
62
|
-
return (t, r) => p.value ? (o(), a("div",
|
|
63
|
+
return (t, r) => p.value ? (o(), a("div", b, [
|
|
63
64
|
l("div", A, [
|
|
64
65
|
(o(), a(m, null, w(3, (e) => l("span", {
|
|
65
66
|
key: e,
|
|
66
|
-
style:
|
|
67
|
+
style: v({ background: e <= c.value ? d.value : "var(--fill)" })
|
|
67
68
|
}, null, 4)), 64))
|
|
68
69
|
]),
|
|
69
70
|
l("div", {
|
|
70
71
|
class: "pw-level",
|
|
71
|
-
style:
|
|
72
|
-
}, u(x(s)("changePassword.strength.label")) + ":" + u(
|
|
72
|
+
style: v({ color: d.value })
|
|
73
|
+
}, u(x(s)("changePassword.strength.label")) + ":" + u(k.value), 5),
|
|
73
74
|
l("ul", B, [
|
|
74
75
|
(o(!0), a(m, null, w(f.value, (e) => (o(), a("li", {
|
|
75
76
|
key: e.key,
|
|
76
77
|
class: P({ ok: e.ok })
|
|
77
78
|
}, [
|
|
78
|
-
q(
|
|
79
|
-
icon: e.ok ? "ph:check-circle
|
|
80
|
-
size:
|
|
79
|
+
q(S, {
|
|
80
|
+
icon: e.ok ? "ph:check-circle" : "ph:circle",
|
|
81
|
+
size: 15,
|
|
82
|
+
class: "pw-ico"
|
|
81
83
|
}, null, 8, ["icon"]),
|
|
82
84
|
z(" " + u(e.text), 1)
|
|
83
85
|
], 2))), 128))
|
|
84
86
|
])
|
|
85
|
-
])) :
|
|
87
|
+
])) : C("", !0);
|
|
86
88
|
}
|
|
87
89
|
});
|
|
88
90
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index2.vue.js","sources":["../../../src/components/PasswordStrength/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 密码强度提示条 + 规则清单。自包含:传入密码字符串即可,内部 onMounted 拉后端当前\n// 生效策略(超管在「安全策略」可改),精确同步不漂移。改密页与建用户页共用。\n// i18n 用 changePassword.* 键:它们只是键路径,为组件改名是纯 churn。\nimport { computed, onMounted, ref } from 'vue'\nimport { useI18n } from 'vue-i18n'\nimport AppIcon from '#/components/AppIcon.vue'\nimport { configApi } from '#/api'\n\nconst props = defineProps<{ value: string }>()\nconst { t } = useI18n()\n\n// 默认 = 后端默认策略,作 fallback(拉取失败仍可用;后端始终强制,弱口令以 passwordTooWeak 兜底)。\nconst policy = ref({\n minLength: 8,\n requireUpper: true,\n requireLower: true,\n requireDigit: true,\n requireSpecial: false,\n})\nonMounted(async () => {\n try {\n policy.value = await configApi.passwordPolicy()\n } catch {\n /* 保留默认;后端仍强制 */\n }\n})\n\nconst checks = computed(() => {\n const p = props.value\n return {\n minLength: p.length >= policy.value.minLength,\n upper: /[A-Z]/.test(p),\n lower: /[a-z]/.test(p),\n digit: /\\d/.test(p),\n special: /[^A-Za-z0-9]/.test(p),\n }\n})\n// 强度:长度达标 + 字符种类数 → 弱(1)/中(2)/强(3);空则 0\nconst strength = computed(() => {\n const p = props.value\n if (!p) return 0\n const c = checks.value\n const variety = [c.upper, c.lower, c.digit, c.special].filter(Boolean).length\n if (!c.minLength || variety <= 1) return 1\n if (variety === 2 || p.length < 12) return 2\n return 3\n})\nconst strengthText = computed(\n () =>\n [\n '',\n t('changePassword.strength.weak'),\n t('changePassword.strength.fair'),\n t('changePassword.strength.strong'),\n ][strength.value],\n)\nconst strengthColor = computed(() => ['', '
|
|
1
|
+
{"version":3,"file":"index2.vue.js","sources":["../../../src/components/PasswordStrength/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 密码强度提示条 + 规则清单。自包含:传入密码字符串即可,内部 onMounted 拉后端当前\n// 生效策略(超管在「安全策略」可改),精确同步不漂移。改密页与建用户页共用。\n// i18n 用 changePassword.* 键:它们只是键路径,为组件改名是纯 churn。\nimport { computed, onMounted, ref } from 'vue'\nimport { useI18n } from 'vue-i18n'\nimport AppIcon from '#/components/AppIcon.vue'\nimport { configApi } from '#/api'\n\nconst props = defineProps<{ value: string }>()\nconst { t } = useI18n()\n\n// 默认 = 后端默认策略,作 fallback(拉取失败仍可用;后端始终强制,弱口令以 passwordTooWeak 兜底)。\nconst policy = ref({\n minLength: 8,\n requireUpper: true,\n requireLower: true,\n requireDigit: true,\n requireSpecial: false,\n})\nonMounted(async () => {\n try {\n policy.value = await configApi.passwordPolicy()\n } catch {\n /* 保留默认;后端仍强制 */\n }\n})\n\nconst checks = computed(() => {\n const p = props.value\n return {\n minLength: p.length >= policy.value.minLength,\n upper: /[A-Z]/.test(p),\n lower: /[a-z]/.test(p),\n digit: /\\d/.test(p),\n special: /[^A-Za-z0-9]/.test(p),\n }\n})\n// 强度:长度达标 + 字符种类数 → 弱(1)/中(2)/强(3);空则 0\nconst strength = computed(() => {\n const p = props.value\n if (!p) return 0\n const c = checks.value\n const variety = [c.upper, c.lower, c.digit, c.special].filter(Boolean).length\n if (!c.minLength || variety <= 1) return 1\n if (variety === 2 || p.length < 12) return 2\n return 3\n})\nconst strengthText = computed(\n () =>\n [\n '',\n t('changePassword.strength.weak'),\n t('changePassword.strength.fair'),\n t('changePassword.strength.strong'),\n ][strength.value],\n)\n// 弱 / 中 / 强 = 语义色 err / warn / ok(设计令牌,明暗两套自动跟随)\nconst strengthColor = computed(() => ['', 'var(--err)', 'var(--warn)', 'var(--ok)'][strength.value])\n// 规则清单按有效策略动态构建:恒显最小长度;大小写/数字仅在策略要求时作硬规则;\n// 特殊字符——策略要求时作硬规则,否则作可选提示。\nconst ruleList = computed(() => {\n const pol = policy.value\n const c = checks.value\n const rows = [\n {\n key: 'minLength',\n ok: c.minLength,\n text: t('changePassword.rules.minLength', { n: pol.minLength }),\n },\n ]\n if (pol.requireUpper)\n rows.push({ key: 'upper', ok: c.upper, text: t('changePassword.rules.upper') })\n if (pol.requireLower)\n rows.push({ key: 'lower', ok: c.lower, text: t('changePassword.rules.lower') })\n if (pol.requireDigit)\n rows.push({ key: 'digit', ok: c.digit, text: t('changePassword.rules.digit') })\n rows.push({\n key: 'special',\n ok: c.special,\n text: pol.requireSpecial\n ? t('changePassword.rules.special')\n : t('changePassword.rules.specialOptional'),\n })\n return rows\n})\n</script>\n\n<template>\n <div v-if=\"value\" class=\"pw-meter\" aria-live=\"polite\">\n <div class=\"pw-bar\">\n <span\n v-for=\"i in 3\"\n :key=\"i\"\n :style=\"{ background: i <= strength ? strengthColor : 'var(--fill)' }\"\n />\n </div>\n <div class=\"pw-level\" :style=\"{ color: strengthColor }\">\n {{ t('changePassword.strength.label') }}:{{ strengthText }}\n </div>\n <ul class=\"pw-rules\">\n <li v-for=\"r in ruleList\" :key=\"r.key\" :class=\"{ ok: r.ok }\">\n <AppIcon :icon=\"r.ok ? 'ph:check-circle' : 'ph:circle'\" :size=\"15\" class=\"pw-ico\" />\n {{ r.text }}\n </li>\n </ul>\n </div>\n</template>\n\n<style scoped>\n/* 强度提示:紧贴上方「新密码」输入框(上拉 6px),与下一项隔 16px。 */\n.pw-meter {\n margin: -6px 0 16px;\n}\n.pw-bar {\n display: flex;\n gap: 6px;\n}\n.pw-bar span {\n flex: 1;\n height: 4px;\n border-radius: 2px;\n transition: background var(--transition-fast);\n}\n.pw-level {\n margin: 6px 0 8px;\n font-size: 13px;\n}\n.pw-rules {\n margin: 0;\n padding: 0;\n list-style: none;\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 4px 12px;\n}\n.pw-rules li {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--text-3);\n}\n.pw-rules li.ok {\n color: var(--ok);\n}\n.pw-ico {\n flex: none;\n}\n</style>\n"],"names":["props","__props","t","useI18n","policy","ref","onMounted","configApi","checks","computed","p","strength","c","variety","strengthText","strengthColor","ruleList","pol","rows","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_Fragment","_renderList","i","_normalizeStyle","_unref","_toDisplayString","_hoisted_3","r","_normalizeClass","_createVNode","AppIcon"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
count?: number;
|
|
3
|
+
};
|
|
4
|
+
declare const __VLS_export: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
5
|
+
declare const _default: typeof __VLS_export;
|
|
6
|
+
export default _default;
|
|
@@ -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-86746be5"]]);
|
|
5
5
|
export {
|
|
6
6
|
m as default
|
|
7
7
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { defineComponent as n, openBlock as o, createElementBlock as a, toDisplayString as r, unref as c } from "vue";
|
|
2
|
+
import { useI18n as s } from "vue-i18n";
|
|
3
|
+
const l = { class: "table-total tabular" }, _ = /* @__PURE__ */ n({
|
|
4
|
+
__name: "index",
|
|
5
|
+
props: {
|
|
6
|
+
count: {}
|
|
7
|
+
},
|
|
8
|
+
setup(t) {
|
|
9
|
+
const { t: e } = s();
|
|
10
|
+
return (p, u) => (o(), a("span", l, r(c(e)("table.total", { n: t.count ?? 0 })), 1));
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
export {
|
|
14
|
+
_ as default
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=index2.vue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index2.vue.js","sources":["../../../src/components/TableTotal/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 分页栏左侧的「共 N 条」:写在 SmartTable 的 #pagination-prefix 插槽里,数字取插槽给的 itemCount,\n// 不要自己再数一遍(远程表格里 itemCount 是后端的 total,不是当前页行数)。\nimport { useI18n } from 'vue-i18n'\n\ndefineProps<{ count?: number }>()\nconst { t } = useI18n()\n</script>\n\n<template>\n <span class=\"table-total tabular\">{{ t('table.total', { n: count ?? 0 }) }}</span>\n</template>\n\n<style scoped>\n.table-total {\n color: var(--text-2);\n white-space: nowrap;\n}\n</style>\n"],"names":["t","useI18n","_openBlock","_createElementBlock","_hoisted_1","_toDisplayString","_unref","__props"],"mappings":";;;;;;;;AAMA,UAAM,EAAE,GAAAA,EAAA,IAAMC,EAAA;sBAIZC,KAAAC,EAAkF,QAAlFC,GAAkFC,EAA7CC,EAAAN,CAAA,sBAAsBO,EAAA,SAAK,GAAA,CAAA,GAAA,CAAA;AAAA;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.vue.js","sources":["../../../src/components/TableZoomButton/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 表格「放大 / 还原」按钮。与 SmartTable 工具栏自带的刷新 / 密度 / 列设置同形态(circle quaternary + tooltip),\n// 放大态换收起图标并染主色 —— 不要写成带文字的 secondary 按钮,那在工具栏里一眼就是外来户。\n//\n// 状态由调用方的 useTableZoom() 持有(一块表一份实例),这里只负责外观与触发。\n// 按钮必须和表格一起进 Teleport 容器:留在 n-card 的 #header-extra 里,放大后会被遮罩盖住,\n// 还原按钮点不到,只能按 Esc。用法见 skills/create-page-variant/split-zoom.md。\nimport { NButton, NTooltip } from 'naive-ui'\nimport { useI18n } from 'vue-i18n'\nimport AppIcon from '#/components/AppIcon.vue'\n\nwithDefaults(defineProps<{ zoomed: boolean; size?: 'tiny' | 'small' | 'medium' | 'large' }>(), {\n size: 'small',\n})\ndefineEmits<{ toggle: [] }>()\n\nconst { t } = useI18n()\n</script>\n\n<template>\n <n-tooltip>\n <template #trigger>\n <n-button\n :size=\"size\"\n circle\n quaternary\n :type=\"zoomed ? 'primary' : 'default'\"\n :aria-label=\"zoomed ? t('table.zoomExit') : t('table.zoom')\"\n @click=\"$emit('toggle')\"\n >\n <template #icon>\n <AppIcon :icon=\"zoomed ? 'ph:corners-in' : 'ph:corners-out'\" />\n </template>\n </n-button>\n </template>\n {{ zoomed ? t('table.zoomExit') : t('table.zoom') }}\n </n-tooltip>\n</template>\n"],"names":["useI18n","_createBlock","_unref","NTooltip","_createVNode","NButton","__props","$emit","AppIcon","_createTextVNode","_toDisplayString"],"mappings":";;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.vue.js","sources":["../../../src/components/TableZoomButton/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * @deprecated SmartTable 自带放大按钮:`:toolbar=\"{ maximize: true }\"`\n * (Teleport 到 body、盖住侧栏与顶栏、不调用浏览器全屏 API,与本实现是同一思路)。\n * 本组件与 useTableZoom 没有内核页面在用,仅为已依赖它们的下游应用保留,下一个 .NET 大版本删除。\n */\n// 表格「放大 / 还原」按钮。与 SmartTable 工具栏自带的刷新 / 密度 / 列设置同形态(circle quaternary + tooltip),\n// 放大态换收起图标并染主色 —— 不要写成带文字的 secondary 按钮,那在工具栏里一眼就是外来户。\n//\n// 状态由调用方的 useTableZoom() 持有(一块表一份实例),这里只负责外观与触发。\n// 按钮必须和表格一起进 Teleport 容器:留在 n-card 的 #header-extra 里,放大后会被遮罩盖住,\n// 还原按钮点不到,只能按 Esc。用法见 skills/create-page-variant/split-zoom.md。\nimport { NButton, NTooltip } from 'naive-ui'\nimport { useI18n } from 'vue-i18n'\nimport AppIcon from '#/components/AppIcon.vue'\n\nwithDefaults(defineProps<{ zoomed: boolean; size?: 'tiny' | 'small' | 'medium' | 'large' }>(), {\n size: 'small',\n})\ndefineEmits<{ toggle: [] }>()\n\nconst { t } = useI18n()\n</script>\n\n<template>\n <n-tooltip>\n <template #trigger>\n <n-button\n :size=\"size\"\n circle\n quaternary\n :type=\"zoomed ? 'primary' : 'default'\"\n :aria-label=\"zoomed ? t('table.zoomExit') : t('table.zoom')\"\n @click=\"$emit('toggle')\"\n >\n <template #icon>\n <AppIcon :icon=\"zoomed ? 'ph:corners-in' : 'ph:corners-out'\" />\n </template>\n </n-button>\n </template>\n {{ zoomed ? t('table.zoomExit') : t('table.zoom') }}\n </n-tooltip>\n</template>\n"],"names":["useI18n","_createBlock","_unref","NTooltip","_createVNode","NButton","__props","$emit","AppIcon","_createTextVNode","_toDisplayString"],"mappings":";;;;;;;;;;;;AAqBA,UAAM,EAAE,EAAA,IAAMA,EAAA;2BAIZC,EAgBYC,EAAAC,CAAA,GAAA,MAAA;AAAA,MAfC,WACT,MAWW;AAAA,QAXXC,EAWWF,EAAAG,CAAA,GAAA;AAAA,UAVR,MAAMC,EAAA;AAAA,UACP,QAAA;AAAA,UACA,YAAA;AAAA,UACC,MAAMA,EAAA,SAAM,YAAA;AAAA,UACZ,cAAYA,EAAA,SAASJ,EAAA,CAAA,sBAAsBA,EAAA,CAAA,EAAC,YAAA;AAAA,UAC5C,gCAAOK,EAAAA,MAAK,QAAA;AAAA,QAAA;UAEF,QACT,MAA+D;AAAA,YAA/DH,EAA+DI,GAAA;AAAA,cAArD,MAAMF,EAAA,SAAM,kBAAA;AAAA,YAAA;;;;;iBAGjB,MACX;AAAA,QADWG,EAAA,MACXC,EAAGJ,EAAA,SAASJ,EAAA,CAAA,sBAAsBA,EAAA,CAAA,EAAC,YAAA,CAAA,GAAA,CAAA;AAAA,MAAA;;;;;"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import o from "./index2.vue.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import r from "../../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
-
const
|
|
4
|
+
const m = /* @__PURE__ */ r(o, [["__scopeId", "data-v-ef8d2925"]]);
|
|
5
5
|
export {
|
|
6
|
-
|
|
6
|
+
m as default
|
|
7
7
|
};
|
|
8
8
|
//# sourceMappingURL=index.vue.js.map
|