@liujitcn/kratos-admin-core 0.0.1
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 +168 -0
- package/build/getEnv.ts +46 -0
- package/build/plugins.ts +206 -0
- package/build/proxy.ts +29 -0
- package/dist/package/declarations/build/getEnv.d.ts +13 -0
- package/dist/package/declarations/build/plugins.d.ts +20 -0
- package/dist/package/declarations/build/proxy.d.ts +10 -0
- package/dist/package/declarations/index.d.ts +7 -0
- package/dist/package/declarations/src/App.vue.d.ts +3 -0
- package/dist/package/declarations/src/api/base/config.d.ts +7 -0
- package/dist/package/declarations/src/api/base/file.d.ts +11 -0
- package/dist/package/declarations/src/api/base/login.d.ts +18 -0
- package/dist/package/declarations/src/api/base/oauth.d.ts +12 -0
- package/dist/package/declarations/src/api/system/auth.d.ts +13 -0
- package/dist/package/declarations/src/api/system/base_dict.d.ts +8 -0
- package/dist/package/declarations/src/api/system/base_tenant.d.ts +9 -0
- package/dist/package/declarations/src/auth.d.ts +1 -0
- package/dist/package/declarations/src/bootstrap.d.ts +23 -0
- package/dist/package/declarations/src/components/Card/DataPanelCard.vue.d.ts +23 -0
- package/dist/package/declarations/src/components/CronExpression/index.vue.d.ts +15 -0
- package/dist/package/declarations/src/components/Dialog/FormDialog.vue.d.ts +74 -0
- package/dist/package/declarations/src/components/Dialog/ProDialog.vue.d.ts +58 -0
- package/dist/package/declarations/src/components/Dict/DictLabel.vue.d.ts +11 -0
- package/dist/package/declarations/src/components/Dict/index.vue.d.ts +30 -0
- package/dist/package/declarations/src/components/ECharts/config/index.d.ts +7 -0
- package/dist/package/declarations/src/components/ECharts/index.vue.d.ts +22 -0
- package/dist/package/declarations/src/components/ErrorMessage/index.vue.d.ts +12 -0
- package/dist/package/declarations/src/components/Grid/components/GridItem.vue.d.ts +34 -0
- package/dist/package/declarations/src/components/Grid/index.vue.d.ts +28 -0
- package/dist/package/declarations/src/components/Grid/interface/index.d.ts +7 -0
- package/dist/package/declarations/src/components/ImportExcel/index.vue.d.ts +26 -0
- package/dist/package/declarations/src/components/Loading/fullScreen.d.ts +5 -0
- package/dist/package/declarations/src/components/Loading/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/components/PasswordStrength/index.vue.d.ts +13 -0
- package/dist/package/declarations/src/components/ProForm/components/DynamicList.vue.d.ts +15 -0
- package/dist/package/declarations/src/components/ProForm/components/KvList.vue.d.ts +26 -0
- package/dist/package/declarations/src/components/ProForm/components/ProFormItem.vue.d.ts +28 -0
- package/dist/package/declarations/src/components/ProForm/index.vue.d.ts +36 -0
- package/dist/package/declarations/src/components/ProForm/interface/index.d.ts +47 -0
- package/dist/package/declarations/src/components/ProTable/components/ColSetting.vue.d.ts +9 -0
- package/dist/package/declarations/src/components/ProTable/components/Pagination.vue.d.ts +15 -0
- package/dist/package/declarations/src/components/ProTable/components/TableColumn.vue.d.ts +9 -0
- package/dist/package/declarations/src/components/ProTable/interface/index.d.ts +187 -0
- package/dist/package/declarations/src/components/ProTable.d.ts +5 -0
- package/dist/package/declarations/src/components/SearchForm/components/SearchFormItem.vue.d.ts +21 -0
- package/dist/package/declarations/src/components/SearchForm/index.vue.d.ts +22 -0
- package/dist/package/declarations/src/components/SelectFilter/index.vue.d.ts +44 -0
- package/dist/package/declarations/src/components/SelectIcon/index.vue.d.ts +19 -0
- package/dist/package/declarations/src/components/SvgIcon/index.vue.d.ts +15 -0
- package/dist/package/declarations/src/components/SwitchDark/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/components/TreeFilter/index.vue.d.ts +5866 -0
- package/dist/package/declarations/src/components/Upload/File.vue.d.ts +24 -0
- package/dist/package/declarations/src/components/Upload/Files.vue.d.ts +26 -0
- package/dist/package/declarations/src/components/Upload/Img.vue.d.ts +43 -0
- package/dist/package/declarations/src/components/Upload/Imgs.vue.d.ts +46 -0
- package/dist/package/declarations/src/components/WangEditor/index.vue.d.ts +29 -0
- package/dist/package/declarations/src/config/index.d.ts +6 -0
- package/dist/package/declarations/src/config/nprogress.d.ts +3 -0
- package/dist/package/declarations/src/directives/index.d.ts +5 -0
- package/dist/package/declarations/src/directives/modules/auth.d.ts +3 -0
- package/dist/package/declarations/src/directives/modules/copy.d.ts +8 -0
- package/dist/package/declarations/src/directives/modules/debounce.d.ts +8 -0
- package/dist/package/declarations/src/directives/modules/draggable.d.ts +3 -0
- package/dist/package/declarations/src/directives/modules/longpress.d.ts +7 -0
- package/dist/package/declarations/src/directives/modules/throttle.d.ts +3 -0
- package/dist/package/declarations/src/directives/modules/waterMarker.d.ts +5 -0
- package/dist/package/declarations/src/enums/httpEnum.d.ts +29 -0
- package/dist/package/declarations/src/format.d.ts +1 -0
- package/dist/package/declarations/src/hooks/interface/index.d.ts +36 -0
- package/dist/package/declarations/src/hooks/useAuthButtons.d.ts +8 -0
- package/dist/package/declarations/src/hooks/useDownload.d.ts +9 -0
- package/dist/package/declarations/src/hooks/useHandleData.d.ts +10 -0
- package/dist/package/declarations/src/hooks/useOnline.d.ts +6 -0
- package/dist/package/declarations/src/hooks/useSelection.d.ts +10 -0
- package/dist/package/declarations/src/hooks/useTable.d.ts +46 -0
- package/dist/package/declarations/src/hooks/useTheme.d.ts +12 -0
- package/dist/package/declarations/src/hooks/useTime.d.ts +13 -0
- package/dist/package/declarations/src/index.d.ts +3 -0
- package/dist/package/declarations/src/layouts/LayoutClassic/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/layouts/LayoutColumns/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/layouts/LayoutTransverse/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/layouts/LayoutVertical/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/layouts/components/Footer/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/layouts/components/Header/ToolBarLeft.vue.d.ts +3 -0
- package/dist/package/declarations/src/layouts/components/Header/ToolBarRight.vue.d.ts +3 -0
- package/dist/package/declarations/src/layouts/components/Header/components/AssemblySize.vue.d.ts +3 -0
- package/dist/package/declarations/src/layouts/components/Header/components/Avatar.vue.d.ts +3 -0
- package/dist/package/declarations/src/layouts/components/Header/components/Breadcrumb.vue.d.ts +3 -0
- package/dist/package/declarations/src/layouts/components/Header/components/CollapseIcon.vue.d.ts +3 -0
- package/dist/package/declarations/src/layouts/components/Header/components/Fullscreen.vue.d.ts +3 -0
- package/dist/package/declarations/src/layouts/components/Header/components/InfoDialog.vue.d.ts +5 -0
- package/dist/package/declarations/src/layouts/components/Header/components/PasswordDialog.vue.d.ts +5 -0
- package/dist/package/declarations/src/layouts/components/Header/components/SearchMenu.vue.d.ts +3 -0
- package/dist/package/declarations/src/layouts/components/Header/components/ThemeSetting.vue.d.ts +3 -0
- package/dist/package/declarations/src/layouts/components/Main/components/Maximize.vue.d.ts +3 -0
- package/dist/package/declarations/src/layouts/components/Main/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/layouts/components/Menu/SubMenu.vue.d.ts +7 -0
- package/dist/package/declarations/src/layouts/components/Tabs/components/MoreButton.vue.d.ts +3 -0
- package/dist/package/declarations/src/layouts/components/Tabs/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/layouts/components/ThemeDrawer/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/layouts/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/layouts/indexAsync.vue.d.ts +3 -0
- package/dist/package/declarations/src/modules/index.d.ts +117 -0
- package/dist/package/declarations/src/modules/kratosAdmin.d.ts +4 -0
- package/dist/package/declarations/src/navigation.d.ts +2 -0
- package/dist/package/declarations/src/request.d.ts +2 -0
- package/dist/package/declarations/src/routers/index.d.ts +21 -0
- package/dist/package/declarations/src/routers/modules/dynamicRouter.d.ts +4 -0
- package/dist/package/declarations/src/routers/modules/staticRouter.d.ts +25 -0
- package/dist/package/declarations/src/rpc/base/v1/config.d.ts +23 -0
- package/dist/package/declarations/src/rpc/base/v1/file.d.ts +52 -0
- package/dist/package/declarations/src/rpc/base/v1/login.d.ts +107 -0
- package/dist/package/declarations/src/rpc/base/v1/oauth.d.ts +167 -0
- package/dist/package/declarations/src/rpc/common/v1/common.d.ts +57 -0
- package/dist/package/declarations/src/rpc/common/v1/enum.d.ts +58 -0
- package/dist/package/declarations/src/rpc/common/v1/types.d.ts +60 -0
- package/dist/package/declarations/src/rpc/google/protobuf/empty.d.ts +11 -0
- package/dist/package/declarations/src/rpc/google/protobuf/wrappers.d.ts +108 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/auth.d.ts +156 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_dict.d.ts +215 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_tenant.d.ts +112 -0
- package/dist/package/declarations/src/rpc/system/common/v1/enum.d.ts +67 -0
- package/dist/package/declarations/src/security.d.ts +3 -0
- package/dist/package/declarations/src/stores/helper/persist.d.ts +9 -0
- package/dist/package/declarations/src/stores/index.d.ts +2 -0
- package/dist/package/declarations/src/stores/interface/index.d.ts +90 -0
- package/dist/package/declarations/src/stores/modules/auth.d.ts +168 -0
- package/dist/package/declarations/src/stores/modules/config.d.ts +26 -0
- package/dist/package/declarations/src/stores/modules/dict.d.ts +32 -0
- package/dist/package/declarations/src/stores/modules/global.d.ts +4 -0
- package/dist/package/declarations/src/stores/modules/keepAlive.d.ts +6 -0
- package/dist/package/declarations/src/stores/modules/tabs.d.ts +13 -0
- package/dist/package/declarations/src/stores/modules/user.d.ts +29 -0
- package/dist/package/declarations/src/stores/runtime.d.ts +4 -0
- package/dist/package/declarations/src/styles/theme/aside.d.ts +4 -0
- package/dist/package/declarations/src/styles/theme/header.d.ts +4 -0
- package/dist/package/declarations/src/styles/theme/menu.d.ts +4 -0
- package/dist/package/declarations/src/table.d.ts +1 -0
- package/dist/package/declarations/src/tenant.d.ts +1 -0
- package/dist/package/declarations/src/utils/color.d.ts +28 -0
- package/dist/package/declarations/src/utils/dict.d.ts +15 -0
- package/dist/package/declarations/src/utils/eleValidate.d.ts +4 -0
- package/dist/package/declarations/src/utils/errorHandler.d.ts +5 -0
- package/dist/package/declarations/src/utils/index.d.ts +192 -0
- package/dist/package/declarations/src/utils/is/index.d.ts +72 -0
- package/dist/package/declarations/src/utils/mittBus.d.ts +2 -0
- package/dist/package/declarations/src/utils/oauthProvider.d.ts +19 -0
- package/dist/package/declarations/src/utils/passwordCrypto.d.ts +6 -0
- package/dist/package/declarations/src/utils/passwordStrength.d.ts +36 -0
- package/dist/package/declarations/src/utils/proTable.d.ts +44 -0
- package/dist/package/declarations/src/utils/request.d.ts +11 -0
- package/dist/package/declarations/src/utils/router.d.ts +14 -0
- package/dist/package/declarations/src/utils/svg.d.ts +4 -0
- package/dist/package/declarations/src/utils/tenant.d.ts +6 -0
- package/dist/package/declarations/src/utils/utils.d.ts +12 -0
- package/dist/package/declarations/src/views/error/403.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/error/404.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/error/500.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/error/pending.vue.d.ts +3 -0
- package/dist/package/declarations/src/views/login/components/LoginForm.vue.d.ts +4 -0
- package/dist/package/declarations/src/views/login/index.vue.d.ts +3 -0
- package/dist/package/declarations/vite.config.d.ts +13 -0
- package/dist/package/src/App.vue +25 -0
- package/dist/package/src/api/base/config.ts +19 -0
- package/dist/package/src/api/base/file.ts +75 -0
- package/dist/package/src/api/base/login.ts +81 -0
- package/dist/package/src/api/base/oauth.ts +50 -0
- package/dist/package/src/api/system/auth.ts +45 -0
- package/dist/package/src/api/system/base_dict.ts +19 -0
- package/dist/package/src/api/system/base_tenant.ts +20 -0
- package/dist/package/src/assets/fonts/DIN.otf +0 -0
- package/dist/package/src/assets/fonts/MetroDF.ttf +0 -0
- package/dist/package/src/assets/fonts/YouSheBiaoTiHei.ttf +0 -0
- package/dist/package/src/assets/fonts/font.scss +14 -0
- package/dist/package/src/assets/iconfont/iconfont.scss +47 -0
- package/dist/package/src/assets/iconfont/iconfont.ttf +0 -0
- package/dist/package/src/assets/images/403.png +0 -0
- package/dist/package/src/assets/images/404.png +0 -0
- package/dist/package/src/assets/images/500.png +0 -0
- package/dist/package/src/assets/images/avatar.png +0 -0
- package/dist/package/src/assets/images/login_bg.svg +33 -0
- package/dist/package/src/assets/images/login_left.png +0 -0
- package/dist/package/src/assets/images/logo.svg +1 -0
- package/dist/package/src/assets/images/notData.png +0 -0
- package/dist/package/src/assets/images/oauth/dingtalk.png +0 -0
- package/dist/package/src/assets/images/oauth/feishu.png +0 -0
- package/dist/package/src/assets/images/oauth/gitee.png +0 -0
- package/dist/package/src/assets/images/oauth/github.png +0 -0
- package/dist/package/src/assets/images/oauth/google.png +0 -0
- package/dist/package/src/assets/images/oauth/wechat.png +0 -0
- package/dist/package/src/assets/images/oauth/wechatwork.png +0 -0
- package/dist/package/src/auth.ts +1 -0
- package/dist/package/src/bootstrap.ts +69 -0
- package/dist/package/src/components/Card/DataPanelCard.vue +67 -0
- package/dist/package/src/components/CronExpression/index.vue +713 -0
- package/dist/package/src/components/Dialog/FormDialog.vue +160 -0
- package/dist/package/src/components/Dialog/ProDialog.vue +96 -0
- package/dist/package/src/components/Dict/DictLabel.vue +62 -0
- package/dist/package/src/components/Dict/index.vue +157 -0
- package/dist/package/src/components/ECharts/config/index.ts +45 -0
- package/dist/package/src/components/ECharts/index.vue +108 -0
- package/dist/package/src/components/ErrorMessage/index.vue +63 -0
- package/dist/package/src/components/Grid/components/GridItem.vue +69 -0
- package/dist/package/src/components/Grid/index.vue +169 -0
- package/dist/package/src/components/Grid/interface/index.ts +8 -0
- package/dist/package/src/components/ImportExcel/index.scss +3 -0
- package/dist/package/src/components/ImportExcel/index.vue +150 -0
- package/dist/package/src/components/Loading/fullScreen.ts +45 -0
- package/dist/package/src/components/Loading/index.scss +67 -0
- package/dist/package/src/components/Loading/index.vue +13 -0
- package/dist/package/src/components/PasswordStrength/index.vue +127 -0
- package/dist/package/src/components/ProForm/components/DynamicList.vue +59 -0
- package/dist/package/src/components/ProForm/components/KvList.vue +73 -0
- package/dist/package/src/components/ProForm/components/ProFormItem.vue +191 -0
- package/dist/package/src/components/ProForm/index.vue +120 -0
- package/dist/package/src/components/ProForm/interface/index.ts +74 -0
- package/dist/package/src/components/ProTable/components/ColSetting.vue +45 -0
- package/dist/package/src/components/ProTable/components/Pagination.vue +58 -0
- package/dist/package/src/components/ProTable/components/TableColumn.vue +234 -0
- package/dist/package/src/components/ProTable/index.vue +567 -0
- package/dist/package/src/components/ProTable/interface/index.ts +223 -0
- package/dist/package/src/components/ProTable.ts +8 -0
- package/dist/package/src/components/SearchForm/components/SearchFormItem.vue +168 -0
- package/dist/package/src/components/SearchForm/index.vue +105 -0
- package/dist/package/src/components/SelectFilter/index.scss +63 -0
- package/dist/package/src/components/SelectFilter/index.vue +113 -0
- package/dist/package/src/components/SelectIcon/index.scss +39 -0
- package/dist/package/src/components/SelectIcon/index.vue +105 -0
- package/dist/package/src/components/SvgIcon/index.vue +35 -0
- package/dist/package/src/components/SwitchDark/index.vue +12 -0
- package/dist/package/src/components/TreeFilter/index.scss +44 -0
- package/dist/package/src/components/TreeFilter/index.vue +207 -0
- package/dist/package/src/components/Upload/File.vue +201 -0
- package/dist/package/src/components/Upload/Files.vue +234 -0
- package/dist/package/src/components/Upload/Img.vue +306 -0
- package/dist/package/src/components/Upload/Imgs.vue +320 -0
- package/dist/package/src/components/WangEditor/index.scss +28 -0
- package/dist/package/src/components/WangEditor/index.vue +154 -0
- package/dist/package/src/config/index.ts +19 -0
- package/dist/package/src/config/nprogress.ts +12 -0
- package/dist/package/src/directives/index.ts +28 -0
- package/dist/package/src/directives/modules/auth.ts +25 -0
- package/dist/package/src/directives/modules/copy.ts +39 -0
- package/dist/package/src/directives/modules/debounce.ts +32 -0
- package/dist/package/src/directives/modules/draggable.ts +50 -0
- package/dist/package/src/directives/modules/longpress.ts +49 -0
- package/dist/package/src/directives/modules/throttle.ts +42 -0
- package/dist/package/src/directives/modules/waterMarker.ts +36 -0
- package/dist/package/src/enums/httpEnum.ts +35 -0
- package/dist/package/src/format.ts +1 -0
- package/dist/package/src/hooks/interface/index.ts +38 -0
- package/dist/package/src/hooks/useAuthButtons.ts +25 -0
- package/dist/package/src/hooks/useDownload.ts +44 -0
- package/dist/package/src/hooks/useHandleData.ts +38 -0
- package/dist/package/src/hooks/useOnline.ts +27 -0
- package/dist/package/src/hooks/useSelection.ts +34 -0
- package/dist/package/src/hooks/useTable.ts +151 -0
- package/dist/package/src/hooks/useTheme.ts +111 -0
- package/dist/package/src/hooks/useTime.ts +38 -0
- package/dist/package/src/index.ts +9 -0
- package/dist/package/src/layouts/LayoutClassic/index.scss +60 -0
- package/dist/package/src/layouts/LayoutClassic/index.vue +64 -0
- package/dist/package/src/layouts/LayoutColumns/index.scss +95 -0
- package/dist/package/src/layouts/LayoutColumns/index.vue +113 -0
- package/dist/package/src/layouts/LayoutTransverse/index.scss +60 -0
- package/dist/package/src/layouts/LayoutTransverse/index.vue +70 -0
- package/dist/package/src/layouts/LayoutVertical/index.scss +70 -0
- package/dist/package/src/layouts/LayoutVertical/index.vue +119 -0
- package/dist/package/src/layouts/components/Footer/index.scss +11 -0
- package/dist/package/src/layouts/components/Footer/index.vue +21 -0
- package/dist/package/src/layouts/components/Header/ToolBarLeft.vue +23 -0
- package/dist/package/src/layouts/components/Header/ToolBarRight.vue +44 -0
- package/dist/package/src/layouts/components/Header/components/AssemblySize.vue +39 -0
- package/dist/package/src/layouts/components/Header/components/Avatar.vue +226 -0
- package/dist/package/src/layouts/components/Header/components/Breadcrumb.vue +117 -0
- package/dist/package/src/layouts/components/Header/components/CollapseIcon.vue +21 -0
- package/dist/package/src/layouts/components/Header/components/Fullscreen.vue +28 -0
- package/dist/package/src/layouts/components/Header/components/InfoDialog.vue +22 -0
- package/dist/package/src/layouts/components/Header/components/PasswordDialog.vue +22 -0
- package/dist/package/src/layouts/components/Header/components/SearchMenu.vue +207 -0
- package/dist/package/src/layouts/components/Header/components/ThemeSetting.vue +14 -0
- package/dist/package/src/layouts/components/Main/components/Maximize.vue +39 -0
- package/dist/package/src/layouts/components/Main/index.scss +14 -0
- package/dist/package/src/layouts/components/Main/index.vue +90 -0
- package/dist/package/src/layouts/components/Menu/SubMenu.vue +132 -0
- package/dist/package/src/layouts/components/Tabs/components/MoreButton.vue +83 -0
- package/dist/package/src/layouts/components/Tabs/index.scss +69 -0
- package/dist/package/src/layouts/components/Tabs/index.vue +111 -0
- package/dist/package/src/layouts/components/ThemeDrawer/index.scss +137 -0
- package/dist/package/src/layouts/components/ThemeDrawer/index.vue +191 -0
- package/dist/package/src/layouts/index.vue +50 -0
- package/dist/package/src/layouts/indexAsync.vue +54 -0
- package/dist/package/src/modules/index.ts +233 -0
- package/dist/package/src/modules/kratosAdmin.ts +17 -0
- package/dist/package/src/navigation.ts +2 -0
- package/dist/package/src/request.ts +2 -0
- package/dist/package/src/routers/index.ts +143 -0
- package/dist/package/src/routers/modules/dynamicRouter.ts +160 -0
- package/dist/package/src/routers/modules/staticRouter.ts +73 -0
- package/dist/package/src/rpc/base/v1/config.ts +34 -0
- package/dist/package/src/rpc/base/v1/file.ts +66 -0
- package/dist/package/src/rpc/base/v1/login.ts +128 -0
- package/dist/package/src/rpc/base/v1/oauth.ts +199 -0
- package/dist/package/src/rpc/common/v1/common.ts +71 -0
- package/dist/package/src/rpc/common/v1/enum.ts +71 -0
- package/dist/package/src/rpc/common/v1/types.ts +77 -0
- package/dist/package/src/rpc/google/protobuf/empty.ts +19 -0
- package/dist/package/src/rpc/google/protobuf/wrappers.ts +124 -0
- package/dist/package/src/rpc/system/admin/v1/auth.ts +208 -0
- package/dist/package/src/rpc/system/admin/v1/base_dict.ts +249 -0
- package/dist/package/src/rpc/system/admin/v1/base_tenant.ts +134 -0
- package/dist/package/src/rpc/system/common/v1/enum.ts +80 -0
- package/dist/package/src/security.ts +3 -0
- package/dist/package/src/stores/helper/persist.ts +19 -0
- package/dist/package/src/stores/index.ts +8 -0
- package/dist/package/src/stores/interface/index.ts +102 -0
- package/dist/package/src/stores/modules/auth.ts +73 -0
- package/dist/package/src/stores/modules/config.ts +119 -0
- package/dist/package/src/stores/modules/dict.ts +65 -0
- package/dist/package/src/stores/modules/global.ts +54 -0
- package/dist/package/src/stores/modules/keepAlive.ts +22 -0
- package/dist/package/src/stores/modules/tabs.ts +77 -0
- package/dist/package/src/stores/modules/user.ts +109 -0
- package/dist/package/src/stores/runtime.ts +4 -0
- package/dist/package/src/styles/common.scss +144 -0
- package/dist/package/src/styles/element-dark.scss +46 -0
- package/dist/package/src/styles/element.scss +333 -0
- package/dist/package/src/styles/reset.scss +143 -0
- package/dist/package/src/styles/theme/aside.ts +16 -0
- package/dist/package/src/styles/theme/header.ts +25 -0
- package/dist/package/src/styles/theme/menu.ts +31 -0
- package/dist/package/src/styles/var.scss +2 -0
- package/dist/package/src/table.ts +1 -0
- package/dist/package/src/tenant.ts +1 -0
- package/dist/package/src/typings/global.d.ts +74 -0
- package/dist/package/src/typings/utils.d.ts +17 -0
- package/dist/package/src/typings/window.d.ts +8 -0
- package/dist/package/src/utils/color.ts +59 -0
- package/dist/package/src/utils/dict.ts +17 -0
- package/dist/package/src/utils/eleValidate.ts +14 -0
- package/dist/package/src/utils/errorHandler.ts +27 -0
- package/dist/package/src/utils/index.ts +403 -0
- package/dist/package/src/utils/is/index.ts +125 -0
- package/dist/package/src/utils/mittBus.ts +5 -0
- package/dist/package/src/utils/oauthProvider.ts +79 -0
- package/dist/package/src/utils/passwordCrypto.ts +71 -0
- package/dist/package/src/utils/passwordStrength.ts +86 -0
- package/dist/package/src/utils/proTable.ts +124 -0
- package/dist/package/src/utils/request.ts +296 -0
- package/dist/package/src/utils/router.ts +43 -0
- package/dist/package/src/utils/svg.ts +13 -0
- package/dist/package/src/utils/tenant.ts +10 -0
- package/dist/package/src/utils/utils.ts +40 -0
- package/dist/package/src/views/error/403.vue +8 -0
- package/dist/package/src/views/error/404.vue +8 -0
- package/dist/package/src/views/error/500.vue +8 -0
- package/dist/package/src/views/error/pending.vue +16 -0
- package/dist/package/src/views/login/components/LoginForm.vue +797 -0
- package/dist/package/src/views/login/index.scss +103 -0
- package/dist/package/src/views/login/index.vue +108 -0
- package/dist/package/src/vite-env.d.ts +3 -0
- package/dist/package/types/generated/auto-imports.d.ts +124 -0
- package/dist/package/types/generated/components.d.ts +151 -0
- package/package.json +199 -0
- package/tsconfig.json +21 -0
- package/types/generated/auto-imports.d.ts +124 -0
- package/types/generated/components.d.ts +151 -0
- package/vite.config.ts +239 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/** 密码强度等级。 */
|
|
2
|
+
export type PasswordStrengthLevel = "empty" | "low" | "medium" | "high";
|
|
3
|
+
|
|
4
|
+
/** 密码强度分析结果。 */
|
|
5
|
+
export interface PasswordStrengthResult {
|
|
6
|
+
/** 命中的复杂度条件数量。 */
|
|
7
|
+
ruleScore: number;
|
|
8
|
+
/** 强度条得分。 */
|
|
9
|
+
strengthScore: number;
|
|
10
|
+
/** 强度等级。 */
|
|
11
|
+
level: PasswordStrengthLevel;
|
|
12
|
+
/** 强度文案。 */
|
|
13
|
+
text: string;
|
|
14
|
+
/** 是否达到允许提交的最高强度。 */
|
|
15
|
+
isValid: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** 密码强度错误提示。 */
|
|
19
|
+
export const PASSWORD_STRENGTH_ERROR_MESSAGE = "密码需同时包含大小写字母、数字、特殊字符,且长度不少于 8 位";
|
|
20
|
+
|
|
21
|
+
/** 密码强度说明文案。 */
|
|
22
|
+
export const PASSWORD_STRENGTH_TIP = "需同时包含大小写字母、数字、特殊字符,且长度不少于 8 位,达到最高强度后才可提交。";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 计算密码强度结果,供表单展示和校验统一复用。
|
|
26
|
+
*
|
|
27
|
+
* @param password 当前密码
|
|
28
|
+
* @returns 密码强度分析结果
|
|
29
|
+
*/
|
|
30
|
+
export function getPasswordStrength(password?: string): PasswordStrengthResult {
|
|
31
|
+
if (!password) {
|
|
32
|
+
return {
|
|
33
|
+
ruleScore: 0,
|
|
34
|
+
strengthScore: 0,
|
|
35
|
+
level: "empty",
|
|
36
|
+
text: "未输入",
|
|
37
|
+
isValid: false
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let ruleScore = 0;
|
|
42
|
+
if (password.length >= 8) ruleScore += 1;
|
|
43
|
+
if (/[a-z]/.test(password) && /[A-Z]/.test(password)) ruleScore += 1;
|
|
44
|
+
if (/\d/.test(password)) ruleScore += 1;
|
|
45
|
+
if (/[^A-Za-z0-9]/.test(password)) ruleScore += 1;
|
|
46
|
+
|
|
47
|
+
if (ruleScore >= 4) {
|
|
48
|
+
return {
|
|
49
|
+
ruleScore,
|
|
50
|
+
strengthScore: 3,
|
|
51
|
+
level: "high",
|
|
52
|
+
text: "高",
|
|
53
|
+
isValid: true
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
if (ruleScore === 3) {
|
|
57
|
+
return {
|
|
58
|
+
ruleScore,
|
|
59
|
+
strengthScore: 2,
|
|
60
|
+
level: "medium",
|
|
61
|
+
text: "中",
|
|
62
|
+
isValid: false
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
ruleScore,
|
|
67
|
+
strengthScore: 1,
|
|
68
|
+
level: "low",
|
|
69
|
+
text: "低",
|
|
70
|
+
isValid: false
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* 校验密码是否达到最高强度,便于表单规则直接复用。
|
|
76
|
+
*
|
|
77
|
+
* @param password 当前密码
|
|
78
|
+
* @returns 校验结果
|
|
79
|
+
*/
|
|
80
|
+
export function validatePasswordStrengthValue(password?: string) {
|
|
81
|
+
const result = getPasswordStrength(password);
|
|
82
|
+
return {
|
|
83
|
+
valid: result.isValid,
|
|
84
|
+
message: result.isValid ? "" : PASSWORD_STRENGTH_ERROR_MESSAGE
|
|
85
|
+
};
|
|
86
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { ColumnProps, EnumProps, TypeProps } from "../components/ProTable/interface";
|
|
2
|
+
import type { OptionBaseDictResponse_BaseDictItem } from "../rpc/system/admin/v1/base_dict";
|
|
3
|
+
import { useDictStoreHook } from "../stores/modules/dict";
|
|
4
|
+
import { isRef } from "vue";
|
|
5
|
+
|
|
6
|
+
/** 字典值输出给表格枚举时的目标类型。 */
|
|
7
|
+
type DictValueType = "number" | "string";
|
|
8
|
+
/** 表格批量操作支持的主键类型。 */
|
|
9
|
+
type SelectedId = string | number;
|
|
10
|
+
|
|
11
|
+
/** 表格单元格支持的对齐方式。 */
|
|
12
|
+
export type TableAlign = "left" | "center" | "right";
|
|
13
|
+
|
|
14
|
+
/** 表格分页入参。 */
|
|
15
|
+
type PageRequestParams = Record<string, any> & {
|
|
16
|
+
/** 当前页码。 */
|
|
17
|
+
page_num?: string | number;
|
|
18
|
+
/** 每页条数。 */
|
|
19
|
+
page_size?: string | number;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/** 归一化后的分页请求。 */
|
|
23
|
+
type NormalizedPageRequest<T extends PageRequestParams> = T & {
|
|
24
|
+
/** 接口请求当前页码。 */
|
|
25
|
+
page_num: number;
|
|
26
|
+
/** 接口请求每页条数。 */
|
|
27
|
+
page_size: number;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 获取表格行的列值,支持点号分隔的多级字段。
|
|
32
|
+
*/
|
|
33
|
+
function getTableCellValue(row: Record<string, any>, prop: string) {
|
|
34
|
+
return prop.split(".").reduce((value, key) => (value == null ? undefined : value[key]), row as any);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 判断值是否为可用于数值对齐的 Number 类型。
|
|
39
|
+
*/
|
|
40
|
+
function isPureNumber(value: unknown) {
|
|
41
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 判断枚举是否来自数据表映射,远程函数和响应式选项都属于动态数据映射。
|
|
46
|
+
*/
|
|
47
|
+
function isDataTableEnum(enumValue: ColumnProps["enum"]) {
|
|
48
|
+
return typeof enumValue === "function" || isRef(enumValue);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 根据列语义和当前表格数据解析单元格对齐方式。
|
|
53
|
+
*
|
|
54
|
+
* 显式 align 始终优先;数据表映射按文本左对齐,字典、静态枚举及预置状态列居中,
|
|
55
|
+
* 金额列和纯数字列右对齐,其余内容左对齐。空表时会先按列语义返回默认值,
|
|
56
|
+
* 数据加载后由响应式表格重新解析。
|
|
57
|
+
*/
|
|
58
|
+
export function resolveTableColumnAlign(column: ColumnProps, rows: Record<string, any>[] = []): TableAlign {
|
|
59
|
+
if (column.align === "left" || column.align === "center" || column.align === "right") return column.align;
|
|
60
|
+
|
|
61
|
+
const centeredTypes: TypeProps[] = ["selection", "radio", "index", "expand", "sort"];
|
|
62
|
+
if (centeredTypes.includes(column.type as TypeProps)) return "center";
|
|
63
|
+
if (column.cellType === "actions" || column.cellType === "status" || column.cellType === "image") return "center";
|
|
64
|
+
if (column.cellType === "money") return "right";
|
|
65
|
+
if (column.dictCode || column.tag) return "center";
|
|
66
|
+
if (column.enum) return isDataTableEnum(column.enum) ? "left" : "center";
|
|
67
|
+
|
|
68
|
+
if (column.prop) {
|
|
69
|
+
const values = rows
|
|
70
|
+
.map(row => getTableCellValue(row, column.prop as string))
|
|
71
|
+
.filter(value => value !== undefined && value !== null && value !== "");
|
|
72
|
+
if (values.length && values.every(isPureNumber)) return "right";
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return "left";
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* 按配置将字典值转换为表格枚举可识别的类型。
|
|
80
|
+
*/
|
|
81
|
+
function transformDictValue(dictItem: OptionBaseDictResponse_BaseDictItem, valueType: DictValueType) {
|
|
82
|
+
if (valueType === "number") return Number(dictItem.value);
|
|
83
|
+
return dictItem.value;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* 将字典缓存转换为 ProTable 搜索枚举数据。
|
|
88
|
+
*/
|
|
89
|
+
export async function buildDictEnum(code: string, valueType: DictValueType = "number") {
|
|
90
|
+
const dictStore = useDictStoreHook();
|
|
91
|
+
const dictList = await dictStore.ensureDictionary(code);
|
|
92
|
+
|
|
93
|
+
const data: EnumProps[] = dictList.map(dictItem => ({
|
|
94
|
+
label: dictItem.label,
|
|
95
|
+
value: transformDictValue(dictItem, valueType),
|
|
96
|
+
tagType: dictItem.tag_type
|
|
97
|
+
}));
|
|
98
|
+
|
|
99
|
+
return { data };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* 统一补齐分页请求参数,避免组件透传时出现字符串页码。
|
|
104
|
+
*/
|
|
105
|
+
export function buildPageRequest<T extends PageRequestParams>(params: T): NormalizedPageRequest<T> {
|
|
106
|
+
const pageNum = Number(params.page_num ?? 1);
|
|
107
|
+
const pageSize = Number(params.page_size ?? 10);
|
|
108
|
+
return {
|
|
109
|
+
...params,
|
|
110
|
+
page_num: pageNum,
|
|
111
|
+
page_size: pageSize
|
|
112
|
+
} as NormalizedPageRequest<T>;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* 统一整理表格多选和单条操作产生的 ID 集合。
|
|
117
|
+
*/
|
|
118
|
+
export function normalizeSelectedIds(selected?: SelectedId | SelectedId[]) {
|
|
119
|
+
if (Array.isArray(selected)) {
|
|
120
|
+
return selected.filter(item => item !== undefined && item !== null && item !== "");
|
|
121
|
+
}
|
|
122
|
+
if (selected === undefined || selected === null || selected === "") return [];
|
|
123
|
+
return [selected];
|
|
124
|
+
}
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import axios, { type InternalAxiosRequestConfig, type AxiosResponse, type AxiosError } from "axios";
|
|
2
|
+
import qs from "qs";
|
|
3
|
+
import { ElMessage, ElMessageBox } from "element-plus";
|
|
4
|
+
import router from "../routers";
|
|
5
|
+
import { LOGIN_URL } from "../config";
|
|
6
|
+
import pinia from "../stores";
|
|
7
|
+
import { useUserStore } from "../stores/modules/user";
|
|
8
|
+
|
|
9
|
+
const apiBasePath = import.meta.env.VITE_APP_BASE_API || "";
|
|
10
|
+
const apiTargetUrl = import.meta.env.VITE_API_URL || import.meta.env.VITE_APP_API_URL || "";
|
|
11
|
+
export const requestBaseURL = `${apiTargetUrl}${apiBasePath}`;
|
|
12
|
+
const SESSION_URL = "/v1/base/session";
|
|
13
|
+
const TOKEN_URL = "/v1/base/token";
|
|
14
|
+
const CAPTCHA_URL = "/v1/base/captcha";
|
|
15
|
+
const CONFIG_URL = "/v1/base/config";
|
|
16
|
+
const PASSWORD_PUBLIC_KEY_URL = "/v1/base/password-public-key";
|
|
17
|
+
const OAUTH_PROVIDER_URL = "/v1/base/oauth/provider";
|
|
18
|
+
const OAUTH_AUTHORIZATION_URL = "/v1/base/oauth/authorization";
|
|
19
|
+
const OAUTH_TICKET_URL = "/v1/base/oauth/ticket";
|
|
20
|
+
const LEGACY_AUTH_URL = "/auth";
|
|
21
|
+
const LEGACY_REFRESH_TOKEN_URL = `${LEGACY_AUTH_URL}/token`;
|
|
22
|
+
const LEGACY_CAPTCHA_URL = "/login/captcha";
|
|
23
|
+
// 认证公共接口不携带旧 token,同时保留旧路径兼容迁移期间的灰度访问。
|
|
24
|
+
const NO_AUTH_URL_SET = new Set([
|
|
25
|
+
SESSION_URL,
|
|
26
|
+
TOKEN_URL,
|
|
27
|
+
CAPTCHA_URL,
|
|
28
|
+
CONFIG_URL,
|
|
29
|
+
PASSWORD_PUBLIC_KEY_URL,
|
|
30
|
+
OAUTH_PROVIDER_URL,
|
|
31
|
+
OAUTH_AUTHORIZATION_URL,
|
|
32
|
+
OAUTH_TICKET_URL,
|
|
33
|
+
LEGACY_AUTH_URL,
|
|
34
|
+
LEGACY_CAPTCHA_URL,
|
|
35
|
+
LEGACY_REFRESH_TOKEN_URL
|
|
36
|
+
]);
|
|
37
|
+
const AUTH_EXPIRED_EXCLUDED_URL_SET = new Set([
|
|
38
|
+
SESSION_URL,
|
|
39
|
+
TOKEN_URL,
|
|
40
|
+
CAPTCHA_URL,
|
|
41
|
+
CONFIG_URL,
|
|
42
|
+
PASSWORD_PUBLIC_KEY_URL,
|
|
43
|
+
OAUTH_PROVIDER_URL,
|
|
44
|
+
OAUTH_AUTHORIZATION_URL,
|
|
45
|
+
OAUTH_TICKET_URL,
|
|
46
|
+
LEGACY_AUTH_URL,
|
|
47
|
+
LEGACY_REFRESH_TOKEN_URL,
|
|
48
|
+
LEGACY_CAPTCHA_URL
|
|
49
|
+
]);
|
|
50
|
+
|
|
51
|
+
/** 支持自动重试的 Axios 请求配置。 */
|
|
52
|
+
type RetryableRequestConfig = InternalAxiosRequestConfig & {
|
|
53
|
+
/** 标记当前请求已经因认证失败重试过,避免刷新失败时递归重放。 */
|
|
54
|
+
_authRetried?: boolean;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// 创建 axios 实例
|
|
58
|
+
const service = axios.create({
|
|
59
|
+
baseURL: requestBaseURL,
|
|
60
|
+
timeout: 50000,
|
|
61
|
+
headers: { "Content-Type": "application/json;charset=utf-8" },
|
|
62
|
+
paramsSerializer: params => qs.stringify(params)
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// 刷新令牌请求使用独立实例,避免与主请求拦截器互相递归。
|
|
66
|
+
const refreshService = axios.create({
|
|
67
|
+
baseURL: requestBaseURL,
|
|
68
|
+
timeout: 50000,
|
|
69
|
+
headers: { "Content-Type": "application/json;charset=utf-8" }
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
/** 获取用户状态仓库 */
|
|
73
|
+
function getUserStore() {
|
|
74
|
+
return useUserStore(pinia);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** 判断当前请求是否需要跳过认证头 */
|
|
78
|
+
function shouldSkipAuth(config: InternalAxiosRequestConfig) {
|
|
79
|
+
if (config.headers.Authorization === "no-auth") return true;
|
|
80
|
+
|
|
81
|
+
const requestUrl = config.url ?? "";
|
|
82
|
+
return NO_AUTH_URL_SET.has(requestUrl);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** 判断当前请求是否不应触发登录失效弹窗 */
|
|
86
|
+
function shouldSkipAuthExpiredPrompt(config?: InternalAxiosRequestConfig) {
|
|
87
|
+
if (!config) return false;
|
|
88
|
+
|
|
89
|
+
const requestUrl = config.url ?? "";
|
|
90
|
+
return AUTH_EXPIRED_EXCLUDED_URL_SET.has(requestUrl);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** 判断当前请求是否需要静默掉错误提示。 */
|
|
94
|
+
function shouldSkipErrorMessage(config?: InternalAxiosRequestConfig) {
|
|
95
|
+
if (!config) return false;
|
|
96
|
+
|
|
97
|
+
const requestUrl = config.url ?? "";
|
|
98
|
+
const requestMethod = String(config.method ?? "").toLowerCase();
|
|
99
|
+
return (requestUrl === SESSION_URL || requestUrl === LEGACY_AUTH_URL) && requestMethod === "delete";
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** 读取访问令牌过期时间 */
|
|
103
|
+
function getTokenExpiresAt() {
|
|
104
|
+
return getUserStore().tokenExpiresAt;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** 判断当前访问令牌是否仍在有效期内。 */
|
|
108
|
+
export function hasValidAccessToken() {
|
|
109
|
+
const userStore = getUserStore();
|
|
110
|
+
return Boolean(userStore.token.trim() && userStore.tokenExpiresAt > Date.now());
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** 读取最新可用访问令牌,必要时先串行刷新,供 axios、fetch 与 SSE 共用。 */
|
|
114
|
+
export async function getRequestAccessToken(): Promise<string> {
|
|
115
|
+
const userStore = getUserStore();
|
|
116
|
+
if (!userStore.token && userStore.refreshToken) {
|
|
117
|
+
await handleTokenRefresh(false);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const expiresAt = getTokenExpiresAt();
|
|
121
|
+
const remainingTime = expiresAt - Date.now();
|
|
122
|
+
if (expiresAt && remainingTime <= 5 * 60 * 1000) {
|
|
123
|
+
await handleTokenRefresh(false);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return getUserStore().token.trim();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** 尝试通过刷新令牌恢复访问令牌,供路由守卫进入页面前调用。 */
|
|
130
|
+
export async function ensureAccessToken() {
|
|
131
|
+
if (hasValidAccessToken()) {
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const userStore = getUserStore();
|
|
136
|
+
if (!userStore.refreshToken) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
try {
|
|
141
|
+
await handleTokenRefresh(false);
|
|
142
|
+
return hasValidAccessToken();
|
|
143
|
+
} catch {
|
|
144
|
+
userStore.clearAuthData();
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// 防止并发 401 重复弹出认证失效确认框。
|
|
150
|
+
let isHandlingAuthExpired = false;
|
|
151
|
+
|
|
152
|
+
/** 统一处理认证失效 */
|
|
153
|
+
export function handleAuthExpired() {
|
|
154
|
+
if (isHandlingAuthExpired) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
isHandlingAuthExpired = true;
|
|
159
|
+
ElMessageBox.confirm("登录状态已失效,请重新登录", "提示", {
|
|
160
|
+
confirmButtonText: "重新登录",
|
|
161
|
+
cancelButtonText: "取消",
|
|
162
|
+
type: "warning",
|
|
163
|
+
closeOnClickModal: false,
|
|
164
|
+
closeOnPressEscape: false
|
|
165
|
+
})
|
|
166
|
+
.then(() => {
|
|
167
|
+
const userStore = getUserStore();
|
|
168
|
+
const currentRoute = router.currentRoute.value;
|
|
169
|
+
const redirect = currentRoute.path === LOGIN_URL ? undefined : currentRoute.fullPath;
|
|
170
|
+
userStore.clearAuthData();
|
|
171
|
+
return router.replace({
|
|
172
|
+
path: LOGIN_URL,
|
|
173
|
+
query: redirect ? { redirect } : undefined
|
|
174
|
+
});
|
|
175
|
+
})
|
|
176
|
+
.finally(() => {
|
|
177
|
+
isHandlingAuthExpired = false;
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// 请求拦截器
|
|
182
|
+
service.interceptors.request.use(
|
|
183
|
+
async (config: InternalAxiosRequestConfig) => {
|
|
184
|
+
const skipAuth = shouldSkipAuth(config);
|
|
185
|
+
const accessToken = skipAuth ? "" : await getRequestAccessToken();
|
|
186
|
+
// 登录、验证码、刷新令牌接口不携带旧 token,避免请求头污染。
|
|
187
|
+
if (!skipAuth && accessToken) {
|
|
188
|
+
config.headers.Authorization = accessToken;
|
|
189
|
+
} else {
|
|
190
|
+
delete config.headers.Authorization;
|
|
191
|
+
}
|
|
192
|
+
return config;
|
|
193
|
+
},
|
|
194
|
+
error => Promise.reject(error)
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
// 响应拦截器
|
|
198
|
+
service.interceptors.response.use(
|
|
199
|
+
(response: AxiosResponse) => {
|
|
200
|
+
// 如果响应是二进制流,则直接返回,用于下载文件、Excel 导出等
|
|
201
|
+
if (response.config.responseType === "blob") {
|
|
202
|
+
return response;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const { code, message, reason, metadata } = response.data;
|
|
206
|
+
if (code === undefined || message === undefined || reason === undefined || metadata === undefined) {
|
|
207
|
+
return response.data;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
ElMessage.error(message || "系统出错");
|
|
211
|
+
return Promise.reject(new Error(message || "Error"));
|
|
212
|
+
},
|
|
213
|
+
async (error: AxiosError) => {
|
|
214
|
+
const status = error.response?.status;
|
|
215
|
+
const data = error.response?.data as { code?: string | number; message?: string } | undefined;
|
|
216
|
+
const code = data?.code;
|
|
217
|
+
const message = data?.message;
|
|
218
|
+
const requestConfig = error.config as RetryableRequestConfig | undefined;
|
|
219
|
+
|
|
220
|
+
// 业务请求仅在 401 时尝试刷新并重放,403 直接展示后端权限错误。
|
|
221
|
+
if ((status === 401 || code === 401) && !shouldSkipAuthExpiredPrompt(requestConfig)) {
|
|
222
|
+
if (requestConfig && !requestConfig._authRetried && getUserStore().refreshToken) {
|
|
223
|
+
requestConfig._authRetried = true;
|
|
224
|
+
try {
|
|
225
|
+
await handleTokenRefresh(false);
|
|
226
|
+
requestConfig.headers.Authorization = getUserStore().token.trim();
|
|
227
|
+
return service(requestConfig);
|
|
228
|
+
} catch (refreshError) {
|
|
229
|
+
console.log("token 刷新失败", refreshError);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
handleAuthExpired();
|
|
233
|
+
} else if (data) {
|
|
234
|
+
if (!shouldSkipErrorMessage(requestConfig)) {
|
|
235
|
+
if (message) {
|
|
236
|
+
ElMessage.error(message);
|
|
237
|
+
} else {
|
|
238
|
+
ElMessage.error("系统出错");
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
} else if (!shouldSkipErrorMessage(requestConfig)) {
|
|
242
|
+
ElMessage.error(error.message || "系统出错");
|
|
243
|
+
}
|
|
244
|
+
return Promise.reject(error.message);
|
|
245
|
+
}
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
export default service;
|
|
249
|
+
|
|
250
|
+
// 刷新 Token 的锁
|
|
251
|
+
let isRefreshing = false;
|
|
252
|
+
let refreshPromise: Promise<void> | null = null;
|
|
253
|
+
|
|
254
|
+
/** 刷新 Token 处理 */
|
|
255
|
+
async function handleTokenRefresh(promptOnFailure = true) {
|
|
256
|
+
if (!isRefreshing) {
|
|
257
|
+
isRefreshing = true;
|
|
258
|
+
refreshPromise = refreshAccessToken()
|
|
259
|
+
.catch(error => {
|
|
260
|
+
if (promptOnFailure) {
|
|
261
|
+
console.log("token 刷新失败", error);
|
|
262
|
+
handleAuthExpired();
|
|
263
|
+
}
|
|
264
|
+
throw error;
|
|
265
|
+
})
|
|
266
|
+
.finally(() => {
|
|
267
|
+
isRefreshing = false;
|
|
268
|
+
refreshPromise = null;
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (refreshPromise) {
|
|
273
|
+
await refreshPromise;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/** 调用刷新令牌接口并回写最新认证信息 */
|
|
278
|
+
async function refreshAccessToken() {
|
|
279
|
+
const userStore = getUserStore();
|
|
280
|
+
if (!userStore.refreshToken) {
|
|
281
|
+
return Promise.reject(new Error("refresh token 不存在"));
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const response = await refreshService.post(
|
|
285
|
+
TOKEN_URL,
|
|
286
|
+
{ refresh_token: userStore.refreshToken },
|
|
287
|
+
{ headers: { Authorization: "no-auth" } }
|
|
288
|
+
);
|
|
289
|
+
const data = response.data;
|
|
290
|
+
userStore.updateTokenAuth(
|
|
291
|
+
data.access_token,
|
|
292
|
+
data.refresh_token ?? userStore.refreshToken,
|
|
293
|
+
data.token_type ?? "",
|
|
294
|
+
data.expires_in
|
|
295
|
+
);
|
|
296
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { RouteLocationRaw, Router } from "vue-router";
|
|
2
|
+
import { initDynamicRouter } from "../routers/modules/dynamicRouter";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 判断当前解析结果是否只命中了全局 404 占位路由。
|
|
6
|
+
*/
|
|
7
|
+
export function isUnmatchedRoute(router: Router, path: string) {
|
|
8
|
+
const resolved = router.resolve(path);
|
|
9
|
+
if (!resolved.matched.length) return true;
|
|
10
|
+
return resolved.matched.some(item => item.path === "/:pathMatch(.*)*");
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 将前端路由地址转换为当前站点的绝对 URL,供后端 OAuth 回调重定向使用。
|
|
15
|
+
*/
|
|
16
|
+
export function resolveFrontendRouteURL(router: Router, location: RouteLocationRaw) {
|
|
17
|
+
const href = router.resolve(location).href;
|
|
18
|
+
if (href.startsWith("#")) {
|
|
19
|
+
return `${window.location.origin}${window.location.pathname}${window.location.search}${href}`;
|
|
20
|
+
}
|
|
21
|
+
const frontendHref = href.startsWith("/") ? href : `${window.location.pathname}${window.location.search}${href}`;
|
|
22
|
+
return new URL(frontendHref, window.location.origin).toString();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 统一处理站内页面跳转;若目标路由尚未注册,则补跑动态路由初始化后重试。
|
|
27
|
+
* 若路由实例已可解析但 push 失败,则降级为浏览器地址跳转。
|
|
28
|
+
*/
|
|
29
|
+
export async function navigateTo(router: Router, path: string, query?: Record<string, string | number>) {
|
|
30
|
+
const target = { path, query };
|
|
31
|
+
|
|
32
|
+
// 隐藏业务页依赖动态菜单注册,首次进入或权限刚调整后可能尚未挂载到路由实例。
|
|
33
|
+
if (isUnmatchedRoute(router, path)) {
|
|
34
|
+
await initDynamicRouter().catch(() => undefined);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (isUnmatchedRoute(router, path)) return;
|
|
38
|
+
|
|
39
|
+
return router.push(target).catch(() => {
|
|
40
|
+
const fallbackResolved = router.resolve(target);
|
|
41
|
+
window.location.href = fallbackResolved.href;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description Loading Svg
|
|
3
|
+
*/
|
|
4
|
+
export const loadingSvg = `
|
|
5
|
+
<path class="path" d="
|
|
6
|
+
M 30 15
|
|
7
|
+
L 28 17
|
|
8
|
+
M 25.61 25.61
|
|
9
|
+
A 15 15, 0, 0, 1, 15 30
|
|
10
|
+
A 15 15, 0, 1, 1, 27.99 7.5
|
|
11
|
+
L 15 15
|
|
12
|
+
" style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"/>
|
|
13
|
+
`;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { defBaseTenantService } from "../api/system/base_tenant";
|
|
2
|
+
|
|
3
|
+
/** 默认租户编码。 */
|
|
4
|
+
export const DEFAULT_TENANT_CODE = "0000";
|
|
5
|
+
|
|
6
|
+
/** 读取租户列表筛选选项。 */
|
|
7
|
+
export async function requestTenantOptions() {
|
|
8
|
+
const response = await defBaseTenantService.OptionBaseTenant({ keyword: "" });
|
|
9
|
+
return { data: response.list ?? [] };
|
|
10
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON 格式化显示。
|
|
3
|
+
*/
|
|
4
|
+
export function formatJson(str: string) {
|
|
5
|
+
try {
|
|
6
|
+
return JSON.stringify(JSON.parse(str), null, 2);
|
|
7
|
+
} catch {
|
|
8
|
+
return str;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 将后端分单位金额转换为元字符串。
|
|
14
|
+
*/
|
|
15
|
+
export function formatPrice(price?: number) {
|
|
16
|
+
if (!price) return "0.00";
|
|
17
|
+
return (price / 100).toFixed(2);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 按静态资源域名补齐图片地址。
|
|
22
|
+
*/
|
|
23
|
+
export function formatSrc(src: string) {
|
|
24
|
+
const value = String(src ?? "").trim();
|
|
25
|
+
if (!value) return value;
|
|
26
|
+
if (/^(https?:)?\/\//.test(value) || value.startsWith("data:") || value.startsWith("blob:")) {
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const configuredBase = String(import.meta.env.VITE_APP_STATIC_URL ?? "").trim();
|
|
31
|
+
if (value.startsWith("/admin/")) {
|
|
32
|
+
return new URL(value, `${window.location.origin}/`).toString();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const staticBase = configuredBase
|
|
36
|
+
? new URL(`${configuredBase.replace(/\/$/, "")}/`, `${window.location.origin}/`).toString()
|
|
37
|
+
: `${window.location.origin}/admin/`;
|
|
38
|
+
const normalizedPath = value.replace(/^\/+/, "").replace(/^admin\/+/, "");
|
|
39
|
+
return new URL(normalizedPath, staticBase).toString();
|
|
40
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<script setup lang="ts" name="403">
|
|
2
|
+
import errorImage from "../../assets/images/403.png";
|
|
3
|
+
import ErrorMessage from "../../components/ErrorMessage/index.vue";
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<template>
|
|
7
|
+
<ErrorMessage code="403" :image="errorImage" message="抱歉,您无权访问该页面~🙅♂️🙅♀️" />
|
|
8
|
+
</template>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<script setup lang="ts" name="404">
|
|
2
|
+
import errorImage from "../../assets/images/404.png";
|
|
3
|
+
import ErrorMessage from "../../components/ErrorMessage/index.vue";
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<template>
|
|
7
|
+
<ErrorMessage code="404" :image="errorImage" message="抱歉,您访问的页面不存在~🤷♂️🤷♀️" />
|
|
8
|
+
</template>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<script setup lang="ts" name="500">
|
|
2
|
+
import errorImage from "../../assets/images/500.png";
|
|
3
|
+
import ErrorMessage from "../../components/ErrorMessage/index.vue";
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<template>
|
|
7
|
+
<ErrorMessage code="500" :image="errorImage" message="抱歉,您的网络不见了~🤦♂️🤦♀️" />
|
|
8
|
+
</template>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<script setup lang="ts" name="Pending"></script>
|
|
2
|
+
|
|
3
|
+
<template>
|
|
4
|
+
<div class="route-pending page-card">
|
|
5
|
+
<el-empty description="该页面暂不可用,请联系管理员检查菜单组件配置" />
|
|
6
|
+
</div>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<style scoped lang="scss">
|
|
10
|
+
.route-pending {
|
|
11
|
+
display: flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
justify-content: center;
|
|
14
|
+
min-height: 360px;
|
|
15
|
+
}
|
|
16
|
+
</style>
|