From 1595cb282aab5399862fac6406b5de550863e3b6 Mon Sep 17 00:00:00 2001
From: 疯狂的狮子Li <15040126243@163.com>
Date: 星期一, 03 四月 2023 00:05:09 +0800
Subject: [PATCH] update 调整代码格式

---
 src/api/system/menu/index.ts                  |   70 
 src/assets/styles/index.scss                  |  192 
 src/api/demo/types.ts                         |   72 
 src/directive/index.ts                        |    6 
 src/store/modules/dict.ts                     |  138 
 src/api/demo/demo.ts                          |   56 
 src/api/system/dept/index.ts                  |   62 
 src/layout/index.vue                          |   24 
 src/views/system/tenant/index.vue             |  514 
 src/views/system/user/authRole.vue            |  172 
 src/views/monitor/logininfor/index.vue        |  280 
 src/views/monitor/operlog/index.vue           |  461 
 src/assets/styles/ruoyi.scss                  |  244 
 html/ie.html                                  |  114 
 src/store/modules/permission.ts               |  230 
 src/api/system/menu/types.ts                  |   88 
 src/utils/errorCode.ts                        |    8 
 src/views/system/tenantPackage/index.vue      |  436 
 src/settings.ts                               |   84 
 src/components/ImageUpload/index.vue          |  298 
 src/plugins/auth.ts                           |  100 
 src/views/monitor/cache/index.vue             |  332 
 src/views/error/404.vue                       |   40 
 src/api/system/dept/types.ts                  |   56 
 src/enums/RespEnum.ts                         |  176 
 src/api/monitor/online/types.ts               |   20 
 src/components/SizeSelect/index.vue           |   28 
 src/views/system/oss/index.vue                |  498 
 src/components/Breadcrumb/index.vue           |   62 
 src/layout/components/Sidebar/Link.vue        |    6 
 src/api/system/ossConfig/types.ts             |   60 
 src/directive/permission/index.ts             |   62 
 src/components/Hamburger/index.vue            |   14 
 src/views/tool/gen/index.vue                  |  338 
 src/components/ParentView/index.vue           |    2 
 vite/plugins/compression.ts                   |   28 
 src/utils/validate.ts                         |   42 
 src/components/TopNav/index.vue               |   40 
 src/components/ImagePreview/index.vue         |   14 
 src/api/monitor/loginInfo/types.ts            |   30 
 src/assets/styles/mixin.scss                  |   86 
 src/views/system/role/index.vue               |  726 
 src/views/system/oss/config.vue               |  541 
 src/api/system/dict/type/types.ts             |   26 
 src/api/system/notice/types.ts                |   36 
 vite/plugins/components.ts                    |   17 
 src/assets/styles/variables.module.scss       |   30 
 src/components/Editor/index.vue               |  256 
 src/api/system/ossConfig/index.ts             |   66 
 src/api/system/notice/index.ts                |   46 
 src/plugins/svgicon.ts                        |   10 
 src/views/system/menu/index.vue               |  684 
 vite.config.ts                                |  208 
 src/views/error/401.vue                       |   36 
 src/enums/layout/LayoutEnum.ts                |    4 
 src/views/system/dict/data.vue                |  444 
 src/views/tool/gen/editTable.vue              |  308 
 src/api/system/dict/type/index.ts             |   62 
 src/api/system/post/types.ts                  |   30 
 src/layout/components/Sidebar/index.vue       |   40 
 src/views/tool/gen/importTable.vue            |  122 
 src/api/system/post/index.ts                  |   46 
 vite/plugins/index.ts                         |   20 
 src/components/RuoYiDoc/index.vue             |    6 
 src/lang/en.ts                                |   46 
 src/assets/styles/sidebar.scss                |  384 
 src/views/system/dept/index.vue               |  438 
 .eslintrc-auto-import.json                    |  558 
 src/store/modules/tagsView.ts                 |  366 
 src/api/login.ts                              |   92 
 src/assets/styles/element-ui.scss             |   86 
 src/store/modules/user.ts                     |  128 
 src/layout/components/TagsView/index.vue      |  310 
 src/types/axios.d.ts                          |   12 
 src/api/types.ts                              |   44 
 src/utils/i18n.ts                             |   14 
 src/permission.ts                             |   84 
 src/api/monitor/loginInfo/index.ts            |   34 
 src/components/TreeSelect/index.vue           |   54 
 src/utils/index.ts                            |  338 
 src/plugins/index.ts                          |   20 
 src/utils/theme.ts                            |   66 
 src/views/system/user/profile/userInfo.vue    |   42 
 src/components/iFrame/index.vue               |    6 
 src/views/system/user/profile/resetPwd.vue    |   30 
 src/layout/components/AppMain.vue             |   40 
 src/utils/ruoyi.ts                            |  370 
 src/api/tool/gen/types.ts                     |  304 
 vite/plugins/auto-import.ts                   |   24 
 src/api/tool/gen/index.ts                     |   98 
 src/views/index.vue                           |  186 
 src/store/modules/app.ts                      |  120 
 src/assets/styles/btn.scss                    |  124 
 src/views/system/user/profile/userAvatar.vue  |  104 
 src/components/Screenfull/index.vue           |    6 
 src/utils/dynamicTitle.ts                     |   12 
 src/enums/MenuTypeEnum.ts                     |   24 
 src/directive/common/copyText.ts              |  100 
 src/lang/zh-cn.ts                             |   44 
 src/plugins/modal.ts                          |  152 
 src/views/register.vue                        |  228 
 src/layout/components/InnerLink/index.vue     |   28 
 src/views/monitor/xxljob/index.vue            |    6 
 vite/plugins/unocss.ts                        |   13 
 .eslintrc.js                                  |   78 
 src/layout/components/Sidebar/Logo.vue        |   40 
 src/views/system/role/authUser.vue            |  204 
 index.html                                    |  380 
 src/enums/SettingTypeEnum.ts                  |   26 
 src/plugins/tab.ts                            |  118 
 src/router/index.ts                           |  276 
 src/utils/scroll-to.ts                        |   82 
 src/types/setting.d.ts                        |  120 
 src/views/tool/build/index.vue                |    2 
 vite/plugins/icons.ts                         |    8 
 src/components/IconSelect/requireIcons.ts     |    4 
 src/types/router.d.ts                         |   56 
 src/plugins/download.ts                       |   98 
 src/utils/permission.ts                       |   60 
 src/views/system/post/index.vue               |  346 
 src/utils/request.ts                          |  248 
 src/views/system/user/profile/index.vue       |  134 
 src/views/tool/gen/basicInfoForm.vue          |   62 
 src/assets/styles/transition.scss             |   26 
 src/types/env.d.ts                            |   70 
 src/components/Pagination/index.vue           |  164 
 README.md                                     |  167 
 src/lang/index.ts                             |   46 
 src/utils/jsencrypt.ts                        |   30 
 src/api/demo/tree.ts                          |   46 
 src/api/system/config/index.ts                |   78 
 tsconfig.json                                 |   48 
 src/layout/components/TagsView/ScrollPane.vue |    6 
 src/utils/dict.ts                             |   40 
 src/api/monitor/operlog/index.ts              |   26 
 src/api/monitor/operlog/types.ts              |   88 
 src/plugins/cache.ts                          |  140 
 src/api/menu.ts                               |    8 
 src/views/system/notice/index.vue             |  369 
 src/api/system/oss/index.ts                   |   26 
 src/components/FileUpload/index.vue           |  286 
 src/layout/components/Settings/index.vue      |  144 
 src/api/system/oss/types.ts                   |   30 
 src/views/system/dict/index.vue               |  384 
 src/views/system/config/index.vue             |  282 
 src/types/components.d.ts                     |   17 
 src/api/system/dict/data/index.ts             |   54 
 src/api/system/config/types.ts                |   30 
 src/layout/components/Navbar.vue              |  192 
 src/types/global.d.ts                         |  144 
 src/api/system/dict/data/types.ts             |   42 
 src/types/auto-imports.d.ts                   |    4 
 src/api/monitor/online/index.ts               |   18 
 src/views/redirect/index.vue                  |    2 
 vite/plugins/svg-icon.ts                      |   10 
 src/views/monitor/admin/index.vue             |    6 
 src/store/modules/settings.ts                 |   82 
 src/views/system/role/selectUser.vue          |  152 
 src/components/HeaderSearch/index.vue         |   32 
 src/layout/components/Sidebar/SidebarItem.vue |  160 
 src/api/system/user/types.ts                  |  102 
 src/components/DictTag/index.vue              |   74 
 src/api/monitor/cache/types.ts                |    6 
 src/animate.ts                                |   56 
 src/views/demo/tree/index.vue                 |  430 
 src/api/system/tenantPackage/index.ts         |   64 
 src/components/SvgIcon/index.vue              |    6 
 src/components/RightToolbar/index.vue         |  100 
 src/views/monitor/online/index.vue            |  144 
 commitlint.config.js                          |   40 
 src/api/system/user/index.ts                  |  154 
 src/types/module.d.ts                         |   32 
 /dev/null                                     |   13 
 src/api/system/tenant/types.ts                |   70 
 src/components/IconSelect/index.vue           |   50 
 src/views/system/user/index.vue               |  912 +-
 src/views/login.vue                           |  228 
 src/views/tool/gen/genInfoForm.vue            |  436 
 src/layout/components/IframeToggle/index.vue  |   18 
 src/api/system/tenantPackage/types.ts         |   28 
 src/views/demo/demo/index.vue                 |  522 
 package.json                                  |  156 
 src/components/RuoYiGit/index.vue             |    6 
 src/api/monitor/cache/index.ts                |   56 
 src/api/system/role/index.ts                  |  132 
 src/api/system/role/types.ts                  |   70 
 .prettierrc.cjs                               |   82 
 src/App.vue                                   |    6 
 src/api/system/tenant/index.ts                |  100 
 189 files changed, 12,195 insertions(+), 12,171 deletions(-)

diff --git a/.eslintrc-auto-import.json b/.eslintrc-auto-import.json
index d8190fd..d076c08 100644
--- a/.eslintrc-auto-import.json
+++ b/.eslintrc-auto-import.json
@@ -1,281 +1,281 @@
 {
-	"globals": {
-		"useRouter": true,
-		"useRoute": true,
-		"EffectScope": true,
-		"ElTable": true,
-		"ElSelect": true,
-		"ElUpload": true,
-		"ElForm": true,
-		"ElTree": true,
-		"ElMessage": true,
-		"ElMessageBox": true,
-		"asyncComputed": true,
-		"autoResetRef": true,
-		"computed": true,
-		"computedAsync": true,
-		"computedEager": true,
-		"computedInject": true,
-		"computedWithControl": true,
-		"controlledComputed": true,
-		"controlledRef": true,
-		"createApp": true,
-		"createEventHook": true,
-		"createGlobalState": true,
-		"createInjectionState": true,
-		"createReactiveFn": true,
-		"createSharedComposable": true,
-		"createUnrefFn": true,
-		"customRef": true,
-		"debouncedRef": true,
-		"debouncedWatch": true,
-		"defineAsyncComponent": true,
-		"defineComponent": true,
-		"eagerComputed": true,
-		"effectScope": true,
-		"extendRef": true,
-		"getCurrentInstance": true,
-		"getCurrentScope": true,
-		"h": true,
-		"ignorableWatch": true,
-		"inject": true,
-		"isDefined": true,
-		"isProxy": true,
-		"isReactive": true,
-		"isReadonly": true,
-		"isRef": true,
-		"makeDestructurable": true,
-		"markRaw": true,
-		"nextTick": true,
-		"onActivated": true,
-		"onBeforeMount": true,
-		"onBeforeUnmount": true,
-		"onBeforeUpdate": true,
-		"onClickOutside": true,
-		"onDeactivated": true,
-		"onErrorCaptured": true,
-		"onKeyStroke": true,
-		"onLongPress": true,
-		"onMounted": true,
-		"onRenderTracked": true,
-		"onRenderTriggered": true,
-		"onScopeDispose": true,
-		"onServerPrefetch": true,
-		"onStartTyping": true,
-		"onUnmounted": true,
-		"onUpdated": true,
-		"pausableWatch": true,
-		"provide": true,
-		"reactify": true,
-		"reactifyObject": true,
-		"reactive": true,
-		"reactiveComputed": true,
-		"reactiveOmit": true,
-		"reactivePick": true,
-		"readonly": true,
-		"ref": true,
-		"refAutoReset": true,
-		"refDebounced": true,
-		"refDefault": true,
-		"refThrottled": true,
-		"refWithControl": true,
-		"resolveComponent": true,
-		"resolveDirective": true,
-		"resolveRef": true,
-		"resolveUnref": true,
-		"shallowReactive": true,
-		"shallowReadonly": true,
-		"shallowRef": true,
-		"syncRef": true,
-		"syncRefs": true,
-		"templateRef": true,
-		"throttledRef": true,
-		"throttledWatch": true,
-		"toRaw": true,
-		"toReactive": true,
-		"toRef": true,
-		"toRefs": true,
-		"triggerRef": true,
-		"tryOnBeforeMount": true,
-		"tryOnBeforeUnmount": true,
-		"tryOnMounted": true,
-		"tryOnScopeDispose": true,
-		"tryOnUnmounted": true,
-		"unref": true,
-		"unrefElement": true,
-		"until": true,
-		"useActiveElement": true,
-		"useArrayEvery": true,
-		"useArrayFilter": true,
-		"useArrayFind": true,
-		"useArrayFindIndex": true,
-		"useArrayFindLast": true,
-		"useArrayJoin": true,
-		"useArrayMap": true,
-		"useArrayReduce": true,
-		"useArraySome": true,
-		"useArrayUnique": true,
-		"useAsyncQueue": true,
-		"useAsyncState": true,
-		"useAttrs": true,
-		"useBase64": true,
-		"useBattery": true,
-		"useBluetooth": true,
-		"useBreakpoints": true,
-		"useBroadcastChannel": true,
-		"useBrowserLocation": true,
-		"useCached": true,
-		"useClipboard": true,
-		"useCloned": true,
-		"useColorMode": true,
-		"useConfirmDialog": true,
-		"useCounter": true,
-		"useCssModule": true,
-		"useCssVar": true,
-		"useCssVars": true,
-		"useCurrentElement": true,
-		"useCycleList": true,
-		"useDark": true,
-		"useDateFormat": true,
-		"useDebounce": true,
-		"useDebounceFn": true,
-		"useDebouncedRefHistory": true,
-		"useDeviceMotion": true,
-		"useDeviceOrientation": true,
-		"useDevicePixelRatio": true,
-		"useDevicesList": true,
-		"useDisplayMedia": true,
-		"useDocumentVisibility": true,
-		"useDraggable": true,
-		"useDropZone": true,
-		"useElementBounding": true,
-		"useElementByPoint": true,
-		"useElementHover": true,
-		"useElementSize": true,
-		"useElementVisibility": true,
-		"useEventBus": true,
-		"useEventListener": true,
-		"useEventSource": true,
-		"useEyeDropper": true,
-		"useFavicon": true,
-		"useFetch": true,
-		"useFileDialog": true,
-		"useFileSystemAccess": true,
-		"useFocus": true,
-		"useFocusWithin": true,
-		"useFps": true,
-		"useFullscreen": true,
-		"useGamepad": true,
-		"useGeolocation": true,
-		"useIdle": true,
-		"useImage": true,
-		"useInfiniteScroll": true,
-		"useIntersectionObserver": true,
-		"useInterval": true,
-		"useIntervalFn": true,
-		"useKeyModifier": true,
-		"useLastChanged": true,
-		"useLocalStorage": true,
-		"useMagicKeys": true,
-		"useManualRefHistory": true,
-		"useMediaControls": true,
-		"useMediaQuery": true,
-		"useMemoize": true,
-		"useMemory": true,
-		"useMounted": true,
-		"useMouse": true,
-		"useMouseInElement": true,
-		"useMousePressed": true,
-		"useMutationObserver": true,
-		"useNavigatorLanguage": true,
-		"useNetwork": true,
-		"useNow": true,
-		"useObjectUrl": true,
-		"useOffsetPagination": true,
-		"useOnline": true,
-		"usePageLeave": true,
-		"useParallax": true,
-		"usePermission": true,
-		"usePointer": true,
-		"usePointerLock": true,
-		"usePointerSwipe": true,
-		"usePreferredColorScheme": true,
-		"usePreferredContrast": true,
-		"usePreferredDark": true,
-		"usePreferredLanguages": true,
-		"usePreferredReducedMotion": true,
-		"usePrevious": true,
-		"useRafFn": true,
-		"useRefHistory": true,
-		"useResizeObserver": true,
-		"useScreenOrientation": true,
-		"useScreenSafeArea": true,
-		"useScriptTag": true,
-		"useScroll": true,
-		"useScrollLock": true,
-		"useSessionStorage": true,
-		"useShare": true,
-		"useSlots": true,
-		"useSorted": true,
-		"useSpeechRecognition": true,
-		"useSpeechSynthesis": true,
-		"useStepper": true,
-		"useStorage": true,
-		"useStorageAsync": true,
-		"useStyleTag": true,
-		"useSupported": true,
-		"useSwipe": true,
-		"useTemplateRefsList": true,
-		"useTextDirection": true,
-		"useTextSelection": true,
-		"useTextareaAutosize": true,
-		"useThrottle": true,
-		"useThrottleFn": true,
-		"useThrottledRefHistory": true,
-		"useTimeAgo": true,
-		"useTimeout": true,
-		"useTimeoutFn": true,
-		"useTimeoutPoll": true,
-		"useTimestamp": true,
-		"useTitle": true,
-		"useToNumber": true,
-		"useToString": true,
-		"useToggle": true,
-		"useTransition": true,
-		"useUrlSearchParams": true,
-		"useUserMedia": true,
-		"useVModel": true,
-		"useVModels": true,
-		"useVibrate": true,
-		"useVirtualList": true,
-		"useWakeLock": true,
-		"useWebNotification": true,
-		"useWebSocket": true,
-		"useWebWorker": true,
-		"useWebWorkerFn": true,
-		"useWindowFocus": true,
-		"useWindowScroll": true,
-		"useWindowSize": true,
-		"watch": true,
-		"watchArray": true,
-		"watchAtMost": true,
-		"watchDebounced": true,
-		"watchEffect": true,
-		"watchIgnorable": true,
-		"watchOnce": true,
-		"watchPausable": true,
-		"watchPostEffect": true,
-		"watchSyncEffect": true,
-		"watchThrottled": true,
-		"watchTriggerable": true,
-		"watchWithFilter": true,
-		"whenever": true,
-		"ImportOption": true,
-		"TreeType": true,
-		"FieldOption": true,
-		"PageData": true,
-		"storeToRefs": true,
-		"DictDataOption": true,
-		"UploadOption": true
-	}
+  "globals": {
+    "useRouter": true,
+    "useRoute": true,
+    "EffectScope": true,
+    "ElTable": true,
+    "ElSelect": true,
+    "ElUpload": true,
+    "ElForm": true,
+    "ElTree": true,
+    "ElMessage": true,
+    "ElMessageBox": true,
+    "asyncComputed": true,
+    "autoResetRef": true,
+    "computed": true,
+    "computedAsync": true,
+    "computedEager": true,
+    "computedInject": true,
+    "computedWithControl": true,
+    "controlledComputed": true,
+    "controlledRef": true,
+    "createApp": true,
+    "createEventHook": true,
+    "createGlobalState": true,
+    "createInjectionState": true,
+    "createReactiveFn": true,
+    "createSharedComposable": true,
+    "createUnrefFn": true,
+    "customRef": true,
+    "debouncedRef": true,
+    "debouncedWatch": true,
+    "defineAsyncComponent": true,
+    "defineComponent": true,
+    "eagerComputed": true,
+    "effectScope": true,
+    "extendRef": true,
+    "getCurrentInstance": true,
+    "getCurrentScope": true,
+    "h": true,
+    "ignorableWatch": true,
+    "inject": true,
+    "isDefined": true,
+    "isProxy": true,
+    "isReactive": true,
+    "isReadonly": true,
+    "isRef": true,
+    "makeDestructurable": true,
+    "markRaw": true,
+    "nextTick": true,
+    "onActivated": true,
+    "onBeforeMount": true,
+    "onBeforeUnmount": true,
+    "onBeforeUpdate": true,
+    "onClickOutside": true,
+    "onDeactivated": true,
+    "onErrorCaptured": true,
+    "onKeyStroke": true,
+    "onLongPress": true,
+    "onMounted": true,
+    "onRenderTracked": true,
+    "onRenderTriggered": true,
+    "onScopeDispose": true,
+    "onServerPrefetch": true,
+    "onStartTyping": true,
+    "onUnmounted": true,
+    "onUpdated": true,
+    "pausableWatch": true,
+    "provide": true,
+    "reactify": true,
+    "reactifyObject": true,
+    "reactive": true,
+    "reactiveComputed": true,
+    "reactiveOmit": true,
+    "reactivePick": true,
+    "readonly": true,
+    "ref": true,
+    "refAutoReset": true,
+    "refDebounced": true,
+    "refDefault": true,
+    "refThrottled": true,
+    "refWithControl": true,
+    "resolveComponent": true,
+    "resolveDirective": true,
+    "resolveRef": true,
+    "resolveUnref": true,
+    "shallowReactive": true,
+    "shallowReadonly": true,
+    "shallowRef": true,
+    "syncRef": true,
+    "syncRefs": true,
+    "templateRef": true,
+    "throttledRef": true,
+    "throttledWatch": true,
+    "toRaw": true,
+    "toReactive": true,
+    "toRef": true,
+    "toRefs": true,
+    "triggerRef": true,
+    "tryOnBeforeMount": true,
+    "tryOnBeforeUnmount": true,
+    "tryOnMounted": true,
+    "tryOnScopeDispose": true,
+    "tryOnUnmounted": true,
+    "unref": true,
+    "unrefElement": true,
+    "until": true,
+    "useActiveElement": true,
+    "useArrayEvery": true,
+    "useArrayFilter": true,
+    "useArrayFind": true,
+    "useArrayFindIndex": true,
+    "useArrayFindLast": true,
+    "useArrayJoin": true,
+    "useArrayMap": true,
+    "useArrayReduce": true,
+    "useArraySome": true,
+    "useArrayUnique": true,
+    "useAsyncQueue": true,
+    "useAsyncState": true,
+    "useAttrs": true,
+    "useBase64": true,
+    "useBattery": true,
+    "useBluetooth": true,
+    "useBreakpoints": true,
+    "useBroadcastChannel": true,
+    "useBrowserLocation": true,
+    "useCached": true,
+    "useClipboard": true,
+    "useCloned": true,
+    "useColorMode": true,
+    "useConfirmDialog": true,
+    "useCounter": true,
+    "useCssModule": true,
+    "useCssVar": true,
+    "useCssVars": true,
+    "useCurrentElement": true,
+    "useCycleList": true,
+    "useDark": true,
+    "useDateFormat": true,
+    "useDebounce": true,
+    "useDebounceFn": true,
+    "useDebouncedRefHistory": true,
+    "useDeviceMotion": true,
+    "useDeviceOrientation": true,
+    "useDevicePixelRatio": true,
+    "useDevicesList": true,
+    "useDisplayMedia": true,
+    "useDocumentVisibility": true,
+    "useDraggable": true,
+    "useDropZone": true,
+    "useElementBounding": true,
+    "useElementByPoint": true,
+    "useElementHover": true,
+    "useElementSize": true,
+    "useElementVisibility": true,
+    "useEventBus": true,
+    "useEventListener": true,
+    "useEventSource": true,
+    "useEyeDropper": true,
+    "useFavicon": true,
+    "useFetch": true,
+    "useFileDialog": true,
+    "useFileSystemAccess": true,
+    "useFocus": true,
+    "useFocusWithin": true,
+    "useFps": true,
+    "useFullscreen": true,
+    "useGamepad": true,
+    "useGeolocation": true,
+    "useIdle": true,
+    "useImage": true,
+    "useInfiniteScroll": true,
+    "useIntersectionObserver": true,
+    "useInterval": true,
+    "useIntervalFn": true,
+    "useKeyModifier": true,
+    "useLastChanged": true,
+    "useLocalStorage": true,
+    "useMagicKeys": true,
+    "useManualRefHistory": true,
+    "useMediaControls": true,
+    "useMediaQuery": true,
+    "useMemoize": true,
+    "useMemory": true,
+    "useMounted": true,
+    "useMouse": true,
+    "useMouseInElement": true,
+    "useMousePressed": true,
+    "useMutationObserver": true,
+    "useNavigatorLanguage": true,
+    "useNetwork": true,
+    "useNow": true,
+    "useObjectUrl": true,
+    "useOffsetPagination": true,
+    "useOnline": true,
+    "usePageLeave": true,
+    "useParallax": true,
+    "usePermission": true,
+    "usePointer": true,
+    "usePointerLock": true,
+    "usePointerSwipe": true,
+    "usePreferredColorScheme": true,
+    "usePreferredContrast": true,
+    "usePreferredDark": true,
+    "usePreferredLanguages": true,
+    "usePreferredReducedMotion": true,
+    "usePrevious": true,
+    "useRafFn": true,
+    "useRefHistory": true,
+    "useResizeObserver": true,
+    "useScreenOrientation": true,
+    "useScreenSafeArea": true,
+    "useScriptTag": true,
+    "useScroll": true,
+    "useScrollLock": true,
+    "useSessionStorage": true,
+    "useShare": true,
+    "useSlots": true,
+    "useSorted": true,
+    "useSpeechRecognition": true,
+    "useSpeechSynthesis": true,
+    "useStepper": true,
+    "useStorage": true,
+    "useStorageAsync": true,
+    "useStyleTag": true,
+    "useSupported": true,
+    "useSwipe": true,
+    "useTemplateRefsList": true,
+    "useTextDirection": true,
+    "useTextSelection": true,
+    "useTextareaAutosize": true,
+    "useThrottle": true,
+    "useThrottleFn": true,
+    "useThrottledRefHistory": true,
+    "useTimeAgo": true,
+    "useTimeout": true,
+    "useTimeoutFn": true,
+    "useTimeoutPoll": true,
+    "useTimestamp": true,
+    "useTitle": true,
+    "useToNumber": true,
+    "useToString": true,
+    "useToggle": true,
+    "useTransition": true,
+    "useUrlSearchParams": true,
+    "useUserMedia": true,
+    "useVModel": true,
+    "useVModels": true,
+    "useVibrate": true,
+    "useVirtualList": true,
+    "useWakeLock": true,
+    "useWebNotification": true,
+    "useWebSocket": true,
+    "useWebWorker": true,
+    "useWebWorkerFn": true,
+    "useWindowFocus": true,
+    "useWindowScroll": true,
+    "useWindowSize": true,
+    "watch": true,
+    "watchArray": true,
+    "watchAtMost": true,
+    "watchDebounced": true,
+    "watchEffect": true,
+    "watchIgnorable": true,
+    "watchOnce": true,
+    "watchPausable": true,
+    "watchPostEffect": true,
+    "watchSyncEffect": true,
+    "watchThrottled": true,
+    "watchTriggerable": true,
+    "watchWithFilter": true,
+    "whenever": true,
+    "ImportOption": true,
+    "TreeType": true,
+    "FieldOption": true,
+    "PageData": true,
+    "storeToRefs": true,
+    "DictDataOption": true,
+    "UploadOption": true
+  }
 }
diff --git a/.eslintrc.js b/.eslintrc.js
index 518d476..2b2e0d0 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,41 +1,41 @@
 module.exports = {
-	env: {
-		browser: true,
-		es2021: true,
-		node: true
-	},
-	parser: 'vue-eslint-parser',
-	extends: [
-		'eslint:recommended',
-		'plugin:vue/vue3-essential',
-		'plugin:@typescript-eslint/recommended',
-		'./.eslintrc-auto-import.json',
-		'plugin:prettier/recommended'
-	],
-	parserOptions: {
-		ecmaVersion: '2020',
-		sourceType: 'module',
-		parser: '@typescript-eslint/parser'
-	},
-	plugins: ['vue', '@typescript-eslint'],
-	rules: {
-		'vue/multi-word-component-names': 'off',
-		'@typescript-eslint/no-empty-function': 'off',
-		'@typescript-eslint/no-explicit-any': 'off',
-		'vue/no-v-model-argument': 'off',
-		'@typescript-eslint/ban-types': [
-			'error',
-			{
-				// 鍏抽棴绌虹被鍨嬫鏌� {}
-				extendDefaults: true,
-				types: {
-					'{}': false
-				}
-			}
-		]
-	},
-	globals: {
-		DialogOption: 'readonly',
-		OptionType: 'readonly'
-	}
+  env: {
+    browser: true,
+    es2021: true,
+    node: true
+  },
+  parser: 'vue-eslint-parser',
+  extends: [
+    'eslint:recommended',
+    'plugin:vue/vue3-essential',
+    'plugin:@typescript-eslint/recommended',
+    './.eslintrc-auto-import.json',
+    'plugin:prettier/recommended'
+  ],
+  parserOptions: {
+    ecmaVersion: '2020',
+    sourceType: 'module',
+    parser: '@typescript-eslint/parser'
+  },
+  plugins: ['vue', '@typescript-eslint'],
+  rules: {
+    'vue/multi-word-component-names': 'off',
+    '@typescript-eslint/no-empty-function': 'off',
+    '@typescript-eslint/no-explicit-any': 'off',
+    'vue/no-v-model-argument': 'off',
+    '@typescript-eslint/ban-types': [
+      'error',
+      {
+        // 鍏抽棴绌虹被鍨嬫鏌� {}
+        extendDefaults: true,
+        types: {
+          '{}': false
+        }
+      }
+    ]
+  },
+  globals: {
+    DialogOption: 'readonly',
+    OptionType: 'readonly'
+  }
 };
diff --git a/.prettierrc.cjs b/.prettierrc.cjs
index 3df4406..fde1071 100644
--- a/.prettierrc.cjs
+++ b/.prettierrc.cjs
@@ -2,45 +2,45 @@
  * 浠g爜鏍煎紡鍖栭厤缃�
  */
 module.exports = {
-	// 涓�琛屾渶澶氬灏戜釜瀛楃
-	printWidth: 150,
-	// 鎸囧畾姣忎釜缂╄繘绾у埆鐨勭┖鏍兼暟
-	tabWidth: 2,
-	// 浣跨敤鍒惰〃绗﹁�屼笉鏄┖鏍肩缉杩涜
-	useTabs: true,
-	// 鍦ㄨ鍙ユ湯灏炬槸鍚﹂渶瑕佸垎鍙�
-	semi: true,
-	// 鏄惁浣跨敤鍗曞紩鍙�
-	singleQuote: true,
-	// 鏇存敼寮曠敤瀵硅薄灞炴�х殑鏃堕棿 鍙�夊��"<as-needed|consistent|preserve>"
-	quoteProps: 'as-needed',
-	// 鍦↗SX涓娇鐢ㄥ崟寮曞彿鑰屼笉鏄弻寮曞彿
-	jsxSingleQuote: false,
-	// 澶氳鏃跺敖鍙兘鎵撳嵃灏鹃殢閫楀彿銆傦紙渚嬪锛屽崟琛屾暟缁勬案杩滀笉浼氬嚭鐜伴�楀彿缁撳熬銆傦級 鍙�夊��"<none|es5|all>"锛岄粯璁one
-	trailingComma: 'none',
-	// 鍦ㄥ璞℃枃瀛椾腑鐨勬嫭鍙蜂箣闂存墦鍗扮┖鏍�
-	bracketSpacing: true,
-	// jsx 鏍囩鐨勫弽灏栨嫭鍙烽渶瑕佹崲琛�
-	jsxBracketSameLine: false,
-	embeddedLanguageFormatting: 'off',
-	// 鍦ㄥ崟鐙殑绠ご鍑芥暟鍙傛暟鍛ㄥ洿鍖呮嫭鎷彿 always锛�(x) => x \ avoid锛歺 => x
-	arrowParens: 'always',
-	// 杩欎袱涓�夐」鍙敤浜庢牸寮忓寲浠ョ粰瀹氬瓧绗﹀亸绉婚噺锛堝垎鍒寘鎷拰涓嶅寘鎷級寮�濮嬪拰缁撴潫鐨勪唬鐮�
-	rangeStart: 0,
-	rangeEnd: Infinity,
-	// 鎸囧畾瑕佷娇鐢ㄧ殑瑙f瀽鍣紝涓嶉渶瑕佸啓鏂囦欢寮�澶寸殑 @prettier
-	requirePragma: false,
-	// 涓嶉渶瑕佽嚜鍔ㄥ湪鏂囦欢寮�澶存彃鍏� @prettier
-	insertPragma: false,
-	// 浣跨敤榛樿鐨勬姌琛屾爣鍑� always\never\preserve
-	proseWrap: 'preserve',
-	// 鎸囧畾HTML鏂囦欢鐨勫叏灞�绌烘牸鏁忔劅搴� css\strict\ignore
-	htmlWhitespaceSensitivity: 'css',
-	// Vue鏂囦欢鑴氭湰鍜屾牱寮忔爣绛剧缉杩�
-	vueIndentScriptAndStyle: false,
-	//鍦� windows 鎿嶄綔绯荤粺涓崲琛岀閫氬父鏄洖杞� (CR) 鍔犳崲琛屽垎闅旂 (LF)锛屼篃灏辨槸鍥炶溅鎹㈣(CRLF)锛�
-	//鐒惰�屽湪 Linux 鍜� Unix 涓彧浣跨敤绠�鍗曠殑鎹㈣鍒嗛殧绗� (LF)銆�
-	//瀵瑰簲鐨勬帶鍒跺瓧绗︿负 "\n" (LF) 鍜� "\r\n"(CRLF)銆俛uto鎰忎负淇濇寔鐜版湁鐨勮灏�
-	// 鎹㈣绗︿娇鐢� lf 缁撳熬鏄� 鍙�夊��"<auto|lf|crlf|cr>"
-	endOfLine: 'auto'
+    // 涓�琛屾渶澶氬灏戜釜瀛楃
+    printWidth: 150,
+    // 鎸囧畾姣忎釜缂╄繘绾у埆鐨勭┖鏍兼暟
+    tabWidth: 2,
+    // 浣跨敤鍒惰〃绗﹁�屼笉鏄┖鏍肩缉杩涜
+    useTabs: false,
+    // 鍦ㄨ鍙ユ湯灏炬槸鍚﹂渶瑕佸垎鍙�
+    semi: true,
+    // 鏄惁浣跨敤鍗曞紩鍙�
+    singleQuote: true,
+    // 鏇存敼寮曠敤瀵硅薄灞炴�х殑鏃堕棿 鍙�夊��"<as-needed|consistent|preserve>"
+    quoteProps: 'as-needed',
+    // 鍦↗SX涓娇鐢ㄥ崟寮曞彿鑰屼笉鏄弻寮曞彿
+    jsxSingleQuote: false,
+    // 澶氳鏃跺敖鍙兘鎵撳嵃灏鹃殢閫楀彿銆傦紙渚嬪锛屽崟琛屾暟缁勬案杩滀笉浼氬嚭鐜伴�楀彿缁撳熬銆傦級 鍙�夊��"<none|es5|all>"锛岄粯璁one
+    trailingComma: 'none',
+    // 鍦ㄥ璞℃枃瀛椾腑鐨勬嫭鍙蜂箣闂存墦鍗扮┖鏍�
+    bracketSpacing: true,
+    // jsx 鏍囩鐨勫弽灏栨嫭鍙烽渶瑕佹崲琛�
+    jsxBracketSameLine: false,
+    embeddedLanguageFormatting: 'off',
+    // 鍦ㄥ崟鐙殑绠ご鍑芥暟鍙傛暟鍛ㄥ洿鍖呮嫭鎷彿 always锛�(x) => x \ avoid锛歺 => x
+    arrowParens: 'always',
+    // 杩欎袱涓�夐」鍙敤浜庢牸寮忓寲浠ョ粰瀹氬瓧绗﹀亸绉婚噺锛堝垎鍒寘鎷拰涓嶅寘鎷級寮�濮嬪拰缁撴潫鐨勪唬鐮�
+    rangeStart: 0,
+    rangeEnd: Infinity,
+    // 鎸囧畾瑕佷娇鐢ㄧ殑瑙f瀽鍣紝涓嶉渶瑕佸啓鏂囦欢寮�澶寸殑 @prettier
+    requirePragma: false,
+    // 涓嶉渶瑕佽嚜鍔ㄥ湪鏂囦欢寮�澶存彃鍏� @prettier
+    insertPragma: false,
+    // 浣跨敤榛樿鐨勬姌琛屾爣鍑� always\never\preserve
+    proseWrap: 'preserve',
+    // 鎸囧畾HTML鏂囦欢鐨勫叏灞�绌烘牸鏁忔劅搴� css\strict\ignore
+    htmlWhitespaceSensitivity: 'css',
+    // Vue鏂囦欢鑴氭湰鍜屾牱寮忔爣绛剧缉杩�
+    vueIndentScriptAndStyle: false,
+    //鍦� windows 鎿嶄綔绯荤粺涓崲琛岀閫氬父鏄洖杞� (CR) 鍔犳崲琛屽垎闅旂 (LF)锛屼篃灏辨槸鍥炶溅鎹㈣(CRLF)锛�
+    //鐒惰�屽湪 Linux 鍜� Unix 涓彧浣跨敤绠�鍗曠殑鎹㈣鍒嗛殧绗� (LF)銆�
+    //瀵瑰簲鐨勬帶鍒跺瓧绗︿负 "\n" (LF) 鍜� "\r\n"(CRLF)銆俛uto鎰忎负淇濇寔鐜版湁鐨勮灏�
+    // 鎹㈣绗︿娇鐢� lf 缁撳熬鏄� 鍙�夊��"<auto|lf|crlf|cr>"
+    endOfLine: 'auto'
 };
diff --git a/README.md b/README.md
index f1df2bc..6644daf 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,9 @@
 ## 骞冲彴绠�浠�
 
-## 骞冲彴绠�浠�
-
-- 鏈粨搴撲负鍓嶇鎶�鏈爤 [Vue3](https://v3.cn.vuejs.org) + [Element Plus](https://element-plus.org/zh-CN) + [Vite](https://cn.vitejs.dev) 鐗堟湰銆�
-- 閰嶅鍚庣浠g爜浠撳簱鍦板潃
-- [RuoYi-Vue-Plus 5.X(娉ㄦ剰鐗堟湰鍙�)](https://gitee.com/dromara/RuoYi-Vue-Plus)
-- [RuoYi-Cloud-Plus 2.X(娉ㄦ剰鐗堟湰鍙�)](https://gitee.com/dromara/RuoYi-Cloud-Plus)
+* 鏈粨搴撲负鍓嶇鎶�鏈爤 [Vue3](https://v3.cn.vuejs.org) + [TS](https://www.typescriptlang.org/) + [Element Plus](https://element-plus.org/zh-CN) + [Vite](https://cn.vitejs.dev) 鐗堟湰銆�
+* 閰嶅鍚庣浠g爜浠撳簱鍦板潃
+* [RuoYi-Vue-Plus 5.X(娉ㄦ剰鐗堟湰鍙�)](https://gitee.com/dromara/RuoYi-Vue-Plus)
+* [RuoYi-Cloud-Plus 2.X(娉ㄦ剰鐗堟湰鍙�)](https://gitee.com/dromara/RuoYi-Cloud-Plus)
 
 ## 鍓嶇杩愯
 
@@ -19,120 +17,57 @@
 # 鍚姩鏈嶅姟
 npm run dev
 
-# 鏋勫缓娴嬭瘯鐜 yarn build:stage
 # 鏋勫缓鐢熶骇鐜 yarn build:prod
 # 鍓嶇璁块棶鍦板潃 http://localhost:80
 ```
 
-## 鏈鏋朵笌 RuoYi 鐨勪笟鍔″樊寮�
+## 鏈鏋朵笌RuoYi鐨勪笟鍔″樊寮�
 
-| 涓氬姟         | 鍔熻兘璇存槑                                                        | 鏈鏋� | RuoYi                          |
-| ------------ | --------------------------------------------------------------- | ------ | ------------------------------ |
-| 绉熸埛绠$悊     | 绯荤粺鍐呯鎴风殑绠$悊 濡�:绉熸埛濂楅銆佽繃鏈熸椂闂淬�佺敤鎴锋暟閲忋�佷紒涓氫俊鎭瓑    | 鏀寔   | 鏃�                             |
-| 绉熸埛濂楅绠$悊 | 绯荤粺鍐呯鎴锋墍鑳戒娇鐢ㄧ殑濂楅绠$悊 濡�:濂楅鍐呮墍鍖呭惈鐨勮彍鍗曠瓑            | 鏀寔   | 鏃�                             |
-| 鐢ㄦ埛绠$悊     | 鐢ㄦ埛鐨勭鐞嗛厤缃� 濡�:鏂板鐢ㄦ埛銆佸垎閰嶇敤鎴锋墍灞為儴闂ㄣ�佽鑹层�佸矖浣嶇瓑      | 鏀寔   | 鏀寔                           |
-| 閮ㄩ棬绠$悊     | 閰嶇疆绯荤粺缁勭粐鏈烘瀯锛堝叕鍙搞�侀儴闂ㄣ�佸皬缁勶級 鏍戠粨鏋勫睍鐜版敮鎸佹暟鎹潈闄�     | 鏀寔   | 鏀寔                           |
-| 宀椾綅绠$悊     | 閰嶇疆绯荤粺鐢ㄦ埛鎵�灞炴媴浠昏亴鍔�                                        | 鏀寔   | 鏀寔                           |
-| 鑿滃崟绠$悊     | 閰嶇疆绯荤粺鑿滃崟銆佹搷浣滄潈闄愩�佹寜閽潈闄愭爣璇嗙瓑                          | 鏀寔   | 鏀寔                           |
-| 瑙掕壊绠$悊     | 瑙掕壊鑿滃崟鏉冮檺鍒嗛厤銆佽缃鑹叉寜鏈烘瀯杩涜鏁版嵁鑼冨洿鏉冮檺鍒掑垎            | 鏀寔   | 鏀寔                           |
-| 瀛楀吀绠$悊     | 瀵圭郴缁熶腑缁忓父浣跨敤鐨勪竴浜涜緝涓哄浐瀹氱殑鏁版嵁杩涜缁存姢                    | 鏀寔   | 鏀寔                           |
-| 鍙傛暟绠$悊     | 瀵圭郴缁熷姩鎬侀厤缃父鐢ㄥ弬鏁�                                          | 鏀寔   | 鏀寔                           |
-| 閫氱煡鍏憡     | 绯荤粺閫氱煡鍏憡淇℃伅鍙戝竷缁存姢                                        | 鏀寔   | 鏀寔                           |
-| 鎿嶄綔鏃ュ織     | 绯荤粺姝e父鎿嶄綔鏃ュ織璁板綍鍜屾煡璇� 绯荤粺寮傚父淇℃伅鏃ュ織璁板綍鍜屾煡璇�           | 鏀寔   | 鏀寔                           |
-| 鐧诲綍鏃ュ織     | 绯荤粺鐧诲綍鏃ュ織璁板綍鏌ヨ鍖呭惈鐧诲綍寮傚父                                | 鏀寔   | 鏀寔                           |
-| 鏂囦欢绠$悊     | 绯荤粺鏂囦欢灞曠ず銆佷笂浼犮�佷笅杞姐�佸垹闄ょ瓑绠$悊                            | 鏀寔   | 鏃�                             |
-| 鏂囦欢閰嶇疆绠$悊 | 绯荤粺鏂囦欢涓婁紶銆佷笅杞芥墍闇�瑕佺殑閰嶇疆淇℃伅鍔ㄦ�佹坊鍔犮�佷慨鏀广�佸垹闄ょ瓑绠$悊    | 鏀寔   | 鏃�                             |
-| 鍦ㄧ嚎鐢ㄦ埛绠$悊 | 宸茬櫥褰曠郴缁熺殑鍦ㄧ嚎鐢ㄦ埛淇℃伅鐩戞帶涓庡己鍒惰涪鍑烘搷浣�                      | 鏀寔   | 鏀寔                           |
-| 瀹氭椂浠诲姟     | 杩愯鎶ヨ〃銆佷换鍔$鐞�(娣诲姞銆佷慨鏀广�佸垹闄�)銆佹棩蹇楃鐞嗐�佹墽琛屽櫒绠$悊绛�    | 鏀寔   | 浠呮敮鎸佷换鍔′笌鏃ュ織绠$悊           |
-| 浠g爜鐢熸垚     | 澶氭暟鎹簮鍓嶅悗绔唬鐮佺殑鐢熸垚锛坖ava銆乭tml銆亁ml銆乻ql锛夋敮鎸� CRUD 涓嬭浇  | 鏀寔   | 浠呮敮鎸佸崟鏁版嵁婧�                 |
-| 绯荤粺鎺ュ彛     | 鏍规嵁涓氬姟浠g爜鑷姩鐢熸垚鐩稿叧鐨� api 鎺ュ彛鏂囨。                         | 鏀寔   | 鏀寔                           |
-| 鏈嶅姟鐩戞帶     | 鐩戣闆嗙兢绯荤粺 CPU銆佸唴瀛樸�佺鐩樸�佸爢鏍堛�佸湪绾挎棩蹇椼�丼pring 鐩稿叧閰嶇疆绛� | 鏀寔   | 浠呮敮鎸佸崟鏈� CPU銆佸唴瀛樸�佺鐩樼洃鎺� |
-| 缂撳瓨鐩戞帶     | 瀵圭郴缁熺殑缂撳瓨淇℃伅鏌ヨ锛屽懡浠ょ粺璁$瓑銆�                              | 鏀寔   | 鏀寔                           |
-| 鍦ㄧ嚎鏋勫缓鍣�   | 鎷栧姩琛ㄥ崟鍏冪礌鐢熸垚鐩稿簲鐨� HTML 浠g爜銆�                              | 鏀寔   | 鏀寔                           |
-| 浣跨敤妗堜緥     | 绯荤粺鐨勪竴浜涘姛鑳芥渚�                                              | 鏀寔   | 涓嶆敮鎸�                         |
+| 涓氬姟     | 鍔熻兘璇存槑                                    | 鏈鏋� | RuoYi            |
+|--------|-----------------------------------------|-----|------------------|
+| 绉熸埛绠$悊   | 绯荤粺鍐呯鎴风殑绠$悊 濡�:绉熸埛濂楅銆佽繃鏈熸椂闂淬�佺敤鎴锋暟閲忋�佷紒涓氫俊鎭瓑         | 鏀寔  | 鏃�                |
+| 绉熸埛濂楅绠$悊 | 绯荤粺鍐呯鎴锋墍鑳戒娇鐢ㄧ殑濂楅绠$悊 濡�:濂楅鍐呮墍鍖呭惈鐨勮彍鍗曠瓑             | 鏀寔  | 鏃�                |
+| 鐢ㄦ埛绠$悊   | 鐢ㄦ埛鐨勭鐞嗛厤缃� 濡�:鏂板鐢ㄦ埛銆佸垎閰嶇敤鎴锋墍灞為儴闂ㄣ�佽鑹层�佸矖浣嶇瓑          | 鏀寔  | 鏀寔               |
+| 閮ㄩ棬绠$悊   | 閰嶇疆绯荤粺缁勭粐鏈烘瀯锛堝叕鍙搞�侀儴闂ㄣ�佸皬缁勶級 鏍戠粨鏋勫睍鐜版敮鎸佹暟鎹潈闄�          | 鏀寔  | 鏀寔               |
+| 宀椾綅绠$悊   | 閰嶇疆绯荤粺鐢ㄦ埛鎵�灞炴媴浠昏亴鍔�                            | 鏀寔  | 鏀寔               |
+| 鑿滃崟绠$悊   | 閰嶇疆绯荤粺鑿滃崟銆佹搷浣滄潈闄愩�佹寜閽潈闄愭爣璇嗙瓑                     | 鏀寔  | 鏀寔               |
+| 瑙掕壊绠$悊   | 瑙掕壊鑿滃崟鏉冮檺鍒嗛厤銆佽缃鑹叉寜鏈烘瀯杩涜鏁版嵁鑼冨洿鏉冮檺鍒掑垎              | 鏀寔  | 鏀寔               |
+| 瀛楀吀绠$悊   | 瀵圭郴缁熶腑缁忓父浣跨敤鐨勪竴浜涜緝涓哄浐瀹氱殑鏁版嵁杩涜缁存姢                  | 鏀寔  | 鏀寔               |
+| 鍙傛暟绠$悊   | 瀵圭郴缁熷姩鎬侀厤缃父鐢ㄥ弬鏁�                             | 鏀寔  | 鏀寔               |
+| 閫氱煡鍏憡   | 绯荤粺閫氱煡鍏憡淇℃伅鍙戝竷缁存姢                            | 鏀寔  | 鏀寔               |
+| 鎿嶄綔鏃ュ織   | 绯荤粺姝e父鎿嶄綔鏃ュ織璁板綍鍜屾煡璇� 绯荤粺寮傚父淇℃伅鏃ュ織璁板綍鍜屾煡璇�             | 鏀寔  | 鏀寔               |
+| 鐧诲綍鏃ュ織   | 绯荤粺鐧诲綍鏃ュ織璁板綍鏌ヨ鍖呭惈鐧诲綍寮傚父                        | 鏀寔  | 鏀寔               |
+| 鏂囦欢绠$悊   | 绯荤粺鏂囦欢灞曠ず銆佷笂浼犮�佷笅杞姐�佸垹闄ょ瓑绠$悊                      | 鏀寔  | 鏃�                |
+| 鏂囦欢閰嶇疆绠$悊 | 绯荤粺鏂囦欢涓婁紶銆佷笅杞芥墍闇�瑕佺殑閰嶇疆淇℃伅鍔ㄦ�佹坊鍔犮�佷慨鏀广�佸垹闄ょ瓑绠$悊          | 鏀寔  | 鏃�                |
+| 鍦ㄧ嚎鐢ㄦ埛绠$悊 | 宸茬櫥褰曠郴缁熺殑鍦ㄧ嚎鐢ㄦ埛淇℃伅鐩戞帶涓庡己鍒惰涪鍑烘搷浣�                   | 鏀寔  | 鏀寔               |
+| 瀹氭椂浠诲姟   | 杩愯鎶ヨ〃銆佷换鍔$鐞�(娣诲姞銆佷慨鏀广�佸垹闄�)銆佹棩蹇楃鐞嗐�佹墽琛屽櫒绠$悊绛�         | 鏀寔  | 浠呮敮鎸佷换鍔′笌鏃ュ織绠$悊       |
+| 浠g爜鐢熸垚   | 澶氭暟鎹簮鍓嶅悗绔唬鐮佺殑鐢熸垚锛坖ava銆乭tml銆亁ml銆乻ql锛夋敮鎸丆RUD涓嬭浇 | 鏀寔  | 浠呮敮鎸佸崟鏁版嵁婧�          |
+| 绯荤粺鎺ュ彛   | 鏍规嵁涓氬姟浠g爜鑷姩鐢熸垚鐩稿叧鐨刟pi鎺ュ彛鏂囨。                    | 鏀寔  | 鏀寔               |
+| 鏈嶅姟鐩戞帶   | 鐩戣闆嗙兢绯荤粺CPU銆佸唴瀛樸�佺鐩樸�佸爢鏍堛�佸湪绾挎棩蹇椼�丼pring鐩稿叧閰嶇疆绛�     | 鏀寔  | 浠呮敮鎸佸崟鏈篊PU銆佸唴瀛樸�佺鐩樼洃鎺� |
+| 缂撳瓨鐩戞帶   | 瀵圭郴缁熺殑缂撳瓨淇℃伅鏌ヨ锛屽懡浠ょ粺璁$瓑銆�                       | 鏀寔  | 鏀寔               |
+| 鍦ㄧ嚎鏋勫缓鍣�  | 鎷栧姩琛ㄥ崟鍏冪礌鐢熸垚鐩稿簲鐨凥TML浠g爜銆�                      | 鏀寔  | 鏀寔               |
+| 浣跨敤妗堜緥   | 绯荤粺鐨勪竴浜涘姛鑳芥渚�                               | 鏀寔  | 涓嶆敮鎸�              |
 
-## 婕旂ず鍥�
+## 婕旂ず鍥句緥
 
-- 鏈粨搴撲负鍓嶇鎶�鏈爤 [Vue3](https://v3.cn.vuejs.org) + [Element Plus](https://element-plus.org/zh-CN) + [Vite](https://cn.vitejs.dev) 鐗堟湰銆�
-- 閰嶅鍚庣浠g爜浠撳簱鍦板潃
-- [RuoYi-Vue-Plus 5.X(娉ㄦ剰鐗堟湰鍙�)](https://gitee.com/dromara/RuoYi-Vue-Plus)
-- [RuoYi-Cloud-Plus 2.X(娉ㄦ剰鐗堟湰鍙�)](https://gitee.com/dromara/RuoYi-Cloud-Plus)
-
-## 鍓嶇杩愯
-
-```bash
-# 鍏嬮殕椤圭洰
-git clone https://gitee.com/JavaLionLi/plus-ui.git
-
-# 瀹夎渚濊禆
-npm install --registry=https://registry.npmmirror.com
-
-# 鍚姩鏈嶅姟
-npm run dev
-
-# 鏋勫缓娴嬭瘯鐜 yarn build:stage
-# 鏋勫缓鐢熶骇鐜 yarn build:prod
-# 鍓嶇璁块棶鍦板潃 http://localhost:80
-```
-
-## 鍚庣鏀归��
-
-鍙傝�冨悗绔唬鐮佸唴 `ruoyi-gen/resources/vm/vue/v3/readme.txt` 璇存槑
-
-## 鍐呯疆鍔熻兘
-
-1. 绉熸埛绠$悊锛氶厤缃郴缁熺鎴凤紝鏀寔 SaaS 鍦烘櫙涓嬬殑澶氱鎴峰姛鑳姐��
-2. 鐢ㄦ埛绠$悊锛氱敤鎴锋槸绯荤粺鎿嶄綔鑰咃紝璇ュ姛鑳戒富瑕佸畬鎴愮郴缁熺敤鎴烽厤缃��
-3. 閮ㄩ棬绠$悊锛氶厤缃郴缁熺粍缁囨満鏋勶紙鍏徃銆侀儴闂ㄣ�佸皬缁勶級锛屾爲缁撴瀯灞曠幇鏀寔鏁版嵁鏉冮檺銆�
-4. 宀椾綅绠$悊锛氶厤缃郴缁熺敤鎴锋墍灞炴媴浠昏亴鍔°��
-5. 鑿滃崟绠$悊锛氶厤缃郴缁熻彍鍗曪紝鎿嶄綔鏉冮檺锛屾寜閽潈闄愭爣璇嗙瓑銆�
-6. 瑙掕壊绠$悊锛氳鑹茶彍鍗曟潈闄愬垎閰嶃�佽缃鑹叉寜鏈烘瀯杩涜鏁版嵁鑼冨洿鏉冮檺鍒掑垎銆�
-7. 瀛楀吀绠$悊锛氬绯荤粺涓粡甯镐娇鐢ㄧ殑涓�浜涜緝涓哄浐瀹氱殑鏁版嵁杩涜缁存姢銆�
-8. 鍙傛暟绠$悊锛氬绯荤粺鍔ㄦ�侀厤缃父鐢ㄥ弬鏁般��
-9. 閫氱煡鍏憡锛氱郴缁熼�氱煡鍏憡淇℃伅鍙戝竷缁存姢銆�
-10. 鎿嶄綔鏃ュ織锛氱郴缁熸甯告搷浣滄棩蹇楄褰曞拰鏌ヨ锛涚郴缁熷紓甯镐俊鎭棩蹇楄褰曞拰鏌ヨ銆�
-11. 鐧诲綍鏃ュ織锛氱郴缁熺櫥褰曟棩蹇楄褰曟煡璇㈠寘鍚櫥褰曞紓甯搞��
-12. 鍦ㄧ嚎鐢ㄦ埛锛氬綋鍓嶇郴缁熶腑娲昏穬鐢ㄦ埛鐘舵�佺洃鎺с��
-13. 瀹氭椂浠诲姟锛氬湪绾匡紙娣诲姞銆佷慨鏀广�佸垹闄�)浠诲姟璋冨害鍖呭惈鎵ц缁撴灉鏃ュ織銆�
-14. 浠g爜鐢熸垚锛氬墠鍚庣浠g爜鐨勭敓鎴愶紙java銆乭tml銆亁ml銆乻ql锛夋敮鎸� CRUD 涓嬭浇 銆�
-15. 绯荤粺鎺ュ彛锛氭牴鎹笟鍔′唬鐮佽嚜鍔ㄧ敓鎴愮浉鍏崇殑 api 鎺ュ彛鏂囨。銆�
-16. 鏈嶅姟鐩戞帶锛氱洃瑙嗗綋鍓嶇郴缁� CPU銆佸唴瀛樸�佺鐩樸�佸爢鏍堢瓑鐩稿叧淇℃伅銆�
-17. 缂撳瓨鐩戞帶锛氬绯荤粺鐨勭紦瀛樹俊鎭煡璇紝鍛戒护缁熻绛夈��
-18. 鍦ㄧ嚎鏋勫缓鍣細鎷栧姩琛ㄥ崟鍏冪礌鐢熸垚鐩稿簲鐨� HTML 浠g爜銆�
-
-## 婕旂ず鍥�
-
-<table>
-    <tr>
-        <td><img src="https://oscimg.oschina.net/oscnet/cd1f90be5f2684f4560c9519c0f2a232ee8.jpg"/></td>
-        <td><img src="https://oscimg.oschina.net/oscnet/1cbcf0e6f257c7d3a063c0e3f2ff989e4b3.jpg"/></td>
-    </tr>
-    <tr>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-8074972883b5ba0622e13246738ebba237a.png"/></td>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-9f88719cdfca9af2e58b352a20e23d43b12.png"/></td>
-    </tr>
-    <tr>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-39bf2584ec3a529b0d5a3b70d15c9b37646.png"/></td>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-936ec82d1f4872e1bc980927654b6007307.png"/></td>
-    </tr>
-	<tr>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-b2d62ceb95d2dd9b3fbe157bb70d26001e9.png"/></td>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-d67451d308b7a79ad6819723396f7c3d77a.png"/></td>
-    </tr>	 
-    <tr>
-        <td><img src="https://oscimg.oschina.net/oscnet/5e8c387724954459291aafd5eb52b456f53.jpg"/></td>
-        <td><img src="https://oscimg.oschina.net/oscnet/644e78da53c2e92a95dfda4f76e6d117c4b.jpg"/></td>
-    </tr>
-	<tr>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-8370a0d02977eebf6dbf854c8450293c937.png"/></td>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-49003ed83f60f633e7153609a53a2b644f7.png"/></td>
-    </tr>
-	<tr>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-d4fe726319ece268d4746602c39cffc0621.png"/></td>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-c195234bbcd30be6927f037a6755e6ab69c.png"/></td>
-    </tr>
-    <tr>
-        <td><img src="https://oscimg.oschina.net/oscnet/b6115bc8c31de52951982e509930b20684a.jpg"/></td>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-5e4daac0bb59612c5038448acbcef235e3a.png"/></td>
-    </tr>
-</table>
+|                                                                                            |                                                                                            |
+|--------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------|
+| ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680077524361362822/270bb429_1766278.png "灞忓箷鎴浘") | ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680077619939771291/989bf9b6_1766278.png "灞忓箷鎴浘") |
+| ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680077681751513929/1c27c5bd_1766278.png "灞忓箷鎴浘") | ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680077721559267315/74d63e23_1766278.png "灞忓箷鎴浘") |
+| ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680077765638904515/1b75d4a6_1766278.png "灞忓箷鎴浘") | ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078026375951297/eded7a4b_1766278.png "灞忓箷鎴浘") |
+| ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078237104531207/0eb1b6a7_1766278.png "灞忓箷鎴浘") | ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078254306078709/5931e22f_1766278.png "灞忓箷鎴浘") |
+| ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078287971528493/0b9af60a_1766278.png "灞忓箷鎴浘") | ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078308138770249/8d3b6696_1766278.png "灞忓箷鎴浘") |
+| ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078352553634393/db5ef880_1766278.png "灞忓箷鎴浘") | ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078378238393374/601e4357_1766278.png "灞忓箷鎴浘") |
+| ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078414983206024/2aae27c1_1766278.png "灞忓箷鎴浘") | ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078446738419874/ecce7d59_1766278.png "灞忓箷鎴浘") |
+| ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078475971341775/149e8634_1766278.png "灞忓箷鎴浘") | ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078491666717143/3fadece7_1766278.png "灞忓箷鎴浘") |
+| ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078558863188826/fb8ced2a_1766278.png "灞忓箷鎴浘") | ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078574561685461/ae68a0b2_1766278.png "灞忓箷鎴浘") |
+| ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078594932772013/9d8bfec6_1766278.png "灞忓箷鎴浘") | ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078626493093532/fcfe4ff6_1766278.png "灞忓箷鎴浘") |
+| ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078643608812515/0295bd4f_1766278.png "灞忓箷鎴浘") | ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078685196286463/d7612c81_1766278.png "灞忓箷鎴浘") |
+| ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078703877318597/56fce0bc_1766278.png "灞忓箷鎴浘") | ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078716586545643/b6dbd68f_1766278.png "灞忓箷鎴浘") |
+| ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078734103217688/eb1e6aa6_1766278.png "灞忓箷鎴浘") | ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078759131415480/73c525d8_1766278.png "灞忓箷鎴浘") |
+| ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078779416197879/75e3ed02_1766278.png "灞忓箷鎴浘") | ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078802329118061/77e10915_1766278.png "灞忓箷鎴浘") |
+| ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078893627848351/34a1c342_1766278.png "灞忓箷鎴浘") | ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078928175016986/f126ec4a_1766278.png "灞忓箷鎴浘") |
+| ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078941718318363/b68a0f72_1766278.png "灞忓箷鎴浘") | ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078963175518631/3bb769a1_1766278.png "灞忓箷鎴浘") |
+| ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680078982294090567/b31c343d_1766278.png "灞忓箷鎴浘") | ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680079000642440444/77ca82a9_1766278.png "灞忓箷鎴浘") |
+| ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680079020995074177/03b7d52e_1766278.png "灞忓箷鎴浘") | ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680079039367822173/76811806_1766278.png "灞忓箷鎴浘") |
+| ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680079274333484664/4dfdc7c0_1766278.png "灞忓箷鎴浘") | ![杈撳叆鍥剧墖璇存槑](https://foruda.gitee.com/images/1680079290467458224/d6715fcf_1766278.png "灞忓箷鎴浘") |
diff --git a/Vite/plugins/auto-import.ts b/Vite/plugins/auto-import.ts
deleted file mode 100644
index c7cee4b..0000000
--- a/Vite/plugins/auto-import.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import AutoImport from 'unplugin-auto-import/vite';
-import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
-import IconsResolver from 'unplugin-icons/resolver';
-
-export default (path: any) => {
-	return AutoImport({
-		// 鑷姩瀵煎叆 Vue 鐩稿叧鍑芥暟
-		imports: ['vue', 'vue-router', '@vueuse/core', 'pinia'],
-		eslintrc: {
-			enabled: false,
-			filepath: './.eslintrc-auto-import.json',
-			globalsPropValue: true
-		},
-		resolvers: [
-			// 鑷姩瀵煎叆 Element Plus 鐩稿叧鍑芥暟ElMessage, ElMessageBox... (甯︽牱寮�)
-			ElementPlusResolver(),
-			IconsResolver({
-				prefix: 'Icon'
-			})
-		],
-		vueTemplate: true, // 鏄惁鍦� vue 妯℃澘涓嚜鍔ㄥ鍏�
-		dts: path.resolve(path.resolve(__dirname, '../../src'), 'types', 'auto-imports.d.ts')
-	});
-};
diff --git a/Vite/plugins/components.ts b/Vite/plugins/components.ts
deleted file mode 100644
index dbc5b19..0000000
--- a/Vite/plugins/components.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import Components from 'unplugin-vue-components/vite';
-import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
-import IconsResolver from 'unplugin-icons/resolver';
-
-export default (path: any) => {
-	return Components({
-		resolvers: [
-			// 鑷姩瀵煎叆 Element Plus 缁勪欢
-			ElementPlusResolver(),
-			// 鑷姩娉ㄥ唽鍥炬爣缁勪欢
-			IconsResolver({
-				enabledCollections: ['ep']
-			})
-		],
-		dts: path.resolve(path.resolve(__dirname, '../../src'), 'types', 'components.d.ts')
-	});
-};
diff --git a/Vite/plugins/compression.ts b/Vite/plugins/compression.ts
deleted file mode 100644
index 15dcee9..0000000
--- a/Vite/plugins/compression.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import compression from 'vite-plugin-compression';
-
-export default function createCompression(env: any) {
-	const { VITE_BUILD_COMPRESS } = env;
-	const plugin: any[] = [];
-	if (VITE_BUILD_COMPRESS) {
-		const compressList = VITE_BUILD_COMPRESS.split(',');
-		if (compressList.includes('gzip')) {
-			// http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#浣跨敤gzip瑙e帇缂╅潤鎬佹枃浠�
-			plugin.push(
-				compression({
-					ext: '.gz',
-					deleteOriginFile: false
-				})
-			);
-		}
-		if (compressList.includes('brotli')) {
-			plugin.push(
-				compression({
-					ext: '.br',
-					algorithm: 'brotliCompress',
-					deleteOriginFile: false
-				})
-			);
-		}
-	}
-	return plugin;
-}
diff --git a/Vite/plugins/icons.ts b/Vite/plugins/icons.ts
deleted file mode 100644
index 174572c..0000000
--- a/Vite/plugins/icons.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import Icons from 'unplugin-icons/vite';
-
-export default () => {
-	return Icons({
-		// 鑷姩瀹夎鍥炬爣搴�
-		autoInstall: true
-	});
-};
diff --git a/Vite/plugins/index.ts b/Vite/plugins/index.ts
deleted file mode 100644
index f95c47f..0000000
--- a/Vite/plugins/index.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import vue from '@vitejs/plugin-vue';
-import createUnoCss from './unocss';
-import createAutoImport from './auto-import';
-import createComponents from './components';
-import createIcons from './icons';
-import createSvgIconsPlugin from './svg-icon';
-import createCompression from './compression';
-import path from 'path';
-
-export default (viteEnv: any, isBuild = false): [] => {
-	const vitePlusgins: any = [];
-	vitePlusgins.push(vue());
-	vitePlusgins.push(createUnoCss());
-	vitePlusgins.push(createAutoImport(path));
-	vitePlusgins.push(createComponents(path));
-	vitePlusgins.push(createCompression(viteEnv));
-	vitePlusgins.push(createIcons());
-	vitePlusgins.push(createSvgIconsPlugin(path, isBuild));
-	return vitePlusgins;
-};
diff --git a/Vite/plugins/svg-icon.ts b/Vite/plugins/svg-icon.ts
deleted file mode 100644
index 0ee8d65..0000000
--- a/Vite/plugins/svg-icon.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
-export default (path: any, isBuild: boolean) => {
-	return createSvgIconsPlugin({
-		// 鎸囧畾闇�瑕佺紦瀛樼殑鍥炬爣鏂囦欢澶�
-		iconDirs: [path.resolve(path.resolve(__dirname, '../../src'), 'assets/icons/svg')],
-		// 鎸囧畾symbolId鏍煎紡
-		symbolId: 'icon-[dir]-[name]',
-		svgoOptions: isBuild
-	});
-};
diff --git a/Vite/plugins/unocss.ts b/Vite/plugins/unocss.ts
deleted file mode 100644
index e9e3254..0000000
--- a/Vite/plugins/unocss.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import UnoCss from 'unocss/vite';
-import { presetUno, presetAttributify, presetIcons } from 'unocss';
-
-export default () => {
-	return UnoCss({
-		presets: [presetUno(), presetAttributify(), presetIcons()],
-		// rules: [['search', {}]],
-		shortcuts: {
-			'panel-title':
-				'pb-[5px] font-sans leading-[1.1] font-medium text-base text-[#6379bb] border-b border-b-solid border-[var(--el-border-color-light)] mb-5 mt-0'
-		}
-	});
-};
diff --git a/commitlint.config.js b/commitlint.config.js
index 21c37d7..3b75ed5 100644
--- a/commitlint.config.js
+++ b/commitlint.config.js
@@ -1,22 +1,22 @@
 module.exports = {
-	extends: ['@commitlint/config-conventional'],
-	rules: {
-		'type-enum': [
-			2,
-			'always',
-			[
-				'feat', // 鏂板姛鑳� feature
-				'fix', // 淇 bug
-				'docs', // 鏂囨。娉ㄩ噴
-				'style', // 浠g爜鏍煎紡
-				'refactor', // 閲嶆瀯
-				'perf', // 鎬ц兘浼樺寲
-				'test', // 澧炲姞娴嬭瘯
-				'chore', // 鏋勫缓杩囩▼鎴栬緟鍔╁伐鍏风殑鍙樺姩
-				'revert', // 鍥為��
-				'build' // 鎵撳寘
-			]
-		],
-		'subject-case': [0]
-	}
+  extends: ['@commitlint/config-conventional'],
+  rules: {
+    'type-enum': [
+      2,
+      'always',
+      [
+        'feat', // 鏂板姛鑳� feature
+        'fix', // 淇 bug
+        'docs', // 鏂囨。娉ㄩ噴
+        'style', // 浠g爜鏍煎紡
+        'refactor', // 閲嶆瀯
+        'perf', // 鎬ц兘浼樺寲
+        'test', // 澧炲姞娴嬭瘯
+        'chore', // 鏋勫缓杩囩▼鎴栬緟鍔╁伐鍏风殑鍙樺姩
+        'revert', // 鍥為��
+        'build' // 鎵撳寘
+      ]
+    ],
+    'subject-case': [0]
+  }
 };
diff --git a/html/ie.html b/html/ie.html
index 52fdef6..87d262d 100644
--- a/html/ie.html
+++ b/html/ie.html
@@ -1,60 +1,60 @@
 <!DOCTYPE html>
 <html lang="zh-CN">
-	<head>
-		<meta charset="UTF-8" />
-		<title>璇峰崌绾ф偍鐨勬祻瑙堝櫒</title>
-		<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />
-		<meta name="renderer" content="webkit" />
-		<base target="_blank" />
-		<style type="text/css">
-			html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{border:0;font-size:100%;font:inherit;vertical-align:baseline;margin:0;padding:0}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:none}table{border-collapse:collapse;border-spacing:0}
-			a{text-decoration:none;color:#0072c6;}a:hover{text-decoration:none;color:#004d8c;}
-			body{width:960px;margin:0 auto;padding:10px;font-size:14px;line-height:24px;color:#454545;font-family:'Microsoft YaHei UI','Microsoft YaHei',DengXian,SimSun,'Segoe UI',Tahoma,Helvetica,sans-serif;overflow-y:scroll}
-			h1{font-size:40px;line-height:80px;font-weight:100;margin-bottom:10px;}
-			h2{font-size:20px;line-height:25px;font-weight:100;margin:10px 0;}
-			em{color:red}
-			p{margin-bottom:10px;}
-			hr{margin:20px 0;border:0;border-top:1px solid #dadada}
-			span{display:block;font-size:12px;line-height:12px;}
-			.clean{clear:both;}
-			.browser{padding:10px 10px;}
-			.browser li{width:auto;padding:0 80px;margin-top:30px;height:34px;line-height:22px;float:left;list-style:none;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAADMCAYAAAAWCXEwAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKTWlDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVN3WJP3Fj7f92UPVkLY8LGXbIEAIiOsCMgQWaIQkgBhhBASQMWFiApWFBURnEhVxILVCkidiOKgKLhnQYqIWotVXDjuH9yntX167+3t+9f7vOec5/zOec8PgBESJpHmomoAOVKFPDrYH49PSMTJvYACFUjgBCAQ5svCZwXFAADwA3l4fnSwP/wBr28AAgBw1S4kEsfh/4O6UCZXACCRAOAiEucLAZBSAMguVMgUAMgYALBTs2QKAJQAAGx5fEIiAKoNAOz0ST4FANipk9wXANiiHKkIAI0BAJkoRyQCQLsAYFWBUiwCwMIAoKxAIi4EwK4BgFm2MkcCgL0FAHaOWJAPQGAAgJlCLMwAIDgCAEMeE80DIEwDoDDSv+CpX3CFuEgBAMDLlc2XS9IzFLiV0Bp38vDg4iHiwmyxQmEXKRBmCeQinJebIxNI5wNMzgwAABr50cH+OD+Q5+bk4eZm52zv9MWi/mvwbyI+IfHf/ryMAgQAEE7P79pf5eXWA3DHAbB1v2upWwDaVgBo3/ldM9sJoFoK0Hr5i3k4/EAenqFQyDwdHAoLC+0lYqG9MOOLPv8z4W/gi372/EAe/tt68ABxmkCZrcCjg/1xYW52rlKO58sEQjFu9+cj/seFf/2OKdHiNLFcLBWK8ViJuFAiTcd5uVKRRCHJleIS6X8y8R+W/QmTdw0ArIZPwE62B7XLbMB+7gECiw5Y0nYAQH7zLYwaC5EAEGc0Mnn3AACTv/mPQCsBAM2XpOMAALzoGFyolBdMxggAAESggSqwQQcMwRSswA6cwR28wBcCYQZEQAwkwDwQQgbkgBwKoRiWQRlUwDrYBLWwAxqgEZrhELTBMTgN5+ASXIHrcBcGYBiewhi8hgkEQcgIE2EhOogRYo7YIs4IF5mOBCJhSDSSgKQg6YgUUSLFyHKkAqlCapFdSCPyLXIUOY1cQPqQ28ggMor8irxHMZSBslED1AJ1QLmoHxqKxqBz0XQ0D12AlqJr0Rq0Hj2AtqKn0UvodXQAfYqOY4DRMQ5mjNlhXIyHRWCJWBomxxZj5Vg1Vo81Yx1YN3YVG8CeYe8IJAKLgBPsCF6EEMJsgpCQR1hMWEOoJewjtBK6CFcJg4Qxwicik6hPtCV6EvnEeGI6sZBYRqwm7iEeIZ4lXicOE1+TSCQOyZLkTgohJZAySQtJa0jbSC2kU6Q+0hBpnEwm65Btyd7kCLKArCCXkbeQD5BPkvvJw+S3FDrFiOJMCaIkUqSUEko1ZT/lBKWfMkKZoKpRzame1AiqiDqfWkltoHZQL1OHqRM0dZolzZsWQ8ukLaPV0JppZ2n3aC/pdLoJ3YMeRZfQl9Jr6Afp5+mD9HcMDYYNg8dIYigZaxl7GacYtxkvmUymBdOXmchUMNcyG5lnmA+Yb1VYKvYqfBWRyhKVOpVWlX6V56pUVXNVP9V5qgtUq1UPq15WfaZGVbNQ46kJ1Bar1akdVbupNq7OUndSj1DPUV+jvl/9gvpjDbKGhUaghkijVGO3xhmNIRbGMmXxWELWclYD6yxrmE1iW7L57Ex2Bfsbdi97TFNDc6pmrGaRZp3mcc0BDsax4PA52ZxKziHODc57LQMtPy2x1mqtZq1+rTfaetq+2mLtcu0W7eva73VwnUCdLJ31Om0693UJuja6UbqFutt1z+o+02PreekJ9cr1Dund0Uf1bfSj9Rfq79bv0R83MDQINpAZbDE4Y/DMkGPoa5hpuNHwhOGoEctoupHEaKPRSaMnuCbuh2fjNXgXPmasbxxirDTeZdxrPGFiaTLbpMSkxeS+Kc2Ua5pmutG003TMzMgs3KzYrMnsjjnVnGueYb7ZvNv8jYWlRZzFSos2i8eW2pZ8ywWWTZb3rJhWPlZ5VvVW16xJ1lzrLOtt1ldsUBtXmwybOpvLtqitm63Edptt3xTiFI8p0in1U27aMez87ArsmuwG7Tn2YfYl9m32zx3MHBId1jt0O3xydHXMdmxwvOuk4TTDqcSpw+lXZxtnoXOd8zUXpkuQyxKXdpcXU22niqdun3rLleUa7rrStdP1o5u7m9yt2W3U3cw9xX2r+00umxvJXcM970H08PdY4nHM452nm6fC85DnL152Xlle+70eT7OcJp7WMG3I28Rb4L3Le2A6Pj1l+s7pAz7GPgKfep+Hvqa+It89viN+1n6Zfgf8nvs7+sv9j/i/4XnyFvFOBWABwQHlAb2BGoGzA2sDHwSZBKUHNQWNBbsGLww+FUIMCQ1ZH3KTb8AX8hv5YzPcZyya0RXKCJ0VWhv6MMwmTB7WEY6GzwjfEH5vpvlM6cy2CIjgR2yIuB9pGZkX+X0UKSoyqi7qUbRTdHF09yzWrORZ+2e9jvGPqYy5O9tqtnJ2Z6xqbFJsY+ybuIC4qriBeIf4RfGXEnQTJAntieTE2MQ9ieNzAudsmjOc5JpUlnRjruXcorkX5unOy553PFk1WZB8OIWYEpeyP+WDIEJQLxhP5aduTR0T8oSbhU9FvqKNolGxt7hKPJLmnVaV9jjdO31D+miGT0Z1xjMJT1IreZEZkrkj801WRNberM/ZcdktOZSclJyjUg1plrQr1zC3KLdPZisrkw3keeZtyhuTh8r35CP5c/PbFWyFTNGjtFKuUA4WTC+oK3hbGFt4uEi9SFrUM99m/ur5IwuCFny9kLBQuLCz2Lh4WfHgIr9FuxYji1MXdy4xXVK6ZHhp8NJ9y2jLspb9UOJYUlXyannc8o5Sg9KlpUMrglc0lamUycturvRauWMVYZVkVe9ql9VbVn8qF5VfrHCsqK74sEa45uJXTl/VfPV5bdra3kq3yu3rSOuk626s91m/r0q9akHV0IbwDa0b8Y3lG19tSt50oXpq9Y7NtM3KzQM1YTXtW8y2rNvyoTaj9nqdf13LVv2tq7e+2Sba1r/dd3vzDoMdFTve75TsvLUreFdrvUV99W7S7oLdjxpiG7q/5n7duEd3T8Wej3ulewf2Re/ranRvbNyvv7+yCW1SNo0eSDpw5ZuAb9qb7Zp3tXBaKg7CQeXBJ9+mfHvjUOihzsPcw83fmX+39QjrSHkr0jq/dawto22gPaG97+iMo50dXh1Hvrf/fu8x42N1xzWPV56gnSg98fnkgpPjp2Snnp1OPz3Umdx590z8mWtdUV29Z0PPnj8XdO5Mt1/3yfPe549d8Lxw9CL3Ytslt0utPa49R35w/eFIr1tv62X3y+1XPK509E3rO9Hv03/6asDVc9f41y5dn3m978bsG7duJt0cuCW69fh29u0XdwruTNxdeo94r/y+2v3qB/oP6n+0/rFlwG3g+GDAYM/DWQ/vDgmHnv6U/9OH4dJHzEfVI0YjjY+dHx8bDRq98mTOk+GnsqcTz8p+Vv9563Or59/94vtLz1j82PAL+YvPv655qfNy76uprzrHI8cfvM55PfGm/K3O233vuO+638e9H5ko/ED+UPPR+mPHp9BP9z7nfP78L/eE8/sl0p8zAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAC7ESURBVHja5Lx5dFRV1rBfgHwYRQQVtB26ZWhtabtfeUGxGxFbUGZF8RMHGkVbRkekVYiKisicVhE0gEwBokgDAhEMMSSQkAECwcxkrlRSqVTqJqnxzs/vj5t7qUyAvr9e37fWV2vtleSm6p6n9t5nn733OVU2RaUaEP5PiqJSbeMXPBTA5/Xhzk9Vnd9vo3HFx21E2LYJX9IRgh6npvyCe9uaqS4K4C3IpXHFx9S99CTuJ8Z0KLVjRlA7ZgTuJ8ZgXxmJL+kIlwAkXBQk6HFq9pWRVA8fSvXwodYgdS892a6EA1UNvouqwXdR99KTeAtyfz2IL+kI1cOHYh9wqwVwKWJqpXbMCOv19gG3Imzb1JF2OgZxfr/NukH4jcNVfyEAE8IU+4BbKet1PfaVke3BtA/i/H6b8aIBt7a4mWmaC0nr55vmqRp8F5V33Mm5LhHtwbQF8SUdsSDCb1I1+K42g1xIWgOYYh9wK+e6RCBs29QxSIWus37aJM51iWjx4so77mwD1d5AHQ1eecedlN9yuyVlva6nrNf14Q7cEmRn4W7u3T2E9ME3UX7L7W1uZg5Weced1s3sA2613ql5LXzQjuRclwjcT4wxTXQeRHC7GLdnHPeensiCVwa3e0PznZk3EbZtwluQa0kofz8NcVNxr++Ce30XnNuv61Bcu7viXt8Fvyu7JYipjfGHxzD+8Bh2j+7fAiZcC+Y0zPDIbCyD6DyV6DyVeDcIQR2C39J4oieNJ3oSOnkVcnZ35Ozu6MVdDHF0N6S4C43OqJYg/0ydzb27hzDx0FjuPT2R+asfa6OVsl7X40s6QoWus/CQk6fWZPHChhxe3lbMCxtyrN9TyxSQSwidvMoC0XK6tRGybPjSRmOuNUKVo4Zxe8YxIu4+Jh4ay/jDY7j39MQWWjnXJYLGFR9Toes8tSaLiavTrIHDxfxfapkCwW8hy9YuhCmhk1fR1FRnaCS1NM4yy8RDYy2tjIkZRXq/HtYsCnqc2sJDTkYsTrU00J6YkEJQR7M/eEGY0MmrcOenqjZA2JmyzTJLuJiOe65LBHUvPUmGR2bE4lQmrk7jqTVZHcrE1WkMWpRIdJ4KnpUXBCHLRl3e16EWIOEaMU00/vAY9na/gsYVH/NdgYe+8w9bMBeSQYsSWXjICcFvL2ga+dhlFwcJ10rjio/ZklprgbSWiavTWvzdd/5hXt5W/OtATC201sq9u4eQ+PVijmSW0nf+YQYtSmTQosR2gUYsTmXQokT6zj9saeRCpmkJ0hxD2gOZeGgsI+Lu45+ps7FXlFmDmDDtSd/5h+k7/zCpZQpa9cwOQciyIR+77LyzFhXlMyZmFOP2jLP8orVWRsTdR2ppHFtSa+k6ZZM1WHvSdcomwyxySceayO4OWTY88TdirygzUkWf18eL2//RQiutYcwYE/Q4tagDOUQ8uo6uUzbRZ3qMJV2nbCLi0XU8tSbrolNXzu6OfOyylgEN4NOkaO5acw/j9ozr0ET37h5imehIZimPL91rAfSZHsOQBfuISS7E7vaTETeX0MmrOoQInbwK+dhlNKWsahni0zPSuGvNPW1M1BrI1NrOwt0WkCn2ijJSS+MYt2ccuQk3oxd36RCi8URPY+HLT1VbgGiSzPsx71laCddMe2Yygf6ZOtuScXvG0XfJn/n8YL+LQnjibyQ34WZ8Xl/bfKSoKL+FVi4EYwKZcu/uIQzaPoExMaPQcrq1ADFX33AI1+6u1OV9HVI6ShU/TYqm75I/dwjTHtDEQ2MZt2ccg7ZPaGGScIDWEBlxc42UoSMQ00StYdoDCgcbtH0Cbx+8p40ZTIBwiFM7RmB3+y+exZvT2YRpDdR6ZoVrw1xRWwN44m/Euf06A6Ki7NLrmnDNmH7TEdSg7RP4/GA/yLK1GdwEKNzSk1M7RlDlqPl1JefOlG2MXTGmXaAxMaMsB/XE34h4tH+7ANlrB7T2iV8OAlDlqOH9mPcsIBPKlF3R16Ad7GwlxoVberYAKCrKv1ghfmkg5sPldLIzZVsLqLErxpC9doAlp3aMICNurlGyVpRdSAu/HqS1Q58rd1JUlI87P1UtKsrHXlGG3e1HCOoov+x2wiX3RxT+o49L1IgutXxVUCfDIxNfLraQDI+M3e3/NdCXbhohqBNfLrIsVzZqmoT6dmXG0SBLTrmJLxd/CVRLECXcDGFaSC1TmHE0yKg4B0P2uxiy38WoOAePHaptAfHYoVqG7HcxcGc5o+IcfFfgsbQUPoYoSa213BbE78oGucTSwpJTbobFFjNgbQHdvi6g8/Z6Om+vZ8h+VxsQE7T/97UMWFvA+Og0UvIryfDIZBQ4CeXvt8a5IAhAY/RImlJWUaHrPHaolhuXFXHN+8e58qNcbomq5P6t3xG973WePLzPgnnsUG0LiP7f1zJwZzk3LisyctfSOFxOJ4lfLzYToQubxu/KpmpWBFWzInguOokrP8ql7/zDRMxLpFfUabasHwlZNnITbmbgznI6b6+3Bu7/fa2lrW5fF9Ar6jQD1hYwLLaYx5fupdi+EiGok748koa4qa010xKkKWUV2UM7kd6vB7tH9yfpnUFkLzQiZOGWnmgHO9N4oie9ok5bA4YPbkqvqNNc8/5xIuYl8tSaLOLLRXambENXF+PxNJD0ziAanVHhYaEliH1lJD/1iqD0qSsIzu2M/N550TZ3QjvYmS3rR1qDtwdhgpgwnabGMj46zRjQsxJdXYw7P1X1pY0GuaRjkMKxPah5qxuV8y6nct7l1LzVDfdyo6miHexM+ou9mblwKfdv/Y77t37HNe8fbwMQDhIxL5FOU2PZklqLJjUYdU7wWxBuN+ricBAF0KQG6pcNovZpw0fCQao/MEBcu7tSOLYHjnu7EZzbmeDczqyfNokrP8ptMXi4XDnzAJ0n72TIgn1oUoMB4VlpgIjj24I0payi9KkrqHj+Ssth2wM5c38f8p68D2nbHKRtc3h86d42A/eZHsOVMw9Y0nXKJmxDvyS1NA70z8Gz0qh5hNvbzpr6ZYMofzyiBUwLkOVdjfR/eVcao0dSl/d1aHx0GhHzEi0TXDnzAJ2mxtJpaixdp2yypM/0GLrcs5D3Y94ztNDsK7qjuxmzDBBz2rYGqZoVQc1b3dr4yfppk+g8eWeLd91aAxGPrqPbyKV0G7mUiEfXMWdz+nmQ0Jsgn1AbT/SkMXrkeZC6vK9DpU9d0S5I5bzLqf6gq6UV7WBn5q9+zDJBuEQ8us4SE6LLPQvpcs9CjmSW4ndlo1XPNBxWLiE34WbSX+wNapEBEsrfT/njERSO7WGBmDA1b3Wj9KkrSO/Xg1WjBjJl/CT+8sQ8a0BT/eGDhwN0uWchXe94ia07YkE+oSLc3gxyQt2yfiSrRg0E+YRqgRSO7UHh2B4UT7ragqmcdznFk67mp14ROO7txpTxk7AN/bLFgN1GLsU29EvrejiACdG59xQjKgu3GzVP9UwIvcmCVwYb102NmBHVBDFNVDUrgjP39yF98E0E5xox5Dcj5lsDhwOYQObg4dK59xR2RV8D4njEo/0NIEd3dkVfgy9t9HkfMTWSO6pXG63kjupF8aSrqXj+SoJzO1M573KmjJ/Eb0bM5y9PzGPBK4Mp3GKUEFvWj+Q3I+a3AOjcewp/eWKesUQ0T1mz2att7oSU9+F5EE2SqXvpSbKHdrIGNmHCoapmRVgh33LezZ3QNncyloGDnVnwyuA2IFvWj0Q+dplREzu6Wy0r9/KubVvg9pWRpPfrwZn7+1haMSHCxdSM/J4RWWufjiC9Xw/m9PgtN9w0uo1JbrhpNI0njAXTrAIbT/TEvb4LjdEj2641vqQjpPfrQfrgm1qYKHxKlz51BbmjerFj4G2WtAYwtWDKglcGG2ZoXrldu43AWDUrAmnbnLaRVZMayHvyPn7qZThoa38pfeoKap+OIDi3M6tGDeSGm0a3GTT82g03jeaGm0bj3H4d8rHLrN0I93LDpDsG3kb68si2a425hfZTrwjSB9/UBiZcM+YM6ghoyvhJpL/Ym+yFhknc67tYQVF+z3gjc3r8Fuf32zpOFTMeHXpRGDNfMYF2j+7PqlEDWTVqIOkv9rZ8SNvcCff6LlTOu9yK1Okv9mZOj9+S8ehQNKmBDhs17vxU9adeES1gwoHKH49oFyhcwhfKynmXWzOu4vkryR7aieyhnQjl7+84QzNNJGzbxN7uV1gw7WmntYZaLw2mmNdrn44ge2gnztzfx9od7zBnDa9t0pdHtgsTDhRustaaCndwEyLj0aG481PVS9r3FSUJj6eBrConMZHvnodpntrh2gkHCgcLl/TBN7G3+xXGLMlIo0LXjU7ixeoaUZIQ3C7OlTtJya8kJvJddgy8DctvWgGFaylcHPd2Y2/3K5jT47esGjWQrTtiyapy4nI6jUrvUmpfUytFRfmkZ6SxdUcs66dNYsfA2ywNtQBrJeb/dgy8jZjId/kx4YgF4fP6Ln1L3uyhhWvnSGYpOw6lEBP5LuunTWLDAw+x4YGHrAi74YGHWD9tEuunTSIm8l227ohtAyBK0i8/pNDagTVJxuf1YXf7OVfuJKvKMF16RhrpGWkcySwlJb+SrCqn1awRgjqaJP9nO0b/Zxo1v+ahS0ZqKJ9QCX5rJMyhN42aRj6h/udB5BKjiAp+i64uNrJ2M0Vs3rUiy4aU92G42X49iCYZDZjUMoX4ctFIcILfGgVU6E0LwEyCxKP98aWNxpc2GvFof+RjlyHlfdjxWnOxh93tJya5kIWHnDx2qJbnopP4NCmaYvtKC0LL6WYkQps70RA3laaUVbjzU1V7RRn2ijK8BbkWUJsM7VIAog7k8MyuPKtD1AJA/9zQQpYN9/oubFk/kpkLl7J4a0KbtrdZa/vSRrfMWS8GcSSzlGd25TH5VIjptTpR9T5SS+OMsrHZD3RHd7SDnTm1YwSzY2KsTtL46DSei07iSGZpm/tKeR8a5gnf0+vI8zfE5zAstpjptTrvifBJeeZ5LTQDkGXDtbsr0fte59mjDmaWaUyv1ZlZpvH3XJlRcQ6Grj5OTHJhy/t7VhrpwMVAog7kMCrOwcs+nZWaccak2L7S0oLpC6d2jGDJiUyWN8E6FVZqsLwJ5ruwYO5O9jFoUSIb4nPOT+/gtxf3kZjkQobFFreAaHRGGZoQbm+hhWd25fHsUQevHilgbo7bAmoNM2S/i6Grj3Mks9Tolcgn1Hb39MzHuXInw9edZrJd4z3xPISuLrYgCrf0ZOuOWKLzVFLLFDIKmlfr5EJmHMxhfoWvDczkUyELxl5RduFUUZNkIvdm8+BpkZd9eocQPyYc6XDnocpRQ+TebObmuFmptdTK5FMhBqwt4K1vMi4cWTMKnIyKczDZrvFJeWaHEBdrbVc5aphxMIflTR1rJaPA2TFI1IEc7k72tZwdYRCLtyZc6h4MMcmF7WrlwRSRAWsLiNyb3T6Iz+vjmV15jIpztIHwxN/I7JgY4svFS47CHk9DG62Y5hm4s5zx0Wntb0CnlikMiy3m06ToFpFSO9iZnSnbeGZXHkcyS8kocF6SHMksZc7m9AuaJyW/si3IltRaZsfEGNM09KZVs2bEzWV5EyzLlXn1SEG7MuNgTruy5JS73dlzd7IvPMi1BIlJLmRnyjbLJFawar7ZHi5NdrSS9jRyd7KPXlGnzQDXyjSlcYY2mk1SuKUnS05kslI7f9M9/HKgdaoh74nn/cR02NV7M9t2A9A/t/qf2uZOvB/zHvNdxk3Mm0bV+36VzK8wxHTWVutPmEbkE6q1hjQ3/yefCvGeeB7k1SPGlLsUeeubDOtnezJnczpvfZPBuXJnGEjzAqSri9FyulG4pSf3b/3OCvErNQNmxsEczpU70ST5kuWXJc9yiZXemQ3du5N9TK/VedmnW1qZm+M+v3r+gpTS42nA42nA5XRa4vE0hFd8zSDBb63cInvtAAYtSuTuZB+T7ZoFYy7tz+zK6+igQZtHRoGTyL3ZLab4M7vyGB+dxpAF+1i8NaEliLmWyNndsa+MZPi60/T/vpaJhTKT7ZqllZWaoZW3vsnA42m4IMS5cifPRScxN8fNeyK87NOZXqszsdDITa55/3i4dgVb0OPUTG2IR/vjzk9Vt6Qau5R3J/uYWCi3MJEJM2dzOkcyS80Q3WKrPia50IIIX2cmnwrxYIpIr6jTPBed1Mo0apFgpv0NcVMR3C5ESWLO5nS6fV3Ag6fFdmHmV/iYcTCHyL3ZRB3IsSRybzbP7MpjfoWvXYj+39cyZME+c7aEgTQ36smy0RA31dostrv9DF193IIJ9xcTxgSam+O2xAQwg9fMMo2JhTIPnjYgBi1KbC+RPq8REyR8iT9X7rRgWptpvssYLBwqHGB6rc7fc2ULYsh+F4MWJbLjUErH09c8ytcaxNTMCxtyGLC2oIUDT6/VO5TJdkMLJsTAneUMWpTYNotvE0eaj3rKxy6zun2t69mdKdt4fOley4lN35ls11pIOIC51D8XnWQu9xcGUQCteibyscuM5n31TKNqD5fm1H9DfA7PRScxdPVxhsUWMyy22Dq4MGS/i2GxxQxfd9oC2HEopb1WVcdtCU2Sqcv7OmTWpGbRLOV9SCh/P0GPUwvPvDIKnMQkFxK5N5s5m9N5LjqJ56KTeOubDFbvzSQlv7LN1P5FxzZ8Xp918v8SWk5WsWStLbr0a5oLHRdY/+GjPP8vtq7+0yCiJOHz+hDcLlxOJ2bzxeV0Irhdlk/9x0B8Xh9VjhoEt6s5rZTaFU1qQHC7qHLU/PpZ05EGqhw1uJxO0CVESSIlv5KoAznM2ZxufTJgzuZ0og7kkJJfaR1mcjmdVDlqflkc6ahSs1eUWdMzJrmQQYsSrYMJNy4raiHmYQWzD2IC2SvKLpa/dAzi8/qsc6cZBU6GLNjHlTMPcEtUJVMSdd45qRGdp7KxDOvDPu+c1JhxNMgtUZVcOfMAQxbss0K7vaLsQqbq+GCtCbEhPodOU2O58qNcZhwNsrMK4t0Xlp1VMONokCs/yqXT1FgrE7sATPvbJK0hblxWxDsnNWugvc7zcqFry3JlbomqbANzSdskpk9kFDjpOmWTpQnzne6sMgbbWWWYY8kpN0tOuYnOU1v8z9TcOyc1blxWRNcpmwwz6dLFjxr7vD5rY+eO13YSMS+Rh/co1iAby4wBluXKLDnl5rsCD1lVxk7FdwUelpxysyxXbvHcjWUwYb9CxLxE7nhtp7X10spELUHMMiHqQA6dJ+9k8KYaJh1u6ZRLTrnZklrb+hS3lURtSa1lySm39fyNZTAlUWfwpho6T95p1rqtS5LzICapJsmWNkbEBpiSqLMs1/gY3DsntfAuT4tDlkrYtci92bxzUmNjmaG9KYk6I2IDbbTStsBqjhma1EBKfiVdp2xiwNoCHt6jMOmwxjsnNev46KWUkaIksfCQk2W5Mu+c1Jh0WGPCfoUBawvoOmWT1d4Miy3nQczIuXpvJp2mxjJ4Uw0T9hsg09KM6fhcdBIxyYWXJM9FJzHjaJBpaTDpsAEzeFMNnabGGhVec+RtA1LlqAFd4vGley0Q8wZTEnWmpWGdWX3sUC3PHnW0K+b/n0qoZ1oaTEszfCQc5PGle0GXwv0k7PxI87S9EMjMMo35rvMdILPDbErrzlA4iOmw4SBh0/iXgUxLg8mnQvw9V2Zmmdau/D1XtpoxpiYe3qPw8B6FW6IqreOCvwpkWhqMinMwaFEi46PTfrFMXG38HLr6OHe8ttPykXZNYzrr4q0JdJoay4C1BS2cdfCmGuZsTrd6Hv/T5ozZJ7no9L1xWZE1fU0bD193unXx3GESFZNcyIb4nDazaUN8Dh6PkTy1O307CmgT9itM2K9YWnkuOumi26wTV6dZR43NXOXKj3LpPHknEY+us0DaDWiWnwCr92bSdcomBm+q4eE9ShsThTXh2jRn5mxOZ/CmmjYzZkRsgE5TY40Q33bhu/iiF66VcJjh604TuTfbUnnk3myGrzttQZgzZtJhzQrvfabHWGNccNELnz2tfSUcJjxADVhbwIC1BdYsMyOp+fyH9yhWGnAks/TS0gDTV4qK8q2NxU5TY7klqrIFTDhQ6+gZ/hwzdoSbpKgo/9LPj5hnR8yUwEwVw810MRkRG7BSRXPpLyrKv/RUsT2YI5mlLZLnEbEBK1q2lhGxASt5vuO1nZY5ioryL5TJX7icENwuioryjV1rr4+oAzkMWbDvouXEkAX7iDqQg8/rQ5MaLgZxaQWWJslWSWkWWBkFzl9UYP2PvgjFPNrj8/osM/2YcIQfE46QnpFmfL7K7SLocWpBj1Mz6+D0jLQWzzPb3b/6aI8SVnCbvXTTVOZxno6kqCjfKlPNUH4pIP9XPGz/N319UFnrf2iKLGi6LmggqCBoIOi6JuiqIqCrgqIrgqyrgoYu6JpiiK4LKgigCpquCCEdQdVVAU0VdP2iMGW29tplmtbcQNQ1QEXXNDQdQGsWHZBbvdQsKkTQfaiaBJrc/PyLPpQ2zqqbL9U10GV0TUbTZUCyQAoaJPaVinx5RmbVKZnVWRpf56r8WKlQFww2Q4bf8VdMXwsEtfkdGb97xSAb8yRG7df4zYYQ3deEsK2WsK1UsK1U6LIqxJWfKQzcEODVw0GS7KbG1F8Pout6C7WuL5Dpv1PBtlLEFgWXfyHTY61Ery91rvkiwLWfB7h6jcxV/5LoskLF9gl0+tjLI7FesuuxzKnrHeqneQdL143Bjacj6wqg4ZFUph8JYvusCdsXIldvhGvXi/T+SuS6dQrXrZO4fp3Ib76UuH5NiD6fi1z/mcgNnwa5epWMbbHG1StEvsoSjbeoq2i60h6MYNN1XTAhNF1vdlBoVFSG7/Nh+1Ti2o1Brl8v03uDyDVfN3DDVz5u+FKh15cKvdbp9FoHvT5X6PW5wjVr4LrPda6NkugTJdL1EwXbIpkVx5sdGaXZ8S9gGgNIJ6ipPHgghO3TED23h+ixTafXZpmb1ofos0ml+9dw1VcaV3wapMvKIF1WSVz+qULPzxV6faZw9Wc613yq0Xt1iN9Ehei+WMG2QObz03JHDtxsGk07P2XRmZ/hx7ZG5rqtMjdubqTHFonrNov8doPMZRvA9pmPqz8X+MNWhb/tkrg/VuGWaJXLPmmk85Imen6m0+sz6BMlcsNqP9etVujysU63jwIcrwy1N6UFm6Zrgma4KKBxrE7lyq999PnaT58dcMNWjV5bFa7d6sP2lcj/+szP6/FNHK2SqQtpSKqIKItUN2psyJH52yYXtkV+uq9UuP5fMj1XqVy9WuWGFSE6LQgxbHMQv6kVXW92B12wKZouSEjGNNMVJvwgYdugcGOsym+2q/TZqnD9dh3bVz5u3h4guVJtnpJa808zkJlBMMS7SQG6vB/gimUKvVdK9Fmu0nu5zLXLZGzvaWzLDhggmoysqwYIKoKqG+rKqVO5douP62JUfvutxg2xCn1iZTpv0rgpRuF0XQAIgRJElSUURUWWZWRZRpFlgrIKeIEg7yaC7X2FXkslei+XDVkmY1sQ4pFNDaA3hwcdNF0XbGjNZwNQWXZaxrZV5XexMjftFLnpW4ne34rYNvjZUywBQUJqEEkMoEk6oqIgySqipCCKEt6Qis8fRNEaAB+TtijYInV6Lwtx7VKRPstkIj5S6PGBRGFtwFCgApquCDYFTQANXZeZkiARsVPnlu9kfhcr0/cbiYivA4w94DM0oet4VQVJUQiJGiFRIiTKBEMSAX+QhoBIvU/C1SQCfpIKGrl8kZerFitcu0Tkuk9ErlsiYXtDYuMpYyobE0gVbIouC6DiDsgMiwtx406Z/rs0+u6WGPCNSI8tIZbnSoCCEvITkBRkWSMUkAgEJbz+EE2+IA3eAPUNjTR6fNTWSni9PuoFN/d8KtBpkcg1n3jp82GQ3h/6sc33seAHb/P6pYOmCTY0VQCNEkHhrgMhfrdL5k/fafT/XqT/boU+sRI/2r0AhESFYFDCF1TwBSWa/CE8TQHcjQFcDX6cdQGq63w43PWU1AoEmup4emMjtvl+enzop/d7Aa57N4Btvo/Z37jCHBzBpuqaAHDOHWDo/iD99in8+XuZO/er/H6fxsB/h0irDgGqoYGAhOAL0eALUd/oo87TRK2nCUddI3anQKXTTUl1DUVVNXga6nh2mwvb6066L3Bz3btOekU2YXtd5MVNDmuVVtEFm6brAmiUu4OMPODnjv0idx+UGHpQ4q6DEnf928+h0iCg0egN0OgXqW8MUCd4cXm81LgbqHIJlDs9lFd5KK90U1hWQ3GlgLOqlrs/rsQ2q45rFjq57q0yukc6sL3iYc62akBDR0fRNcGmq5oAQYSAyuQEibsPhnjgkMYD8T4ePOTnv/ZrfJrtBTWE4A3ibvRTJ3hx1jdRXddApbOeMoebEruL3Ao3p8vqOVVSR1JuDZkFtbywvgDb0zl0eqmanm+Wct2bFdhmlvP2Po/hH6qIrmiCTdNUAVVElTVeyfTz10My435UGHNE5JGfJIYf1ZiV4kFo8uILBKirD+LwBHC43Dhq6ymurqfAUU9ORS05RSU0NHmQVRW/JCMqOho6354U6DEri04z8+nxWim2fxSx8ZgLEAlJCqoiCzZZUwVZVECDjUVNDD8s8sRRlSmJOs8mwbPHZJ466iO2yI8aDNJU56a8tpGqaicOZx2FVfWcLa8lq7CMBn8IHfAGZQKSik/SQAoBOjEZtdiezqTTS/l0fzmPrFIBNB9CUCcoSYJN0TTBKymgS5TXBXn8pwCTj8lMT1WZmarx+nGR2Rk680+GOFleh9/bgMtZR3V1HYWVLvJKajiTV0pVjRsV8IVEgrLaLApeERSCAAx5/xS2+48zZvlZAmKIQFMTHq+PppAi2DRdFQIyyKIfRImoMz6ePO7lpUyJl08r/PN0iMjTEh9kS6zNEUgp92GvaaDAXstZh4DLG0JoChAMyviDMn5Jxi/K+EISIVnFr0h4JWPZ33a8mNteSCI6vhpZbMDhaqChyYfHHxRsmhYURBECoRDoMvkukVfTFN7IlHk7W+aDXIlVOSHW5ob4qhi2F4v8WNLIiSov5wLgkVVERSUYMqa2LyTjF1UCkkpQ1vGLImJAxCsai2SdKFJQ6aG0ooqK+gBuVxOCTxBsuq4IkqQSFCVCkgyqzg8lXt5J9/H+WViVJ7G+KMSOEoVdJSp77DJxdRrH3Rq5goLDJyMERRqCIt6QbPiHqBAQFSRJJSCrhGSZJklDUs/nIefsNRRXe3DWefE0NjUf21BURFEiGDRWVH9I5Nu8Rt7Pk/lXocbWIpFvKzT2VSr8YJdIcEqk1Svke2TsPhV3SMYTEmkISngDCr6QTFBSCUkqQUnFL2kEJUNLflFF1aGuyUepow6HuxG34DdyVkVRkCQFUVLxBWR0ScEfFPmuuIG1hTIxpSr/rpA46FBIqJHJdGmcqVPJa1Co9MrUBiTcQQlPQKYhoNAUUvCJCn5JJSApBCTZEr8oEVJU/IpKiaOOmnov9Q1+QyOqqiErGqKiIYk6/mAATQ4QalRItPvZU+EnvkrmxxqJRJdIVp1KTr1GQaNChVei2idTE9BwBRTqAzKeoEyjKNMkKvglhaCkNAMZogAeX4DS6npcDQE8jYHmM0aajqLqyLJOSNbwSTJev0woEKCxyU9OdZCEkgAJ1UGSBYWsBo3cRihq0qj0KVT5ZBwBjdqQRn1IRhBVGiWVRlklqOiIikZQ1hAV4ytjJE2n0ummqt6LU/AjNAYEm64jaBqoqo6iaEiKhiirBESVhkAQr9eH0ChSUu3nVGkdGY4mUmt8ZLoC5DWoFDUplHpVKnw6VT6ZWn+IuqCEJ6TQEFINzUgSflXFJ8nUe304XALVdQ3UNwaob/TT5A0ZILoO4TCyrBKSZHxBGcEfxNPgpdETwO32U+ZoIKesnrPlHrLtbn6urCfPXk+B3U2R3cO5qgbOVTVQUilwrkKgtEqguLKe4sp6yhwNlNg9VLkEhKYgjd4QTX6RYFA+X2Dpuo6maaiqiqqqKIqGKKn4QwrekERjIIC70YenMUBjk0S9EKK23our3ovb48Xj8SI0BfD4ROq9IdyNQeoa/Lg8AZxuPzV1PuobRASfguAN0egP4Q1KBEMykqwKNkAxMnpDNM1oSxhQGrKiI6oqTapIkyTiDYUIiDLBkEwoICOGjHghKxqKqqCoEooqEVJFgkqIkBIiKIsEpBB+MYA/FMAXkgiICiHRmK2KoilWo6bZRIKu61bjRdd1QdEQVBVBkzRBlVRBFhVBVTRBUXRBknVB1hAUECQQNF0XUHVB13RB0XRBVDRBUjRBUTVBUlRBlBRBlGQhJGuCJOuCouiCpuqCqqpl/7Eemqor5HnS2Ja/hPezpvCP1PuYlfo3vvo5EnfA0baH9qs+CKZpBIIh7DUuyuw1lNprqHDU4mnwoqoamq5xyn2YVTkv8cKJO3n+TH+eTB7Ao/H9eSr+TnbmrfyfgdiddZzKKaK0yklhuYN6oWVfvabay+6Tu3gzaSJPpPZm9E9XMmnvH1n60wKSanZypuEg35WuZlrCMLb9vPSXgzicdWTkFLX7vya5Dq/spk62s8v1AW+cu53ns29kSd6z/Fi9mZ/L8tpqVFfZeHYxBe7MSwdJy85v8Xd1oJwDFRtZlTeTD88+wcKsMSzMGsv8rL8wNbMnc7LuJN6xg6AcsF6TW1xBkzfQct9P8pDrSkfT1QuDKKrKz8UV1t+V3kKi89/m1YyhvHlyMPOz/ouFZ4fwYe59fJAzjLfO3s66wuep8p7jbF0iUTkzOe76/rzZ6jxUVteGtch06gL2C4PIikJFtcv6e3/ZeuamDOHNU//NivwxfFY8jnXlE/iyYiKflz/Eh4WD2Gv/CL/YQIJjI2+dvJvXTt7FtJS+LPt5OvVBY383KEoUlFaGzSz5wqb5ubC0WSsyG3PfZUbKnXzw8wOsKX6EdWUT+NI+nq8cY1nrGMnikjuJd0Xhld1sr3iTt37+IyuLHmZN0WMszxnPzLSBvJnxMMWNPxv7vUITLrdw8VlzMswnNud+xD+O3cGy3LF8ce5R1pZN4IuKsXzlGM0X1SP4uPJ2jgpraJAcfFb+CJHnbuOz8pF8UT6OL0om8nnRJFblPcrLaXfxxolROHzGd2idq7xIHBEavTQFQwAcLNvMP5Lu5JOcsawpmsRnJROIKnuYtVWjWVP9Vz6q7McRz0pUTSa2Zh6LSgeytOJPfGa/j3UVY1lTMoFPz01kdcEjLM95hNmp/8UHmU+j6MYnlrJyz3UMknHW0IbDW8rLyfexIGs4nxU8zqqi8Xx07gGiKkfyheN+ltnvJEFYGdYOFWlUqjniWcGK8iFElQ1jTek4Pi2awOqCR1iZ9wgfnx3Hs4l9+aHc+BqH2voGRFFqC+JpaEKSjOR2Y84iZqX8majcx1ieN57Xc+/hvXPD+aziAZaX30VGY0yH0/1s00E+KR7KquL7+ezceFbnT2BFzkSW5Uzg7VP38UbKQ3hCdc1aKWoLktHsG06/nbnJ9/H+6VGsyJnIC9l38kreMNaUPsKSkkHsdy26aABMcK3lw4L/5l9FY1mdP56lOeP55Ox4Psh+mOeT7+BAyUZj17O8qiWIKMkUlNoBOFQaw4zkQSw+M5bZp+7in7mPsKnkFVade4DPSsfTJNVeFCSk+lhbPIVl+Q+wMnccS8+OY/GZsXxwZjTTj9/OkqwXACi3O/H5A+dBKhy1lFQac33t2bf5R/KdvJnxFxadnkSyYzuf5j3BssIR/Kt4DBvLp/NF2dOsqXiSNRVPsKbyCeNnxZN8XjaFz4ufJrr4Bf5V8Agr8h5iWc5YPs4ey4enR/P+6YeYnfZn3kh9CAUfqgz2Gtd5kLOFpZTYjUMHH516jmlJA3jjxHCO2XexteBtFpwZyqqC0awo+huLCv7Eu4W38V7x73mvtD/vl/Xl/bJ+vFfye94tuo2F+X/g3dw/szT/b6zIHcMnZ0fz0ZmHWXT6ISKzRvJq5mBeSh5MSeNZyzyyrBggWTlFlNsNssiMKYz9oQe7i/9FmmM/r6bezZKfx7Is5yGW5f+NFYUjWHXuflaXDmN12V+JKhtGVNkwVpX9lZXFw1lRNILl+Q/ySc6DfHRmFIuyRhF5ciRvZ/6NNzPvZ3baIJ5N+AM/1xsfXcg9V47XH2wLMidpFE/9eAcVQg7Lsp7j9fShfHTmIT4+M4rIrKG8ljGAeSf78eaZfszP7sc/z/bln9n9mH+mH29m9eO1jP7MPfF7ZibfxvSE3zP1UD+eiruVxw/cxIT9fRj+764Mje3M6bqjAOQVl+MPhgyQvHPllFQapnkhfgRf5y7haNV3PJvwe945+QDvnnyAf2bcQ0zR22S7fySzbj+Z7n2cdO/jZP1eTtbvI9O9j8y6fWS49pHm3Edq9T6OV+0luXIPRyt2k1C+i/jybzhYupUfSrfjV40wX1zhQNN0A8RR66bEbjjr5p+Xc9IRz9snJvJ88h94O/N+3s64j1dS7mJLXuT/v0e/vT6qa93nnVXXdXLOlRtJi6qSWLmL8Yd682rGvcxLG8qbJ4byRuoQXj56L+UNuRcdoDHk5kDJNvaXbuZA2Rb2l21hX9nX7C3byNaCKJKr4pqnbw3+QLBlQDttxn4dPsh4hseP3sjcjP/m5dRBvJYymNdTBjMtvh8rT865KMja0wsZvqsr4/f3ZNyBnjx88CpGxV3BiAM2bt5iY8PPKwz/KKlsG1lDooTgCRJAYPKR/jyb2pcZaQOZdfyPzDn+J145/l/MSfojU364lW05yzuE2F30FU/80JcZSQN5+fifmH38Tmam3MGM1Dt4LOE6pv90DyHFCGLZ+SXtL3pn88rJCR5hbPy1TEq6jqnJv2XGsduZdfwPzD52By8n/5FZSX9g8sGbeDflGU7VHMUTqKMhVM/Z2hMsSZ/JY3G38I/E25l77I/MOv4HZhy/nRkptzE1+Rbu+beNhMrvjLEKSi+cj0T+8AaPZfTi2eQ/8Gj89fz96C3MSB7AjOTfMzPpNmYn3c7MowN4/IdrmXKoPy8l3MtLP/2Fpw7fxiMHr+HFxH7MTrqNmUm/56XkAbyY3I/pyb/jr/tsRJ542hqnOGydaRdkxv6J/DXBxvflX/Fd0Rru2W3jmYTrmZnUnxlJ/ZhxtB+zjg5g1tH+vJBwM1Pjr+fZ+Ot5PuFmZiX2Y9ZR43kvJfXlpeR+PJ90M3/da2Nm4gME5MZ2c5F2QV5OeYA/7rZxrOYgANE/f8S933ViTFxXZiX1ZfbRvsxK7MusxFuZnXgrs8JkZuKtzEi8lZlHf8espL48Gd+Lu3fbeDVpLA1BY+kvc7T7ZTktQUQlyLQjg/nzv20cyo+zrsdX7OKR/bcybLeNp368hpd+uok5ib9lbuKtzfI75ib+jtmJv2PGT7fwfMJveOj7zty/O4JPs+YjKsYUdTc04Wloav/YRusLz/04lAeTIsgsPENewfnc0is1EH32Qx47MICH913F+O//F+O/t/H4wW7877gIHtnfhXHfd2Hs91cyZl9v3k19lgLPaev15TV1NDR6Oz4/0vrC26ceYVhcL45X/GB4d2Eljf7Q+cJI9pHqiGPVqVeZd+wRZicOZ0bCvbyS9DAfpD3PnnNfUuO3ny9NVI2T+eVI8oVPGrUB2ZsfzX1HehJTtMK6FgyJZOYW0+gXf1EIz8wro9LhvKTn2lrugkMoFOS5n/7C0APXYK8tb3GepMrh5HB8Cmknz5JbXEpBSQVlFbVU2N0UlVWRW1RK1s95/JCQzMkzPyPLMpqm4ff7CQQChEIhJElCURQ0TcPsVOm6fn6tCT+oUOkq4bGE27n/qzv4KeMIwVCQQCBAbV0ttXW1VFRWkJ19lrS0DJKSj5F4NInk5OOcPHmK/Px8amtrcbvd1NTU4HQ6cbvdNDU1WTCyLKOqaguYDmvfgNzE4bIYdpWv4UT5EezuMkQl9B877PT/DQC7cLwx8LR3hQAAAABJRU5ErkJggg==) no-repeat;padding-left:40px}
-			.browser .browser-firefox{background-position:0 -34px}
-			.browser .browser-ie{background-position:0 -68px;margin-left:0px}
-			.browser .browser-360{background-position:0 -170px;margin-left: -27px}
-		</style>
-	</head>
-	<body style="margin-top:50px">
-		<h1>璇峰崌绾ф偍鐨勬祻瑙堝櫒锛屼互渚挎垜浠洿濂界殑涓烘偍鎻愪緵鏈嶅姟锛�</h1>
-		<p>鎮ㄦ鍦ㄤ娇鐢� Internet Explorer 鐨勬棭鏈熺増鏈紙IE11浠ヤ笅鐗堟湰鎴栦娇鐢ㄨ鍐呮牳鐨勬祻瑙堝櫒锛夈�傝繖鎰忓懗鐫�鍦ㄥ崌绾ф祻瑙堝櫒鍓嶏紝鎮ㄥ皢鏃犳硶璁块棶姝ょ綉绔欍��</p>
-		<hr />
-		<h2>璇锋敞鎰忥細寰蒋鍏徃瀵筗indows XP 鍙� Internet Explorer 鏃╂湡鐗堟湰鐨勬敮鎸佸凡缁忕粨鏉�</h2>
-		<p>
-			鑷� 2016 骞� 1 鏈� 12 鏃ヨ捣锛孧icrosoft 涓嶅啀涓� IE 11
-			浠ヤ笅鐗堟湰鎻愪緵鐩稿簲鏀寔鍜屾洿鏂般�傛病鏈夊叧閿殑娴忚鍣ㄥ畨鍏ㄦ洿鏂帮紝鎮ㄧ殑鐢佃剳鍙兘鏄撳彈鏈夊鐥呮瘨銆侀棿璋嶈蒋浠跺拰鍏朵粬鎭舵剰杞欢鐨勬敾鍑伙紝瀹冧滑鍙互绐冨彇鎴栨崯瀹虫偍鐨勪笟鍔℃暟鎹拰淇℃伅銆傝鍙傞槄
-			<a href="https://www.microsoft.com/zh-cn/WindowsForBusiness/End-of-IE-support"
-				>寰蒋瀵� Internet Explorer 鏃╂湡鐗堟湰鐨勬敮鎸佸皢浜� 2016 骞� 1 鏈� 12 鏃ョ粨鏉熺殑璇存槑</a
-			>
-			銆�
-		</p>
-		<hr />
-		<h2>鎮ㄥ彲浠ラ�夋嫨鏇村厛杩涚殑娴忚鍣�</h2>
-		<p>鎺ㄨ崘浣跨敤浠ヤ笅娴忚鍣ㄧ殑鏈�鏂扮増鏈�傚鏋滄偍鐨勭數鑴戝凡鏈変互涓嬫祻瑙堝櫒鐨勬渶鏂扮増鏈垯鐩存帴浣跨敤璇ユ祻瑙堝櫒璁块棶鍗冲彲銆�</p>
-		<ul class="browser">
-			<li class="browser-chrome">
-				<a href="https://www.google.cn/chrome/browser/desktop/index.html?hl=zh-CN&standalone=1"> 璋锋瓕娴忚鍣�<span>Google Chrome</span></a>
-			</li>
-			<li class="browser-firefox">
-				<a href="https://www.mozilla.org/zh-CN/firefox/new/"> 鐏嫄娴忚鍣�<span>Mozilla Firefox</span></a>
-			</li>
-			<li class="browser-ie">
-				<a href="https://windows.microsoft.com/zh-cn/internet-explorer/download-ie"> IE 11 娴忚鍣�<span>Internet Explorer</span></a>
-			</li>
-			<li class="browser-360">
-				<a href="http://se.360.cn/"> 360瀹夊叏娴忚鍣�<span>360 Chrome</span></a>
-			</li>
-			<div class="clean"></div>
-		</ul>
-		<hr />
-	</body>
+  <head>
+    <meta charset="UTF-8" />
+    <title>璇峰崌绾ф偍鐨勬祻瑙堝櫒</title>
+    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />
+    <meta name="renderer" content="webkit" />
+    <base target="_blank" />
+    <style type="text/css">
+      html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{border:0;font-size:100%;font:inherit;vertical-align:baseline;margin:0;padding:0}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:none}table{border-collapse:collapse;border-spacing:0}
+      a{text-decoration:none;color:#0072c6;}a:hover{text-decoration:none;color:#004d8c;}
+      body{width:960px;margin:0 auto;padding:10px;font-size:14px;line-height:24px;color:#454545;font-family:'Microsoft YaHei UI','Microsoft YaHei',DengXian,SimSun,'Segoe UI',Tahoma,Helvetica,sans-serif;overflow-y:scroll}
+      h1{font-size:40px;line-height:80px;font-weight:100;margin-bottom:10px;}
+      h2{font-size:20px;line-height:25px;font-weight:100;margin:10px 0;}
+      em{color:red}
+      p{margin-bottom:10px;}
+      hr{margin:20px 0;border:0;border-top:1px solid #dadada}
+      span{display:block;font-size:12px;line-height:12px;}
+      .clean{clear:both;}
+      .browser{padding:10px 10px;}
+      .browser li{width:auto;padding:0 80px;margin-top:30px;height:34px;line-height:22px;float:left;list-style:none;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAADMCAYAAAAWCXEwAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKTWlDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVN3WJP3Fj7f92UPVkLY8LGXbIEAIiOsCMgQWaIQkgBhhBASQMWFiApWFBURnEhVxILVCkidiOKgKLhnQYqIWotVXDjuH9yntX167+3t+9f7vOec5/zOec8PgBESJpHmomoAOVKFPDrYH49PSMTJvYACFUjgBCAQ5svCZwXFAADwA3l4fnSwP/wBr28AAgBw1S4kEsfh/4O6UCZXACCRAOAiEucLAZBSAMguVMgUAMgYALBTs2QKAJQAAGx5fEIiAKoNAOz0ST4FANipk9wXANiiHKkIAI0BAJkoRyQCQLsAYFWBUiwCwMIAoKxAIi4EwK4BgFm2MkcCgL0FAHaOWJAPQGAAgJlCLMwAIDgCAEMeE80DIEwDoDDSv+CpX3CFuEgBAMDLlc2XS9IzFLiV0Bp38vDg4iHiwmyxQmEXKRBmCeQinJebIxNI5wNMzgwAABr50cH+OD+Q5+bk4eZm52zv9MWi/mvwbyI+IfHf/ryMAgQAEE7P79pf5eXWA3DHAbB1v2upWwDaVgBo3/ldM9sJoFoK0Hr5i3k4/EAenqFQyDwdHAoLC+0lYqG9MOOLPv8z4W/gi372/EAe/tt68ABxmkCZrcCjg/1xYW52rlKO58sEQjFu9+cj/seFf/2OKdHiNLFcLBWK8ViJuFAiTcd5uVKRRCHJleIS6X8y8R+W/QmTdw0ArIZPwE62B7XLbMB+7gECiw5Y0nYAQH7zLYwaC5EAEGc0Mnn3AACTv/mPQCsBAM2XpOMAALzoGFyolBdMxggAAESggSqwQQcMwRSswA6cwR28wBcCYQZEQAwkwDwQQgbkgBwKoRiWQRlUwDrYBLWwAxqgEZrhELTBMTgN5+ASXIHrcBcGYBiewhi8hgkEQcgIE2EhOogRYo7YIs4IF5mOBCJhSDSSgKQg6YgUUSLFyHKkAqlCapFdSCPyLXIUOY1cQPqQ28ggMor8irxHMZSBslED1AJ1QLmoHxqKxqBz0XQ0D12AlqJr0Rq0Hj2AtqKn0UvodXQAfYqOY4DRMQ5mjNlhXIyHRWCJWBomxxZj5Vg1Vo81Yx1YN3YVG8CeYe8IJAKLgBPsCF6EEMJsgpCQR1hMWEOoJewjtBK6CFcJg4Qxwicik6hPtCV6EvnEeGI6sZBYRqwm7iEeIZ4lXicOE1+TSCQOyZLkTgohJZAySQtJa0jbSC2kU6Q+0hBpnEwm65Btyd7kCLKArCCXkbeQD5BPkvvJw+S3FDrFiOJMCaIkUqSUEko1ZT/lBKWfMkKZoKpRzame1AiqiDqfWkltoHZQL1OHqRM0dZolzZsWQ8ukLaPV0JppZ2n3aC/pdLoJ3YMeRZfQl9Jr6Afp5+mD9HcMDYYNg8dIYigZaxl7GacYtxkvmUymBdOXmchUMNcyG5lnmA+Yb1VYKvYqfBWRyhKVOpVWlX6V56pUVXNVP9V5qgtUq1UPq15WfaZGVbNQ46kJ1Bar1akdVbupNq7OUndSj1DPUV+jvl/9gvpjDbKGhUaghkijVGO3xhmNIRbGMmXxWELWclYD6yxrmE1iW7L57Ex2Bfsbdi97TFNDc6pmrGaRZp3mcc0BDsax4PA52ZxKziHODc57LQMtPy2x1mqtZq1+rTfaetq+2mLtcu0W7eva73VwnUCdLJ31Om0693UJuja6UbqFutt1z+o+02PreekJ9cr1Dund0Uf1bfSj9Rfq79bv0R83MDQINpAZbDE4Y/DMkGPoa5hpuNHwhOGoEctoupHEaKPRSaMnuCbuh2fjNXgXPmasbxxirDTeZdxrPGFiaTLbpMSkxeS+Kc2Ua5pmutG003TMzMgs3KzYrMnsjjnVnGueYb7ZvNv8jYWlRZzFSos2i8eW2pZ8ywWWTZb3rJhWPlZ5VvVW16xJ1lzrLOtt1ldsUBtXmwybOpvLtqitm63Edptt3xTiFI8p0in1U27aMez87ArsmuwG7Tn2YfYl9m32zx3MHBId1jt0O3xydHXMdmxwvOuk4TTDqcSpw+lXZxtnoXOd8zUXpkuQyxKXdpcXU22niqdun3rLleUa7rrStdP1o5u7m9yt2W3U3cw9xX2r+00umxvJXcM970H08PdY4nHM452nm6fC85DnL152Xlle+70eT7OcJp7WMG3I28Rb4L3Le2A6Pj1l+s7pAz7GPgKfep+Hvqa+It89viN+1n6Zfgf8nvs7+sv9j/i/4XnyFvFOBWABwQHlAb2BGoGzA2sDHwSZBKUHNQWNBbsGLww+FUIMCQ1ZH3KTb8AX8hv5YzPcZyya0RXKCJ0VWhv6MMwmTB7WEY6GzwjfEH5vpvlM6cy2CIjgR2yIuB9pGZkX+X0UKSoyqi7qUbRTdHF09yzWrORZ+2e9jvGPqYy5O9tqtnJ2Z6xqbFJsY+ybuIC4qriBeIf4RfGXEnQTJAntieTE2MQ9ieNzAudsmjOc5JpUlnRjruXcorkX5unOy553PFk1WZB8OIWYEpeyP+WDIEJQLxhP5aduTR0T8oSbhU9FvqKNolGxt7hKPJLmnVaV9jjdO31D+miGT0Z1xjMJT1IreZEZkrkj801WRNberM/ZcdktOZSclJyjUg1plrQr1zC3KLdPZisrkw3keeZtyhuTh8r35CP5c/PbFWyFTNGjtFKuUA4WTC+oK3hbGFt4uEi9SFrUM99m/ur5IwuCFny9kLBQuLCz2Lh4WfHgIr9FuxYji1MXdy4xXVK6ZHhp8NJ9y2jLspb9UOJYUlXyannc8o5Sg9KlpUMrglc0lamUycturvRauWMVYZVkVe9ql9VbVn8qF5VfrHCsqK74sEa45uJXTl/VfPV5bdra3kq3yu3rSOuk626s91m/r0q9akHV0IbwDa0b8Y3lG19tSt50oXpq9Y7NtM3KzQM1YTXtW8y2rNvyoTaj9nqdf13LVv2tq7e+2Sba1r/dd3vzDoMdFTve75TsvLUreFdrvUV99W7S7oLdjxpiG7q/5n7duEd3T8Wej3ulewf2Re/ranRvbNyvv7+yCW1SNo0eSDpw5ZuAb9qb7Zp3tXBaKg7CQeXBJ9+mfHvjUOihzsPcw83fmX+39QjrSHkr0jq/dawto22gPaG97+iMo50dXh1Hvrf/fu8x42N1xzWPV56gnSg98fnkgpPjp2Snnp1OPz3Umdx590z8mWtdUV29Z0PPnj8XdO5Mt1/3yfPe549d8Lxw9CL3Ytslt0utPa49R35w/eFIr1tv62X3y+1XPK509E3rO9Hv03/6asDVc9f41y5dn3m978bsG7duJt0cuCW69fh29u0XdwruTNxdeo94r/y+2v3qB/oP6n+0/rFlwG3g+GDAYM/DWQ/vDgmHnv6U/9OH4dJHzEfVI0YjjY+dHx8bDRq98mTOk+GnsqcTz8p+Vv9563Or59/94vtLz1j82PAL+YvPv655qfNy76uprzrHI8cfvM55PfGm/K3O233vuO+638e9H5ko/ED+UPPR+mPHp9BP9z7nfP78L/eE8/sl0p8zAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAC7ESURBVHja5Lx5dFRV1rBfgHwYRQQVtB26ZWhtabtfeUGxGxFbUGZF8RMHGkVbRkekVYiKisicVhE0gEwBokgDAhEMMSSQkAECwcxkrlRSqVTqJqnxzs/vj5t7qUyAvr9e37fWV2vtleSm6p6n9t5nn733OVU2RaUaEP5PiqJSbeMXPBTA5/Xhzk9Vnd9vo3HFx21E2LYJX9IRgh6npvyCe9uaqS4K4C3IpXHFx9S99CTuJ8Z0KLVjRlA7ZgTuJ8ZgXxmJL+kIlwAkXBQk6HFq9pWRVA8fSvXwodYgdS892a6EA1UNvouqwXdR99KTeAtyfz2IL+kI1cOHYh9wqwVwKWJqpXbMCOv19gG3Imzb1JF2OgZxfr/NukH4jcNVfyEAE8IU+4BbKet1PfaVke3BtA/i/H6b8aIBt7a4mWmaC0nr55vmqRp8F5V33Mm5LhHtwbQF8SUdsSDCb1I1+K42g1xIWgOYYh9wK+e6RCBs29QxSIWus37aJM51iWjx4so77mwD1d5AHQ1eecedlN9yuyVlva6nrNf14Q7cEmRn4W7u3T2E9ME3UX7L7W1uZg5Weced1s3sA2613ql5LXzQjuRclwjcT4wxTXQeRHC7GLdnHPeensiCVwa3e0PznZk3EbZtwluQa0kofz8NcVNxr++Ce30XnNuv61Bcu7viXt8Fvyu7JYipjfGHxzD+8Bh2j+7fAiZcC+Y0zPDIbCyD6DyV6DyVeDcIQR2C39J4oieNJ3oSOnkVcnZ35Ozu6MVdDHF0N6S4C43OqJYg/0ydzb27hzDx0FjuPT2R+asfa6OVsl7X40s6QoWus/CQk6fWZPHChhxe3lbMCxtyrN9TyxSQSwidvMoC0XK6tRGybPjSRmOuNUKVo4Zxe8YxIu4+Jh4ay/jDY7j39MQWWjnXJYLGFR9Toes8tSaLiavTrIHDxfxfapkCwW8hy9YuhCmhk1fR1FRnaCS1NM4yy8RDYy2tjIkZRXq/HtYsCnqc2sJDTkYsTrU00J6YkEJQR7M/eEGY0MmrcOenqjZA2JmyzTJLuJiOe65LBHUvPUmGR2bE4lQmrk7jqTVZHcrE1WkMWpRIdJ4KnpUXBCHLRl3e16EWIOEaMU00/vAY9na/gsYVH/NdgYe+8w9bMBeSQYsSWXjICcFvL2ga+dhlFwcJ10rjio/ZklprgbSWiavTWvzdd/5hXt5W/OtATC201sq9u4eQ+PVijmSW0nf+YQYtSmTQosR2gUYsTmXQokT6zj9saeRCpmkJ0hxD2gOZeGgsI+Lu45+ps7FXlFmDmDDtSd/5h+k7/zCpZQpa9cwOQciyIR+77LyzFhXlMyZmFOP2jLP8orVWRsTdR2ppHFtSa+k6ZZM1WHvSdcomwyxySceayO4OWTY88TdirygzUkWf18eL2//RQiutYcwYE/Q4tagDOUQ8uo6uUzbRZ3qMJV2nbCLi0XU8tSbrolNXzu6OfOyylgEN4NOkaO5acw/j9ozr0ET37h5imehIZimPL91rAfSZHsOQBfuISS7E7vaTETeX0MmrOoQInbwK+dhlNKWsahni0zPSuGvNPW1M1BrI1NrOwt0WkCn2ijJSS+MYt2ccuQk3oxd36RCi8URPY+HLT1VbgGiSzPsx71laCddMe2Yygf6ZOtuScXvG0XfJn/n8YL+LQnjibyQ34WZ8Xl/bfKSoKL+FVi4EYwKZcu/uIQzaPoExMaPQcrq1ADFX33AI1+6u1OV9HVI6ShU/TYqm75I/dwjTHtDEQ2MZt2ccg7ZPaGGScIDWEBlxc42UoSMQ00StYdoDCgcbtH0Cbx+8p40ZTIBwiFM7RmB3+y+exZvT2YRpDdR6ZoVrw1xRWwN44m/Euf06A6Ki7NLrmnDNmH7TEdSg7RP4/GA/yLK1GdwEKNzSk1M7RlDlqPl1JefOlG2MXTGmXaAxMaMsB/XE34h4tH+7ANlrB7T2iV8OAlDlqOH9mPcsIBPKlF3R16Ad7GwlxoVberYAKCrKv1ghfmkg5sPldLIzZVsLqLErxpC9doAlp3aMICNurlGyVpRdSAu/HqS1Q58rd1JUlI87P1UtKsrHXlGG3e1HCOoov+x2wiX3RxT+o49L1IgutXxVUCfDIxNfLraQDI+M3e3/NdCXbhohqBNfLrIsVzZqmoT6dmXG0SBLTrmJLxd/CVRLECXcDGFaSC1TmHE0yKg4B0P2uxiy38WoOAePHaptAfHYoVqG7HcxcGc5o+IcfFfgsbQUPoYoSa213BbE78oGucTSwpJTbobFFjNgbQHdvi6g8/Z6Om+vZ8h+VxsQE7T/97UMWFvA+Og0UvIryfDIZBQ4CeXvt8a5IAhAY/RImlJWUaHrPHaolhuXFXHN+8e58qNcbomq5P6t3xG973WePLzPgnnsUG0LiP7f1zJwZzk3LisyctfSOFxOJ4lfLzYToQubxu/KpmpWBFWzInguOokrP8ql7/zDRMxLpFfUabasHwlZNnITbmbgznI6b6+3Bu7/fa2lrW5fF9Ar6jQD1hYwLLaYx5fupdi+EiGok748koa4qa010xKkKWUV2UM7kd6vB7tH9yfpnUFkLzQiZOGWnmgHO9N4oie9ok5bA4YPbkqvqNNc8/5xIuYl8tSaLOLLRXambENXF+PxNJD0ziAanVHhYaEliH1lJD/1iqD0qSsIzu2M/N550TZ3QjvYmS3rR1qDtwdhgpgwnabGMj46zRjQsxJdXYw7P1X1pY0GuaRjkMKxPah5qxuV8y6nct7l1LzVDfdyo6miHexM+ou9mblwKfdv/Y77t37HNe8fbwMQDhIxL5FOU2PZklqLJjUYdU7wWxBuN+ricBAF0KQG6pcNovZpw0fCQao/MEBcu7tSOLYHjnu7EZzbmeDczqyfNokrP8ptMXi4XDnzAJ0n72TIgn1oUoMB4VlpgIjj24I0payi9KkrqHj+Ssth2wM5c38f8p68D2nbHKRtc3h86d42A/eZHsOVMw9Y0nXKJmxDvyS1NA70z8Gz0qh5hNvbzpr6ZYMofzyiBUwLkOVdjfR/eVcao0dSl/d1aHx0GhHzEi0TXDnzAJ2mxtJpaixdp2yypM/0GLrcs5D3Y94ztNDsK7qjuxmzDBBz2rYGqZoVQc1b3dr4yfppk+g8eWeLd91aAxGPrqPbyKV0G7mUiEfXMWdz+nmQ0Jsgn1AbT/SkMXrkeZC6vK9DpU9d0S5I5bzLqf6gq6UV7WBn5q9+zDJBuEQ8us4SE6LLPQvpcs9CjmSW4ndlo1XPNBxWLiE34WbSX+wNapEBEsrfT/njERSO7WGBmDA1b3Wj9KkrSO/Xg1WjBjJl/CT+8sQ8a0BT/eGDhwN0uWchXe94ia07YkE+oSLc3gxyQt2yfiSrRg0E+YRqgRSO7UHh2B4UT7ragqmcdznFk67mp14ROO7txpTxk7AN/bLFgN1GLsU29EvrejiACdG59xQjKgu3GzVP9UwIvcmCVwYb102NmBHVBDFNVDUrgjP39yF98E0E5xox5Dcj5lsDhwOYQObg4dK59xR2RV8D4njEo/0NIEd3dkVfgy9t9HkfMTWSO6pXG63kjupF8aSrqXj+SoJzO1M573KmjJ/Eb0bM5y9PzGPBK4Mp3GKUEFvWj+Q3I+a3AOjcewp/eWKesUQ0T1mz2att7oSU9+F5EE2SqXvpSbKHdrIGNmHCoapmRVgh33LezZ3QNncyloGDnVnwyuA2IFvWj0Q+dplREzu6Wy0r9/KubVvg9pWRpPfrwZn7+1haMSHCxdSM/J4RWWufjiC9Xw/m9PgtN9w0uo1JbrhpNI0njAXTrAIbT/TEvb4LjdEj2641vqQjpPfrQfrgm1qYKHxKlz51BbmjerFj4G2WtAYwtWDKglcGG2ZoXrldu43AWDUrAmnbnLaRVZMayHvyPn7qZThoa38pfeoKap+OIDi3M6tGDeSGm0a3GTT82g03jeaGm0bj3H4d8rHLrN0I93LDpDsG3kb68si2a425hfZTrwjSB9/UBiZcM+YM6ghoyvhJpL/Ym+yFhknc67tYQVF+z3gjc3r8Fuf32zpOFTMeHXpRGDNfMYF2j+7PqlEDWTVqIOkv9rZ8SNvcCff6LlTOu9yK1Okv9mZOj9+S8ehQNKmBDhs17vxU9adeES1gwoHKH49oFyhcwhfKynmXWzOu4vkryR7aieyhnQjl7+84QzNNJGzbxN7uV1gw7WmntYZaLw2mmNdrn44ge2gnztzfx9od7zBnDa9t0pdHtgsTDhRustaaCndwEyLj0aG481PVS9r3FSUJj6eBrConMZHvnodpntrh2gkHCgcLl/TBN7G3+xXGLMlIo0LXjU7ixeoaUZIQ3C7OlTtJya8kJvJddgy8DctvWgGFaylcHPd2Y2/3K5jT47esGjWQrTtiyapy4nI6jUrvUmpfUytFRfmkZ6SxdUcs66dNYsfA2ywNtQBrJeb/dgy8jZjId/kx4YgF4fP6Ln1L3uyhhWvnSGYpOw6lEBP5LuunTWLDAw+x4YGHrAi74YGHWD9tEuunTSIm8l227ohtAyBK0i8/pNDagTVJxuf1YXf7OVfuJKvKMF16RhrpGWkcySwlJb+SrCqn1awRgjqaJP9nO0b/Zxo1v+ahS0ZqKJ9QCX5rJMyhN42aRj6h/udB5BKjiAp+i64uNrJ2M0Vs3rUiy4aU92G42X49iCYZDZjUMoX4ctFIcILfGgVU6E0LwEyCxKP98aWNxpc2GvFof+RjlyHlfdjxWnOxh93tJya5kIWHnDx2qJbnopP4NCmaYvtKC0LL6WYkQps70RA3laaUVbjzU1V7RRn2ijK8BbkWUJsM7VIAog7k8MyuPKtD1AJA/9zQQpYN9/oubFk/kpkLl7J4a0KbtrdZa/vSRrfMWS8GcSSzlGd25TH5VIjptTpR9T5SS+OMsrHZD3RHd7SDnTm1YwSzY2KsTtL46DSei07iSGZpm/tKeR8a5gnf0+vI8zfE5zAstpjptTrvifBJeeZ5LTQDkGXDtbsr0fte59mjDmaWaUyv1ZlZpvH3XJlRcQ6Grj5OTHJhy/t7VhrpwMVAog7kMCrOwcs+nZWaccak2L7S0oLpC6d2jGDJiUyWN8E6FVZqsLwJ5ruwYO5O9jFoUSIb4nPOT+/gtxf3kZjkQobFFreAaHRGGZoQbm+hhWd25fHsUQevHilgbo7bAmoNM2S/i6Grj3Mks9Tolcgn1Hb39MzHuXInw9edZrJd4z3xPISuLrYgCrf0ZOuOWKLzVFLLFDIKmlfr5EJmHMxhfoWvDczkUyELxl5RduFUUZNkIvdm8+BpkZd9eocQPyYc6XDnocpRQ+TebObmuFmptdTK5FMhBqwt4K1vMi4cWTMKnIyKczDZrvFJeWaHEBdrbVc5aphxMIflTR1rJaPA2TFI1IEc7k72tZwdYRCLtyZc6h4MMcmF7WrlwRSRAWsLiNyb3T6Iz+vjmV15jIpztIHwxN/I7JgY4svFS47CHk9DG62Y5hm4s5zx0Wntb0CnlikMiy3m06ToFpFSO9iZnSnbeGZXHkcyS8kocF6SHMksZc7m9AuaJyW/si3IltRaZsfEGNM09KZVs2bEzWV5EyzLlXn1SEG7MuNgTruy5JS73dlzd7IvPMi1BIlJLmRnyjbLJFawar7ZHi5NdrSS9jRyd7KPXlGnzQDXyjSlcYY2mk1SuKUnS05kslI7f9M9/HKgdaoh74nn/cR02NV7M9t2A9A/t/qf2uZOvB/zHvNdxk3Mm0bV+36VzK8wxHTWVutPmEbkE6q1hjQ3/yefCvGeeB7k1SPGlLsUeeubDOtnezJnczpvfZPBuXJnGEjzAqSri9FyulG4pSf3b/3OCvErNQNmxsEczpU70ST5kuWXJc9yiZXemQ3du5N9TK/VedmnW1qZm+M+v3r+gpTS42nA42nA5XRa4vE0hFd8zSDBb63cInvtAAYtSuTuZB+T7ZoFYy7tz+zK6+igQZtHRoGTyL3ZLab4M7vyGB+dxpAF+1i8NaEliLmWyNndsa+MZPi60/T/vpaJhTKT7ZqllZWaoZW3vsnA42m4IMS5cifPRScxN8fNeyK87NOZXqszsdDITa55/3i4dgVb0OPUTG2IR/vjzk9Vt6Qau5R3J/uYWCi3MJEJM2dzOkcyS80Q3WKrPia50IIIX2cmnwrxYIpIr6jTPBed1Mo0apFgpv0NcVMR3C5ESWLO5nS6fV3Ag6fFdmHmV/iYcTCHyL3ZRB3IsSRybzbP7MpjfoWvXYj+39cyZME+c7aEgTQ36smy0RA31dostrv9DF193IIJ9xcTxgSam+O2xAQwg9fMMo2JhTIPnjYgBi1KbC+RPq8REyR8iT9X7rRgWptpvssYLBwqHGB6rc7fc2ULYsh+F4MWJbLjUErH09c8ytcaxNTMCxtyGLC2oIUDT6/VO5TJdkMLJsTAneUMWpTYNotvE0eaj3rKxy6zun2t69mdKdt4fOley4lN35ls11pIOIC51D8XnWQu9xcGUQCteibyscuM5n31TKNqD5fm1H9DfA7PRScxdPVxhsUWMyy22Dq4MGS/i2GxxQxfd9oC2HEopb1WVcdtCU2Sqcv7OmTWpGbRLOV9SCh/P0GPUwvPvDIKnMQkFxK5N5s5m9N5LjqJ56KTeOubDFbvzSQlv7LN1P5FxzZ8Xp918v8SWk5WsWStLbr0a5oLHRdY/+GjPP8vtq7+0yCiJOHz+hDcLlxOJ2bzxeV0Irhdlk/9x0B8Xh9VjhoEt6s5rZTaFU1qQHC7qHLU/PpZ05EGqhw1uJxO0CVESSIlv5KoAznM2ZxufTJgzuZ0og7kkJJfaR1mcjmdVDlqflkc6ahSs1eUWdMzJrmQQYsSrYMJNy4raiHmYQWzD2IC2SvKLpa/dAzi8/qsc6cZBU6GLNjHlTMPcEtUJVMSdd45qRGdp7KxDOvDPu+c1JhxNMgtUZVcOfMAQxbss0K7vaLsQqbq+GCtCbEhPodOU2O58qNcZhwNsrMK4t0Xlp1VMONokCs/yqXT1FgrE7sATPvbJK0hblxWxDsnNWugvc7zcqFry3JlbomqbANzSdskpk9kFDjpOmWTpQnzne6sMgbbWWWYY8kpN0tOuYnOU1v8z9TcOyc1blxWRNcpmwwz6dLFjxr7vD5rY+eO13YSMS+Rh/co1iAby4wBluXKLDnl5rsCD1lVxk7FdwUelpxysyxXbvHcjWUwYb9CxLxE7nhtp7X10spELUHMMiHqQA6dJ+9k8KYaJh1u6ZRLTrnZklrb+hS3lURtSa1lySm39fyNZTAlUWfwpho6T95p1rqtS5LzICapJsmWNkbEBpiSqLMs1/gY3DsntfAuT4tDlkrYtci92bxzUmNjmaG9KYk6I2IDbbTStsBqjhma1EBKfiVdp2xiwNoCHt6jMOmwxjsnNev46KWUkaIksfCQk2W5Mu+c1Jh0WGPCfoUBawvoOmWT1d4Miy3nQczIuXpvJp2mxjJ4Uw0T9hsg09KM6fhcdBIxyYWXJM9FJzHjaJBpaTDpsAEzeFMNnabGGhVec+RtA1LlqAFd4vGley0Q8wZTEnWmpWGdWX3sUC3PHnW0K+b/n0qoZ1oaTEszfCQc5PGle0GXwv0k7PxI87S9EMjMMo35rvMdILPDbErrzlA4iOmw4SBh0/iXgUxLg8mnQvw9V2Zmmdau/D1XtpoxpiYe3qPw8B6FW6IqreOCvwpkWhqMinMwaFEi46PTfrFMXG38HLr6OHe8ttPykXZNYzrr4q0JdJoay4C1BS2cdfCmGuZsTrd6Hv/T5ozZJ7no9L1xWZE1fU0bD193unXx3GESFZNcyIb4nDazaUN8Dh6PkTy1O307CmgT9itM2K9YWnkuOumi26wTV6dZR43NXOXKj3LpPHknEY+us0DaDWiWnwCr92bSdcomBm+q4eE9ShsThTXh2jRn5mxOZ/CmmjYzZkRsgE5TY40Q33bhu/iiF66VcJjh604TuTfbUnnk3myGrzttQZgzZtJhzQrvfabHWGNccNELnz2tfSUcJjxADVhbwIC1BdYsMyOp+fyH9yhWGnAks/TS0gDTV4qK8q2NxU5TY7klqrIFTDhQ6+gZ/hwzdoSbpKgo/9LPj5hnR8yUwEwVw810MRkRG7BSRXPpLyrKv/RUsT2YI5mlLZLnEbEBK1q2lhGxASt5vuO1nZY5ioryL5TJX7icENwuioryjV1rr4+oAzkMWbDvouXEkAX7iDqQg8/rQ5MaLgZxaQWWJslWSWkWWBkFzl9UYP2PvgjFPNrj8/osM/2YcIQfE46QnpFmfL7K7SLocWpBj1Mz6+D0jLQWzzPb3b/6aI8SVnCbvXTTVOZxno6kqCjfKlPNUH4pIP9XPGz/N319UFnrf2iKLGi6LmggqCBoIOi6JuiqIqCrgqIrgqyrgoYu6JpiiK4LKgigCpquCCEdQdVVAU0VdP2iMGW29tplmtbcQNQ1QEXXNDQdQGsWHZBbvdQsKkTQfaiaBJrc/PyLPpQ2zqqbL9U10GV0TUbTZUCyQAoaJPaVinx5RmbVKZnVWRpf56r8WKlQFww2Q4bf8VdMXwsEtfkdGb97xSAb8yRG7df4zYYQ3deEsK2WsK1UsK1U6LIqxJWfKQzcEODVw0GS7KbG1F8Pout6C7WuL5Dpv1PBtlLEFgWXfyHTY61Ery91rvkiwLWfB7h6jcxV/5LoskLF9gl0+tjLI7FesuuxzKnrHeqneQdL143Bjacj6wqg4ZFUph8JYvusCdsXIldvhGvXi/T+SuS6dQrXrZO4fp3Ib76UuH5NiD6fi1z/mcgNnwa5epWMbbHG1StEvsoSjbeoq2i60h6MYNN1XTAhNF1vdlBoVFSG7/Nh+1Ti2o1Brl8v03uDyDVfN3DDVz5u+FKh15cKvdbp9FoHvT5X6PW5wjVr4LrPda6NkugTJdL1EwXbIpkVx5sdGaXZ8S9gGgNIJ6ipPHgghO3TED23h+ixTafXZpmb1ofos0ml+9dw1VcaV3wapMvKIF1WSVz+qULPzxV6faZw9Wc613yq0Xt1iN9Ehei+WMG2QObz03JHDtxsGk07P2XRmZ/hx7ZG5rqtMjdubqTHFonrNov8doPMZRvA9pmPqz8X+MNWhb/tkrg/VuGWaJXLPmmk85Imen6m0+sz6BMlcsNqP9etVujysU63jwIcrwy1N6UFm6Zrgma4KKBxrE7lyq999PnaT58dcMNWjV5bFa7d6sP2lcj/+szP6/FNHK2SqQtpSKqIKItUN2psyJH52yYXtkV+uq9UuP5fMj1XqVy9WuWGFSE6LQgxbHMQv6kVXW92B12wKZouSEjGNNMVJvwgYdugcGOsym+2q/TZqnD9dh3bVz5u3h4guVJtnpJa808zkJlBMMS7SQG6vB/gimUKvVdK9Fmu0nu5zLXLZGzvaWzLDhggmoysqwYIKoKqG+rKqVO5douP62JUfvutxg2xCn1iZTpv0rgpRuF0XQAIgRJElSUURUWWZWRZRpFlgrIKeIEg7yaC7X2FXkslei+XDVkmY1sQ4pFNDaA3hwcdNF0XbGjNZwNQWXZaxrZV5XexMjftFLnpW4ne34rYNvjZUywBQUJqEEkMoEk6oqIgySqipCCKEt6Qis8fRNEaAB+TtijYInV6Lwtx7VKRPstkIj5S6PGBRGFtwFCgApquCDYFTQANXZeZkiARsVPnlu9kfhcr0/cbiYivA4w94DM0oet4VQVJUQiJGiFRIiTKBEMSAX+QhoBIvU/C1SQCfpIKGrl8kZerFitcu0Tkuk9ErlsiYXtDYuMpYyobE0gVbIouC6DiDsgMiwtx406Z/rs0+u6WGPCNSI8tIZbnSoCCEvITkBRkWSMUkAgEJbz+EE2+IA3eAPUNjTR6fNTWSni9PuoFN/d8KtBpkcg1n3jp82GQ3h/6sc33seAHb/P6pYOmCTY0VQCNEkHhrgMhfrdL5k/fafT/XqT/boU+sRI/2r0AhESFYFDCF1TwBSWa/CE8TQHcjQFcDX6cdQGq63w43PWU1AoEmup4emMjtvl+enzop/d7Aa57N4Btvo/Z37jCHBzBpuqaAHDOHWDo/iD99in8+XuZO/er/H6fxsB/h0irDgGqoYGAhOAL0eALUd/oo87TRK2nCUddI3anQKXTTUl1DUVVNXga6nh2mwvb6066L3Bz3btOekU2YXtd5MVNDmuVVtEFm6brAmiUu4OMPODnjv0idx+UGHpQ4q6DEnf928+h0iCg0egN0OgXqW8MUCd4cXm81LgbqHIJlDs9lFd5KK90U1hWQ3GlgLOqlrs/rsQ2q45rFjq57q0yukc6sL3iYc62akBDR0fRNcGmq5oAQYSAyuQEibsPhnjgkMYD8T4ePOTnv/ZrfJrtBTWE4A3ibvRTJ3hx1jdRXddApbOeMoebEruL3Ao3p8vqOVVSR1JuDZkFtbywvgDb0zl0eqmanm+Wct2bFdhmlvP2Po/hH6qIrmiCTdNUAVVElTVeyfTz10My435UGHNE5JGfJIYf1ZiV4kFo8uILBKirD+LwBHC43Dhq6ymurqfAUU9ORS05RSU0NHmQVRW/JCMqOho6354U6DEri04z8+nxWim2fxSx8ZgLEAlJCqoiCzZZUwVZVECDjUVNDD8s8sRRlSmJOs8mwbPHZJ466iO2yI8aDNJU56a8tpGqaicOZx2FVfWcLa8lq7CMBn8IHfAGZQKSik/SQAoBOjEZtdiezqTTS/l0fzmPrFIBNB9CUCcoSYJN0TTBKymgS5TXBXn8pwCTj8lMT1WZmarx+nGR2Rk680+GOFleh9/bgMtZR3V1HYWVLvJKajiTV0pVjRsV8IVEgrLaLApeERSCAAx5/xS2+48zZvlZAmKIQFMTHq+PppAi2DRdFQIyyKIfRImoMz6ePO7lpUyJl08r/PN0iMjTEh9kS6zNEUgp92GvaaDAXstZh4DLG0JoChAMyviDMn5Jxi/K+EISIVnFr0h4JWPZ33a8mNteSCI6vhpZbMDhaqChyYfHHxRsmhYURBECoRDoMvkukVfTFN7IlHk7W+aDXIlVOSHW5ob4qhi2F4v8WNLIiSov5wLgkVVERSUYMqa2LyTjF1UCkkpQ1vGLImJAxCsai2SdKFJQ6aG0ooqK+gBuVxOCTxBsuq4IkqQSFCVCkgyqzg8lXt5J9/H+WViVJ7G+KMSOEoVdJSp77DJxdRrH3Rq5goLDJyMERRqCIt6QbPiHqBAQFSRJJSCrhGSZJklDUs/nIefsNRRXe3DWefE0NjUf21BURFEiGDRWVH9I5Nu8Rt7Pk/lXocbWIpFvKzT2VSr8YJdIcEqk1Svke2TsPhV3SMYTEmkISngDCr6QTFBSCUkqQUnFL2kEJUNLflFF1aGuyUepow6HuxG34DdyVkVRkCQFUVLxBWR0ScEfFPmuuIG1hTIxpSr/rpA46FBIqJHJdGmcqVPJa1Co9MrUBiTcQQlPQKYhoNAUUvCJCn5JJSApBCTZEr8oEVJU/IpKiaOOmnov9Q1+QyOqqiErGqKiIYk6/mAATQ4QalRItPvZU+EnvkrmxxqJRJdIVp1KTr1GQaNChVei2idTE9BwBRTqAzKeoEyjKNMkKvglhaCkNAMZogAeX4DS6npcDQE8jYHmM0aajqLqyLJOSNbwSTJev0woEKCxyU9OdZCEkgAJ1UGSBYWsBo3cRihq0qj0KVT5ZBwBjdqQRn1IRhBVGiWVRlklqOiIikZQ1hAV4ytjJE2n0ummqt6LU/AjNAYEm64jaBqoqo6iaEiKhiirBESVhkAQr9eH0ChSUu3nVGkdGY4mUmt8ZLoC5DWoFDUplHpVKnw6VT6ZWn+IuqCEJ6TQEFINzUgSflXFJ8nUe304XALVdQ3UNwaob/TT5A0ZILoO4TCyrBKSZHxBGcEfxNPgpdETwO32U+ZoIKesnrPlHrLtbn6urCfPXk+B3U2R3cO5qgbOVTVQUilwrkKgtEqguLKe4sp6yhwNlNg9VLkEhKYgjd4QTX6RYFA+X2Dpuo6maaiqiqqqKIqGKKn4QwrekERjIIC70YenMUBjk0S9EKK23our3ovb48Xj8SI0BfD4ROq9IdyNQeoa/Lg8AZxuPzV1PuobRASfguAN0egP4Q1KBEMykqwKNkAxMnpDNM1oSxhQGrKiI6oqTapIkyTiDYUIiDLBkEwoICOGjHghKxqKqqCoEooqEVJFgkqIkBIiKIsEpBB+MYA/FMAXkgiICiHRmK2KoilWo6bZRIKu61bjRdd1QdEQVBVBkzRBlVRBFhVBVTRBUXRBknVB1hAUECQQNF0XUHVB13RB0XRBVDRBUjRBUTVBUlRBlBRBlGQhJGuCJOuCouiCpuqCqqpl/7Eemqor5HnS2Ja/hPezpvCP1PuYlfo3vvo5EnfA0baH9qs+CKZpBIIh7DUuyuw1lNprqHDU4mnwoqoamq5xyn2YVTkv8cKJO3n+TH+eTB7Ao/H9eSr+TnbmrfyfgdiddZzKKaK0yklhuYN6oWVfvabay+6Tu3gzaSJPpPZm9E9XMmnvH1n60wKSanZypuEg35WuZlrCMLb9vPSXgzicdWTkFLX7vya5Dq/spk62s8v1AW+cu53ns29kSd6z/Fi9mZ/L8tpqVFfZeHYxBe7MSwdJy85v8Xd1oJwDFRtZlTeTD88+wcKsMSzMGsv8rL8wNbMnc7LuJN6xg6AcsF6TW1xBkzfQct9P8pDrSkfT1QuDKKrKz8UV1t+V3kKi89/m1YyhvHlyMPOz/ouFZ4fwYe59fJAzjLfO3s66wuep8p7jbF0iUTkzOe76/rzZ6jxUVteGtch06gL2C4PIikJFtcv6e3/ZeuamDOHNU//NivwxfFY8jnXlE/iyYiKflz/Eh4WD2Gv/CL/YQIJjI2+dvJvXTt7FtJS+LPt5OvVBY383KEoUlFaGzSz5wqb5ubC0WSsyG3PfZUbKnXzw8wOsKX6EdWUT+NI+nq8cY1nrGMnikjuJd0Xhld1sr3iTt37+IyuLHmZN0WMszxnPzLSBvJnxMMWNPxv7vUITLrdw8VlzMswnNud+xD+O3cGy3LF8ce5R1pZN4IuKsXzlGM0X1SP4uPJ2jgpraJAcfFb+CJHnbuOz8pF8UT6OL0om8nnRJFblPcrLaXfxxolROHzGd2idq7xIHBEavTQFQwAcLNvMP5Lu5JOcsawpmsRnJROIKnuYtVWjWVP9Vz6q7McRz0pUTSa2Zh6LSgeytOJPfGa/j3UVY1lTMoFPz01kdcEjLM95hNmp/8UHmU+j6MYnlrJyz3UMknHW0IbDW8rLyfexIGs4nxU8zqqi8Xx07gGiKkfyheN+ltnvJEFYGdYOFWlUqjniWcGK8iFElQ1jTek4Pi2awOqCR1iZ9wgfnx3Hs4l9+aHc+BqH2voGRFFqC+JpaEKSjOR2Y84iZqX8majcx1ieN57Xc+/hvXPD+aziAZaX30VGY0yH0/1s00E+KR7KquL7+ezceFbnT2BFzkSW5Uzg7VP38UbKQ3hCdc1aKWoLktHsG06/nbnJ9/H+6VGsyJnIC9l38kreMNaUPsKSkkHsdy26aABMcK3lw4L/5l9FY1mdP56lOeP55Ox4Psh+mOeT7+BAyUZj17O8qiWIKMkUlNoBOFQaw4zkQSw+M5bZp+7in7mPsKnkFVade4DPSsfTJNVeFCSk+lhbPIVl+Q+wMnccS8+OY/GZsXxwZjTTj9/OkqwXACi3O/H5A+dBKhy1lFQac33t2bf5R/KdvJnxFxadnkSyYzuf5j3BssIR/Kt4DBvLp/NF2dOsqXiSNRVPsKbyCeNnxZN8XjaFz4ufJrr4Bf5V8Agr8h5iWc5YPs4ey4enR/P+6YeYnfZn3kh9CAUfqgz2Gtd5kLOFpZTYjUMHH516jmlJA3jjxHCO2XexteBtFpwZyqqC0awo+huLCv7Eu4W38V7x73mvtD/vl/Xl/bJ+vFfye94tuo2F+X/g3dw/szT/b6zIHcMnZ0fz0ZmHWXT6ISKzRvJq5mBeSh5MSeNZyzyyrBggWTlFlNsNssiMKYz9oQe7i/9FmmM/r6bezZKfx7Is5yGW5f+NFYUjWHXuflaXDmN12V+JKhtGVNkwVpX9lZXFw1lRNILl+Q/ySc6DfHRmFIuyRhF5ciRvZ/6NNzPvZ3baIJ5N+AM/1xsfXcg9V47XH2wLMidpFE/9eAcVQg7Lsp7j9fShfHTmIT4+M4rIrKG8ljGAeSf78eaZfszP7sc/z/bln9n9mH+mH29m9eO1jP7MPfF7ZibfxvSE3zP1UD+eiruVxw/cxIT9fRj+764Mje3M6bqjAOQVl+MPhgyQvHPllFQapnkhfgRf5y7haNV3PJvwe945+QDvnnyAf2bcQ0zR22S7fySzbj+Z7n2cdO/jZP1eTtbvI9O9j8y6fWS49pHm3Edq9T6OV+0luXIPRyt2k1C+i/jybzhYupUfSrfjV40wX1zhQNN0A8RR66bEbjjr5p+Xc9IRz9snJvJ88h94O/N+3s64j1dS7mJLXuT/v0e/vT6qa93nnVXXdXLOlRtJi6qSWLmL8Yd682rGvcxLG8qbJ4byRuoQXj56L+UNuRcdoDHk5kDJNvaXbuZA2Rb2l21hX9nX7C3byNaCKJKr4pqnbw3+QLBlQDttxn4dPsh4hseP3sjcjP/m5dRBvJYymNdTBjMtvh8rT865KMja0wsZvqsr4/f3ZNyBnjx88CpGxV3BiAM2bt5iY8PPKwz/KKlsG1lDooTgCRJAYPKR/jyb2pcZaQOZdfyPzDn+J145/l/MSfojU364lW05yzuE2F30FU/80JcZSQN5+fifmH38Tmam3MGM1Dt4LOE6pv90DyHFCGLZ+SXtL3pn88rJCR5hbPy1TEq6jqnJv2XGsduZdfwPzD52By8n/5FZSX9g8sGbeDflGU7VHMUTqKMhVM/Z2hMsSZ/JY3G38I/E25l77I/MOv4HZhy/nRkptzE1+Rbu+beNhMrvjLEKSi+cj0T+8AaPZfTi2eQ/8Gj89fz96C3MSB7AjOTfMzPpNmYn3c7MowN4/IdrmXKoPy8l3MtLP/2Fpw7fxiMHr+HFxH7MTrqNmUm/56XkAbyY3I/pyb/jr/tsRJ542hqnOGydaRdkxv6J/DXBxvflX/Fd0Rru2W3jmYTrmZnUnxlJ/ZhxtB+zjg5g1tH+vJBwM1Pjr+fZ+Ot5PuFmZiX2Y9ZR43kvJfXlpeR+PJ90M3/da2Nm4gME5MZ2c5F2QV5OeYA/7rZxrOYgANE/f8S933ViTFxXZiX1ZfbRvsxK7MusxFuZnXgrs8JkZuKtzEi8lZlHf8espL48Gd+Lu3fbeDVpLA1BY+kvc7T7ZTktQUQlyLQjg/nzv20cyo+zrsdX7OKR/bcybLeNp368hpd+uok5ib9lbuKtzfI75ib+jtmJv2PGT7fwfMJveOj7zty/O4JPs+YjKsYUdTc04Wloav/YRusLz/04lAeTIsgsPENewfnc0is1EH32Qx47MICH913F+O//F+O/t/H4wW7877gIHtnfhXHfd2Hs91cyZl9v3k19lgLPaev15TV1NDR6Oz4/0vrC26ceYVhcL45X/GB4d2Eljf7Q+cJI9pHqiGPVqVeZd+wRZicOZ0bCvbyS9DAfpD3PnnNfUuO3ny9NVI2T+eVI8oVPGrUB2ZsfzX1HehJTtMK6FgyJZOYW0+gXf1EIz8wro9LhvKTn2lrugkMoFOS5n/7C0APXYK8tb3GepMrh5HB8Cmknz5JbXEpBSQVlFbVU2N0UlVWRW1RK1s95/JCQzMkzPyPLMpqm4ff7CQQChEIhJElCURQ0TcPsVOm6fn6tCT+oUOkq4bGE27n/qzv4KeMIwVCQQCBAbV0ttXW1VFRWkJ19lrS0DJKSj5F4NInk5OOcPHmK/Px8amtrcbvd1NTU4HQ6cbvdNDU1WTCyLKOqaguYDmvfgNzE4bIYdpWv4UT5EezuMkQl9B877PT/DQC7cLwx8LR3hQAAAABJRU5ErkJggg==) no-repeat;padding-left:40px}
+      .browser .browser-firefox{background-position:0 -34px}
+      .browser .browser-ie{background-position:0 -68px;margin-left:0px}
+      .browser .browser-360{background-position:0 -170px;margin-left: -27px}
+    </style>
+  </head>
+  <body style="margin-top:50px">
+    <h1>璇峰崌绾ф偍鐨勬祻瑙堝櫒锛屼互渚挎垜浠洿濂界殑涓烘偍鎻愪緵鏈嶅姟锛�</h1>
+    <p>鎮ㄦ鍦ㄤ娇鐢� Internet Explorer 鐨勬棭鏈熺増鏈紙IE11浠ヤ笅鐗堟湰鎴栦娇鐢ㄨ鍐呮牳鐨勬祻瑙堝櫒锛夈�傝繖鎰忓懗鐫�鍦ㄥ崌绾ф祻瑙堝櫒鍓嶏紝鎮ㄥ皢鏃犳硶璁块棶姝ょ綉绔欍��</p>
+    <hr />
+    <h2>璇锋敞鎰忥細寰蒋鍏徃瀵筗indows XP 鍙� Internet Explorer 鏃╂湡鐗堟湰鐨勬敮鎸佸凡缁忕粨鏉�</h2>
+    <p>
+      鑷� 2016 骞� 1 鏈� 12 鏃ヨ捣锛孧icrosoft 涓嶅啀涓� IE 11
+      浠ヤ笅鐗堟湰鎻愪緵鐩稿簲鏀寔鍜屾洿鏂般�傛病鏈夊叧閿殑娴忚鍣ㄥ畨鍏ㄦ洿鏂帮紝鎮ㄧ殑鐢佃剳鍙兘鏄撳彈鏈夊鐥呮瘨銆侀棿璋嶈蒋浠跺拰鍏朵粬鎭舵剰杞欢鐨勬敾鍑伙紝瀹冧滑鍙互绐冨彇鎴栨崯瀹虫偍鐨勪笟鍔℃暟鎹拰淇℃伅銆傝鍙傞槄
+      <a href="https://www.microsoft.com/zh-cn/WindowsForBusiness/End-of-IE-support"
+        >寰蒋瀵� Internet Explorer 鏃╂湡鐗堟湰鐨勬敮鎸佸皢浜� 2016 骞� 1 鏈� 12 鏃ョ粨鏉熺殑璇存槑</a
+      >
+      銆�
+    </p>
+    <hr />
+    <h2>鎮ㄥ彲浠ラ�夋嫨鏇村厛杩涚殑娴忚鍣�</h2>
+    <p>鎺ㄨ崘浣跨敤浠ヤ笅娴忚鍣ㄧ殑鏈�鏂扮増鏈�傚鏋滄偍鐨勭數鑴戝凡鏈変互涓嬫祻瑙堝櫒鐨勬渶鏂扮増鏈垯鐩存帴浣跨敤璇ユ祻瑙堝櫒璁块棶鍗冲彲銆�</p>
+    <ul class="browser">
+      <li class="browser-chrome">
+        <a href="https://www.google.cn/chrome/browser/desktop/index.html?hl=zh-CN&standalone=1"> 璋锋瓕娴忚鍣�<span>Google Chrome</span></a>
+      </li>
+      <li class="browser-firefox">
+        <a href="https://www.mozilla.org/zh-CN/firefox/new/"> 鐏嫄娴忚鍣�<span>Mozilla Firefox</span></a>
+      </li>
+      <li class="browser-ie">
+        <a href="https://windows.microsoft.com/zh-cn/internet-explorer/download-ie"> IE 11 娴忚鍣�<span>Internet Explorer</span></a>
+      </li>
+      <li class="browser-360">
+        <a href="http://se.360.cn/"> 360瀹夊叏娴忚鍣�<span>360 Chrome</span></a>
+      </li>
+      <div class="clean"></div>
+    </ul>
+    <hr />
+  </body>
 </html>
diff --git a/index.html b/index.html
index e641b01..c0dab51 100644
--- a/index.html
+++ b/index.html
@@ -1,217 +1,217 @@
 <!DOCTYPE html>
 <html>
-	<head>
-		<meta charset="utf-8" />
-		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
-		<meta name="renderer" content="webkit" />
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
-		<link rel="icon" href="/favicon.ico" />
-		<title>RuoYi-Vue-Plus澶氱鎴风鐞嗙郴缁�</title>
-		<!--[if lt IE 11
-			]><script>
-				window.location.href='/html/ie.html';
-			</script><!
-		[endif]-->
-		<style>
-			html,
-			body,
-			#app {
-			  height: 100%;
-			  margin: 0px;
-			  padding: 0px;
-			}
+  <head>
+    <meta charset="utf-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
+    <meta name="renderer" content="webkit" />
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
+    <link rel="icon" href="/favicon.ico" />
+    <title>RuoYi-Vue-Plus澶氱鎴风鐞嗙郴缁�</title>
+    <!--[if lt IE 11
+      ]><script>
+        window.location.href='/html/ie.html';
+      </script><!
+    [endif]-->
+    <style>
+      html,
+      body,
+      #app {
+        height: 100%;
+        margin: 0px;
+        padding: 0px;
+      }
 
-			.chromeframe {
-			  margin: 0.2em 0;
-			  background: #ccc;
-			  color: #000;
-			  padding: 0.2em 0;
-			}
+      .chromeframe {
+        margin: 0.2em 0;
+        background: #ccc;
+        color: #000;
+        padding: 0.2em 0;
+      }
 
-			#loader-wrapper {
-			  position: fixed;
-			  top: 0;
-			  left: 0;
-			  width: 100%;
-			  height: 100%;
-			  z-index: 999999;
-			}
+      #loader-wrapper {
+        position: fixed;
+        top: 0;
+        left: 0;
+        width: 100%;
+        height: 100%;
+        z-index: 999999;
+      }
 
-			#loader {
-			  display: block;
-			  position: relative;
-			  left: 50%;
-			  top: 50%;
-			  width: 150px;
-			  height: 150px;
-			  margin: -75px 0 0 -75px;
-			  border-radius: 50%;
-			  border: 3px solid transparent;
-			  border-top-color: #FFF;
-			  -webkit-animation: spin 2s linear infinite;
-			  -ms-animation: spin 2s linear infinite;
-			  -moz-animation: spin 2s linear infinite;
-			  -o-animation: spin 2s linear infinite;
-			  animation: spin 2s linear infinite;
-			  z-index: 1001;
-			}
+      #loader {
+        display: block;
+        position: relative;
+        left: 50%;
+        top: 50%;
+        width: 150px;
+        height: 150px;
+        margin: -75px 0 0 -75px;
+        border-radius: 50%;
+        border: 3px solid transparent;
+        border-top-color: #FFF;
+        -webkit-animation: spin 2s linear infinite;
+        -ms-animation: spin 2s linear infinite;
+        -moz-animation: spin 2s linear infinite;
+        -o-animation: spin 2s linear infinite;
+        animation: spin 2s linear infinite;
+        z-index: 1001;
+      }
 
-			#loader:before {
-			  content: "";
-			  position: absolute;
-			  top: 5px;
-			  left: 5px;
-			  right: 5px;
-			  bottom: 5px;
-			  border-radius: 50%;
-			  border: 3px solid transparent;
-			  border-top-color: #FFF;
-			  -webkit-animation: spin 3s linear infinite;
-			  -moz-animation: spin 3s linear infinite;
-			  -o-animation: spin 3s linear infinite;
-			  -ms-animation: spin 3s linear infinite;
-			  animation: spin 3s linear infinite;
-			}
+      #loader:before {
+        content: "";
+        position: absolute;
+        top: 5px;
+        left: 5px;
+        right: 5px;
+        bottom: 5px;
+        border-radius: 50%;
+        border: 3px solid transparent;
+        border-top-color: #FFF;
+        -webkit-animation: spin 3s linear infinite;
+        -moz-animation: spin 3s linear infinite;
+        -o-animation: spin 3s linear infinite;
+        -ms-animation: spin 3s linear infinite;
+        animation: spin 3s linear infinite;
+      }
 
-			#loader:after {
-			  content: "";
-			  position: absolute;
-			  top: 15px;
-			  left: 15px;
-			  right: 15px;
-			  bottom: 15px;
-			  border-radius: 50%;
-			  border: 3px solid transparent;
-			  border-top-color: #FFF;
-			  -moz-animation: spin 1.5s linear infinite;
-			  -o-animation: spin 1.5s linear infinite;
-			  -ms-animation: spin 1.5s linear infinite;
-			  -webkit-animation: spin 1.5s linear infinite;
-			  animation: spin 1.5s linear infinite;
-			}
+      #loader:after {
+        content: "";
+        position: absolute;
+        top: 15px;
+        left: 15px;
+        right: 15px;
+        bottom: 15px;
+        border-radius: 50%;
+        border: 3px solid transparent;
+        border-top-color: #FFF;
+        -moz-animation: spin 1.5s linear infinite;
+        -o-animation: spin 1.5s linear infinite;
+        -ms-animation: spin 1.5s linear infinite;
+        -webkit-animation: spin 1.5s linear infinite;
+        animation: spin 1.5s linear infinite;
+      }
 
 
-			@-webkit-keyframes spin {
-			  0% {
-			    -webkit-transform: rotate(0deg);
-			    -ms-transform: rotate(0deg);
-			    transform: rotate(0deg);
-			  }
+      @-webkit-keyframes spin {
+        0% {
+          -webkit-transform: rotate(0deg);
+          -ms-transform: rotate(0deg);
+          transform: rotate(0deg);
+        }
 
-			  100% {
-			    -webkit-transform: rotate(360deg);
-			    -ms-transform: rotate(360deg);
-			    transform: rotate(360deg);
-			  }
-			}
+        100% {
+          -webkit-transform: rotate(360deg);
+          -ms-transform: rotate(360deg);
+          transform: rotate(360deg);
+        }
+      }
 
-			@keyframes spin {
-			  0% {
-			    -webkit-transform: rotate(0deg);
-			    -ms-transform: rotate(0deg);
-			    transform: rotate(0deg);
-			  }
+      @keyframes spin {
+        0% {
+          -webkit-transform: rotate(0deg);
+          -ms-transform: rotate(0deg);
+          transform: rotate(0deg);
+        }
 
-			  100% {
-			    -webkit-transform: rotate(360deg);
-			    -ms-transform: rotate(360deg);
-			    transform: rotate(360deg);
-			  }
-			}
+        100% {
+          -webkit-transform: rotate(360deg);
+          -ms-transform: rotate(360deg);
+          transform: rotate(360deg);
+        }
+      }
 
 
-			#loader-wrapper .loader-section {
-			  position: fixed;
-			  top: 0;
-			  width: 51%;
-			  height: 100%;
-			  background: #7171C6;
-			  z-index: 1000;
-			  -webkit-transform: translateX(0);
-			  -ms-transform: translateX(0);
-			  transform: translateX(0);
-			}
+      #loader-wrapper .loader-section {
+        position: fixed;
+        top: 0;
+        width: 51%;
+        height: 100%;
+        background: #7171C6;
+        z-index: 1000;
+        -webkit-transform: translateX(0);
+        -ms-transform: translateX(0);
+        transform: translateX(0);
+      }
 
-			#loader-wrapper .loader-section.section-left {
-			  left: 0;
-			}
+      #loader-wrapper .loader-section.section-left {
+        left: 0;
+      }
 
-			#loader-wrapper .loader-section.section-right {
-			  right: 0;
-			}
+      #loader-wrapper .loader-section.section-right {
+        right: 0;
+      }
 
 
-			.loaded #loader-wrapper .loader-section.section-left {
-			  -webkit-transform: translateX(-100%);
-			  -ms-transform: translateX(-100%);
-			  transform: translateX(-100%);
-			  -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
-			  transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
-			}
+      .loaded #loader-wrapper .loader-section.section-left {
+        -webkit-transform: translateX(-100%);
+        -ms-transform: translateX(-100%);
+        transform: translateX(-100%);
+        -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
+        transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
+      }
 
-			.loaded #loader-wrapper .loader-section.section-right {
-			  -webkit-transform: translateX(100%);
-			  -ms-transform: translateX(100%);
-			  transform: translateX(100%);
-			  -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
-			  transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
-			}
+      .loaded #loader-wrapper .loader-section.section-right {
+        -webkit-transform: translateX(100%);
+        -ms-transform: translateX(100%);
+        transform: translateX(100%);
+        -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
+        transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
+      }
 
-			.loaded #loader {
-			  opacity: 0;
-			  -webkit-transition: all 0.3s ease-out;
-			  transition: all 0.3s ease-out;
-			}
+      .loaded #loader {
+        opacity: 0;
+        -webkit-transition: all 0.3s ease-out;
+        transition: all 0.3s ease-out;
+      }
 
-			.loaded #loader-wrapper {
-			  visibility: hidden;
-			  -webkit-transform: translateY(-100%);
-			  -ms-transform: translateY(-100%);
-			  transform: translateY(-100%);
-			  -webkit-transition: all 0.3s 1s ease-out;
-			  transition: all 0.3s 1s ease-out;
-			}
+      .loaded #loader-wrapper {
+        visibility: hidden;
+        -webkit-transform: translateY(-100%);
+        -ms-transform: translateY(-100%);
+        transform: translateY(-100%);
+        -webkit-transition: all 0.3s 1s ease-out;
+        transition: all 0.3s 1s ease-out;
+      }
 
-			.no-js #loader-wrapper {
-			  display: none;
-			}
+      .no-js #loader-wrapper {
+        display: none;
+      }
 
-			.no-js h1 {
-			  color: #222222;
-			}
+      .no-js h1 {
+        color: #222222;
+      }
 
-			#loader-wrapper .load_title {
-			  font-family: 'Open Sans';
-			  color: #FFF;
-			  font-size: 19px;
-			  width: 100%;
-			  text-align: center;
-			  z-index: 9999999999999;
-			  position: absolute;
-			  top: 60%;
-			  opacity: 1;
-			  line-height: 30px;
-			}
+      #loader-wrapper .load_title {
+        font-family: 'Open Sans';
+        color: #FFF;
+        font-size: 19px;
+        width: 100%;
+        text-align: center;
+        z-index: 9999999999999;
+        position: absolute;
+        top: 60%;
+        opacity: 1;
+        line-height: 30px;
+      }
 
-			#loader-wrapper .load_title span {
-			  font-weight: normal;
-			  font-style: italic;
-			  font-size: 13px;
-			  color: #FFF;
-			  opacity: 0.5;
-			}
-		</style>
-	</head>
+      #loader-wrapper .load_title span {
+        font-weight: normal;
+        font-style: italic;
+        font-size: 13px;
+        color: #FFF;
+        opacity: 0.5;
+      }
+    </style>
+  </head>
 
-	<body>
-		<div id="app">
-			<div id="loader-wrapper">
-				<div id="loader"></div>
-				<div class="loader-section section-left"></div>
-				<div class="loader-section section-right"></div>
-				<div class="load_title">姝e湪鍔犺浇绯荤粺璧勬簮锛岃鑰愬績绛夊緟</div>
-			</div>
-		</div>
-		<script type="module" src="/src/main.ts"></script>
-	</body>
+  <body>
+    <div id="app">
+      <div id="loader-wrapper">
+        <div id="loader"></div>
+        <div class="loader-section section-left"></div>
+        <div class="loader-section section-right"></div>
+        <div class="load_title">姝e湪鍔犺浇绯荤粺璧勬簮锛岃鑰愬績绛夊緟</div>
+      </div>
+    </div>
+    <script type="module" src="/src/main.ts"></script>
+  </body>
 </html>
diff --git a/package.json b/package.json
index c71573e..dc25173 100644
--- a/package.json
+++ b/package.json
@@ -1,80 +1,80 @@
 {
-	"name": "ruoyi-vue-plus",
-	"version": "5.0.0-SNAPSHOT",
-	"description": "RuoYi-Vue-Plus澶氱鎴风鐞嗙郴缁�",
-	"author": "LionLi",
-	"license": "MIT",
-	"scripts": {
-		"dev": "vite serve --mode development",
-		"build:prod": "vite build --mode production &&vue-tsc --noEmit",
-		"preview": "vite preview",
-		"lint": "eslint src/**/*.{ts,js,vue} --fix",
-		"prepare": "husky install",
-		"prettier": "prettier --write ."
-	},
-	"repository": {
-		"type": "git",
-		"url": "https://gitee.com/JavaLionLi/plus-ui.git"
-	},
-	"dependencies": {
-		"@element-plus/icons-vue": "2.1.0",
-		"@vueup/vue-quill": "1.1.0",
-		"@vueuse/core": "9.5.0",
-		"animate.css": "4.1.1",
-		"await-to-js": "^3.0.0",
-		"axios": "^1.3.4",
-		"echarts": "5.4.0",
-		"element-plus": "2.2.27",
-		"file-saver": "2.0.5",
-		"fuse.js": "6.6.2",
-		"js-cookie": "3.0.1",
-		"jsencrypt": "3.3.1",
-		"nprogress": "0.2.0",
-		"path-browserify": "1.0.1",
-		"path-to-regexp": "6.2.0",
-		"pinia": "2.0.22",
-		"screenfull": "6.0.0",
-		"vue": "3.2.45",
-		"vue-cropper": "1.0.3",
-		"vue-i18n": "9.2.2",
-		"vue-router": "4.1.4"
-	},
-	"devDependencies": {
-		"@iconify/json": "^2.2.40",
-		"@intlify/unplugin-vue-i18n": "0.8.2",
-		"@types/file-saver": "2.0.5",
-		"@types/js-cookie": "3.0.3",
-		"@types/node": "18.14.2",
-		"@types/nprogress": "0.2.0",
-		"@types/path-browserify": "^1.0.0",
-		"@typescript-eslint/eslint-plugin": "5.56.0",
-		"@typescript-eslint/parser": "5.56.0",
-		"@unocss/preset-attributify": "^0.50.6",
-		"@unocss/preset-icons": "^0.50.6",
-		"@unocss/preset-uno": "^0.50.6",
-		"@vitejs/plugin-vue": "4.0.0",
-		"@vue/compiler-sfc": "3.2.45",
-		"autoprefixer": "10.4.14",
-		"eslint": "8.36.0",
-		"eslint-config-prettier": "8.8.0",
-		"eslint-plugin-prettier": "4.2.1",
-		"eslint-plugin-vue": "9.9.0",
-		"fast-glob": "^3.2.11",
-		"husky": "7.0.4",
-		"postcss": "^8.4.21",
-		"prettier": "2.8.6",
-		"sass": "1.56.1",
-		"typescript": "4.9.5",
-		"unocss": "^0.50.6",
-		"unplugin-auto-import": "0.13.0",
-		"unplugin-icons": "0.15.1",
-		"unplugin-vue-components": "0.23.0",
-		"vite": "4.1.4",
-		"vite-plugin-compression": "0.5.1",
-		"vite-plugin-svg-icons": "2.0.1",
-		"vite-plugin-vue-setup-extend": "0.4.0",
-		"vitest": "^0.29.7",
-		"vue-eslint-parser": "9.1.0",
-		"vue-tsc": "0.35.0"
-	}
+  "name": "ruoyi-vue-plus",
+  "version": "5.0.0-SNAPSHOT",
+  "description": "RuoYi-Vue-Plus澶氱鎴风鐞嗙郴缁�",
+  "author": "LionLi",
+  "license": "MIT",
+  "scripts": {
+    "dev": "vite serve --mode development",
+    "build:prod": "vite build --mode production &&vue-tsc --noEmit",
+    "preview": "vite preview",
+    "lint": "eslint src/**/*.{ts,js,vue} --fix",
+    "prepare": "husky install",
+    "prettier": "prettier --write ."
+  },
+  "repository": {
+    "type": "git",
+    "url": "https://gitee.com/JavaLionLi/plus-ui.git"
+  },
+  "dependencies": {
+    "@element-plus/icons-vue": "2.1.0",
+    "@vueup/vue-quill": "1.1.0",
+    "@vueuse/core": "9.5.0",
+    "animate.css": "4.1.1",
+    "await-to-js": "^3.0.0",
+    "axios": "^1.3.4",
+    "echarts": "5.4.0",
+    "element-plus": "2.2.27",
+    "file-saver": "2.0.5",
+    "fuse.js": "6.6.2",
+    "js-cookie": "3.0.1",
+    "jsencrypt": "3.3.1",
+    "nprogress": "0.2.0",
+    "path-browserify": "1.0.1",
+    "path-to-regexp": "6.2.0",
+    "pinia": "2.0.22",
+    "screenfull": "6.0.0",
+    "vue": "3.2.45",
+    "vue-cropper": "1.0.3",
+    "vue-i18n": "9.2.2",
+    "vue-router": "4.1.4"
+  },
+  "devDependencies": {
+    "@iconify/json": "^2.2.40",
+    "@intlify/unplugin-vue-i18n": "0.8.2",
+    "@types/file-saver": "2.0.5",
+    "@types/js-cookie": "3.0.3",
+    "@types/node": "18.14.2",
+    "@types/nprogress": "0.2.0",
+    "@types/path-browserify": "^1.0.0",
+    "@typescript-eslint/eslint-plugin": "5.56.0",
+    "@typescript-eslint/parser": "5.56.0",
+    "@unocss/preset-attributify": "^0.50.6",
+    "@unocss/preset-icons": "^0.50.6",
+    "@unocss/preset-uno": "^0.50.6",
+    "@vitejs/plugin-vue": "4.0.0",
+    "@vue/compiler-sfc": "3.2.45",
+    "autoprefixer": "10.4.14",
+    "eslint": "8.36.0",
+    "eslint-config-prettier": "8.8.0",
+    "eslint-plugin-prettier": "4.2.1",
+    "eslint-plugin-vue": "9.9.0",
+    "fast-glob": "^3.2.11",
+    "husky": "7.0.4",
+    "postcss": "^8.4.21",
+    "prettier": "2.8.6",
+    "sass": "1.56.1",
+    "typescript": "4.9.5",
+    "unocss": "^0.50.6",
+    "unplugin-auto-import": "0.13.0",
+    "unplugin-icons": "0.15.1",
+    "unplugin-vue-components": "0.23.0",
+    "vite": "4.1.4",
+    "vite-plugin-compression": "0.5.1",
+    "vite-plugin-svg-icons": "2.0.1",
+    "vite-plugin-vue-setup-extend": "0.4.0",
+    "vitest": "^0.29.7",
+    "vue-eslint-parser": "9.1.0",
+    "vue-tsc": "0.35.0"
+  }
 }
diff --git a/src/App.vue b/src/App.vue
index d073319..41ffdd4 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,7 +1,7 @@
 <template>
-	<el-config-provider :locale="appStore.locale" :size="size">
-		<router-view />
-	</el-config-provider>
+  <el-config-provider :locale="appStore.locale" :size="size">
+    <router-view />
+  </el-config-provider>
 </template>
 
 <script setup lang="ts">
diff --git a/src/animate.ts b/src/animate.ts
index 8cfe4f5..7a23df8 100644
--- a/src/animate.ts
+++ b/src/animate.ts
@@ -2,47 +2,47 @@
 const animatePrefix = 'animate__animated ';
 // 寮�鍚殢鏈哄姩鐢� 闅忔満鍔ㄧ敾鍊�
 const animateList: string[] = [
-	animatePrefix + 'animate__pulse',
-	animatePrefix + 'animate__rubberBand',
-	animatePrefix + 'animate__bounceIn',
-	animatePrefix + 'animate__bounceInLeft',
-	animatePrefix + 'animate__fadeIn',
-	animatePrefix + 'animate__fadeInLeft',
-	animatePrefix + 'animate__fadeInDown',
-	animatePrefix + 'animate__fadeInUp',
-	animatePrefix + 'animate__flipInX',
-	animatePrefix + 'animate__lightSpeedInLeft',
-	animatePrefix + 'animate__rotateInDownLeft',
-	animatePrefix + 'animate__rollIn',
-	animatePrefix + 'animate__rotateInDownLeft',
-	animatePrefix + 'animate__zoomIn',
-	animatePrefix + 'animate__zoomInDown',
-	animatePrefix + 'animate__slideInLeft',
-	animatePrefix + 'animate__lightSpeedIn'
+  animatePrefix + 'animate__pulse',
+  animatePrefix + 'animate__rubberBand',
+  animatePrefix + 'animate__bounceIn',
+  animatePrefix + 'animate__bounceInLeft',
+  animatePrefix + 'animate__fadeIn',
+  animatePrefix + 'animate__fadeInLeft',
+  animatePrefix + 'animate__fadeInDown',
+  animatePrefix + 'animate__fadeInUp',
+  animatePrefix + 'animate__flipInX',
+  animatePrefix + 'animate__lightSpeedInLeft',
+  animatePrefix + 'animate__rotateInDownLeft',
+  animatePrefix + 'animate__rollIn',
+  animatePrefix + 'animate__rotateInDownLeft',
+  animatePrefix + 'animate__zoomIn',
+  animatePrefix + 'animate__zoomInDown',
+  animatePrefix + 'animate__slideInLeft',
+  animatePrefix + 'animate__lightSpeedIn'
 ];
 // 鍏抽棴闅忔満鍔ㄧ敾鍚庣殑榛樿鏁堟灉
 const defaultAnimate = animatePrefix + 'animate__fadeIn';
 // 鎼滅储闅愯棌鏄剧ず鍔ㄧ敾
 const searchAnimate = {
-	enter: '',
-	leave: ''
+  enter: '',
+  leave: ''
 };
 
 // 鑿滃崟鎼滅储鍔ㄧ敾
 const menuSearchAnimate = {
-	enter: animatePrefix + 'animate__fadeIn',
-	leave: animatePrefix + 'animate__fadeOut'
+  enter: animatePrefix + 'animate__fadeIn',
+  leave: animatePrefix + 'animate__fadeOut'
 };
 // logo鍔ㄧ敾
 const logoAnimate = {
-	enter: animatePrefix + 'animate__fadeIn',
-	leave: animatePrefix + 'animate__fadeOut'
+  enter: animatePrefix + 'animate__fadeIn',
+  leave: animatePrefix + 'animate__fadeOut'
 };
 
 export default {
-	animateList,
-	defaultAnimate,
-	searchAnimate,
-	menuSearchAnimate,
-	logoAnimate
+  animateList,
+  defaultAnimate,
+  searchAnimate,
+  menuSearchAnimate,
+  logoAnimate
 };
diff --git a/src/api/demo/demo.ts b/src/api/demo/demo.ts
index 9ae5c74..01034ff 100644
--- a/src/api/demo/demo.ts
+++ b/src/api/demo/demo.ts
@@ -4,52 +4,52 @@
 
 // 鏌ヨ娴嬭瘯鍗曡〃鍒楄〃
 export function listDemo(query: DemoQuery): AxiosPromise<DemoVO[]> {
-	return request({
-		url: '/demo/demo/list',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/demo/demo/list',
+    method: 'get',
+    params: query
+  });
 }
 
 // 鑷畾涔夊垎椤垫帴鍙�
 export function pageDemo(query: DemoQuery): AxiosPromise<DemoVO[]> {
-	return request({
-		url: '/demo/demo/page',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/demo/demo/page',
+    method: 'get',
+    params: query
+  });
 }
 
 // 鏌ヨ娴嬭瘯鍗曡〃璇︾粏
 export function getDemo(id: string | number): AxiosPromise<DemoVO> {
-	return request({
-		url: '/demo/demo/' + id,
-		method: 'get'
-	});
+  return request({
+    url: '/demo/demo/' + id,
+    method: 'get'
+  });
 }
 
 // 鏂板娴嬭瘯鍗曡〃
 export function addDemo(data: DemoForm) {
-	return request({
-		url: '/demo/demo',
-		method: 'post',
-		data: data
-	});
+  return request({
+    url: '/demo/demo',
+    method: 'post',
+    data: data
+  });
 }
 
 // 淇敼娴嬭瘯鍗曡〃
 export function updateDemo(data: DemoForm) {
-	return request({
-		url: '/demo/demo',
-		method: 'put',
-		data: data
-	});
+  return request({
+    url: '/demo/demo',
+    method: 'put',
+    data: data
+  });
 }
 
 // 鍒犻櫎娴嬭瘯鍗曡〃
 export function delDemo(id: string | number | Array<string | number>) {
-	return request({
-		url: '/demo/demo/' + id,
-		method: 'delete'
-	});
+  return request({
+    url: '/demo/demo/' + id,
+    method: 'delete'
+  });
 }
diff --git a/src/api/demo/tree.ts b/src/api/demo/tree.ts
index 7c36a39..87a2246 100644
--- a/src/api/demo/tree.ts
+++ b/src/api/demo/tree.ts
@@ -4,43 +4,43 @@
 
 // 鏌ヨ娴嬭瘯鏍戣〃鍒楄〃
 export function listTree(query?: DemoTreeQuery): AxiosPromise<DemoTreeVO[]> {
-	return request({
-		url: '/demo/tree/list',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/demo/tree/list',
+    method: 'get',
+    params: query
+  });
 }
 
 // 鏌ヨ娴嬭瘯鏍戣〃璇︾粏
 export function getTree(id: string | number): AxiosPromise<DemoTreeVO> {
-	return request({
-		url: '/demo/tree/' + id,
-		method: 'get'
-	});
+  return request({
+    url: '/demo/tree/' + id,
+    method: 'get'
+  });
 }
 
 // 鏂板娴嬭瘯鏍戣〃
 export function addTree(data: DemoTreeForm) {
-	return request({
-		url: '/demo/tree',
-		method: 'post',
-		data: data
-	});
+  return request({
+    url: '/demo/tree',
+    method: 'post',
+    data: data
+  });
 }
 
 // 淇敼娴嬭瘯鏍戣〃
 export function updateTree(data: DemoTreeForm) {
-	return request({
-		url: '/demo/tree',
-		method: 'put',
-		data: data
-	});
+  return request({
+    url: '/demo/tree',
+    method: 'put',
+    data: data
+  });
 }
 
 // 鍒犻櫎娴嬭瘯鏍戣〃
 export function delTree(id: string | number | Array<string | number>) {
-	return request({
-		url: '/demo/tree/' + id,
-		method: 'delete'
-	});
+  return request({
+    url: '/demo/tree/' + id,
+    method: 'delete'
+  });
 }
diff --git a/src/api/demo/types.ts b/src/api/demo/types.ts
index ae8ec70..b756b83 100644
--- a/src/api/demo/types.ts
+++ b/src/api/demo/types.ts
@@ -1,55 +1,55 @@
 export interface DemoVO extends BaseEntity {
-	id: number | string;
-	deptId: number | string;
-	userId: number | string;
-	orderNum: number;
-	testKey: string;
-	value: string;
-	createByName: string;
-	updateByName?: any;
+  id: number | string;
+  deptId: number | string;
+  userId: number | string;
+  orderNum: number;
+  testKey: string;
+  value: string;
+  createByName: string;
+  updateByName?: any;
 }
 
 export interface DemoQuery extends PageQuery {
-	testKey: string;
-	value: string;
-	createTime: string;
+  testKey: string;
+  value: string;
+  createTime: string;
 }
 export interface DemoForm {
-	id: string | number | undefined;
-	deptId: string | number | undefined;
-	userId: string | number | undefined;
-	orderNum: number;
-	testKey: string;
-	value: string;
-	version: string;
-	ossConfigId: string | number | undefined;
-	createTime?: string;
+  id: string | number | undefined;
+  deptId: string | number | undefined;
+  userId: string | number | undefined;
+  orderNum: number;
+  testKey: string;
+  value: string;
+  version: string;
+  ossConfigId: string | number | undefined;
+  createTime?: string;
 }
 
 export interface DemoTreeVO extends BaseEntity {
-	id: number | string;
-	parentId: number | string;
-	deptId: number | string;
-	userId: number | string;
-	treeName: string;
-	children?: DemoTreeVO[];
+  id: number | string;
+  parentId: number | string;
+  deptId: number | string;
+  userId: number | string;
+  treeName: string;
+  children?: DemoTreeVO[];
 }
 
 export interface DemoTreeQuery {
-	treeName: string;
-	createTime: string;
+  treeName: string;
+  createTime: string;
 }
 
 export interface DemoTreeForm {
-	id: string | number | undefined;
-	parentId: string | number | undefined;
-	deptId: string | number | undefined;
-	userId: string | number | undefined;
-	treeName: string;
+  id: string | number | undefined;
+  parentId: string | number | undefined;
+  deptId: string | number | undefined;
+  userId: string | number | undefined;
+  treeName: string;
 }
 
 export interface DemoTreeOptionsType {
-	id: string | number;
-	treeName: string;
-	children?: DemoTreeOptionsType[];
+  id: string | number;
+  treeName: string;
+  children?: DemoTreeOptionsType[];
 }
diff --git a/src/api/login.ts b/src/api/login.ts
index b20e1a8..b95a0c0 100644
--- a/src/api/login.ts
+++ b/src/api/login.ts
@@ -8,74 +8,74 @@
  * @returns
  */
 export function login(data: LoginData): AxiosPromise<LoginResult> {
-	const params = {
-		tenantId: data.tenantId,
-		username: data.username.trim(),
-		password: data.password,
-		code: data.code,
-		uuid: data.uuid
-	};
-	return request({
-		url: '/auth/login',
-		headers: {
-			isToken: false
-		},
-		method: 'post',
-		data: params
-	});
+  const params = {
+    tenantId: data.tenantId,
+    username: data.username.trim(),
+    password: data.password,
+    code: data.code,
+    uuid: data.uuid
+  };
+  return request({
+    url: '/auth/login',
+    headers: {
+      isToken: false
+    },
+    method: 'post',
+    data: params
+  });
 }
 
 // 娉ㄥ唽鏂规硶
 export function register(data: any) {
-	return request({
-		url: '/auth/register',
-		headers: {
-			isToken: false
-		},
-		method: 'post',
-		data: data
-	});
+  return request({
+    url: '/auth/register',
+    headers: {
+      isToken: false
+    },
+    method: 'post',
+    data: data
+  });
 }
 
 /**
  * 娉ㄩ攢
  */
 export function logout() {
-	return request({
-		url: '/auth/logout',
-		method: 'post'
-	});
+  return request({
+    url: '/auth/logout',
+    method: 'post'
+  });
 }
 
 /**
  * 鑾峰彇楠岃瘉鐮�
  */
 export function getCodeImg(): AxiosPromise<VerifyCodeResult> {
-	return request({
-		url: '/code',
-		headers: {
-			isToken: false
-		},
-		method: 'get',
-		timeout: 20000
-	});
+  return request({
+    url: '/code',
+    headers: {
+      isToken: false
+    },
+    method: 'get',
+    timeout: 20000
+  });
 }
 
 // 鑾峰彇鐢ㄦ埛璇︾粏淇℃伅
 export function getInfo(): AxiosPromise<UserInfo> {
-	return request({
-		url: '/system/user/getInfo',
-		method: 'get'
-	});
+  return request({
+    url: '/system/user/getInfo',
+    method: 'get'
+  });
 }
 
 // 鑾峰彇绉熸埛鍒楄〃
 export function getTenantList(): AxiosPromise<TenantInfo> {
-	return request({
-		url: '/auth/tenant/list',
-		headers: {
-			isToken: false
-		},
-		method: 'get'
-	});
+  return request({
+    url: '/auth/tenant/list',
+    headers: {
+      isToken: false
+    },
+    method: 'get'
+  });
 }
diff --git a/src/api/menu.ts b/src/api/menu.ts
index 7aae599..a3ae80e 100644
--- a/src/api/menu.ts
+++ b/src/api/menu.ts
@@ -4,8 +4,8 @@
 
 // 鑾峰彇璺敱
 export function getRouters(): AxiosPromise<RouteRecordRaw[]> {
-	return request({
-		url: '/system/menu/getRouters',
-		method: 'get'
-	});
+  return request({
+    url: '/system/menu/getRouters',
+    method: 'get'
+  });
 }
diff --git a/src/api/monitor/cache/index.ts b/src/api/monitor/cache/index.ts
index 5c16aaf..e45d6fb 100644
--- a/src/api/monitor/cache/index.ts
+++ b/src/api/monitor/cache/index.ts
@@ -4,56 +4,56 @@
 
 // 鏌ヨ缂撳瓨璇︾粏
 export function getCache(): AxiosPromise<CacheVO> {
-	return request({
-		url: '/monitor/cache',
-		method: 'get'
-	});
+  return request({
+    url: '/monitor/cache',
+    method: 'get'
+  });
 }
 
 // 鏌ヨ缂撳瓨鍚嶇О鍒楄〃
 export function listCacheName() {
-	return request({
-		url: '/monitor/cache/getNames',
-		method: 'get'
-	});
+  return request({
+    url: '/monitor/cache/getNames',
+    method: 'get'
+  });
 }
 
 // 鏌ヨ缂撳瓨閿悕鍒楄〃
 export function listCacheKey(cacheName: string) {
-	return request({
-		url: '/monitor/cache/getKeys/' + cacheName,
-		method: 'get'
-	});
+  return request({
+    url: '/monitor/cache/getKeys/' + cacheName,
+    method: 'get'
+  });
 }
 
 // 鏌ヨ缂撳瓨鍐呭
 export function getCacheValue(cacheName: string, cacheKey: string) {
-	return request({
-		url: '/monitor/cache/getValue/' + cacheName + '/' + cacheKey,
-		method: 'get'
-	});
+  return request({
+    url: '/monitor/cache/getValue/' + cacheName + '/' + cacheKey,
+    method: 'get'
+  });
 }
 
 // 娓呯悊鎸囧畾鍚嶇О缂撳瓨
 export function clearCacheName(cacheName: string) {
-	return request({
-		url: '/monitor/cache/clearCacheName/' + cacheName,
-		method: 'delete'
-	});
+  return request({
+    url: '/monitor/cache/clearCacheName/' + cacheName,
+    method: 'delete'
+  });
 }
 
 // 娓呯悊鎸囧畾閿悕缂撳瓨
 export function clearCacheKey(cacheName: string, cacheKey: string) {
-	return request({
-		url: '/monitor/cache/clearCacheKey/' + cacheName + '/' + cacheKey,
-		method: 'delete'
-	});
+  return request({
+    url: '/monitor/cache/clearCacheKey/' + cacheName + '/' + cacheKey,
+    method: 'delete'
+  });
 }
 
 // 娓呯悊鍏ㄩ儴缂撳瓨
 export function clearCacheAll() {
-	return request({
-		url: '/monitor/cache/clearCacheAll',
-		method: 'delete'
-	});
+  return request({
+    url: '/monitor/cache/clearCacheAll',
+    method: 'delete'
+  });
 }
diff --git a/src/api/monitor/cache/types.ts b/src/api/monitor/cache/types.ts
index 540fafd..4017b65 100644
--- a/src/api/monitor/cache/types.ts
+++ b/src/api/monitor/cache/types.ts
@@ -1,7 +1,7 @@
 export interface CacheVO {
-	commandStats: Array<{ name: string; value: string }>;
+  commandStats: Array<{ name: string; value: string }>;
 
-	dbSize: number;
+  dbSize: number;
 
-	info: { [key: string]: string };
+  info: { [key: string]: string };
 }
diff --git a/src/api/monitor/loginInfo/index.ts b/src/api/monitor/loginInfo/index.ts
index 482a74a..f8877c9 100644
--- a/src/api/monitor/loginInfo/index.ts
+++ b/src/api/monitor/loginInfo/index.ts
@@ -4,33 +4,33 @@
 
 // 鏌ヨ鐧诲綍鏃ュ織鍒楄〃
 export function list(query: LoginInfoQuery): AxiosPromise<LoginInfoVO[]> {
-	return request({
-		url: '/monitor/logininfor/list',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/monitor/logininfor/list',
+    method: 'get',
+    params: query
+  });
 }
 
 // 鍒犻櫎鐧诲綍鏃ュ織
 export function delLoginInfo(infoId: string | number | Array<string | number>) {
-	return request({
-		url: '/monitor/logininfor/' + infoId,
-		method: 'delete'
-	});
+  return request({
+    url: '/monitor/logininfor/' + infoId,
+    method: 'delete'
+  });
 }
 
 // 瑙i攣鐢ㄦ埛鐧诲綍鐘舵��
 export function unlockLoginInfo(userName: string | Array<string>) {
-	return request({
-		url: '/monitor/logininfor/unlock/' + userName,
-		method: 'get'
-	});
+  return request({
+    url: '/monitor/logininfor/unlock/' + userName,
+    method: 'get'
+  });
 }
 
 // 娓呯┖鐧诲綍鏃ュ織
 export function cleanLoginInfo() {
-	return request({
-		url: '/monitor/logininfor/clean',
-		method: 'delete'
-	});
+  return request({
+    url: '/monitor/logininfor/clean',
+    method: 'delete'
+  });
 }
diff --git a/src/api/monitor/loginInfo/types.ts b/src/api/monitor/loginInfo/types.ts
index c037b7a..202c779 100644
--- a/src/api/monitor/loginInfo/types.ts
+++ b/src/api/monitor/loginInfo/types.ts
@@ -1,20 +1,20 @@
 export interface LoginInfoVO {
-	infoId: string | number;
-	tenantId: string | number;
-	userName: string;
-	status: string;
-	ipaddr: string;
-	loginLocation: string;
-	browser: string;
-	os: string;
-	msg: string;
-	loginTime: string;
+  infoId: string | number;
+  tenantId: string | number;
+  userName: string;
+  status: string;
+  ipaddr: string;
+  loginLocation: string;
+  browser: string;
+  os: string;
+  msg: string;
+  loginTime: string;
 }
 
 export interface LoginInfoQuery extends PageQuery {
-	ipaddr: string;
-	userName: string;
-	status: string;
-	orderByColumn: string;
-	isAsc: string;
+  ipaddr: string;
+  userName: string;
+  status: string;
+  orderByColumn: string;
+  isAsc: string;
 }
diff --git a/src/api/monitor/online/index.ts b/src/api/monitor/online/index.ts
index bedbde4..3d9034a 100644
--- a/src/api/monitor/online/index.ts
+++ b/src/api/monitor/online/index.ts
@@ -4,17 +4,17 @@
 
 // 鏌ヨ鍦ㄧ嚎鐢ㄦ埛鍒楄〃
 export function list(query: OnlineQuery): AxiosPromise<OnlineVO[]> {
-	return request({
-		url: '/monitor/online/list',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/monitor/online/list',
+    method: 'get',
+    params: query
+  });
 }
 
 // 寮洪��鐢ㄦ埛
 export function forceLogout(tokenId: string) {
-	return request({
-		url: '/monitor/online/' + tokenId,
-		method: 'delete'
-	});
+  return request({
+    url: '/monitor/online/' + tokenId,
+    method: 'delete'
+  });
 }
diff --git a/src/api/monitor/online/types.ts b/src/api/monitor/online/types.ts
index f873d59..8c0ec27 100644
--- a/src/api/monitor/online/types.ts
+++ b/src/api/monitor/online/types.ts
@@ -1,15 +1,15 @@
 export interface OnlineQuery extends PageQuery {
-	ipaddr: string;
-	userName: string;
+  ipaddr: string;
+  userName: string;
 }
 
 export interface OnlineVO extends BaseEntity {
-	tokenId: string;
-	deptName: string;
-	userName: string;
-	ipaddr: string;
-	loginLocation: string;
-	browser: string;
-	os: string;
-	loginTime: number;
+  tokenId: string;
+  deptName: string;
+  userName: string;
+  ipaddr: string;
+  loginLocation: string;
+  browser: string;
+  os: string;
+  loginTime: number;
 }
diff --git a/src/api/monitor/operlog/index.ts b/src/api/monitor/operlog/index.ts
index d7e5faa..7ac3453 100644
--- a/src/api/monitor/operlog/index.ts
+++ b/src/api/monitor/operlog/index.ts
@@ -4,25 +4,25 @@
 
 // 鏌ヨ鎿嶄綔鏃ュ織鍒楄〃
 export function list(query: OperLogQuery): AxiosPromise<OperLogVO[]> {
-	return request({
-		url: '/monitor/operlog/list',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/monitor/operlog/list',
+    method: 'get',
+    params: query
+  });
 }
 
 // 鍒犻櫎鎿嶄綔鏃ュ織
 export function delOperlog(operId: string | number | Array<string | number>) {
-	return request({
-		url: '/monitor/operlog/' + operId,
-		method: 'delete'
-	});
+  return request({
+    url: '/monitor/operlog/' + operId,
+    method: 'delete'
+  });
 }
 
 // 娓呯┖鎿嶄綔鏃ュ織
 export function cleanOperlog() {
-	return request({
-		url: '/monitor/operlog/clean',
-		method: 'delete'
-	});
+  return request({
+    url: '/monitor/operlog/clean',
+    method: 'delete'
+  });
 }
diff --git a/src/api/monitor/operlog/types.ts b/src/api/monitor/operlog/types.ts
index 71bc00c..9a67fa2 100644
--- a/src/api/monitor/operlog/types.ts
+++ b/src/api/monitor/operlog/types.ts
@@ -1,52 +1,52 @@
 export interface OperLogQuery extends PageQuery {
-	title: string;
-	operName: string;
-	businessType: string;
-	status: string;
-	orderByColumn: string;
-	isAsc: string;
+  title: string;
+  operName: string;
+  businessType: string;
+  status: string;
+  orderByColumn: string;
+  isAsc: string;
 }
 
 export interface OperLogVO extends BaseEntity {
-	operId: string | number;
-	tenantId: string;
-	title: string;
-	businessType: number;
-	businessTypes: number[] | undefined;
-	method: string;
-	requestMethod: string;
-	operatorType: number;
-	operName: string;
-	deptName: string;
-	operUrl: string;
-	operIp: string;
-	operLocation: string;
-	operParam: string;
-	jsonResult: string;
-	status: number;
-	errorMsg: string;
-	operTime: string;
-	costTime: number;
+  operId: string | number;
+  tenantId: string;
+  title: string;
+  businessType: number;
+  businessTypes: number[] | undefined;
+  method: string;
+  requestMethod: string;
+  operatorType: number;
+  operName: string;
+  deptName: string;
+  operUrl: string;
+  operIp: string;
+  operLocation: string;
+  operParam: string;
+  jsonResult: string;
+  status: number;
+  errorMsg: string;
+  operTime: string;
+  costTime: number;
 }
 
 export interface OperLogForm {
-	operId: number | string | undefined;
-	tenantId: string | number | undefined;
-	title: string;
-	businessType: number;
-	businessTypes: number[] | undefined;
-	method: string;
-	requestMethod: string;
-	operatorType: number;
-	operName: string;
-	deptName: string;
-	operUrl: string;
-	operIp: string;
-	operLocation: string;
-	operParam: string;
-	jsonResult: string;
-	status: number;
-	errorMsg: string;
-	operTime: string;
-	costTime: number;
+  operId: number | string | undefined;
+  tenantId: string | number | undefined;
+  title: string;
+  businessType: number;
+  businessTypes: number[] | undefined;
+  method: string;
+  requestMethod: string;
+  operatorType: number;
+  operName: string;
+  deptName: string;
+  operUrl: string;
+  operIp: string;
+  operLocation: string;
+  operParam: string;
+  jsonResult: string;
+  status: number;
+  errorMsg: string;
+  operTime: string;
+  costTime: number;
 }
diff --git a/src/api/system/config/index.ts b/src/api/system/config/index.ts
index ad87668..2eb7b94 100644
--- a/src/api/system/config/index.ts
+++ b/src/api/system/config/index.ts
@@ -4,71 +4,71 @@
 
 // 鏌ヨ鍙傛暟鍒楄〃
 export function listConfig(query: ConfigQuery): AxiosPromise<ConfigVO[]> {
-	return request({
-		url: '/system/config/list',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/system/config/list',
+    method: 'get',
+    params: query
+  });
 }
 
 // 鏌ヨ鍙傛暟璇︾粏
 export function getConfig(configId: string | number): AxiosPromise<ConfigVO> {
-	return request({
-		url: '/system/config/' + configId,
-		method: 'get'
-	});
+  return request({
+    url: '/system/config/' + configId,
+    method: 'get'
+  });
 }
 
 // 鏍规嵁鍙傛暟閿悕鏌ヨ鍙傛暟鍊�
 export function getConfigKey(configKey: string): AxiosPromise<ConfigVO> {
-	return request({
-		url: '/system/config/configKey/' + configKey,
-		method: 'get'
-	});
+  return request({
+    url: '/system/config/configKey/' + configKey,
+    method: 'get'
+  });
 }
 
 // 鏂板鍙傛暟閰嶇疆
 export function addConfig(data: ConfigForm) {
-	return request({
-		url: '/system/config',
-		method: 'post',
-		data: data
-	});
+  return request({
+    url: '/system/config',
+    method: 'post',
+    data: data
+  });
 }
 
 // 淇敼鍙傛暟閰嶇疆
 export function updateConfig(data: ConfigForm) {
-	return request({
-		url: '/system/config',
-		method: 'put',
-		data: data
-	});
+  return request({
+    url: '/system/config',
+    method: 'put',
+    data: data
+  });
 }
 
 // 淇敼鍙傛暟閰嶇疆
 export function updateConfigByKey(key: string, value: any) {
-	return request({
-		url: '/system/config/updateByKey',
-		method: 'put',
-		data: {
-			configKey: key,
-			configValue: value
-		}
-	});
+  return request({
+    url: '/system/config/updateByKey',
+    method: 'put',
+    data: {
+      configKey: key,
+      configValue: value
+    }
+  });
 }
 
 // 鍒犻櫎鍙傛暟閰嶇疆
 export function delConfig(configId: string | number | Array<string | number>) {
-	return request({
-		url: '/system/config/' + configId,
-		method: 'delete'
-	});
+  return request({
+    url: '/system/config/' + configId,
+    method: 'delete'
+  });
 }
 
 // 鍒锋柊鍙傛暟缂撳瓨
 export function refreshCache() {
-	return request({
-		url: '/system/config/refreshCache',
-		method: 'delete'
-	});
+  return request({
+    url: '/system/config/refreshCache',
+    method: 'delete'
+  });
 }
diff --git a/src/api/system/config/types.ts b/src/api/system/config/types.ts
index f51f91d..b68f073 100644
--- a/src/api/system/config/types.ts
+++ b/src/api/system/config/types.ts
@@ -1,23 +1,23 @@
 export interface ConfigVO extends BaseEntity {
-	configId: number | string;
-	configName: string;
-	configKey: string;
-	configValue: string;
-	configType: string;
-	remark: string;
+  configId: number | string;
+  configName: string;
+  configKey: string;
+  configValue: string;
+  configType: string;
+  remark: string;
 }
 
 export interface ConfigForm {
-	configId: number | string | undefined;
-	configName: string;
-	configKey: string;
-	configValue: string;
-	configType: string;
-	remark: string;
+  configId: number | string | undefined;
+  configName: string;
+  configKey: string;
+  configValue: string;
+  configType: string;
+  remark: string;
 }
 
 export interface ConfigQuery extends PageQuery {
-	configName: string;
-	configKey: string;
-	configType: string;
+  configName: string;
+  configKey: string;
+  configType: string;
 }
diff --git a/src/api/system/dept/index.ts b/src/api/system/dept/index.ts
index 85dcf1a..7e097fd 100644
--- a/src/api/system/dept/index.ts
+++ b/src/api/system/dept/index.ts
@@ -4,59 +4,59 @@
 
 // 鏌ヨ閮ㄩ棬鍒楄〃
 export const listDept = (query?: DeptQuery) => {
-	return request({
-		url: '/system/dept/list',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/system/dept/list',
+    method: 'get',
+    params: query
+  });
 };
 
 // 鏌ヨ閮ㄩ棬鍒楄〃锛堟帓闄よ妭鐐癸級
 export const listDeptExcludeChild = (deptId: string | number): AxiosPromise<DeptVO[]> => {
-	return request({
-		url: '/system/dept/list/exclude/' + deptId,
-		method: 'get'
-	});
+  return request({
+    url: '/system/dept/list/exclude/' + deptId,
+    method: 'get'
+  });
 };
 
 // 鏌ヨ閮ㄩ棬璇︾粏
 export const getDept = (deptId: string | number): AxiosPromise<DeptVO> => {
-	return request({
-		url: '/system/dept/' + deptId,
-		method: 'get'
-	});
+  return request({
+    url: '/system/dept/' + deptId,
+    method: 'get'
+  });
 };
 
 // 鏌ヨ閮ㄩ棬涓嬫媺鏍戠粨鏋�
 export const treeselect = (): AxiosPromise<DeptVO[]> => {
-	return request({
-		url: '/system/dept/treeselect',
-		method: 'get'
-	});
+  return request({
+    url: '/system/dept/treeselect',
+    method: 'get'
+  });
 };
 
 // 鏂板閮ㄩ棬
 export const addDept = (data: DeptForm) => {
-	return request({
-		url: '/system/dept',
-		method: 'post',
-		data: data
-	});
+  return request({
+    url: '/system/dept',
+    method: 'post',
+    data: data
+  });
 };
 
 // 淇敼閮ㄩ棬
 export const updateDept = (data: DeptForm) => {
-	return request({
-		url: '/system/dept',
-		method: 'put',
-		data: data
-	});
+  return request({
+    url: '/system/dept',
+    method: 'put',
+    data: data
+  });
 };
 
 // 鍒犻櫎閮ㄩ棬
 export const delDept = (deptId: number | string) => {
-	return request({
-		url: '/system/dept/' + deptId,
-		method: 'delete'
-	});
+  return request({
+    url: '/system/dept/' + deptId,
+    method: 'delete'
+  });
 };
diff --git a/src/api/system/dept/types.ts b/src/api/system/dept/types.ts
index 9fe52e5..867dbde 100644
--- a/src/api/system/dept/types.ts
+++ b/src/api/system/dept/types.ts
@@ -2,44 +2,44 @@
  * 閮ㄩ棬鏌ヨ鍙傛暟
  */
 export interface DeptQuery extends PageQuery {
-	deptName?: string;
-	status?: number;
+  deptName?: string;
+  status?: number;
 }
 
 /**
  * 閮ㄩ棬绫诲瀷
  */
 export interface DeptVO extends BaseEntity {
-	id: number | string;
-	parentName: string;
-	parentId: number | string;
-	children: DeptVO[];
-	deptId: number | string;
-	deptName: string;
-	orderNum: number;
-	leader: string;
-	phone: string;
-	email: string;
-	status: string;
-	delFlag: string;
-	ancestors: string;
-	menuId: string | number;
+  id: number | string;
+  parentName: string;
+  parentId: number | string;
+  children: DeptVO[];
+  deptId: number | string;
+  deptName: string;
+  orderNum: number;
+  leader: string;
+  phone: string;
+  email: string;
+  status: string;
+  delFlag: string;
+  ancestors: string;
+  menuId: string | number;
 }
 
 /**
  * 閮ㄩ棬琛ㄥ崟绫诲瀷
  */
 export interface DeptForm {
-	parentName?: string;
-	parentId?: number | string;
-	children?: DeptForm[];
-	deptId?: number | string;
-	deptName?: string;
-	orderNum?: number;
-	leader?: string;
-	phone?: string;
-	email?: string;
-	status?: string;
-	delFlag?: string;
-	ancestors?: string;
+  parentName?: string;
+  parentId?: number | string;
+  children?: DeptForm[];
+  deptId?: number | string;
+  deptName?: string;
+  orderNum?: number;
+  leader?: string;
+  phone?: string;
+  email?: string;
+  status?: string;
+  delFlag?: string;
+  ancestors?: string;
 }
diff --git a/src/api/system/dict/data/index.ts b/src/api/system/dict/data/index.ts
index e36b5a3..7692abc 100644
--- a/src/api/system/dict/data/index.ts
+++ b/src/api/system/dict/data/index.ts
@@ -3,51 +3,51 @@
 import { DictDataForm, DictDataQuery, DictDataVO } from './types';
 // 鏍规嵁瀛楀吀绫诲瀷鏌ヨ瀛楀吀鏁版嵁淇℃伅
 export function getDicts(dictType: string): AxiosPromise<DictDataVO[]> {
-	return request({
-		url: '/system/dict/data/type/' + dictType,
-		method: 'get'
-	});
+  return request({
+    url: '/system/dict/data/type/' + dictType,
+    method: 'get'
+  });
 }
 
 // 鏌ヨ瀛楀吀鏁版嵁鍒楄〃
 export function listData(query: DictDataQuery): AxiosPromise<DictDataVO[]> {
-	return request({
-		url: '/system/dict/data/list',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/system/dict/data/list',
+    method: 'get',
+    params: query
+  });
 }
 
 // 鏌ヨ瀛楀吀鏁版嵁璇︾粏
 export function getData(dictCode: string | number): AxiosPromise<DictDataVO> {
-	return request({
-		url: '/system/dict/data/' + dictCode,
-		method: 'get'
-	});
+  return request({
+    url: '/system/dict/data/' + dictCode,
+    method: 'get'
+  });
 }
 
 // 鏂板瀛楀吀鏁版嵁
 export function addData(data: DictDataForm) {
-	return request({
-		url: '/system/dict/data',
-		method: 'post',
-		data: data
-	});
+  return request({
+    url: '/system/dict/data',
+    method: 'post',
+    data: data
+  });
 }
 
 // 淇敼瀛楀吀鏁版嵁
 export function updateData(data: DictDataForm) {
-	return request({
-		url: '/system/dict/data',
-		method: 'put',
-		data: data
-	});
+  return request({
+    url: '/system/dict/data',
+    method: 'put',
+    data: data
+  });
 }
 
 // 鍒犻櫎瀛楀吀鏁版嵁
 export function delData(dictCode: string | number | Array<string | number>) {
-	return request({
-		url: '/system/dict/data/' + dictCode,
-		method: 'delete'
-	});
+  return request({
+    url: '/system/dict/data/' + dictCode,
+    method: 'delete'
+  });
 }
diff --git a/src/api/system/dict/data/types.ts b/src/api/system/dict/data/types.ts
index bed715d..a57b017 100644
--- a/src/api/system/dict/data/types.ts
+++ b/src/api/system/dict/data/types.ts
@@ -1,29 +1,29 @@
 export interface DictDataQuery extends PageQuery {
-	dictName: string;
-	dictType: string;
-	status: string;
-	dictLabel: string;
+  dictName: string;
+  dictType: string;
+  status: string;
+  dictLabel: string;
 }
 
 export interface DictDataVO extends BaseEntity {
-	dictCode: string;
-	dictLabel: string;
-	dictValue: string;
-	cssClass: string;
-	listClass: ElTagType;
-	dictSort: number;
-	status: string;
-	remark: string;
+  dictCode: string;
+  dictLabel: string;
+  dictValue: string;
+  cssClass: string;
+  listClass: ElTagType;
+  dictSort: number;
+  status: string;
+  remark: string;
 }
 
 export interface DictDataForm {
-	dictType?: string;
-	dictCode: string | undefined;
-	dictLabel: string;
-	dictValue: string;
-	cssClass: string;
-	listClass: ElTagType;
-	dictSort: number;
-	status: string;
-	remark: string;
+  dictType?: string;
+  dictCode: string | undefined;
+  dictLabel: string;
+  dictValue: string;
+  cssClass: string;
+  listClass: ElTagType;
+  dictSort: number;
+  status: string;
+  remark: string;
 }
diff --git a/src/api/system/dict/type/index.ts b/src/api/system/dict/type/index.ts
index 5acebee..7dc3d66 100644
--- a/src/api/system/dict/type/index.ts
+++ b/src/api/system/dict/type/index.ts
@@ -4,59 +4,59 @@
 
 // 鏌ヨ瀛楀吀绫诲瀷鍒楄〃
 export function listType(query: DictTypeQuery): AxiosPromise<DictTypeVO[]> {
-	return request({
-		url: '/system/dict/type/list',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/system/dict/type/list',
+    method: 'get',
+    params: query
+  });
 }
 
 // 鏌ヨ瀛楀吀绫诲瀷璇︾粏
 export function getType(dictId: number | string): AxiosPromise<DictTypeVO> {
-	return request({
-		url: '/system/dict/type/' + dictId,
-		method: 'get'
-	});
+  return request({
+    url: '/system/dict/type/' + dictId,
+    method: 'get'
+  });
 }
 
 // 鏂板瀛楀吀绫诲瀷
 export function addType(data: DictTypeForm) {
-	return request({
-		url: '/system/dict/type',
-		method: 'post',
-		data: data
-	});
+  return request({
+    url: '/system/dict/type',
+    method: 'post',
+    data: data
+  });
 }
 
 // 淇敼瀛楀吀绫诲瀷
 export function updateType(data: DictTypeForm) {
-	return request({
-		url: '/system/dict/type',
-		method: 'put',
-		data: data
-	});
+  return request({
+    url: '/system/dict/type',
+    method: 'put',
+    data: data
+  });
 }
 
 // 鍒犻櫎瀛楀吀绫诲瀷
 export function delType(dictId: string | number | Array<string | number>) {
-	return request({
-		url: '/system/dict/type/' + dictId,
-		method: 'delete'
-	});
+  return request({
+    url: '/system/dict/type/' + dictId,
+    method: 'delete'
+  });
 }
 
 // 鍒锋柊瀛楀吀缂撳瓨
 export function refreshCache() {
-	return request({
-		url: '/system/dict/type/refreshCache',
-		method: 'delete'
-	});
+  return request({
+    url: '/system/dict/type/refreshCache',
+    method: 'delete'
+  });
 }
 
 // 鑾峰彇瀛楀吀閫夋嫨妗嗗垪琛�
 export function optionselect(): AxiosPromise<DictTypeVO[]> {
-	return request({
-		url: '/system/dict/type/optionselect',
-		method: 'get'
-	});
+  return request({
+    url: '/system/dict/type/optionselect',
+    method: 'get'
+  });
 }
diff --git a/src/api/system/dict/type/types.ts b/src/api/system/dict/type/types.ts
index 67ad07c..9e52ac6 100644
--- a/src/api/system/dict/type/types.ts
+++ b/src/api/system/dict/type/types.ts
@@ -1,21 +1,21 @@
 export interface DictTypeVO extends BaseEntity {
-	dictId: number | string;
-	dictName: string;
-	dictType: string;
-	status: string;
-	remark: string;
+  dictId: number | string;
+  dictName: string;
+  dictType: string;
+  status: string;
+  remark: string;
 }
 
 export interface DictTypeForm {
-	dictId: number | string | undefined;
-	dictName: string;
-	dictType: string;
-	status: string;
-	remark: string;
+  dictId: number | string | undefined;
+  dictName: string;
+  dictType: string;
+  status: string;
+  remark: string;
 }
 
 export interface DictTypeQuery extends PageQuery {
-	dictName: string;
-	dictType: string;
-	status: string;
+  dictName: string;
+  dictType: string;
+  status: string;
 }
diff --git a/src/api/system/menu/index.ts b/src/api/system/menu/index.ts
index 82f76b0..7a0cf74 100644
--- a/src/api/system/menu/index.ts
+++ b/src/api/system/menu/index.ts
@@ -4,67 +4,67 @@
 
 // 鏌ヨ鑿滃崟鍒楄〃
 export const listMenu = (query?: MenuQuery): AxiosPromise<MenuVO[]> => {
-	return request({
-		url: '/system/menu/list',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/system/menu/list',
+    method: 'get',
+    params: query
+  });
 };
 
 // 鏌ヨ鑿滃崟璇︾粏
 export const getMenu = (menuId: string | number): AxiosPromise<MenuVO> => {
-	return request({
-		url: '/system/menu/' + menuId,
-		method: 'get'
-	});
+  return request({
+    url: '/system/menu/' + menuId,
+    method: 'get'
+  });
 };
 
 // 鏌ヨ鑿滃崟涓嬫媺鏍戠粨鏋�
 export const treeselect = (): AxiosPromise<MenuTreeOption[]> => {
-	return request({
-		url: '/system/menu/treeselect',
-		method: 'get'
-	});
+  return request({
+    url: '/system/menu/treeselect',
+    method: 'get'
+  });
 };
 
 // 鏍规嵁瑙掕壊ID鏌ヨ鑿滃崟涓嬫媺鏍戠粨鏋�
 export const roleMenuTreeselect = (roleId: string | number): AxiosPromise<RoleMenuTree> => {
-	return request({
-		url: '/system/menu/roleMenuTreeselect/' + roleId,
-		method: 'get'
-	});
+  return request({
+    url: '/system/menu/roleMenuTreeselect/' + roleId,
+    method: 'get'
+  });
 };
 
 // 鏍规嵁瑙掕壊ID鏌ヨ鑿滃崟涓嬫媺鏍戠粨鏋�
 export const tenantPackageMenuTreeselect = (packageId: string | number): AxiosPromise<RoleMenuTree> => {
-	return request({
-		url: '/system/menu/tenantPackageMenuTreeselect/' + packageId,
-		method: 'get'
-	});
+  return request({
+    url: '/system/menu/tenantPackageMenuTreeselect/' + packageId,
+    method: 'get'
+  });
 };
 
 // 鏂板鑿滃崟
 export const addMenu = (data: MenuForm) => {
-	return request({
-		url: '/system/menu',
-		method: 'post',
-		data: data
-	});
+  return request({
+    url: '/system/menu',
+    method: 'post',
+    data: data
+  });
 };
 
 // 淇敼鑿滃崟
 export const updateMenu = (data: MenuForm) => {
-	return request({
-		url: '/system/menu',
-		method: 'put',
-		data: data
-	});
+  return request({
+    url: '/system/menu',
+    method: 'put',
+    data: data
+  });
 };
 
 // 鍒犻櫎鑿滃崟
 export const delMenu = (menuId: string | number) => {
-	return request({
-		url: '/system/menu/' + menuId,
-		method: 'delete'
-	});
+  return request({
+    url: '/system/menu/' + menuId,
+    method: 'delete'
+  });
 };
diff --git a/src/api/system/menu/types.ts b/src/api/system/menu/types.ts
index 2eb43e5..ca19840 100644
--- a/src/api/system/menu/types.ts
+++ b/src/api/system/menu/types.ts
@@ -4,66 +4,66 @@
  * 鑿滃崟鏍戝舰缁撴瀯绫诲瀷
  */
 export interface MenuTreeOption {
-	id: string | number;
-	label: string;
-	parentId: string | number;
-	weight: number;
-	children?: MenuTreeOption[];
+  id: string | number;
+  label: string;
+  parentId: string | number;
+  weight: number;
+  children?: MenuTreeOption[];
 }
 
 export interface RoleMenuTree {
-	menus: MenuTreeOption[];
-	checkedKeys: string[];
+  menus: MenuTreeOption[];
+  checkedKeys: string[];
 }
 
 /**
  * 鑿滃崟鏌ヨ鍙傛暟绫诲瀷
  */
 export interface MenuQuery {
-	keywords?: string;
-	menuName?: string;
-	status?: string;
+  keywords?: string;
+  menuName?: string;
+  status?: string;
 }
 
 /**
  * 鑿滃崟瑙嗗浘瀵硅薄绫诲瀷
  */
 export interface MenuVO extends BaseEntity {
-	parentName: string;
-	parentId: string | number;
-	children: MenuVO[];
-	menuId: string | number;
-	menuName: string;
-	orderNum: number;
-	path: string;
-	component: string;
-	queryParam: string;
-	isFrame: string;
-	isCache: string;
-	menuType: MenuTypeEnum;
-	visible: string;
-	status: string;
-	icon: string;
-	remark: string;
+  parentName: string;
+  parentId: string | number;
+  children: MenuVO[];
+  menuId: string | number;
+  menuName: string;
+  orderNum: number;
+  path: string;
+  component: string;
+  queryParam: string;
+  isFrame: string;
+  isCache: string;
+  menuType: MenuTypeEnum;
+  visible: string;
+  status: string;
+  icon: string;
+  remark: string;
 }
 
 export interface MenuForm {
-	parentName?: string;
-	parentId?: string | number;
-	children?: MenuForm[];
-	menuId?: string | number;
-	menuName: string;
-	orderNum: number;
-	path: string;
-	component?: string;
-	queryParam?: string;
-	isFrame?: string;
-	isCache?: string;
-	menuType?: MenuTypeEnum;
-	visible?: string;
-	status?: string;
-	icon?: string;
-	remark?: string;
-	query?: string;
-	perms?: string;
+  parentName?: string;
+  parentId?: string | number;
+  children?: MenuForm[];
+  menuId?: string | number;
+  menuName: string;
+  orderNum: number;
+  path: string;
+  component?: string;
+  queryParam?: string;
+  isFrame?: string;
+  isCache?: string;
+  menuType?: MenuTypeEnum;
+  visible?: string;
+  status?: string;
+  icon?: string;
+  remark?: string;
+  query?: string;
+  perms?: string;
 }
diff --git a/src/api/system/notice/index.ts b/src/api/system/notice/index.ts
index f08fbab..285d1f4 100644
--- a/src/api/system/notice/index.ts
+++ b/src/api/system/notice/index.ts
@@ -3,43 +3,43 @@
 import { AxiosPromise } from 'axios';
 // 鏌ヨ鍏憡鍒楄〃
 export function listNotice(query: NoticeQuery): AxiosPromise<NoticeVO[]> {
-	return request({
-		url: '/system/notice/list',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/system/notice/list',
+    method: 'get',
+    params: query
+  });
 }
 
 // 鏌ヨ鍏憡璇︾粏
 export function getNotice(noticeId: string | number): AxiosPromise<NoticeVO> {
-	return request({
-		url: '/system/notice/' + noticeId,
-		method: 'get'
-	});
+  return request({
+    url: '/system/notice/' + noticeId,
+    method: 'get'
+  });
 }
 
 // 鏂板鍏憡
 export function addNotice(data: NoticeForm) {
-	return request({
-		url: '/system/notice',
-		method: 'post',
-		data: data
-	});
+  return request({
+    url: '/system/notice',
+    method: 'post',
+    data: data
+  });
 }
 
 // 淇敼鍏憡
 export function updateNotice(data: NoticeForm) {
-	return request({
-		url: '/system/notice',
-		method: 'put',
-		data: data
-	});
+  return request({
+    url: '/system/notice',
+    method: 'put',
+    data: data
+  });
 }
 
 // 鍒犻櫎鍏憡
 export function delNotice(noticeId: string | number | Array<string | number>) {
-	return request({
-		url: '/system/notice/' + noticeId,
-		method: 'delete'
-	});
+  return request({
+    url: '/system/notice/' + noticeId,
+    method: 'delete'
+  });
 }
diff --git a/src/api/system/notice/types.ts b/src/api/system/notice/types.ts
index 74a38fc..abfd5b2 100644
--- a/src/api/system/notice/types.ts
+++ b/src/api/system/notice/types.ts
@@ -1,26 +1,26 @@
 export interface NoticeVO extends BaseEntity {
-	noticeId: number;
-	noticeTitle: string;
-	noticeType: string;
-	noticeContent: string;
-	status: string;
-	remark: string;
-	createByName: string;
+  noticeId: number;
+  noticeTitle: string;
+  noticeType: string;
+  noticeContent: string;
+  status: string;
+  remark: string;
+  createByName: string;
 }
 
 export interface NoticeQuery extends PageQuery {
-	noticeTitle: string;
-	createByName: string;
-	status: string;
-	noticeType: string;
+  noticeTitle: string;
+  createByName: string;
+  status: string;
+  noticeType: string;
 }
 
 export interface NoticeForm {
-	noticeId: number | string | undefined;
-	noticeTitle: string;
-	noticeType: string;
-	noticeContent: string;
-	status: string;
-	remark: string;
-	createByName: string;
+  noticeId: number | string | undefined;
+  noticeTitle: string;
+  noticeType: string;
+  noticeContent: string;
+  status: string;
+  remark: string;
+  createByName: string;
 }
diff --git a/src/api/system/oss/index.ts b/src/api/system/oss/index.ts
index 9735a4d..6821d4e 100644
--- a/src/api/system/oss/index.ts
+++ b/src/api/system/oss/index.ts
@@ -4,25 +4,25 @@
 
 // 鏌ヨOSS瀵硅薄瀛樺偍鍒楄〃
 export function listOss(query: OssQuery): AxiosPromise<OssVO[]> {
-	return request({
-		url: '/system/oss/list',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/system/oss/list',
+    method: 'get',
+    params: query
+  });
 }
 
 // 鏌ヨOSS瀵硅薄鍩轰簬id涓�
 export function listByIds(ossId: string | number): AxiosPromise<OssVO[]> {
-	return request({
-		url: '/system/oss/listByIds/' + ossId,
-		method: 'get'
-	});
+  return request({
+    url: '/system/oss/listByIds/' + ossId,
+    method: 'get'
+  });
 }
 
 // 鍒犻櫎OSS瀵硅薄瀛樺偍
 export function delOss(ossId: string | number | Array<string | number>) {
-	return request({
-		url: '/system/oss/' + ossId,
-		method: 'delete'
-	});
+  return request({
+    url: '/system/oss/' + ossId,
+    method: 'delete'
+  });
 }
diff --git a/src/api/system/oss/types.ts b/src/api/system/oss/types.ts
index ee30efd..bc0bc1f 100644
--- a/src/api/system/oss/types.ts
+++ b/src/api/system/oss/types.ts
@@ -1,22 +1,22 @@
 export interface OssVO extends BaseEntity {
-	ossId: string | number;
-	fileName: string;
-	originalName: string;
-	fileSuffix: string;
-	url: string;
-	createByName: string;
-	service: string;
+  ossId: string | number;
+  fileName: string;
+  originalName: string;
+  fileSuffix: string;
+  url: string;
+  createByName: string;
+  service: string;
 }
 
 export interface OssQuery extends PageQuery {
-	fileName: string;
-	originalName: string;
-	fileSuffix: string;
-	createTime: string;
-	service: string;
-	orderByColumn: string;
-	isAsc: string;
+  fileName: string;
+  originalName: string;
+  fileSuffix: string;
+  createTime: string;
+  service: string;
+  orderByColumn: string;
+  isAsc: string;
 }
 export interface OssForm {
-	file: undefined | string;
+  file: undefined | string;
 }
diff --git a/src/api/system/ossConfig/index.ts b/src/api/system/ossConfig/index.ts
index 99a7a2f..b9ff537 100644
--- a/src/api/system/ossConfig/index.ts
+++ b/src/api/system/ossConfig/index.ts
@@ -4,57 +4,57 @@
 
 // 鏌ヨ瀵硅薄瀛樺偍閰嶇疆鍒楄〃
 export function listOssConfig(query: OssConfigQuery): AxiosPromise<OssConfigVO[]> {
-	return request({
-		url: '/system/oss/config/list',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/system/oss/config/list',
+    method: 'get',
+    params: query
+  });
 }
 
 // 鏌ヨ瀵硅薄瀛樺偍閰嶇疆璇︾粏
 export function getOssConfig(ossConfigId: string | number): AxiosPromise<OssConfigVO> {
-	return request({
-		url: '/system/oss/config/' + ossConfigId,
-		method: 'get'
-	});
+  return request({
+    url: '/system/oss/config/' + ossConfigId,
+    method: 'get'
+  });
 }
 
 // 鏂板瀵硅薄瀛樺偍閰嶇疆
 export function addOssConfig(data: OssConfigForm) {
-	return request({
-		url: '/system/oss/config',
-		method: 'post',
-		data: data
-	});
+  return request({
+    url: '/system/oss/config',
+    method: 'post',
+    data: data
+  });
 }
 
 // 淇敼瀵硅薄瀛樺偍閰嶇疆
 export function updateOssConfig(data: OssConfigForm) {
-	return request({
-		url: '/system/oss/config',
-		method: 'put',
-		data: data
-	});
+  return request({
+    url: '/system/oss/config',
+    method: 'put',
+    data: data
+  });
 }
 
 // 鍒犻櫎瀵硅薄瀛樺偍閰嶇疆
 export function delOssConfig(ossConfigId: string | number | Array<string | number>) {
-	return request({
-		url: '/system/oss/config/' + ossConfigId,
-		method: 'delete'
-	});
+  return request({
+    url: '/system/oss/config/' + ossConfigId,
+    method: 'delete'
+  });
 }
 
 // 瀵硅薄瀛樺偍鐘舵�佷慨鏀�
 export function changeOssConfigStatus(ossConfigId: string | number, status: string, configKey: string) {
-	const data = {
-		ossConfigId,
-		status,
-		configKey
-	};
-	return request({
-		url: '/system/oss/config/changeStatus',
-		method: 'put',
-		data: data
-	});
+  const data = {
+    ossConfigId,
+    status,
+    configKey
+  };
+  return request({
+    url: '/system/oss/config/changeStatus',
+    method: 'put',
+    data: data
+  });
 }
diff --git a/src/api/system/ossConfig/types.ts b/src/api/system/ossConfig/types.ts
index 1d1c5c1..d227bd0 100644
--- a/src/api/system/ossConfig/types.ts
+++ b/src/api/system/ossConfig/types.ts
@@ -1,38 +1,38 @@
 export interface OssConfigVO extends BaseEntity {
-	ossConfigId: number | string;
-	configKey: string;
-	accessKey: string;
-	secretKey: string;
-	bucketName: string;
-	prefix: string;
-	endpoint: string;
-	domain: string;
-	isHttps: string;
-	region: string;
-	status: string;
-	ext1: string;
-	remark: string;
-	accessPolicy: string;
+  ossConfigId: number | string;
+  configKey: string;
+  accessKey: string;
+  secretKey: string;
+  bucketName: string;
+  prefix: string;
+  endpoint: string;
+  domain: string;
+  isHttps: string;
+  region: string;
+  status: string;
+  ext1: string;
+  remark: string;
+  accessPolicy: string;
 }
 
 export interface OssConfigQuery extends PageQuery {
-	configKey: string;
-	bucketName: string;
-	status: string;
+  configKey: string;
+  bucketName: string;
+  status: string;
 }
 
 export interface OssConfigForm {
-	ossConfigId: string | number | undefined;
-	configKey: string;
-	accessKey: string;
-	secretKey: string;
-	bucketName: string;
-	prefix: string;
-	endpoint: string;
-	domain: string;
-	isHttps: string;
-	accessPolicy: string;
-	region: string;
-	status: string;
-	remark: string;
+  ossConfigId: string | number | undefined;
+  configKey: string;
+  accessKey: string;
+  secretKey: string;
+  bucketName: string;
+  prefix: string;
+  endpoint: string;
+  domain: string;
+  isHttps: string;
+  accessPolicy: string;
+  region: string;
+  status: string;
+  remark: string;
 }
diff --git a/src/api/system/post/index.ts b/src/api/system/post/index.ts
index 84d5615..3e523ab 100644
--- a/src/api/system/post/index.ts
+++ b/src/api/system/post/index.ts
@@ -4,43 +4,43 @@
 
 // 鏌ヨ宀椾綅鍒楄〃
 export function listPost(query: PostQuery): AxiosPromise<PostVO[]> {
-	return request({
-		url: '/system/post/list',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/system/post/list',
+    method: 'get',
+    params: query
+  });
 }
 
 // 鏌ヨ宀椾綅璇︾粏
 export function getPost(postId: string | number): AxiosPromise<PostVO> {
-	return request({
-		url: '/system/post/' + postId,
-		method: 'get'
-	});
+  return request({
+    url: '/system/post/' + postId,
+    method: 'get'
+  });
 }
 
 // 鏂板宀椾綅
 export function addPost(data: PostForm) {
-	return request({
-		url: '/system/post',
-		method: 'post',
-		data: data
-	});
+  return request({
+    url: '/system/post',
+    method: 'post',
+    data: data
+  });
 }
 
 // 淇敼宀椾綅
 export function updatePost(data: PostForm) {
-	return request({
-		url: '/system/post',
-		method: 'put',
-		data: data
-	});
+  return request({
+    url: '/system/post',
+    method: 'put',
+    data: data
+  });
 }
 
 // 鍒犻櫎宀椾綅
 export function delPost(postId: string | number | (string | number)[]) {
-	return request({
-		url: '/system/post/' + postId,
-		method: 'delete'
-	});
+  return request({
+    url: '/system/post/' + postId,
+    method: 'delete'
+  });
 }
diff --git a/src/api/system/post/types.ts b/src/api/system/post/types.ts
index 079619a..84e6786 100644
--- a/src/api/system/post/types.ts
+++ b/src/api/system/post/types.ts
@@ -1,23 +1,23 @@
 export interface PostVO extends BaseEntity {
-	postId: number | string;
-	postCode: string;
-	postName: string;
-	postSort: number;
-	status: string;
-	remark: string;
+  postId: number | string;
+  postCode: string;
+  postName: string;
+  postSort: number;
+  status: string;
+  remark: string;
 }
 
 export interface PostForm {
-	postId: number | string | undefined;
-	postCode: string;
-	postName: string;
-	postSort: number;
-	status: string;
-	remark: string;
+  postId: number | string | undefined;
+  postCode: string;
+  postName: string;
+  postSort: number;
+  status: string;
+  remark: string;
 }
 
 export interface PostQuery extends PageQuery {
-	postCode: string;
-	postName: string;
-	status: string;
+  postCode: string;
+  postName: string;
+  status: string;
 }
diff --git a/src/api/system/role/index.ts b/src/api/system/role/index.ts
index 04633de..4e8b612 100644
--- a/src/api/system/role/index.ts
+++ b/src/api/system/role/index.ts
@@ -5,32 +5,32 @@
 import request from '@/utils/request';
 
 export const listRole = (query: RoleQuery): AxiosPromise<RoleVO[]> => {
-	return request({
-		url: '/system/role/list',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/system/role/list',
+    method: 'get',
+    params: query
+  });
 };
 
 /**
  * 鏌ヨ瑙掕壊璇︾粏
  */
 export const getRole = (roleId: string | number): AxiosPromise<RoleVO> => {
-	return request({
-		url: '/system/role/' + roleId,
-		method: 'get'
-	});
+  return request({
+    url: '/system/role/' + roleId,
+    method: 'get'
+  });
 };
 
 /**
  * 鏂板瑙掕壊
  */
 export const addRole = (data: any) => {
-	return request({
-		url: '/system/role',
-		method: 'post',
-		data: data
-	});
+  return request({
+    url: '/system/role',
+    method: 'post',
+    data: data
+  });
 };
 
 /**
@@ -38,107 +38,107 @@
  * @param data
  */
 export const updateRole = (data: any) => {
-	return request({
-		url: '/system/role',
-		method: 'put',
-		data: data
-	});
+  return request({
+    url: '/system/role',
+    method: 'put',
+    data: data
+  });
 };
 
 /**
  * 瑙掕壊鏁版嵁鏉冮檺
  */
 export const dataScope = (data: any) => {
-	return request({
-		url: '/system/role/dataScope',
-		method: 'put',
-		data: data
-	});
+  return request({
+    url: '/system/role/dataScope',
+    method: 'put',
+    data: data
+  });
 };
 
 /**
  * 瑙掕壊鐘舵�佷慨鏀�
  */
 export const changeRoleStatus = (roleId: string | number, status: string) => {
-	const data = {
-		roleId,
-		status
-	};
-	return request({
-		url: '/system/role/changeStatus',
-		method: 'put',
-		data: data
-	});
+  const data = {
+    roleId,
+    status
+  };
+  return request({
+    url: '/system/role/changeStatus',
+    method: 'put',
+    data: data
+  });
 };
 
 /**
  * 鍒犻櫎瑙掕壊
  */
 export const delRole = (roleId: Array<string | number> | string | number) => {
-	return request({
-		url: '/system/role/' + roleId,
-		method: 'delete'
-	});
+  return request({
+    url: '/system/role/' + roleId,
+    method: 'delete'
+  });
 };
 
 /**
  * 鏌ヨ瑙掕壊宸叉巿鏉冪敤鎴峰垪琛�
  */
 export const allocatedUserList = (query: UserQuery): AxiosPromise<UserVO[]> => {
-	return request({
-		url: '/system/role/authUser/allocatedList',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/system/role/authUser/allocatedList',
+    method: 'get',
+    params: query
+  });
 };
 
 /**
  * 鏌ヨ瑙掕壊鏈巿鏉冪敤鎴峰垪琛�
  */
 export const unallocatedUserList = (query: UserQuery): AxiosPromise<UserVO[]> => {
-	return request({
-		url: '/system/role/authUser/unallocatedList',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/system/role/authUser/unallocatedList',
+    method: 'get',
+    params: query
+  });
 };
 
 /**
  * 鍙栨秷鐢ㄦ埛鎺堟潈瑙掕壊
  */
 export const authUserCancel = (data: any) => {
-	return request({
-		url: '/system/role/authUser/cancel',
-		method: 'put',
-		data: data
-	});
+  return request({
+    url: '/system/role/authUser/cancel',
+    method: 'put',
+    data: data
+  });
 };
 
 /**
  * 鎵归噺鍙栨秷鐢ㄦ埛鎺堟潈瑙掕壊
  */
 export const authUserCancelAll = (data: any) => {
-	return request({
-		url: '/system/role/authUser/cancelAll',
-		method: 'put',
-		params: data
-	});
+  return request({
+    url: '/system/role/authUser/cancelAll',
+    method: 'put',
+    params: data
+  });
 };
 
 /**
  * 鎺堟潈鐢ㄦ埛閫夋嫨
  */
 export const authUserSelectAll = (data: any) => {
-	return request({
-		url: '/system/role/authUser/selectAll',
-		method: 'put',
-		params: data
-	});
+  return request({
+    url: '/system/role/authUser/selectAll',
+    method: 'put',
+    params: data
+  });
 };
 // 鏍规嵁瑙掕壊ID鏌ヨ閮ㄩ棬鏍戠粨鏋�
 export const deptTreeSelect = (roleId: string | number): AxiosPromise<RoleDeptTree> => {
-	return request({
-		url: '/system/role/deptTree/' + roleId,
-		method: 'get'
-	});
+  return request({
+    url: '/system/role/deptTree/' + roleId,
+    method: 'get'
+  });
 };
diff --git a/src/api/system/role/types.ts b/src/api/system/role/types.ts
index df741d7..4558c78 100644
--- a/src/api/system/role/types.ts
+++ b/src/api/system/role/types.ts
@@ -2,51 +2,51 @@
  * 鑿滃崟鏍戝舰缁撴瀯绫诲瀷
  */
 export interface DeptTreeOption {
-	id: string;
-	label: string;
-	parentId: string;
-	weight: number;
-	children?: DeptTreeOption[];
+  id: string;
+  label: string;
+  parentId: string;
+  weight: number;
+  children?: DeptTreeOption[];
 }
 
 export interface RoleDeptTree {
-	checkedKeys: string[];
-	depts: DeptTreeOption[];
+  checkedKeys: string[];
+  depts: DeptTreeOption[];
 }
 
 export interface RoleVO extends BaseEntity {
-	roleId: string | number;
-	roleName: string;
-	roleKey: string;
-	roleSort: number;
-	dataScope: string;
-	menuCheckStrictly: boolean;
-	deptCheckStrictly: boolean;
-	status: string;
-	delFlag: string;
-	remark?: any;
-	flag: boolean;
-	menuIds?: Array<string | number>;
-	deptIds?: Array<string | number>;
-	admin: boolean;
+  roleId: string | number;
+  roleName: string;
+  roleKey: string;
+  roleSort: number;
+  dataScope: string;
+  menuCheckStrictly: boolean;
+  deptCheckStrictly: boolean;
+  status: string;
+  delFlag: string;
+  remark?: any;
+  flag: boolean;
+  menuIds?: Array<string | number>;
+  deptIds?: Array<string | number>;
+  admin: boolean;
 }
 
 export interface RoleQuery extends PageQuery {
-	roleName: string;
-	roleKey: string;
-	status: string;
+  roleName: string;
+  roleKey: string;
+  status: string;
 }
 
 export interface RoleForm {
-	roleName: string;
-	roleKey: string;
-	roleSort: number;
-	status: string;
-	menuCheckStrictly: boolean;
-	deptCheckStrictly: boolean;
-	remark: string;
-	dataScope?: number;
-	roleId: string | undefined;
-	menuIds: Array<string | number>;
-	deptIds: Array<string | number>;
+  roleName: string;
+  roleKey: string;
+  roleSort: number;
+  status: string;
+  menuCheckStrictly: boolean;
+  deptCheckStrictly: boolean;
+  remark: string;
+  dataScope?: number;
+  roleId: string | undefined;
+  menuIds: Array<string | number>;
+  deptIds: Array<string | number>;
 }
diff --git a/src/api/system/tenant/index.ts b/src/api/system/tenant/index.ts
index 92c78f3..28ec66e 100644
--- a/src/api/system/tenant/index.ts
+++ b/src/api/system/tenant/index.ts
@@ -4,86 +4,86 @@
 
 // 鏌ヨ绉熸埛鍒楄〃
 export function listTenant(query: TenantQuery): AxiosPromise<TenantVO[]> {
-	return request({
-		url: '/system/tenant/list',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/system/tenant/list',
+    method: 'get',
+    params: query
+  });
 }
 
 // 鏌ヨ绉熸埛璇︾粏
 export function getTenant(id: string | number): AxiosPromise<TenantVO> {
-	return request({
-		url: '/system/tenant/' + id,
-		method: 'get'
-	});
+  return request({
+    url: '/system/tenant/' + id,
+    method: 'get'
+  });
 }
 
 // 鏂板绉熸埛
 export function addTenant(data: TenantForm) {
-	return request({
-		url: '/system/tenant',
-		method: 'post',
-		data: data
-	});
+  return request({
+    url: '/system/tenant',
+    method: 'post',
+    data: data
+  });
 }
 
 // 淇敼绉熸埛
 export function updateTenant(data: TenantForm) {
-	return request({
-		url: '/system/tenant',
-		method: 'put',
-		data: data
-	});
+  return request({
+    url: '/system/tenant',
+    method: 'put',
+    data: data
+  });
 }
 
 // 绉熸埛鐘舵�佷慨鏀�
 export function changeTenantStatus(id: string | number, tenantId: string | number, status: string) {
-	const data = {
-		id,
-		tenantId,
-		status
-	};
-	return request({
-		url: '/system/tenant/changeStatus',
-		method: 'put',
-		data: data
-	});
+  const data = {
+    id,
+    tenantId,
+    status
+  };
+  return request({
+    url: '/system/tenant/changeStatus',
+    method: 'put',
+    data: data
+  });
 }
 
 // 鍒犻櫎绉熸埛
 export function delTenant(id: string | number | Array<string | number>) {
-	return request({
-		url: '/system/tenant/' + id,
-		method: 'delete'
-	});
+  return request({
+    url: '/system/tenant/' + id,
+    method: 'delete'
+  });
 }
 
 // 鍔ㄦ�佸垏鎹㈢鎴�
 export function dynamicTenant(tenantId: string | number) {
-	return request({
-		url: '/system/tenant/dynamic/' + tenantId,
-		method: 'get'
-	});
+  return request({
+    url: '/system/tenant/dynamic/' + tenantId,
+    method: 'get'
+  });
 }
 
 // 娓呴櫎鍔ㄦ�佺鎴�
 export function dynamicClear() {
-	return request({
-		url: '/system/tenant/dynamic/clear',
-		method: 'get'
-	});
+  return request({
+    url: '/system/tenant/dynamic/clear',
+    method: 'get'
+  });
 }
 
 // 鍚屾绉熸埛濂楅
 export function syncTenantPackage(tenantId: string | number, packageId: string | number) {
-	const data = {
-		tenantId,
-		packageId
-	};
-	return request({
-		url: '/system/tenant/syncTenantPackage',
-		method: 'get',
-		params: data
-	});
+  const data = {
+    tenantId,
+    packageId
+  };
+  return request({
+    url: '/system/tenant/syncTenantPackage',
+    method: 'get',
+    params: data
+  });
 }
diff --git a/src/api/system/tenant/types.ts b/src/api/system/tenant/types.ts
index 92cb991..25395fa 100644
--- a/src/api/system/tenant/types.ts
+++ b/src/api/system/tenant/types.ts
@@ -1,46 +1,46 @@
 export interface TenantVO extends BaseEntity {
-	id: number | string;
-	tenantId: number | string;
-	username: string;
-	contactUserName: string;
-	contactPhone: string;
-	companyName: string;
-	licenseNumber: string;
-	address: string;
-	domain: string;
-	intro: string;
-	remark: string;
-	packageId: string | number;
-	expireTime: string;
-	accountCount: number;
-	status: string;
+  id: number | string;
+  tenantId: number | string;
+  username: string;
+  contactUserName: string;
+  contactPhone: string;
+  companyName: string;
+  licenseNumber: string;
+  address: string;
+  domain: string;
+  intro: string;
+  remark: string;
+  packageId: string | number;
+  expireTime: string;
+  accountCount: number;
+  status: string;
 }
 
 export interface TenantQuery extends PageQuery {
-	tenantId: string | number;
+  tenantId: string | number;
 
-	contactUserName: string;
+  contactUserName: string;
 
-	contactPhone: string;
+  contactPhone: string;
 
-	companyName: string;
+  companyName: string;
 }
 
 export interface TenantForm {
-	id: number | string | undefined;
-	tenantId: number | string | undefined;
-	username: string;
-	password: string;
-	contactUserName: string;
-	contactPhone: string;
-	companyName: string;
-	licenseNumber: string;
-	domain: string;
-	address: string;
-	intro: string;
-	remark: string;
-	packageId: string | number;
-	expireTime: string;
-	accountCount: number;
-	status: string;
+  id: number | string | undefined;
+  tenantId: number | string | undefined;
+  username: string;
+  password: string;
+  contactUserName: string;
+  contactPhone: string;
+  companyName: string;
+  licenseNumber: string;
+  domain: string;
+  address: string;
+  intro: string;
+  remark: string;
+  packageId: string | number;
+  expireTime: string;
+  accountCount: number;
+  status: string;
 }
diff --git a/src/api/system/tenantPackage/index.ts b/src/api/system/tenantPackage/index.ts
index af26b65..814a732 100644
--- a/src/api/system/tenantPackage/index.ts
+++ b/src/api/system/tenantPackage/index.ts
@@ -4,56 +4,56 @@
 
 // 鏌ヨ绉熸埛濂楅鍒楄〃
 export function listTenantPackage(query?: TenantPkgQuery): AxiosPromise<TenantPkgVO[]> {
-	return request({
-		url: '/system/tenant/package/list',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/system/tenant/package/list',
+    method: 'get',
+    params: query
+  });
 }
 
 // 鏌ヨ绉熸埛濂楅璇︾粏
 export function getTenantPackage(packageId: string | number): AxiosPromise<TenantPkgVO> {
-	return request({
-		url: '/system/tenant/package/' + packageId,
-		method: 'get'
-	});
+  return request({
+    url: '/system/tenant/package/' + packageId,
+    method: 'get'
+  });
 }
 
 // 鏂板绉熸埛濂楅
 export function addTenantPackage(data: TenantPkgForm) {
-	return request({
-		url: '/system/tenant/package',
-		method: 'post',
-		data: data
-	});
+  return request({
+    url: '/system/tenant/package',
+    method: 'post',
+    data: data
+  });
 }
 
 // 淇敼绉熸埛濂楅
 export function updateTenantPackage(data: TenantPkgForm) {
-	return request({
-		url: '/system/tenant/package',
-		method: 'put',
-		data: data
-	});
+  return request({
+    url: '/system/tenant/package',
+    method: 'put',
+    data: data
+  });
 }
 
 // 绉熸埛濂楅鐘舵�佷慨鏀�
 export function changePackageStatus(packageId: number | string, status: string) {
-	const data = {
-		packageId,
-		status
-	};
-	return request({
-		url: '/system/tenant/package/changeStatus',
-		method: 'put',
-		data: data
-	});
+  const data = {
+    packageId,
+    status
+  };
+  return request({
+    url: '/system/tenant/package/changeStatus',
+    method: 'put',
+    data: data
+  });
 }
 
 // 鍒犻櫎绉熸埛濂楅
 export function delTenantPackage(packageId: string | number | Array<string | number>) {
-	return request({
-		url: '/system/tenant/package/' + packageId,
-		method: 'delete'
-	});
+  return request({
+    url: '/system/tenant/package/' + packageId,
+    method: 'delete'
+  });
 }
diff --git a/src/api/system/tenantPackage/types.ts b/src/api/system/tenantPackage/types.ts
index cee4fc0..e9013a3 100644
--- a/src/api/system/tenantPackage/types.ts
+++ b/src/api/system/tenantPackage/types.ts
@@ -1,22 +1,22 @@
 export interface TenantPkgVO extends BaseEntity {
-	packageId: string | number;
-	packageName: string;
-	menuIds: string;
-	remark: string;
-	menuCheckStrictly: boolean;
-	status: string;
+  packageId: string | number;
+  packageName: string;
+  menuIds: string;
+  remark: string;
+  menuCheckStrictly: boolean;
+  status: string;
 }
 
 export interface TenantPkgQuery extends PageQuery {
-	packageName: string;
-	status: string;
+  packageName: string;
+  status: string;
 }
 
 export interface TenantPkgForm {
-	packageId: string | number | undefined;
-	packageName: string;
-	menuIds: string;
-	remark: string;
-	menuCheckStrictly: boolean;
-	status: string;
+  packageId: string | number | undefined;
+  packageName: string;
+  menuIds: string;
+  remark: string;
+  menuCheckStrictly: boolean;
+  status: string;
 }
diff --git a/src/api/system/user/index.ts b/src/api/system/user/index.ts
index d25e16c..d9fc1bd 100644
--- a/src/api/system/user/index.ts
+++ b/src/api/system/user/index.ts
@@ -10,11 +10,11 @@
  * @param query
  */
 export function listUser(query: UserQuery): AxiosPromise<UserVO[]> {
-	return request({
-		url: '/system/user/list',
-		method: 'get',
-		params: query
-	});
+  return request({
+    url: '/system/user/list',
+    method: 'get',
+    params: query
+  });
 }
 
 /**
@@ -22,32 +22,32 @@
  * @param userId
  */
 export function getUser(userId?: string | number): AxiosPromise<UserInfoVO> {
-	return request({
-		url: '/system/user/' + parseStrEmpty(userId),
-		method: 'get'
-	});
+  return request({
+    url: '/system/user/' + parseStrEmpty(userId),
+    method: 'get'
+  });
 }
 
 /**
  * 鏂板鐢ㄦ埛
  */
 export function addUser(data: UserForm) {
-	return request({
-		url: '/system/user',
-		method: 'post',
-		data: data
-	});
+  return request({
+    url: '/system/user',
+    method: 'post',
+    data: data
+  });
 }
 
 /**
  * 淇敼鐢ㄦ埛
  */
 export function updateUser(data: UserForm) {
-	return request({
-		url: '/system/user',
-		method: 'put',
-		data: data
-	});
+  return request({
+    url: '/system/user',
+    method: 'put',
+    data: data
+  });
 }
 
 /**
@@ -55,10 +55,10 @@
  * @param userId 鐢ㄦ埛ID
  */
 export function delUser(userId: Array<string | number> | string | number) {
-	return request({
-		url: '/system/user/' + userId,
-		method: 'delete'
-	});
+  return request({
+    url: '/system/user/' + userId,
+    method: 'delete'
+  });
 }
 
 /**
@@ -67,15 +67,15 @@
  * @param password 瀵嗙爜
  */
 export function resetUserPwd(userId: string | number, password: string) {
-	const data = {
-		userId,
-		password
-	};
-	return request({
-		url: '/system/user/resetPwd',
-		method: 'put',
-		data: data
-	});
+  const data = {
+    userId,
+    password
+  };
+  return request({
+    url: '/system/user/resetPwd',
+    method: 'put',
+    data: data
+  });
 }
 
 /**
@@ -84,25 +84,25 @@
  * @param status 鐢ㄦ埛鐘舵��
  */
 export function changeUserStatus(userId: number | string, status: string) {
-	const data = {
-		userId,
-		status
-	};
-	return request({
-		url: '/system/user/changeStatus',
-		method: 'put',
-		data: data
-	});
+  const data = {
+    userId,
+    status
+  };
+  return request({
+    url: '/system/user/changeStatus',
+    method: 'put',
+    data: data
+  });
 }
 
 /**
  * 鏌ヨ鐢ㄦ埛涓汉淇℃伅
  */
 export function getUserProfile(): AxiosPromise<UserInfoVO> {
-	return request({
-		url: '/system/user/profile',
-		method: 'get'
-	});
+  return request({
+    url: '/system/user/profile',
+    method: 'get'
+  });
 }
 
 /**
@@ -110,11 +110,11 @@
  * @param data 鐢ㄦ埛淇℃伅
  */
 export function updateUserProfile(data: UserForm) {
-	return request({
-		url: '/system/user/profile',
-		method: 'put',
-		data: data
-	});
+  return request({
+    url: '/system/user/profile',
+    method: 'put',
+    data: data
+  });
 }
 
 /**
@@ -123,15 +123,15 @@
  * @param newPassword 鏂板瘑鐮�
  */
 export function updateUserPwd(oldPassword: string, newPassword: string) {
-	const data = {
-		oldPassword,
-		newPassword
-	};
-	return request({
-		url: '/system/user/profile/updatePwd',
-		method: 'put',
-		params: data
-	});
+  const data = {
+    oldPassword,
+    newPassword
+  };
+  return request({
+    url: '/system/user/profile/updatePwd',
+    method: 'put',
+    params: data
+  });
 }
 
 /**
@@ -139,11 +139,11 @@
  * @param data 澶村儚鏂囦欢
  */
 export function uploadAvatar(data: FormData) {
-	return request({
-		url: '/system/user/profile/avatar',
-		method: 'post',
-		data: data
-	});
+  return request({
+    url: '/system/user/profile/avatar',
+    method: 'post',
+    data: data
+  });
 }
 
 /**
@@ -151,10 +151,10 @@
  * @param userId 鐢ㄦ埛ID
  */
 export function getAuthRole(userId: string | number): AxiosPromise<{ user: UserVO; roles: RoleVO[] }> {
-	return request({
-		url: '/system/user/authRole/' + userId,
-		method: 'get'
-	});
+  return request({
+    url: '/system/user/authRole/' + userId,
+    method: 'get'
+  });
 }
 
 /**
@@ -162,19 +162,19 @@
  * @param data 鐢ㄦ埛ID
  */
 export function updateAuthRole(data: { userId: string; roleIds: string }) {
-	return request({
-		url: '/system/user/authRole',
-		method: 'put',
-		params: data
-	});
+  return request({
+    url: '/system/user/authRole',
+    method: 'put',
+    params: data
+  });
 }
 
 /**
  * 鏌ヨ閮ㄩ棬涓嬫媺鏍戠粨鏋�
  */
 export function deptTreeSelect(): AxiosPromise<DeptVO[]> {
-	return request({
-		url: '/system/user/deptTree',
-		method: 'get'
-	});
+  return request({
+    url: '/system/user/deptTree',
+    method: 'get'
+  });
 }
diff --git a/src/api/system/user/types.ts b/src/api/system/user/types.ts
index 997b6d4..77e9c32 100644
--- a/src/api/system/user/types.ts
+++ b/src/api/system/user/types.ts
@@ -6,79 +6,79 @@
  * 鐢ㄦ埛淇℃伅
  */
 export interface UserInfo {
-	user: UserVO;
-	roles: string[];
-	permissions: string[];
+  user: UserVO;
+  roles: string[];
+  permissions: string[];
 }
 
 /**
  * 鐢ㄦ埛鏌ヨ瀵硅薄绫诲瀷
  */
 export interface UserQuery extends PageQuery {
-	userName?: string;
-	phonenumber?: string;
-	status?: string;
-	deptId?: string | number;
-	roleId?: string | number;
+  userName?: string;
+  phonenumber?: string;
+  status?: string;
+  deptId?: string | number;
+  roleId?: string | number;
 }
 
 /**
  * 鐢ㄦ埛杩斿洖瀵硅薄
  */
 export interface UserVO extends BaseEntity {
-	userId: string | number;
-	deptId: number;
-	userName: string;
-	nickName: string;
-	userType: string;
-	email: string;
-	phonenumber: string;
-	sex: string;
-	avatar: string;
-	status: string;
-	delFlag: string;
-	loginIp: string;
-	loginDate: string;
-	remark: string;
-	dept: DeptVO;
-	roles: RoleVO[];
-	roleIds: any;
-	postIds: any;
-	roleId: any;
-	admin: boolean;
+  userId: string | number;
+  deptId: number;
+  userName: string;
+  nickName: string;
+  userType: string;
+  email: string;
+  phonenumber: string;
+  sex: string;
+  avatar: string;
+  status: string;
+  delFlag: string;
+  loginIp: string;
+  loginDate: string;
+  remark: string;
+  dept: DeptVO;
+  roles: RoleVO[];
+  roleIds: any;
+  postIds: any;
+  roleId: any;
+  admin: boolean;
 }
 
 /**
  * 鐢ㄦ埛琛ㄥ崟绫诲瀷
  */
 export interface UserForm {
-	id?: string;
-	userId?: string;
-	deptId?: number;
-	userName: string;
-	nickName?: string;
-	password: string;
-	phonenumber?: string;
-	email?: string;
-	sex?: string;
-	status: string;
-	remark?: string;
-	postIds: string[];
-	roleIds: string[];
+  id?: string;
+  userId?: string;
+  deptId?: number;
+  userName: string;
+  nickName?: string;
+  password: string;
+  phonenumber?: string;
+  email?: string;
+  sex?: string;
+  status: string;
+  remark?: string;
+  postIds: string[];
+  roleIds: string[];
 }
 
 export interface UserInfoVO {
-	user: UserVO;
-	roles: RoleVO[];
-	roleIds: string[];
-	posts: PostVO[];
-	postIds: string[];
-	roleGroup: string;
-	postGroup: string;
+  user: UserVO;
+  roles: RoleVO[];
+  roleIds: string[];
+  posts: PostVO[];
+  postIds: string[];
+  roleGroup: string;
+  postGroup: string;
 }
 
 export interface ResetPwdForm {
-	oldPassword: string;
-	newPassword: string;
-	confirmPassword: string;
+  oldPassword: string;
+  newPassword: string;
+  confirmPassword: string;
 }
diff --git a/src/api/tool/gen/index.ts b/src/api/tool/gen/index.ts
index 9b0f2f0..b95e865 100644
--- a/src/api/tool/gen/index.ts
+++ b/src/api/tool/gen/index.ts
@@ -4,84 +4,84 @@
 
 // 鏌ヨ鐢熸垚琛ㄦ暟鎹�
 export const listTable = (query: TableQuery): AxiosPromise<TableVO[]> => {
-	return request({
-		headers: { datasource: localStorage.getItem('dataName') },
-		url: '/tool/gen/list',
-		method: 'get',
-		params: query
-	});
+  return request({
+    headers: { datasource: localStorage.getItem('dataName') },
+    url: '/tool/gen/list',
+    method: 'get',
+    params: query
+  });
 };
 // 鏌ヨdb鏁版嵁搴撳垪琛�
 export const listDbTable = (query: DbTableQuery): AxiosPromise<DbTableVO[]> => {
-	return request({
-		headers: { datasource: localStorage.getItem('dataName') },
-		url: '/tool/gen/db/list',
-		method: 'get',
-		params: query
-	});
+  return request({
+    headers: { datasource: localStorage.getItem('dataName') },
+    url: '/tool/gen/db/list',
+    method: 'get',
+    params: query
+  });
 };
 
 // 鏌ヨ琛ㄨ缁嗕俊鎭�
 export const getGenTable = (tableId: string | number): AxiosPromise<GenTableVO> => {
-	return request({
-		headers: { datasource: localStorage.getItem('dataName') },
-		url: '/tool/gen/' + tableId,
-		method: 'get'
-	});
+  return request({
+    headers: { datasource: localStorage.getItem('dataName') },
+    url: '/tool/gen/' + tableId,
+    method: 'get'
+  });
 };
 
 // 淇敼浠g爜鐢熸垚淇℃伅
 export const updateGenTable = (data: DbTableForm) => {
-	return request({
-		headers: { datasource: localStorage.getItem('dataName') },
-		url: '/tool/gen',
-		method: 'put',
-		data: data
-	});
+  return request({
+    headers: { datasource: localStorage.getItem('dataName') },
+    url: '/tool/gen',
+    method: 'put',
+    data: data
+  });
 };
 
 // 瀵煎叆琛�
 export const importTable = (data: { tables: string }) => {
-	return request({
-		headers: { datasource: localStorage.getItem('dataName') },
-		url: '/tool/gen/importTable',
-		method: 'post',
-		params: data
-	});
+  return request({
+    headers: { datasource: localStorage.getItem('dataName') },
+    url: '/tool/gen/importTable',
+    method: 'post',
+    params: data
+  });
 };
 
 // 棰勮鐢熸垚浠g爜
 export const previewTable = (tableId: string | number) => {
-	return request({
-		headers: { datasource: localStorage.getItem('dataName') },
-		url: '/tool/gen/preview/' + tableId,
-		method: 'get'
-	});
+  return request({
+    headers: { datasource: localStorage.getItem('dataName') },
+    url: '/tool/gen/preview/' + tableId,
+    method: 'get'
+  });
 };
 
 // 鍒犻櫎琛ㄦ暟鎹�
 export const delTable = (tableId: string | number | Array<string | number>) => {
-	return request({
-		headers: { datasource: localStorage.getItem('dataName') },
-		url: '/tool/gen/' + tableId,
-		method: 'delete'
-	});
+  return request({
+    headers: { datasource: localStorage.getItem('dataName') },
+    url: '/tool/gen/' + tableId,
+    method: 'delete'
+  });
 };
 
 // 鐢熸垚浠g爜锛堣嚜瀹氫箟璺緞锛�
 export const genCode = (tableName: string) => {
-	return request({
-		headers: { datasource: localStorage.getItem('dataName') },
-		url: '/tool/gen/genCode/' + tableName,
-		method: 'get'
-	});
+  return request({
+    headers: { datasource: localStorage.getItem('dataName') },
+    url: '/tool/gen/genCode/' + tableName,
+    method: 'get'
+  });
 };
 
 // 鍚屾鏁版嵁搴�
 export const synchDb = (tableName: string) => {
-	return request({
-		headers: { datasource: localStorage.getItem('dataName') },
-		url: '/tool/gen/synchDb/' + tableName,
-		method: 'get'
-	});
+  return request({
+    headers: { datasource: localStorage.getItem('dataName') },
+    url: '/tool/gen/synchDb/' + tableName,
+    method: 'get'
+  });
 };
diff --git a/src/api/tool/gen/types.ts b/src/api/tool/gen/types.ts
index 1acb0ff..662c6e5 100644
--- a/src/api/tool/gen/types.ts
+++ b/src/api/tool/gen/types.ts
@@ -1,178 +1,178 @@
 export interface TableVO extends BaseEntity {
-	createDept: number | string;
-	tableId: string | number;
-	tableName: string;
-	tableComment: string;
-	subTableName?: any;
-	subTableFkName?: any;
-	className: string;
-	tplCategory: string;
-	packageName: string;
-	moduleName: string;
-	businessName: string;
-	functionName: string;
-	functionAuthor: string;
-	genType: string;
-	genPath: string;
-	pkColumn?: any;
-	columns?: any;
-	options?: any;
-	remark?: any;
-	treeCode?: any;
-	treeParentCode?: any;
-	treeName?: any;
-	menuIds?: any;
-	parentMenuId?: any;
-	parentMenuName?: any;
-	tree: boolean;
-	crud: boolean;
+  createDept: number | string;
+  tableId: string | number;
+  tableName: string;
+  tableComment: string;
+  subTableName?: any;
+  subTableFkName?: any;
+  className: string;
+  tplCategory: string;
+  packageName: string;
+  moduleName: string;
+  businessName: string;
+  functionName: string;
+  functionAuthor: string;
+  genType: string;
+  genPath: string;
+  pkColumn?: any;
+  columns?: any;
+  options?: any;
+  remark?: any;
+  treeCode?: any;
+  treeParentCode?: any;
+  treeName?: any;
+  menuIds?: any;
+  parentMenuId?: any;
+  parentMenuName?: any;
+  tree: boolean;
+  crud: boolean;
 }
 
 export interface TableQuery extends PageQuery {
-	tableName: string;
-	tableComment: string;
-	dataName: string;
+  tableName: string;
+  tableComment: string;
+  dataName: string;
 }
 
 export interface DbColumnVO extends BaseEntity {
-	createDept?: any;
-	columnId?: any;
-	tableId?: any;
-	columnName?: any;
-	columnComment?: any;
-	columnType?: any;
-	javaType?: any;
-	javaField?: any;
-	isPk?: any;
-	isIncrement?: any;
-	isRequired?: any;
-	isInsert?: any;
-	isEdit?: any;
-	isList?: any;
-	isQuery?: any;
-	queryType?: any;
-	htmlType?: any;
-	dictType?: any;
-	sort?: any;
-	increment: boolean;
-	capJavaField?: any;
-	usableColumn: boolean;
-	superColumn: boolean;
-	list: boolean;
-	pk: boolean;
-	insert: boolean;
-	edit: boolean;
-	query: boolean;
-	required: boolean;
+  createDept?: any;
+  columnId?: any;
+  tableId?: any;
+  columnName?: any;
+  columnComment?: any;
+  columnType?: any;
+  javaType?: any;
+  javaField?: any;
+  isPk?: any;
+  isIncrement?: any;
+  isRequired?: any;
+  isInsert?: any;
+  isEdit?: any;
+  isList?: any;
+  isQuery?: any;
+  queryType?: any;
+  htmlType?: any;
+  dictType?: any;
+  sort?: any;
+  increment: boolean;
+  capJavaField?: any;
+  usableColumn: boolean;
+  superColumn: boolean;
+  list: boolean;
+  pk: boolean;
+  insert: boolean;
+  edit: boolean;
+  query: boolean;
+  required: boolean;
 }
 
 export interface DbTableVO {
-	createDept?: any;
-	tableId?: any;
-	tableName: string;
-	tableComment: string;
-	subTableName?: any;
-	subTableFkName?: any;
-	className?: any;
-	tplCategory?: any;
-	packageName?: any;
-	moduleName?: any;
-	businessName?: any;
-	functionName?: any;
-	functionAuthor?: any;
-	genType?: any;
-	genPath?: any;
-	pkColumn?: any;
-	columns: DbColumnVO[];
-	options?: any;
-	remark?: any;
-	treeCode?: any;
-	treeParentCode?: any;
-	treeName?: any;
-	menuIds?: any;
-	parentMenuId?: any;
-	parentMenuName?: any;
-	tree: boolean;
-	crud: boolean;
+  createDept?: any;
+  tableId?: any;
+  tableName: string;
+  tableComment: string;
+  subTableName?: any;
+  subTableFkName?: any;
+  className?: any;
+  tplCategory?: any;
+  packageName?: any;
+  moduleName?: any;
+  businessName?: any;
+  functionName?: any;
+  functionAuthor?: any;
+  genType?: any;
+  genPath?: any;
+  pkColumn?: any;
+  columns: DbColumnVO[];
+  options?: any;
+  remark?: any;
+  treeCode?: any;
+  treeParentCode?: any;
+  treeName?: any;
+  menuIds?: any;
+  parentMenuId?: any;
+  parentMenuName?: any;
+  tree: boolean;
+  crud: boolean;
 }
 
 export interface DbTableQuery extends PageQuery {
-	tableName: string;
-	tableComment: string;
+  tableName: string;
+  tableComment: string;
 }
 
 export interface GenTableVO {
-	info: DbTableVO;
-	rows: DbColumnVO[];
-	tables: DbTableVO[];
+  info: DbTableVO;
+  rows: DbColumnVO[];
+  tables: DbTableVO[];
 }
 
 export interface DbColumnForm extends BaseEntity {
-	createDept: number;
-	columnId: string;
-	tableId: string;
-	columnName: string;
-	columnComment: string;
-	columnType: string;
-	javaType: string;
-	javaField: string;
-	isPk: string;
-	isIncrement: string;
-	isRequired: string;
-	isInsert?: any;
-	isEdit: string;
-	isList: string;
-	isQuery?: any;
-	queryType: string;
-	htmlType: string;
-	dictType: string;
-	sort: number;
-	increment: boolean;
-	capJavaField: string;
-	usableColumn: boolean;
-	superColumn: boolean;
-	list: boolean;
-	pk: boolean;
-	insert: boolean;
-	edit: boolean;
-	query: boolean;
-	required: boolean;
+  createDept: number;
+  columnId: string;
+  tableId: string;
+  columnName: string;
+  columnComment: string;
+  columnType: string;
+  javaType: string;
+  javaField: string;
+  isPk: string;
+  isIncrement: string;
+  isRequired: string;
+  isInsert?: any;
+  isEdit: string;
+  isList: string;
+  isQuery?: any;
+  queryType: string;
+  htmlType: string;
+  dictType: string;
+  sort: number;
+  increment: boolean;
+  capJavaField: string;
+  usableColumn: boolean;
+  superColumn: boolean;
+  list: boolean;
+  pk: boolean;
+  insert: boolean;
+  edit: boolean;
+  query: boolean;
+  required: boolean;
 }
 
 export interface DbParamForm {
-	treeCode?: any;
-	treeName?: any;
-	treeParentCode?: any;
-	parentMenuId: string;
+  treeCode?: any;
+  treeName?: any;
+  treeParentCode?: any;
+  parentMenuId: string;
 }
 
 export interface DbTableForm extends BaseEntity {
-	createDept?: any;
-	tableId: string | string;
-	tableName: string;
-	tableComment: string;
-	subTableName?: any;
-	subTableFkName?: any;
-	className: string;
-	tplCategory: string;
-	packageName: string;
-	moduleName: string;
-	businessName: string;
-	functionName: string;
-	functionAuthor: string;
-	genType: string;
-	genPath: string;
-	pkColumn?: any;
-	columns: DbColumnForm[];
-	options: string;
-	remark?: any;
-	treeCode?: any;
-	treeParentCode?: any;
-	treeName?: any;
-	menuIds?: any;
-	parentMenuId: string;
-	parentMenuName?: any;
-	tree: boolean;
-	crud: boolean;
-	params: DbParamForm;
+  createDept?: any;
+  tableId: string | string;
+  tableName: string;
+  tableComment: string;
+  subTableName?: any;
+  subTableFkName?: any;
+  className: string;
+  tplCategory: string;
+  packageName: string;
+  moduleName: string;
+  businessName: string;
+  functionName: string;
+  functionAuthor: string;
+  genType: string;
+  genPath: string;
+  pkColumn?: any;
+  columns: DbColumnForm[];
+  options: string;
+  remark?: any;
+  treeCode?: any;
+  treeParentCode?: any;
+  treeName?: any;
+  menuIds?: any;
+  parentMenuId: string;
+  parentMenuName?: any;
+  tree: boolean;
+  crud: boolean;
+  params: DbParamForm;
 }
diff --git a/src/api/types.ts b/src/api/types.ts
index 5ecfb17..68fb427 100644
--- a/src/api/types.ts
+++ b/src/api/types.ts
@@ -2,53 +2,53 @@
  * 娉ㄥ唽
  */
 export type RegisterForm = {
-	tenantId: string;
-	username: string;
-	password: string;
-	confirmPassword?: string;
-	code?: string;
-	uuid?: string;
-	userType?: string;
+  tenantId: string;
+  username: string;
+  password: string;
+  confirmPassword?: string;
+  code?: string;
+  uuid?: string;
+  userType?: string;
 };
 
 /**
  * 鐧诲綍璇锋眰
  */
 export interface LoginData {
-	tenantId: string;
-	username: string;
-	password: string;
-	rememberMe?: boolean;
-	code?: string;
-	uuid?: string;
+  tenantId: string;
+  username: string;
+  password: string;
+  rememberMe?: boolean;
+  code?: string;
+  uuid?: string;
 }
 
 /**
  * 鐧诲綍鍝嶅簲
  */
 export interface LoginResult {
-	token: string;
+  token: string;
 }
 
 /**
  * 楠岃瘉鐮佽繑鍥�
  */
 export interface VerifyCodeResult {
-	captchaEnabled: boolean;
-	uuid?: string;
-	img?: string;
+  captchaEnabled: boolean;
+  uuid?: string;
+  img?: string;
 }
 
 /**
  * 绉熸埛
  */
 export interface TenantVO {
-	companyName: string;
-	domain: any;
-	tenantId: string;
+  companyName: string;
+  domain: any;
+  tenantId: string;
 }
 
 export interface TenantInfo {
-	tenantEnabled: boolean;
-	voList: TenantVO[];
+  tenantEnabled: boolean;
+  voList: TenantVO[];
 }
diff --git a/src/assets/styles/btn.scss b/src/assets/styles/btn.scss
index a1d854a..a1ccd01 100644
--- a/src/assets/styles/btn.scss
+++ b/src/assets/styles/btn.scss
@@ -1,99 +1,99 @@
 @import './variables.module.scss';
 
 @mixin colorBtn($color) {
-	background: $color;
+  background: $color;
 
-	&:hover {
-		color: $color;
+  &:hover {
+    color: $color;
 
-		&:before,
-		&:after {
-			background: $color;
-		}
-	}
+    &:before,
+    &:after {
+      background: $color;
+    }
+  }
 }
 
 .blue-btn {
-	@include colorBtn($blue);
+  @include colorBtn($blue);
 }
 
 .light-blue-btn {
-	@include colorBtn($light-blue);
+  @include colorBtn($light-blue);
 }
 
 .red-btn {
-	@include colorBtn($red);
+  @include colorBtn($red);
 }
 
 .pink-btn {
-	@include colorBtn($pink);
+  @include colorBtn($pink);
 }
 
 .green-btn {
-	@include colorBtn($green);
+  @include colorBtn($green);
 }
 
 .tiffany-btn {
-	@include colorBtn($tiffany);
+  @include colorBtn($tiffany);
 }
 
 .yellow-btn {
-	@include colorBtn($yellow);
+  @include colorBtn($yellow);
 }
 
 .pan-btn {
-	font-size: 14px;
-	color: #fff;
-	padding: 14px 36px;
-	border-radius: 8px;
-	border: none;
-	outline: none;
-	transition: 600ms ease all;
-	position: relative;
-	display: inline-block;
+  font-size: 14px;
+  color: #fff;
+  padding: 14px 36px;
+  border-radius: 8px;
+  border: none;
+  outline: none;
+  transition: 600ms ease all;
+  position: relative;
+  display: inline-block;
 
-	&:hover {
-		background: #fff;
+  &:hover {
+    background: #fff;
 
-		&:before,
-		&:after {
-			width: 100%;
-			transition: 600ms ease all;
-		}
-	}
+    &:before,
+    &:after {
+      width: 100%;
+      transition: 600ms ease all;
+    }
+  }
 
-	&:before,
-	&:after {
-		content: '';
-		position: absolute;
-		top: 0;
-		right: 0;
-		height: 2px;
-		width: 0;
-		transition: 400ms ease all;
-	}
+  &:before,
+  &:after {
+    content: '';
+    position: absolute;
+    top: 0;
+    right: 0;
+    height: 2px;
+    width: 0;
+    transition: 400ms ease all;
+  }
 
-	&::after {
-		right: inherit;
-		top: inherit;
-		left: 0;
-		bottom: 0;
-	}
+  &::after {
+    right: inherit;
+    top: inherit;
+    left: 0;
+    bottom: 0;
+  }
 }
 
 .custom-button {
-	display: inline-block;
-	line-height: 1;
-	white-space: nowrap;
-	cursor: pointer;
-	background: #fff;
-	color: #fff;
-	-webkit-appearance: none;
-	text-align: center;
-	box-sizing: border-box;
-	outline: 0;
-	margin: 0;
-	padding: 10px 15px;
-	font-size: 14px;
-	border-radius: 4px;
+  display: inline-block;
+  line-height: 1;
+  white-space: nowrap;
+  cursor: pointer;
+  background: #fff;
+  color: #fff;
+  -webkit-appearance: none;
+  text-align: center;
+  box-sizing: border-box;
+  outline: 0;
+  margin: 0;
+  padding: 10px 15px;
+  font-size: 14px;
+  border-radius: 4px;
 }
diff --git a/src/assets/styles/element-ui.scss b/src/assets/styles/element-ui.scss
index 44731b6..26d4f8a 100644
--- a/src/assets/styles/element-ui.scss
+++ b/src/assets/styles/element-ui.scss
@@ -1,97 +1,97 @@
 // cover some element-ui styles
 
 .el-divider--horizontal {
-	margin-bottom: 10px;
-	margin-top: 10px;
+  margin-bottom: 10px;
+  margin-top: 10px;
 }
 
 .el-breadcrumb__inner,
 .el-breadcrumb__inner a {
-	font-weight: 400 !important;
+  font-weight: 400 !important;
 }
 
 .el-upload {
-	input[type='file'] {
-		display: none !important;
-	}
+  input[type='file'] {
+    display: none !important;
+  }
 }
 
 .el-upload__input {
-	display: none;
+  display: none;
 }
 
 .cell {
-	.el-tag {
-		margin-right: 0px;
-	}
+  .el-tag {
+    margin-right: 0px;
+  }
 }
 
 .small-padding {
-	.cell {
-		padding-left: 5px;
-		padding-right: 5px;
-	}
+  .cell {
+    padding-left: 5px;
+    padding-right: 5px;
+  }
 }
 
 .fixed-width {
-	.el-button--mini {
-		padding: 7px 10px;
-		width: 60px;
-	}
+  .el-button--mini {
+    padding: 7px 10px;
+    width: 60px;
+  }
 }
 
 .status-col {
-	.cell {
-		padding: 0 10px;
-		text-align: center;
+  .cell {
+    padding: 0 10px;
+    text-align: center;
 
-		.el-tag {
-			margin-right: 0px;
-		}
-	}
+    .el-tag {
+      margin-right: 0px;
+    }
+  }
 }
 
 // to fixed https://github.com/ElemeFE/element/issues/2461
 .el-dialog {
-	transform: none;
-	left: 0;
-	position: relative;
-	margin: 0 auto;
+  transform: none;
+  left: 0;
+  position: relative;
+  margin: 0 auto;
 }
 
 // refine element ui upload
 .upload-container {
-	.el-upload {
-		width: 100%;
+  .el-upload {
+    width: 100%;
 
-		.el-upload-dragger {
-			width: 100%;
-			height: 200px;
-		}
-	}
+    .el-upload-dragger {
+      width: 100%;
+      height: 200px;
+    }
+  }
 }
 
 // dropdown
 .el-dropdown-menu {
-	a {
-		display: block;
-	}
+  a {
+    display: block;
+  }
 }
 
 // fix date-picker ui bug in filter-item
 .el-range-editor.el-input__inner {
-	display: inline-flex !important;
+  display: inline-flex !important;
 }
 
 // to fix el-date-picker css style
 .el-range-separator {
-	box-sizing: content-box;
+  box-sizing: content-box;
 }
 
 .el-menu--collapse>div>.el-submenu>.el-submenu__title .el-submenu__icon-arrow {
-	display: none;
+  display: none;
 }
 
 .el-dropdown .el-dropdown-link {
-	color: var(--el-color-primary) !important;
+  color: var(--el-color-primary) !important;
 }
\ No newline at end of file
diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss
index c768719..41c3d3f 100644
--- a/src/assets/styles/index.scss
+++ b/src/assets/styles/index.scss
@@ -9,201 +9,201 @@
 @import 'element-plus/dist/index.css';
 
 body {
-	height: 100%;
-	margin: 0;
-	-moz-osx-font-smoothing: grayscale;
-	-webkit-font-smoothing: antialiased;
-	text-rendering: optimizeLegibility;
-	font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
+  height: 100%;
+  margin: 0;
+  -moz-osx-font-smoothing: grayscale;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+  font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
 }
 
 label {
-	font-weight: 700;
+  font-weight: 700;
 }
 
 html {
-	height: 100%;
-	box-sizing: border-box;
+  height: 100%;
+  box-sizing: border-box;
 }
 
 #app {
-	height: 100%;
+  height: 100%;
 }
 
 *,
 *:before,
 *:after {
-	box-sizing: inherit;
+  box-sizing: inherit;
 }
 
 .no-padding {
-	padding: 0px !important;
+  padding: 0px !important;
 }
 
 .padding-content {
-	padding: 4px 0;
+  padding: 4px 0;
 }
 
 a:focus,
 a:active {
-	outline: none;
+  outline: none;
 }
 
 a,
 a:focus,
 a:hover {
-	cursor: pointer;
-	color: inherit;
-	text-decoration: none;
+  cursor: pointer;
+  color: inherit;
+  text-decoration: none;
 }
 
 div:focus {
-	outline: none;
+  outline: none;
 }
 
 .fr {
-	float: right;
+  float: right;
 }
 
 .fl {
-	float: left;
+  float: left;
 }
 
 .pr-5 {
-	padding-right: 5px;
+  padding-right: 5px;
 }
 
 .pl-5 {
-	padding-left: 5px;
+  padding-left: 5px;
 }
 
 .block {
-	display: block;
+  display: block;
 }
 
 .pointer {
-	cursor: pointer;
+  cursor: pointer;
 }
 
 .inlineBlock {
-	display: block;
+  display: block;
 }
 
 .clearfix {
-	&:after {
-		visibility: hidden;
-		display: block;
-		font-size: 0;
-		content: ' ';
-		clear: both;
-		height: 0;
-	}
+  &:after {
+    visibility: hidden;
+    display: block;
+    font-size: 0;
+    content: ' ';
+    clear: both;
+    height: 0;
+  }
 }
 
 aside {
-	background: #eef1f6;
-	padding: 8px 24px;
-	margin-bottom: 20px;
-	border-radius: 2px;
-	display: block;
-	line-height: 32px;
-	font-size: 16px;
-	font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
-		sans-serif;
-	color: #2c3e50;
-	-webkit-font-smoothing: antialiased;
-	-moz-osx-font-smoothing: grayscale;
+  background: #eef1f6;
+  padding: 8px 24px;
+  margin-bottom: 20px;
+  border-radius: 2px;
+  display: block;
+  line-height: 32px;
+  font-size: 16px;
+  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
+    sans-serif;
+  color: #2c3e50;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
 
-	a {
-		color: #337ab7;
-		cursor: pointer;
+  a {
+    color: #337ab7;
+    cursor: pointer;
 
-		&:hover {
-			color: rgb(32, 160, 255);
-		}
-	}
+    &:hover {
+      color: rgb(32, 160, 255);
+    }
+  }
 }
 
 //main-container鍏ㄥ眬鏍峰紡
 .app-container {
-	padding: 20px;
+  padding: 20px;
 }
 
 // search闈㈡澘鏍峰紡
 .panel,
 .search {
-	margin-bottom: 0.75rem;
-	border-radius: 0.25rem;
-	border: 1px solid var(--el-border-color-light);
-	background-color: var(--el-bg-color-overlay);
-	padding: 0.75rem;
-	--tw-shadow: var(--el-box-shadow-light);
-	--tw-shadow-colored: var(--el-box-shadow-light);
-	box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+  margin-bottom: 0.75rem;
+  border-radius: 0.25rem;
+  border: 1px solid var(--el-border-color-light);
+  background-color: var(--el-bg-color-overlay);
+  padding: 0.75rem;
+  --tw-shadow: var(--el-box-shadow-light);
+  --tw-shadow-colored: var(--el-box-shadow-light);
+  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
 }
 
 .components-container {
-	margin: 30px 50px;
-	position: relative;
+  margin: 30px 50px;
+  position: relative;
 }
 
 .pagination-container {
-	margin-top: 30px;
+  margin-top: 30px;
 }
 
 .text-center {
-	text-align: center;
+  text-align: center;
 }
 
 .sub-navbar {
-	height: 50px;
-	line-height: 50px;
-	position: relative;
-	width: 100%;
-	text-align: right;
-	padding-right: 20px;
-	transition: 600ms ease position;
-	background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%);
+  height: 50px;
+  line-height: 50px;
+  position: relative;
+  width: 100%;
+  text-align: right;
+  padding-right: 20px;
+  transition: 600ms ease position;
+  background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%);
 
-	.subtitle {
-		font-size: 20px;
-		color: #fff;
-	}
+  .subtitle {
+    font-size: 20px;
+    color: #fff;
+  }
 
-	&.draft {
-		background: #d0d0d0;
-	}
+  &.draft {
+    background: #d0d0d0;
+  }
 
-	&.deleted {
-		background: #d0d0d0;
-	}
+  &.deleted {
+    background: #d0d0d0;
+  }
 }
 
 .link-type,
 .link-type:focus {
-	color: #337ab7;
-	cursor: pointer;
+  color: #337ab7;
+  cursor: pointer;
 
-	&:hover {
-		color: rgb(32, 160, 255);
-	}
+  &:hover {
+    color: rgb(32, 160, 255);
+  }
 }
 
 .filter-container {
-	padding-bottom: 10px;
+  padding-bottom: 10px;
 
-	.filter-item {
-		display: inline-block;
-		vertical-align: middle;
-		margin-bottom: 10px;
-	}
+  .filter-item {
+    display: inline-block;
+    vertical-align: middle;
+    margin-bottom: 10px;
+  }
 }
 
 //refine vue-multiselect plugin
 .multiselect {
-	line-height: 16px;
+  line-height: 16px;
 }
 
 .multiselect--active {
-	z-index: 1000 !important;
+  z-index: 1000 !important;
 }
\ No newline at end of file
diff --git a/src/assets/styles/mixin.scss b/src/assets/styles/mixin.scss
index b5e121c..5250e71 100644
--- a/src/assets/styles/mixin.scss
+++ b/src/assets/styles/mixin.scss
@@ -1,60 +1,60 @@
 @mixin clearfix {
-	&:after {
-		content: '';
-		display: table;
-		clear: both;
-	}
+  &:after {
+    content: '';
+    display: table;
+    clear: both;
+  }
 }
 
 @mixin scrollBar {
-	&::-webkit-scrollbar-track-piece {
-		background: #d3dce6;
-	}
+  &::-webkit-scrollbar-track-piece {
+    background: #d3dce6;
+  }
 
-	&::-webkit-scrollbar {
-		width: 6px;
-	}
+  &::-webkit-scrollbar {
+    width: 6px;
+  }
 
-	&::-webkit-scrollbar-thumb {
-		background: #99a9bf;
-		border-radius: 20px;
-	}
+  &::-webkit-scrollbar-thumb {
+    background: #99a9bf;
+    border-radius: 20px;
+  }
 }
 
 @mixin relative {
-	position: relative;
-	width: 100%;
-	height: 100%;
+  position: relative;
+  width: 100%;
+  height: 100%;
 }
 
 @mixin pct($pct) {
-	width: #{$pct};
-	position: relative;
-	margin: 0 auto;
+  width: #{$pct};
+  position: relative;
+  margin: 0 auto;
 }
 
 @mixin triangle($width, $height, $color, $direction) {
-	$width: $width/2;
-	$color-border-style: $height solid $color;
-	$transparent-border-style: $width solid transparent;
-	height: 0;
-	width: 0;
+  $width: $width/2;
+  $color-border-style: $height solid $color;
+  $transparent-border-style: $width solid transparent;
+  height: 0;
+  width: 0;
 
-	@if $direction==up {
-		border-bottom: $color-border-style;
-		border-left: $transparent-border-style;
-		border-right: $transparent-border-style;
-	} @else if $direction==right {
-		border-left: $color-border-style;
-		border-top: $transparent-border-style;
-		border-bottom: $transparent-border-style;
-	} @else if $direction==down {
-		border-top: $color-border-style;
-		border-left: $transparent-border-style;
-		border-right: $transparent-border-style;
-	} @else if $direction==left {
-		border-right: $color-border-style;
-		border-top: $transparent-border-style;
-		border-bottom: $transparent-border-style;
-	}
+  @if $direction==up {
+    border-bottom: $color-border-style;
+    border-left: $transparent-border-style;
+    border-right: $transparent-border-style;
+  } @else if $direction==right {
+    border-left: $color-border-style;
+    border-top: $transparent-border-style;
+    border-bottom: $transparent-border-style;
+  } @else if $direction==down {
+    border-top: $color-border-style;
+    border-left: $transparent-border-style;
+    border-right: $transparent-border-style;
+  } @else if $direction==left {
+    border-right: $color-border-style;
+    border-top: $transparent-border-style;
+    border-bottom: $transparent-border-style;
+  }
 }
diff --git a/src/assets/styles/ruoyi.scss b/src/assets/styles/ruoyi.scss
index bb2ca5c..2e00d00 100644
--- a/src/assets/styles/ruoyi.scss
+++ b/src/assets/styles/ruoyi.scss
@@ -5,52 +5,52 @@
 
 /** 鍩虹閫氱敤 **/
 .pt5 {
-	padding-top: 5px;
+  padding-top: 5px;
 }
 .pr5 {
-	padding-right: 5px;
+  padding-right: 5px;
 }
 .pb5 {
-	padding-bottom: 5px;
+  padding-bottom: 5px;
 }
 .mt5 {
-	margin-top: 5px;
+  margin-top: 5px;
 }
 .mr5 {
-	margin-right: 5px;
+  margin-right: 5px;
 }
 .mb5 {
-	margin-bottom: 5px;
+  margin-bottom: 5px;
 }
 .mb8 {
-	margin-bottom: 8px;
+  margin-bottom: 8px;
 }
 .ml5 {
-	margin-left: 5px;
+  margin-left: 5px;
 }
 .mt10 {
-	margin-top: 10px;
+  margin-top: 10px;
 }
 .mr10 {
-	margin-right: 10px;
+  margin-right: 10px;
 }
 .mb10 {
-	margin-bottom: 10px;
+  margin-bottom: 10px;
 }
 .ml10 {
-	margin-left: 10px;
+  margin-left: 10px;
 }
 .mt20 {
-	margin-top: 20px;
+  margin-top: 20px;
 }
 .mr20 {
-	margin-right: 20px;
+  margin-right: 20px;
 }
 .mb20 {
-	margin-bottom: 20px;
+  margin-bottom: 20px;
 }
 .ml20 {
-	margin-left: 20px;
+  margin-left: 20px;
 }
 
 .h1,
@@ -65,226 +65,226 @@
 h4,
 h5,
 h6 {
-	font-family: inherit;
-	font-weight: 500;
-	line-height: 1.1;
-	color: inherit;
+  font-family: inherit;
+  font-weight: 500;
+  line-height: 1.1;
+  color: inherit;
 }
 
 .el-form .el-form-item__label {
-	font-weight: 700;
+  font-weight: 700;
 }
 .el-dialog:not(.is-fullscreen) {
-	margin-top: 6vh !important;
+  margin-top: 6vh !important;
 }
 
 .el-dialog.scrollbar .el-dialog__body {
-	overflow: auto;
-	overflow-x: hidden;
-	max-height: 70vh;
-	padding: 10px 20px 0;
+  overflow: auto;
+  overflow-x: hidden;
+  max-height: 70vh;
+  padding: 10px 20px 0;
 }
 
 .el-table {
-	.el-table__header-wrapper,
-	.el-table__fixed-header-wrapper {
-		th {
-			word-break: break-word;
-			background-color: #f8f8f9 !important;
-			color: #515a6e;
-			height: 40px !important;
-			font-size: 13px;
-		}
-	}
-	.el-table__body-wrapper {
-		.el-button [class*='el-icon-'] + span {
-			margin-left: 1px;
-		}
-	}
+  .el-table__header-wrapper,
+  .el-table__fixed-header-wrapper {
+    th {
+      word-break: break-word;
+      background-color: #f8f8f9 !important;
+      color: #515a6e;
+      height: 40px !important;
+      font-size: 13px;
+    }
+  }
+  .el-table__body-wrapper {
+    .el-button [class*='el-icon-'] + span {
+      margin-left: 1px;
+    }
+  }
 }
 
 /** 琛ㄥ崟甯冨眬 **/
 .form-header {
-	font-size: 15px;
-	color: #6379bb;
-	border-bottom: 1px solid #ddd;
-	margin: 8px 10px 25px 10px;
-	padding-bottom: 5px;
+  font-size: 15px;
+  color: #6379bb;
+  border-bottom: 1px solid #ddd;
+  margin: 8px 10px 25px 10px;
+  padding-bottom: 5px;
 }
 
 /** 琛ㄦ牸甯冨眬 **/
 .pagination-container {
-	// position: relative;
-	height: 25px;
-	margin-bottom: 10px;
-	margin-top: 15px;
-	padding: 10px 20px !important;
+  // position: relative;
+  height: 25px;
+  margin-bottom: 10px;
+  margin-top: 15px;
+  padding: 10px 20px !important;
 }
 
 /* tree border */
 .tree-border {
-	margin-top: 5px;
-	border: 1px solid #e5e6e7;
-	background: #ffffff none;
-	border-radius: 4px;
-	width: 100%;
+  margin-top: 5px;
+  border: 1px solid #e5e6e7;
+  background: #ffffff none;
+  border-radius: 4px;
+  width: 100%;
 }
 
 .pagination-container .el-pagination {
-	//right: 0;
-	//position: absolute;
+  //right: 0;
+  //position: absolute;
 }
 
 @media (max-width: 768px) {
-	.pagination-container .el-pagination > .el-pagination__jump {
-		display: none !important;
-	}
-	.pagination-container .el-pagination > .el-pagination__sizes {
-		display: none !important;
-	}
+  .pagination-container .el-pagination > .el-pagination__jump {
+    display: none !important;
+  }
+  .pagination-container .el-pagination > .el-pagination__sizes {
+    display: none !important;
+  }
 }
 
 .el-table .fixed-width .el-button--small {
-	padding-left: 0;
-	padding-right: 0;
-	width: inherit;
+  padding-left: 0;
+  padding-right: 0;
+  width: inherit;
 }
 
 /** 琛ㄦ牸鏇村鎿嶄綔涓嬫媺鏍峰紡 */
 .el-table .el-dropdown-link {
-	cursor: pointer;
-	color: #409eff;
-	margin-left: 10px;
+  cursor: pointer;
+  color: #409eff;
+  margin-left: 10px;
 }
 
 .el-table .el-dropdown,
 .el-icon-arrow-down {
-	font-size: 12px;
+  font-size: 12px;
 }
 
 .el-tree-node__content > .el-checkbox {
-	margin-right: 8px;
+  margin-right: 8px;
 }
 
 .list-group-striped > .list-group-item {
-	border-left: 0;
-	border-right: 0;
-	border-radius: 0;
-	padding-left: 0;
-	padding-right: 0;
+  border-left: 0;
+  border-right: 0;
+  border-radius: 0;
+  padding-left: 0;
+  padding-right: 0;
 }
 
 .list-group {
-	padding-left: 0px;
-	list-style: none;
+  padding-left: 0px;
+  list-style: none;
 }
 
 .list-group-item {
-	border-bottom: 1px solid #e7eaec;
-	border-top: 1px solid #e7eaec;
-	margin-bottom: -1px;
-	padding: 11px 0px;
-	font-size: 13px;
+  border-bottom: 1px solid #e7eaec;
+  border-top: 1px solid #e7eaec;
+  margin-bottom: -1px;
+  padding: 11px 0px;
+  font-size: 13px;
 }
 
 .pull-right {
-	float: right !important;
+  float: right !important;
 }
 
 .el-card__header {
-	padding: 14px 15px 7px !important;
-	min-height: 40px;
+  padding: 14px 15px 7px !important;
+  min-height: 40px;
 }
 
 .el-card__body {
-	padding: 15px 20px 20px 20px !important;
+  padding: 15px 20px 20px 20px !important;
 }
 
 .card-box {
-	padding-right: 15px;
-	padding-left: 15px;
-	margin-bottom: 10px;
+  padding-right: 15px;
+  padding-left: 15px;
+  margin-bottom: 10px;
 }
 
 /* button color */
 .el-button--cyan.is-active,
 .el-button--cyan:active {
-	background: #20b2aa;
-	border-color: #20b2aa;
-	color: #ffffff;
+  background: #20b2aa;
+  border-color: #20b2aa;
+  color: #ffffff;
 }
 
 .el-button--cyan:focus,
 .el-button--cyan:hover {
-	background: #48d1cc;
-	border-color: #48d1cc;
-	color: #ffffff;
+  background: #48d1cc;
+  border-color: #48d1cc;
+  color: #ffffff;
 }
 
 .el-button--cyan {
-	background-color: #20b2aa;
-	border-color: #20b2aa;
-	color: #ffffff;
+  background-color: #20b2aa;
+  border-color: #20b2aa;
+  color: #ffffff;
 }
 
 /* text color */
 .text-navy {
-	color: #1ab394;
+  color: #1ab394;
 }
 
 .text-primary {
-	color: inherit;
+  color: inherit;
 }
 
 .text-success {
-	color: #1c84c6;
+  color: #1c84c6;
 }
 
 .text-info {
-	color: #23c6c8;
+  color: #23c6c8;
 }
 
 .text-warning {
-	color: #f8ac59;
+  color: #f8ac59;
 }
 
 .text-danger {
-	color: #ed5565;
+  color: #ed5565;
 }
 
 .text-muted {
-	color: #888888;
+  color: #888888;
 }
 
 /* image */
 .img-circle {
-	border-radius: 50%;
+  border-radius: 50%;
 }
 
 .img-lg {
-	width: 120px;
-	height: 120px;
+  width: 120px;
+  height: 120px;
 }
 
 .avatar-upload-preview {
-	position: absolute;
-	top: 50%;
-	transform: translate(50%, -50%);
-	width: 200px;
-	height: 200px;
-	border-radius: 50%;
-	box-shadow: 0 0 4px #ccc;
-	overflow: hidden;
+  position: absolute;
+  top: 50%;
+  transform: translate(50%, -50%);
+  width: 200px;
+  height: 200px;
+  border-radius: 50%;
+  box-shadow: 0 0 4px #ccc;
+  overflow: hidden;
 }
 
 /* 鎷栨嫿鍒楁牱寮� */
 .sortable-ghost {
-	opacity: 0.8;
-	color: #fff !important;
-	background: #42b983 !important;
+  opacity: 0.8;
+  color: #fff !important;
+  background: #42b983 !important;
 }
 
 /* 琛ㄦ牸鍙充晶宸ュ叿鏍忔牱寮� */
 .top-right-btn {
-	margin-left: auto;
+  margin-left: auto;
 }
diff --git a/src/assets/styles/sidebar.scss b/src/assets/styles/sidebar.scss
index abe6f3a..4e0e84b 100644
--- a/src/assets/styles/sidebar.scss
+++ b/src/assets/styles/sidebar.scss
@@ -1,236 +1,236 @@
 #app {
-	.main-container {
-		min-height: 100%;
-		transition: margin-left 0.28s;
-		margin-left: $base-sidebar-width;
-		position: relative;
-	}
+  .main-container {
+    min-height: 100%;
+    transition: margin-left 0.28s;
+    margin-left: $base-sidebar-width;
+    position: relative;
+  }
 
-	.sidebarHide {
-		margin-left: 0 !important;
-	}
+  .sidebarHide {
+    margin-left: 0 !important;
+  }
 
-	.sidebar-container {
-		-webkit-transition: width 0.28s;
-		transition: width 0.28s;
-		width: $base-sidebar-width !important;
-		background-color: $base-menu-background;
-		height: 100%;
-		position: fixed;
-		font-size: 0px;
-		top: 0;
-		bottom: 0;
-		left: 0;
-		z-index: 1001;
-		overflow: hidden;
-		-webkit-box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
-		box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
+  .sidebar-container {
+    -webkit-transition: width 0.28s;
+    transition: width 0.28s;
+    width: $base-sidebar-width !important;
+    background-color: $base-menu-background;
+    height: 100%;
+    position: fixed;
+    font-size: 0px;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    z-index: 1001;
+    overflow: hidden;
+    -webkit-box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
+    box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
 
-		// reset element-ui css
-		.horizontal-collapse-transition {
-			transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
-		}
+    // reset element-ui css
+    .horizontal-collapse-transition {
+      transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
+    }
 
-		.scrollbar-wrapper {
-			overflow-x: hidden !important;
-		}
+    .scrollbar-wrapper {
+      overflow-x: hidden !important;
+    }
 
-		.el-scrollbar__bar.is-vertical {
-			right: 0px;
-		}
+    .el-scrollbar__bar.is-vertical {
+      right: 0px;
+    }
 
-		.el-scrollbar {
-			height: 100%;
-		}
+    .el-scrollbar {
+      height: 100%;
+    }
 
-		&.has-logo {
-			.el-scrollbar {
-				height: calc(100% - 50px);
-			}
-		}
+    &.has-logo {
+      .el-scrollbar {
+        height: calc(100% - 50px);
+      }
+    }
 
-		.is-horizontal {
-			display: none;
-		}
+    .is-horizontal {
+      display: none;
+    }
 
-		a {
-			display: inline-block;
-			width: 100%;
-			overflow: hidden;
-		}
+    a {
+      display: inline-block;
+      width: 100%;
+      overflow: hidden;
+    }
 
-		.svg-icon {
-			margin-right: 16px;
-		}
+    .svg-icon {
+      margin-right: 16px;
+    }
 
-		.el-menu {
-			border: none;
-			height: 100%;
-			width: 100% !important;
-		}
+    .el-menu {
+      border: none;
+      height: 100%;
+      width: 100% !important;
+    }
 
-		.el-menu-item,
-		.menu-title {
-			overflow: hidden !important;
-			text-overflow: ellipsis !important;
-			white-space: nowrap !important;
-		}
+    .el-menu-item,
+    .menu-title {
+      overflow: hidden !important;
+      text-overflow: ellipsis !important;
+      white-space: nowrap !important;
+    }
 
-		.el-menu-item .el-menu-tooltip__trigger {
-			display: inline-block !important;
-		}
+    .el-menu-item .el-menu-tooltip__trigger {
+      display: inline-block !important;
+    }
 
-		// menu hover
-		.sub-menu-title-noDropdown,
-		.el-sub-menu__title {
-			&:hover {
-				background-color: rgba(0, 0, 0, 0.06) !important;
-			}
-		}
+    // menu hover
+    .sub-menu-title-noDropdown,
+    .el-sub-menu__title {
+      &:hover {
+        background-color: rgba(0, 0, 0, 0.06) !important;
+      }
+    }
 
-		& .theme-dark .is-active > .el-sub-menu__title {
-			color: $base-menu-color-active !important;
-		}
+    & .theme-dark .is-active > .el-sub-menu__title {
+      color: $base-menu-color-active !important;
+    }
 
-		& .nest-menu .el-sub-menu > .el-sub-menu__title,
-		& .el-sub-menu .el-menu-item {
-			min-width: $base-sidebar-width !important;
+    & .nest-menu .el-sub-menu > .el-sub-menu__title,
+    & .el-sub-menu .el-menu-item {
+      min-width: $base-sidebar-width !important;
 
-			&:hover {
-				background-color: rgba(0, 0, 0, 0.06) !important;
-			}
-		}
+      &:hover {
+        background-color: rgba(0, 0, 0, 0.06) !important;
+      }
+    }
 
-		& .theme-dark .nest-menu .el-sub-menu > .el-sub-menu__title,
-		& .theme-dark .el-sub-menu .el-menu-item {
-			background-color: $base-sub-menu-background !important;
+    & .theme-dark .nest-menu .el-sub-menu > .el-sub-menu__title,
+    & .theme-dark .el-sub-menu .el-menu-item {
+      background-color: $base-sub-menu-background !important;
 
-			&:hover {
-				background-color: $base-sub-menu-hover !important;
-			}
-		}
-	}
+      &:hover {
+        background-color: $base-sub-menu-hover !important;
+      }
+    }
+  }
 
-	.hideSidebar {
-		.sidebar-container {
-			width: 54px !important;
-		}
+  .hideSidebar {
+    .sidebar-container {
+      width: 54px !important;
+    }
 
-		.main-container {
-			margin-left: 54px;
-		}
+    .main-container {
+      margin-left: 54px;
+    }
 
-		.sub-menu-title-noDropdown {
-			padding: 0 !important;
-			position: relative;
+    .sub-menu-title-noDropdown {
+      padding: 0 !important;
+      position: relative;
 
-			.el-tooltip {
-				padding: 0 !important;
+      .el-tooltip {
+        padding: 0 !important;
 
-				.svg-icon {
-					margin-left: 20px;
-				}
-			}
-		}
+        .svg-icon {
+          margin-left: 20px;
+        }
+      }
+    }
 
-		.el-sub-menu {
-			overflow: hidden;
+    .el-sub-menu {
+      overflow: hidden;
 
-			& > .el-sub-menu__title {
-				padding: 0 !important;
+      & > .el-sub-menu__title {
+        padding: 0 !important;
 
-				.svg-icon {
-					margin-left: 20px;
-				}
-			}
-		}
+        .svg-icon {
+          margin-left: 20px;
+        }
+      }
+    }
 
-		.el-menu--collapse {
-			.el-sub-menu {
-				& > .el-sub-menu__title {
-					& > span {
-						height: 0;
-						width: 0;
-						overflow: hidden;
-						visibility: hidden;
-						display: inline-block;
-					}
-					& > i {
-						height: 0;
-						width: 0;
-						overflow: hidden;
-						visibility: hidden;
-						display: inline-block;
-					}
-				}
-			}
-		}
-	}
+    .el-menu--collapse {
+      .el-sub-menu {
+        & > .el-sub-menu__title {
+          & > span {
+            height: 0;
+            width: 0;
+            overflow: hidden;
+            visibility: hidden;
+            display: inline-block;
+          }
+          & > i {
+            height: 0;
+            width: 0;
+            overflow: hidden;
+            visibility: hidden;
+            display: inline-block;
+          }
+        }
+      }
+    }
+  }
 
-	.el-menu--collapse .el-menu .el-sub-menu {
-		min-width: $base-sidebar-width !important;
-	}
+  .el-menu--collapse .el-menu .el-sub-menu {
+    min-width: $base-sidebar-width !important;
+  }
 
-	// mobile responsive
-	.mobile {
-		.main-container {
-			margin-left: 0px;
-		}
+  // mobile responsive
+  .mobile {
+    .main-container {
+      margin-left: 0px;
+    }
 
-		.sidebar-container {
-			transition: transform 0.28s;
-			width: $base-sidebar-width !important;
-		}
+    .sidebar-container {
+      transition: transform 0.28s;
+      width: $base-sidebar-width !important;
+    }
 
-		&.hideSidebar {
-			.sidebar-container {
-				pointer-events: none;
-				transition-duration: 0.3s;
-				transform: translate3d(-$base-sidebar-width, 0, 0);
-			}
-		}
-	}
+    &.hideSidebar {
+      .sidebar-container {
+        pointer-events: none;
+        transition-duration: 0.3s;
+        transform: translate3d(-$base-sidebar-width, 0, 0);
+      }
+    }
+  }
 
-	.withoutAnimation {
-		.main-container,
-		.sidebar-container {
-			transition: none;
-		}
-	}
+  .withoutAnimation {
+    .main-container,
+    .sidebar-container {
+      transition: none;
+    }
+  }
 }
 
 // when menu collapsed
 .el-menu--vertical {
-	& > .el-menu {
-		.svg-icon {
-			margin-right: 16px;
-		}
-	}
+  & > .el-menu {
+    .svg-icon {
+      margin-right: 16px;
+    }
+  }
 
-	.nest-menu .el-sub-menu > .el-sub-menu__title,
-	.el-menu-item {
-		&:hover {
-			// you can use $sub-menuHover
-			background-color: rgba(0, 0, 0, 0.06) !important;
-		}
-	}
+  .nest-menu .el-sub-menu > .el-sub-menu__title,
+  .el-menu-item {
+    &:hover {
+      // you can use $sub-menuHover
+      background-color: rgba(0, 0, 0, 0.06) !important;
+    }
+  }
 
-	// the scroll bar appears when the sub-menu is too long
-	> .el-menu--popup {
-		max-height: 100vh;
-		overflow-y: auto;
+  // the scroll bar appears when the sub-menu is too long
+  > .el-menu--popup {
+    max-height: 100vh;
+    overflow-y: auto;
 
-		&::-webkit-scrollbar-track-piece {
-			background: #d3dce6;
-		}
+    &::-webkit-scrollbar-track-piece {
+      background: #d3dce6;
+    }
 
-		&::-webkit-scrollbar {
-			width: 6px;
-		}
+    &::-webkit-scrollbar {
+      width: 6px;
+    }
 
-		&::-webkit-scrollbar-thumb {
-			background: #99a9bf;
-			border-radius: 20px;
-		}
-	}
+    &::-webkit-scrollbar-thumb {
+      background: #99a9bf;
+      border-radius: 20px;
+    }
+  }
 }
diff --git a/src/assets/styles/transition.scss b/src/assets/styles/transition.scss
index 1e43947..5fc9592 100644
--- a/src/assets/styles/transition.scss
+++ b/src/assets/styles/transition.scss
@@ -3,51 +3,51 @@
 /* fade */
 .fade-enter-active,
 .fade-leave-active {
-	transition: opacity 0.28s;
+  transition: opacity 0.28s;
 }
 
 .fade-enter,
 .fade-leave-active {
-	opacity: 0;
+  opacity: 0;
 }
 
 /* fade-transform */
 .fade-transform--move,
 .fade-transform-leave-active,
 .fade-transform-enter-active {
-	transition: all 0.5s;
+  transition: all 0.5s;
 }
 
 .fade-transform-leave-active {
-	position: absolute;
+  position: absolute;
 }
 
 .fade-transform-enter {
-	opacity: 0;
-	transform: translateX(-30px);
+  opacity: 0;
+  transform: translateX(-30px);
 }
 
 .fade-transform-leave-to {
-	opacity: 0;
-	transform: translateX(30px);
+  opacity: 0;
+  transform: translateX(30px);
 }
 
 /* breadcrumb transition */
 .breadcrumb-enter-active,
 .breadcrumb-leave-active {
-	transition: all 0.5s;
+  transition: all 0.5s;
 }
 
 .breadcrumb-enter,
 .breadcrumb-leave-active {
-	opacity: 0;
-	transform: translateX(20px);
+  opacity: 0;
+  transform: translateX(20px);
 }
 
 .breadcrumb-move {
-	transition: all 0.5s;
+  transition: all 0.5s;
 }
 
 .breadcrumb-leave-active {
-	position: absolute;
+  position: absolute;
 }
diff --git a/src/assets/styles/variables.module.scss b/src/assets/styles/variables.module.scss
index d43b407..639b23b 100644
--- a/src/assets/styles/variables.module.scss
+++ b/src/assets/styles/variables.module.scss
@@ -47,19 +47,19 @@
 // the :export directive is the magic sauce for webpack
 // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
 :export {
-	menuColor: $base-menu-color;
-	menuLightColor: $base-menu-light-color;
-	menuColorActive: $base-menu-color-active;
-	menuBackground: $base-menu-background;
-	menuLightBackground: $base-menu-light-background;
-	subMenuBackground: $base-sub-menu-background;
-	subMenuHover: $base-sub-menu-hover;
-	sideBarWidth: $base-sidebar-width;
-	logoTitleColor: $base-logo-title-color;
-	logoLightTitleColor: $base-logo-light-title-color;
-	primaryColor: $--color-primary;
-	successColor: $--color-success;
-	dangerColor: $--color-danger;
-	infoColor: $--color-info;
-	warningColor: $--color-warning;
+  menuColor: $base-menu-color;
+  menuLightColor: $base-menu-light-color;
+  menuColorActive: $base-menu-color-active;
+  menuBackground: $base-menu-background;
+  menuLightBackground: $base-menu-light-background;
+  subMenuBackground: $base-sub-menu-background;
+  subMenuHover: $base-sub-menu-hover;
+  sideBarWidth: $base-sidebar-width;
+  logoTitleColor: $base-logo-title-color;
+  logoLightTitleColor: $base-logo-light-title-color;
+  primaryColor: $--color-primary;
+  successColor: $--color-success;
+  dangerColor: $--color-danger;
+  infoColor: $--color-info;
+  warningColor: $--color-warning;
 }
diff --git a/src/components/Breadcrumb/index.vue b/src/components/Breadcrumb/index.vue
index 1d138e4..435d0cc 100644
--- a/src/components/Breadcrumb/index.vue
+++ b/src/components/Breadcrumb/index.vue
@@ -1,3 +1,15 @@
+<template>
+  <el-breadcrumb class="app-breadcrumb" separator="/">
+    <transition-group name="breadcrumb">
+      <el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path">
+        <span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect">{{
+          item.meta?.title }}</span>
+        <a v-else @click.prevent="handleLink(item)">{{ item.meta?.title }}</a>
+      </el-breadcrumb-item>
+    </transition-group>
+  </el-breadcrumb>
+</template>
+
 <script setup lang="ts">
 import { RouteLocationMatched } from 'vue-router'
 
@@ -6,48 +18,36 @@
 const levelList = ref<RouteLocationMatched[]>([])
 
 const getBreadcrumb = () => {
-  // only show routes with meta.title
-  let matched = route.matched.filter(item => item.meta && item.meta.title);
-  const first = matched[0]
-  // 鍒ゆ柇鏄惁涓洪椤�
-  if (!isDashboard(first)) {
-    matched = ([{ path: '/index', meta: { title: '棣栭〉' } }] as any).concat(matched)
-  }
-  levelList.value = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
+    // only show routes with meta.title
+    let matched = route.matched.filter(item => item.meta && item.meta.title);
+    const first = matched[0]
+    // 鍒ゆ柇鏄惁涓洪椤�
+    if (!isDashboard(first)) {
+        matched = ([{ path: '/index', meta: { title: '棣栭〉' } }] as any).concat(matched)
+    }
+    levelList.value = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
 }
 const isDashboard = (route: RouteLocationMatched) => {
-  const name = route && route.name as string
-  if (!name) {
-    return false
-  }
-  return name.trim() === 'Index'
+    const name = route && route.name as string
+    if (!name) {
+        return false
+    }
+    return name.trim() === 'Index'
 }
 const handleLink = (item: RouteLocationMatched) => {
-  const { redirect, path } = item
-  redirect ? router.push(redirect as string) : router.push(path)
+    const { redirect, path } = item
+    redirect ? router.push(redirect as string) : router.push(path)
 }
 
 watchEffect(() => {
-  // if you go to the redirect page, do not update the breadcrumbs
-  if (route.path.startsWith('/redirect/')) return
-  getBreadcrumb()
+    // if you go to the redirect page, do not update the breadcrumbs
+    if (route.path.startsWith('/redirect/')) return
+    getBreadcrumb()
 })
 onMounted(() => {
-  getBreadcrumb();
+    getBreadcrumb();
 })
 </script>
-
-<template>
-	<el-breadcrumb class="app-breadcrumb" separator="/">
-		<transition-group name="breadcrumb">
-			<el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path">
-				<span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect">{{
-          item.meta?.title }}</span>
-				<a v-else @click.prevent="handleLink(item)">{{ item.meta?.title }}</a>
-			</el-breadcrumb-item>
-		</transition-group>
-	</el-breadcrumb>
-</template>
 
 <style lang="scss" scoped>
 .app-breadcrumb.el-breadcrumb {
diff --git a/src/components/DictTag/index.vue b/src/components/DictTag/index.vue
index 7b7a657..827a7af 100644
--- a/src/components/DictTag/index.vue
+++ b/src/components/DictTag/index.vue
@@ -1,49 +1,49 @@
+<template>
+  <div>
+    <template v-for="(item, index) in options">
+      <template v-if="values.includes(item.value)">
+        <span
+          v-if="item.elTagType == 'default' || item.elTagType == ''"
+          :key="item.value"
+          :index="index"
+          :class="item.elTagClass"
+          >{{ item.label }}</span
+        >
+        <el-tag
+          v-else
+          :disable-transitions="true"
+          :key="item.value + ''"
+          :index="index"
+          :type="item.elTagType === 'primary' ? '' : item.elTagType"
+          :class="item.elTagClass"
+          >{{ item.label }}</el-tag
+        >
+      </template>
+    </template>
+  </div>
+</template>
+
 <script setup lang="ts">
 import { PropType } from 'vue';
 
 const props = defineProps({
-  // 鏁版嵁
-  options: {
-    type: Array as PropType<DictDataOption[]>,
-    default: null,
-  },
-  // 褰撳墠鐨勫��
-  value: [Number, String, Array],
+    // 鏁版嵁
+    options: {
+        type: Array as PropType<DictDataOption[]>,
+        default: null,
+    },
+    // 褰撳墠鐨勫��
+    value: [Number, String, Array],
 })
 
 const values = computed(() => {
-	if (props.value !== null && typeof props.value !== 'undefined') {
-		return Array.isArray(props.value) ? props.value : [String(props.value)];
-	} else {
-		return [];
-	}
+    if (props.value !== null && typeof props.value !== 'undefined') {
+        return Array.isArray(props.value) ? props.value : [String(props.value)];
+    } else {
+        return [];
+    }
 })
 </script>
-
-<template>
-	<div>
-		<template v-for="(item, index) in options">
-			<template v-if="values.includes(item.value)">
-				<span
-					v-if="item.elTagType == 'default' || item.elTagType == ''"
-					:key="item.value"
-					:index="index"
-					:class="item.elTagClass"
-					>{{ item.label }}</span
-				>
-				<el-tag
-					v-else
-					:disable-transitions="true"
-					:key="item.value + ''"
-					:index="index"
-					:type="item.elTagType === 'primary' ? '' : item.elTagType"
-					:class="item.elTagClass"
-					>{{ item.label }}</el-tag
-				>
-			</template>
-		</template>
-	</div>
-</template>
 
 <style scoped>
 .el-tag + .el-tag {
diff --git a/src/components/Editor/index.vue b/src/components/Editor/index.vue
index b7c18c3..e250050 100644
--- a/src/components/Editor/index.vue
+++ b/src/components/Editor/index.vue
@@ -1,3 +1,31 @@
+<template>
+  <div>
+    <el-upload
+      :action="upload.url"
+      :before-upload="handleBeforeUpload"
+      :on-success="handleUploadSuccess"
+      :on-error="handleUploadError"
+      class="editor-img-uploader"
+      name="file"
+      :show-file-list="false"
+      :headers="upload.headers"
+      style="display: none"
+      v-if="type === 'url'"
+    >
+    </el-upload>
+    <div class="editor">
+      <quill-editor
+        ref="myQuillEditor"
+        v-model:content="content"
+        contentType="html"
+        @textChange="(e: any) => $emit('update:modelValue', content)"
+        :options="options"
+        :style="styles"
+      />
+    </div>
+  </div>
+</template>
+
 <script setup lang="ts">
 import { QuillEditor, Quill } from '@vueup/vue-quill';
 import '@vueup/vue-quill/dist/vue-quill.snow.css';
@@ -5,165 +33,137 @@
 import { ComponentInternalInstance } from "vue";
 
 const props = defineProps({
-  /* 缂栬緫鍣ㄧ殑鍐呭 */
-  modelValue: {
-    type: String,
-  },
-  /* 楂樺害 */
-  height: {
-    type: Number,
-    default: null,
-  },
-  /* 鏈�灏忛珮搴� */
-  minHeight: {
-    type: Number,
-    default: null,
-  },
-  /* 鍙 */
-  readOnly: {
-    type: Boolean,
-    default: false,
-  },
-  /* 涓婁紶鏂囦欢澶у皬闄愬埗(MB) */
-  fileSize: {
-    type: Number,
-    default: 5,
-  },
-  /* 绫诲瀷锛坆ase64鏍煎紡銆乽rl鏍煎紡锛� */
-  type: {
-    type: String,
-    default: "url",
-  }
+    /* 缂栬緫鍣ㄧ殑鍐呭 */
+    modelValue: {
+        type: String,
+    },
+    /* 楂樺害 */
+    height: {
+        type: Number,
+        default: null,
+    },
+    /* 鏈�灏忛珮搴� */
+    minHeight: {
+        type: Number,
+        default: null,
+    },
+    /* 鍙 */
+    readOnly: {
+        type: Boolean,
+        default: false,
+    },
+    /* 涓婁紶鏂囦欢澶у皬闄愬埗(MB) */
+    fileSize: {
+        type: Number,
+        default: 5,
+    },
+    /* 绫诲瀷锛坆ase64鏍煎紡銆乽rl鏍煎紡锛� */
+    type: {
+        type: String,
+        default: "url",
+    }
 });
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 
 const upload = reactive<UploadOption>({
-  headers: { Authorization: "Bearer " + getToken() },
-  url: import.meta.env.VITE_APP_BASE_API + '/system/oss/upload'
+    headers: { Authorization: "Bearer " + getToken() },
+    url: import.meta.env.VITE_APP_BASE_API + '/system/oss/upload'
 })
 const myQuillEditor = ref();
 
 const options = ref({
-  theme: "snow",
-  bounds: document.body,
-  debug: "warn",
-  modules: {
-    // 宸ュ叿鏍忛厤缃�
-    toolbar: {
-      container: [
-        ["bold", "italic", "underline", "strike"],       // 鍔犵矖 鏂滀綋 涓嬪垝绾� 鍒犻櫎绾�
-        ["blockquote", "code-block"],                    // 寮曠敤  浠g爜鍧�
-        [{ list: "ordered" }, { list: "bullet"} ],       // 鏈夊簭銆佹棤搴忓垪琛�
-        [{ indent: "-1" }, { indent: "+1" }],            // 缂╄繘
-        [{ size: ["small", false, "large", "huge"] }],   // 瀛椾綋澶у皬
-        [{ header: [1, 2, 3, 4, 5, 6, false] }],         // 鏍囬
-        [{ color: [] }, { background: [] }],             // 瀛椾綋棰滆壊銆佸瓧浣撹儗鏅鑹�
-        [{ align: [] }],                                 // 瀵归綈鏂瑰紡
-        ["clean"],                                       // 娓呴櫎鏂囨湰鏍煎紡
-        ["link", "image", "video"]                       // 閾炬帴銆佸浘鐗囥�佽棰�
-      ],
-      handlers: {
-        image: function (value: any) {
-          if (value) {
-            // 璋冪敤element鍥剧墖涓婁紶
-            (document.querySelector(".editor-img-uploader>.el-upload") as HTMLDivElement)?.click();
-          } else {
-            Quill.format("image", true);
-          }
-        },
-      },
-    }
-  },
-  placeholder: '璇疯緭鍏ュ唴瀹�',
-  readOnly: props.readOnly,
+    theme: "snow",
+    bounds: document.body,
+    debug: "warn",
+    modules: {
+        // 宸ュ叿鏍忛厤缃�
+        toolbar: {
+            container: [
+                ["bold", "italic", "underline", "strike"],       // 鍔犵矖 鏂滀綋 涓嬪垝绾� 鍒犻櫎绾�
+                ["blockquote", "code-block"],                    // 寮曠敤  浠g爜鍧�
+                [{ list: "ordered" }, { list: "bullet"} ],       // 鏈夊簭銆佹棤搴忓垪琛�
+                [{ indent: "-1" }, { indent: "+1" }],            // 缂╄繘
+                [{ size: ["small", false, "large", "huge"] }],   // 瀛椾綋澶у皬
+                [{ header: [1, 2, 3, 4, 5, 6, false] }],         // 鏍囬
+                [{ color: [] }, { background: [] }],             // 瀛椾綋棰滆壊銆佸瓧浣撹儗鏅鑹�
+                [{ align: [] }],                                 // 瀵归綈鏂瑰紡
+                ["clean"],                                       // 娓呴櫎鏂囨湰鏍煎紡
+                ["link", "image", "video"]                       // 閾炬帴銆佸浘鐗囥�佽棰�
+            ],
+            handlers: {
+                image: function (value: any) {
+                    if (value) {
+                        // 璋冪敤element鍥剧墖涓婁紶
+                        (document.querySelector(".editor-img-uploader>.el-upload") as HTMLDivElement)?.click();
+                    } else {
+                        Quill.format("image", true);
+                    }
+                },
+            },
+        }
+    },
+    placeholder: '璇疯緭鍏ュ唴瀹�',
+    readOnly: props.readOnly,
 });
 
 const styles = computed(() => {
-  let style: any = {};
-  if (props.minHeight) {
-    style.minHeight = `${props.minHeight}px`;
-  }
-  if (props.height) {
-    style.height = `${props.height}px`;
-  }
-  return style;
+    let style: any = {};
+    if (props.minHeight) {
+        style.minHeight = `${props.minHeight}px`;
+    }
+    if (props.height) {
+        style.height = `${props.height}px`;
+    }
+    return style;
 })
 
 const content = ref("");
 watch(() => props.modelValue, (v) => {
-  if (v !== content.value) {
-    content.value = v === undefined ? "<p></p>" : v;
-  }
+    if (v !== content.value) {
+        content.value = v === undefined ? "<p></p>" : v;
+    }
 }, { immediate: true });
 
 // 鍥剧墖涓婁紶鎴愬姛杩斿洖鍥剧墖鍦板潃
 const handleUploadSuccess = (res: any) => {
-  // 鑾峰彇瀵屾枃鏈疄渚�
-  let quill = toRaw(myQuillEditor.value).getQuill();
-  // 濡傛灉涓婁紶鎴愬姛
-  if (res.code === 200) {
-    // 鑾峰彇鍏夋爣浣嶇疆
-    let length = quill.selection.savedRange.index;
-    // 鎻掑叆鍥剧墖锛宺es涓烘湇鍔″櫒杩斿洖鐨勫浘鐗囬摼鎺ュ湴鍧�
-    quill.insertEmbed(length, "image", res.data.url);
-    // 璋冩暣鍏夋爣鍒版渶鍚�
-    quill.setSelection(length + 1);
-    proxy?.$modal.closeLoading();
-  } else {
-    proxy?.$modal.loading(res.msg);
-    proxy?.$modal.closeLoading();
-  }
+    // 鑾峰彇瀵屾枃鏈疄渚�
+    let quill = toRaw(myQuillEditor.value).getQuill();
+    // 濡傛灉涓婁紶鎴愬姛
+    if (res.code === 200) {
+        // 鑾峰彇鍏夋爣浣嶇疆
+        let length = quill.selection.savedRange.index;
+        // 鎻掑叆鍥剧墖锛宺es涓烘湇鍔″櫒杩斿洖鐨勫浘鐗囬摼鎺ュ湴鍧�
+        quill.insertEmbed(length, "image", res.data.url);
+        // 璋冩暣鍏夋爣鍒版渶鍚�
+        quill.setSelection(length + 1);
+        proxy?.$modal.closeLoading();
+    } else {
+        proxy?.$modal.loading(res.msg);
+        proxy?.$modal.closeLoading();
+    }
 }
 
 // 鍥剧墖涓婁紶鍓嶆嫤鎴�
 const handleBeforeUpload = (file: any) => {
-  // 鏍℃鏂囦欢澶у皬
-  if (props.fileSize) {
-    const isLt = file.size / 1024 / 1024 < props.fileSize;
-    if (!isLt) {
-      proxy?.$modal.msgError(`涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 ${props.fileSize} MB!`);
-      return false;
+    // 鏍℃鏂囦欢澶у皬
+    if (props.fileSize) {
+        const isLt = file.size / 1024 / 1024 < props.fileSize;
+        if (!isLt) {
+            proxy?.$modal.msgError(`涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 ${props.fileSize} MB!`);
+            return false;
+        }
     }
-  }
-  proxy?.$modal.loading('姝e湪涓婁紶鏂囦欢锛岃绋嶅��...');
-  return true;
+    proxy?.$modal.loading('姝e湪涓婁紶鏂囦欢锛岃绋嶅��...');
+    return true;
 }
 
 // 鍥剧墖澶辫触鎷︽埅
 const handleUploadError = (err: any) => {
-  console.error(err);
-  proxy?.$modal.msgError('涓婁紶鏂囦欢澶辫触');
+    console.error(err);
+    proxy?.$modal.msgError('涓婁紶鏂囦欢澶辫触');
 }
 </script>
-
-<template>
-	<div>
-		<el-upload
-			:action="upload.url"
-			:before-upload="handleBeforeUpload"
-			:on-success="handleUploadSuccess"
-			:on-error="handleUploadError"
-			class="editor-img-uploader"
-			name="file"
-			:show-file-list="false"
-			:headers="upload.headers"
-			style="display: none"
-			v-if="type === 'url'"
-		>
-		</el-upload>
-		<div class="editor">
-			<quill-editor
-				ref="myQuillEditor"
-				v-model:content="content"
-				contentType="html"
-				@textChange="(e: any) => $emit('update:modelValue', content)"
-				:options="options"
-				:style="styles"
-			/>
-		</div>
-	</div>
-</template>
 
 <style>
 .editor, .ql-toolbar {
diff --git a/src/components/FileUpload/index.vue b/src/components/FileUpload/index.vue
index cc24f36..9d8f742 100644
--- a/src/components/FileUpload/index.vue
+++ b/src/components/FileUpload/index.vue
@@ -1,3 +1,47 @@
+<template>
+  <div class="upload-file">
+    <el-upload
+      multiple
+      :action="uploadFileUrl"
+      :before-upload="handleBeforeUpload"
+      :file-list="fileList"
+      :limit="limit"
+      :on-error="handleUploadError"
+      :on-exceed="handleExceed"
+      :on-success="handleUploadSuccess"
+      :show-file-list="false"
+      :headers="headers"
+      class="upload-file-uploader"
+      ref="fileUploadRef"
+    >
+      <!-- 涓婁紶鎸夐挳 -->
+      <el-button type="primary">閫夊彇鏂囦欢</el-button>
+    </el-upload>
+    <!-- 涓婁紶鎻愮ず -->
+    <div class="el-upload__tip" v-if="showTip">
+      璇蜂笂浼�
+      <template v-if="fileSize">
+        澶у皬涓嶈秴杩� <b style="color: #f56c6c">{{ fileSize }}MB</b>
+      </template>
+      <template v-if="fileType">
+        鏍煎紡涓� <b style="color: #f56c6c">{{ fileType.join("/") }}</b>
+      </template>
+      鐨勬枃浠�
+    </div>
+    <!-- 鏂囦欢鍒楄〃 -->
+    <transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
+      <li :key="file.uid" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList">
+        <el-link :href="`${file.url}`" :underline="false" target="_blank">
+          <span class="el-icon-document"> {{ getFileName(file.name) }} </span>
+        </el-link>
+        <div class="ele-upload-list__item-content-action">
+          <el-link :underline="false" @click="handleDelete(index)" type="danger">鍒犻櫎</el-link>
+        </div>
+      </li>
+    </transition-group>
+  </div>
+</template>
+
 <script setup lang="ts">
 import { getToken } from "@/utils/auth";
 import { listByIds, delOss } from "@/api/system/oss";
@@ -5,27 +49,27 @@
 import { ElUpload, UploadFile } from "element-plus";
 
 const props = defineProps({
-  modelValue: [String, Object, Array],
-  // 鏁伴噺闄愬埗
-  limit: {
-    type: Number,
-    default: 5,
-  },
-  // 澶у皬闄愬埗(MB)
-  fileSize: {
-    type: Number,
-    default: 5,
-  },
-  // 鏂囦欢绫诲瀷, 渚嬪['png', 'jpg', 'jpeg']
-  fileType: {
-    type: Array,
-    default: () => ["doc", "xls", "ppt", "txt", "pdf"],
-  },
-  // 鏄惁鏄剧ず鎻愮ず
-  isShowTip: {
-    type: Boolean,
-    default: true
-  }
+    modelValue: [String, Object, Array],
+    // 鏁伴噺闄愬埗
+    limit: {
+        type: Number,
+        default: 5,
+    },
+    // 澶у皬闄愬埗(MB)
+    fileSize: {
+        type: Number,
+        default: 5,
+    },
+    // 鏂囦欢绫诲瀷, 渚嬪['png', 'jpg', 'jpeg']
+    fileType: {
+        type: Array,
+        default: () => ["doc", "xls", "ppt", "txt", "pdf"],
+    },
+    // 鏄惁鏄剧ず鎻愮ず
+    isShowTip: {
+        type: Boolean,
+        default: true
+    }
 });
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
@@ -39,171 +83,127 @@
 
 const fileList = ref<any[]>([]);
 const showTip = computed(
-  () => props.isShowTip && (props.fileType || props.fileSize)
+    () => props.isShowTip && (props.fileType || props.fileSize)
 );
 
 const fileUploadRef = ref(ElUpload);
 
 watch(() => props.modelValue, async val => {
-  if (val) {
-    let temp = 1;
-    // 棣栧厛灏嗗�艰浆涓烘暟缁�
-    let list = [];
-    if (Array.isArray(val)) {
-      list = val;
-    } else {
-      const res =  await listByIds(val as string)
-      list = res.data.map((oss) => {
-          const data = { name: oss.originalName, url: oss.url, ossId: oss.ossId };
-          return data;
+    if (val) {
+        let temp = 1;
+        // 棣栧厛灏嗗�艰浆涓烘暟缁�
+        let list = [];
+        if (Array.isArray(val)) {
+            list = val;
+        } else {
+            const res =  await listByIds(val as string)
+            list = res.data.map((oss) => {
+                const data = { name: oss.originalName, url: oss.url, ossId: oss.ossId };
+                return data;
+            });
+        }
+        // 鐒跺悗灏嗘暟缁勮浆涓哄璞℃暟缁�
+        fileList.value = list.map(item => {
+            item = {name: item.name, url: item.url, ossId: item.ossId};
+            item.uid = item.uid || new Date().getTime() + temp++;
+            return item;
         });
+    } else {
+        fileList.value = [];
+        return [];
     }
-    // 鐒跺悗灏嗘暟缁勮浆涓哄璞℃暟缁�
-    fileList.value = list.map(item => {
-      item = {name: item.name, url: item.url, ossId: item.ossId};
-      item.uid = item.uid || new Date().getTime() + temp++;
-      return item;
-    });
-  } else {
-    fileList.value = [];
-    return [];
-  }
 },{ deep: true, immediate: true });
 
 // 涓婁紶鍓嶆牎妫�鏍煎紡鍜屽ぇ灏�
 const handleBeforeUpload = (file: any) => {
-  // 鏍℃鏂囦欢绫诲瀷
-  if (props.fileType.length) {
-    const fileName = file.name.split('.');
-    const fileExt = fileName[fileName.length - 1];
-    const isTypeOk = props.fileType.indexOf(fileExt) >= 0;
-    if (!isTypeOk) {
-      proxy?.$modal.msgError(`鏂囦欢鏍煎紡涓嶆纭�, 璇蜂笂浼�${props.fileType.join("/")}鏍煎紡鏂囦欢!`);
-      return false;
+    // 鏍℃鏂囦欢绫诲瀷
+    if (props.fileType.length) {
+        const fileName = file.name.split('.');
+        const fileExt = fileName[fileName.length - 1];
+        const isTypeOk = props.fileType.indexOf(fileExt) >= 0;
+        if (!isTypeOk) {
+            proxy?.$modal.msgError(`鏂囦欢鏍煎紡涓嶆纭�, 璇蜂笂浼�${props.fileType.join("/")}鏍煎紡鏂囦欢!`);
+            return false;
+        }
     }
-  }
-  // 鏍℃鏂囦欢澶у皬
-  if (props.fileSize) {
-    const isLt = file.size / 1024 / 1024 < props.fileSize;
-    if (!isLt) {
-      proxy?.$modal.msgError(`涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 ${props.fileSize} MB!`);
-      return false;
+    // 鏍℃鏂囦欢澶у皬
+    if (props.fileSize) {
+        const isLt = file.size / 1024 / 1024 < props.fileSize;
+        if (!isLt) {
+            proxy?.$modal.msgError(`涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 ${props.fileSize} MB!`);
+            return false;
+        }
     }
-  }
-  proxy?.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
-  number.value++;
-  return true;
+    proxy?.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
+    number.value++;
+    return true;
 }
 
 // 鏂囦欢涓暟瓒呭嚭
 const handleExceed = () => {
-  proxy?.$modal.msgError(`涓婁紶鏂囦欢鏁伴噺涓嶈兘瓒呰繃 ${props.limit} 涓�!`);
+    proxy?.$modal.msgError(`涓婁紶鏂囦欢鏁伴噺涓嶈兘瓒呰繃 ${props.limit} 涓�!`);
 }
 
 // 涓婁紶澶辫触
 const handleUploadError = () => {
-  proxy?.$modal.msgError("涓婁紶鏂囦欢澶辫触");
+    proxy?.$modal.msgError("涓婁紶鏂囦欢澶辫触");
 }
 
 // 涓婁紶鎴愬姛鍥炶皟
 const handleUploadSuccess = (res:any, file: UploadFile) => {
-  if (res.code === 200) {
-    uploadList.value.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId });
-    uploadedSuccessfully();
-  } else {
-    number.value--;
-    proxy?.$modal.closeLoading();
-    proxy?.$modal.msgError(res.msg);
-    fileUploadRef.value.handleRemove(file);
-    uploadedSuccessfully();
-  }
+    if (res.code === 200) {
+        uploadList.value.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId });
+        uploadedSuccessfully();
+    } else {
+        number.value--;
+        proxy?.$modal.closeLoading();
+        proxy?.$modal.msgError(res.msg);
+        fileUploadRef.value.handleRemove(file);
+        uploadedSuccessfully();
+    }
 }
 
 // 鍒犻櫎鏂囦欢
 const handleDelete = (index: number) => {
-  let ossId = fileList.value[index].ossId;
-  delOss(ossId);
-  fileList.value.splice(index, 1);
-  emit("update:modelValue", listToString(fileList.value));
+    let ossId = fileList.value[index].ossId;
+    delOss(ossId);
+    fileList.value.splice(index, 1);
+    emit("update:modelValue", listToString(fileList.value));
 }
 
 // 涓婁紶缁撴潫澶勭悊
 const uploadedSuccessfully =() => {
-  if (number.value > 0 && uploadList.value.length === number.value) {
-    fileList.value = fileList.value.filter(f => f.url !== undefined).concat(uploadList.value);
-    uploadList.value = [];
-    number.value = 0;
-    emit("update:modelValue", listToString(fileList.value));
-    proxy?.$modal.closeLoading();
-  }
+    if (number.value > 0 && uploadList.value.length === number.value) {
+        fileList.value = fileList.value.filter(f => f.url !== undefined).concat(uploadList.value);
+        uploadList.value = [];
+        number.value = 0;
+        emit("update:modelValue", listToString(fileList.value));
+        proxy?.$modal.closeLoading();
+    }
 }
 
 // 鑾峰彇鏂囦欢鍚嶇О
 const getFileName = (name: string) => {
-  // 濡傛灉鏄痷rl閭d箞鍙栨渶鍚庣殑鍚嶅瓧 濡傛灉涓嶆槸鐩存帴杩斿洖
-  if (name.lastIndexOf("/") > -1) {
-    return name.slice(name.lastIndexOf("/") + 1);
-  } else {
-    return name;
-  }
+    // 濡傛灉鏄痷rl閭d箞鍙栨渶鍚庣殑鍚嶅瓧 濡傛灉涓嶆槸鐩存帴杩斿洖
+    if (name.lastIndexOf("/") > -1) {
+        return name.slice(name.lastIndexOf("/") + 1);
+    } else {
+        return name;
+    }
 }
 
 // 瀵硅薄杞垚鎸囧畾瀛楃涓插垎闅�
 const listToString = (list: any[], separator?: string) => {
-  let strs = "";
-  separator = separator || ",";
-  list.forEach(item => {
-    if (item.ossId) {
-      strs += item.ossId + separator;
-    }
-  })
-  return strs != "" ? strs.substring(0, strs.length - 1) : "";
+    let strs = "";
+    separator = separator || ",";
+    list.forEach(item => {
+        if (item.ossId) {
+            strs += item.ossId + separator;
+        }
+    })
+    return strs != "" ? strs.substring(0, strs.length - 1) : "";
 }
 </script>
-
-<template>
-	<div class="upload-file">
-		<el-upload
-			multiple
-			:action="uploadFileUrl"
-			:before-upload="handleBeforeUpload"
-			:file-list="fileList"
-			:limit="limit"
-			:on-error="handleUploadError"
-			:on-exceed="handleExceed"
-			:on-success="handleUploadSuccess"
-			:show-file-list="false"
-			:headers="headers"
-			class="upload-file-uploader"
-			ref="fileUploadRef"
-		>
-			<!-- 涓婁紶鎸夐挳 -->
-			<el-button type="primary">閫夊彇鏂囦欢</el-button>
-		</el-upload>
-		<!-- 涓婁紶鎻愮ず -->
-		<div class="el-upload__tip" v-if="showTip">
-			璇蜂笂浼�
-			<template v-if="fileSize">
-				澶у皬涓嶈秴杩� <b style="color: #f56c6c">{{ fileSize }}MB</b>
-			</template>
-			<template v-if="fileType">
-				鏍煎紡涓� <b style="color: #f56c6c">{{ fileType.join("/") }}</b>
-			</template>
-			鐨勬枃浠�
-		</div>
-		<!-- 鏂囦欢鍒楄〃 -->
-		<transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
-			<li :key="file.uid" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList">
-				<el-link :href="`${file.url}`" :underline="false" target="_blank">
-					<span class="el-icon-document"> {{ getFileName(file.name) }} </span>
-				</el-link>
-				<div class="ele-upload-list__item-content-action">
-					<el-link :underline="false" @click="handleDelete(index)" type="danger">鍒犻櫎</el-link>
-				</div>
-			</li>
-		</transition-group>
-	</div>
-</template>
 
 <style scoped lang="scss">
 .upload-file-uploader {
diff --git a/src/components/Hamburger/index.vue b/src/components/Hamburger/index.vue
index ab3c60f..a9ed788 100644
--- a/src/components/Hamburger/index.vue
+++ b/src/components/Hamburger/index.vue
@@ -13,13 +13,13 @@
 </script>
 
 <template>
-	<div style="padding: 0 15px;" @click="toggleClick">
-		<svg :class="{'is-active':isActive}" class="hamburger" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="64" height="64">
-			<path
-				d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z"
-			/>
-		</svg>
-	</div>
+  <div style="padding: 0 15px;" @click="toggleClick">
+    <svg :class="{'is-active':isActive}" class="hamburger" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="64" height="64">
+      <path
+        d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z"
+      />
+    </svg>
+  </div>
 </template>
 
 <style scoped>
diff --git a/src/components/HeaderSearch/index.vue b/src/components/HeaderSearch/index.vue
index e6b9531..a8fc1c8 100644
--- a/src/components/HeaderSearch/index.vue
+++ b/src/components/HeaderSearch/index.vue
@@ -122,22 +122,22 @@
 </script>
 
 <template>
-	<div :class="{ 'show': show }" class="header-search">
-		<svg-icon class-name="search-icon" icon-class="search" @click.stop="click" />
-		<el-select
-			ref="headerSearchSelectRef"
-			v-model="search"
-			:remote-method="querySearch"
-			filterable
-			default-first-option
-			remote
-			placeholder="Search"
-			class="header-search-select"
-			@change="change"
-		>
-			<el-option v-for="option in options" :key="option.item.path" :value="option.item" :label="option.item.title.join(' > ')" />
-		</el-select>
-	</div>
+  <div :class="{ 'show': show }" class="header-search">
+    <svg-icon class-name="search-icon" icon-class="search" @click.stop="click" />
+    <el-select
+      ref="headerSearchSelectRef"
+      v-model="search"
+      :remote-method="querySearch"
+      filterable
+      default-first-option
+      remote
+      placeholder="Search"
+      class="header-search-select"
+      @change="change"
+    >
+      <el-option v-for="option in options" :key="option.item.path" :value="option.item" :label="option.item.title.join(' > ')" />
+    </el-select>
+  </div>
 </template>
 
 <style lang="scss" scoped>
diff --git a/src/components/IconSelect/index.vue b/src/components/IconSelect/index.vue
index 97c601e..63afe85 100644
--- a/src/components/IconSelect/index.vue
+++ b/src/components/IconSelect/index.vue
@@ -44,34 +44,34 @@
 </script>
 
 <template>
-	<div class="relative" :style="{ width: width }">
-		<el-input v-model="modelValue" readonly @click="visible = !visible" placeholder="鐐瑰嚮閫夋嫨鍥炬爣">
-			<template #prepend>
-				<svg-icon :icon-class="modelValue as string"></svg-icon>
-			</template>
-		</el-input>
+  <div class="relative" :style="{ width: width }">
+    <el-input v-model="modelValue" readonly @click="visible = !visible" placeholder="鐐瑰嚮閫夋嫨鍥炬爣">
+      <template #prepend>
+        <svg-icon :icon-class="modelValue as string"></svg-icon>
+      </template>
+    </el-input>
 
-		<el-popover shadow="none" :visible="visible" placement="bottom-end" trigger="click" :width="450">
-			<template #reference>
-				<div @click="visible = !visible" class="cursor-pointer text-[#999] absolute right-[10px] top-0 height-[32px] leading-[32px]">
-					<i-ep-caret-top v-show="visible"></i-ep-caret-top>
-					<i-ep-caret-bottom v-show="!visible"></i-ep-caret-bottom>
-				</div>
-			</template>
+    <el-popover shadow="none" :visible="visible" placement="bottom-end" trigger="click" :width="450">
+      <template #reference>
+        <div @click="visible = !visible" class="cursor-pointer text-[#999] absolute right-[10px] top-0 height-[32px] leading-[32px]">
+          <i-ep-caret-top v-show="visible"></i-ep-caret-top>
+          <i-ep-caret-bottom v-show="!visible"></i-ep-caret-bottom>
+        </div>
+      </template>
 
-			<el-input class="p-2" v-model="filterValue" placeholder="鎼滅储鍥炬爣" clearable @input="filterIcons" />
+      <el-input class="p-2" v-model="filterValue" placeholder="鎼滅储鍥炬爣" clearable @input="filterIcons" />
 
-			<el-scrollbar height="w-[200px]">
-				<ul class="icon-list">
-					<el-tooltip v-for="(iconName, index) in iconNames" :key="index" :content="iconName" placement="bottom" effect="light">
-						<li class="icon-item" @click="selectedIcon(iconName)">
-							<svg-icon color="var(--el-text-color-regular)" :icon-class="iconName" />
-						</li>
-					</el-tooltip>
-				</ul>
-			</el-scrollbar>
-		</el-popover>
-	</div>
+      <el-scrollbar height="w-[200px]">
+        <ul class="icon-list">
+          <el-tooltip v-for="(iconName, index) in iconNames" :key="index" :content="iconName" placement="bottom" effect="light">
+            <li class="icon-item" @click="selectedIcon(iconName)">
+              <svg-icon color="var(--el-text-color-regular)" :icon-class="iconName" />
+            </li>
+          </el-tooltip>
+        </ul>
+      </el-scrollbar>
+    </el-popover>
+  </div>
 </template>
 
 <style scoped lang="scss">
diff --git a/src/components/IconSelect/requireIcons.ts b/src/components/IconSelect/requireIcons.ts
index 31ed49c..9f06d69 100644
--- a/src/components/IconSelect/requireIcons.ts
+++ b/src/components/IconSelect/requireIcons.ts
@@ -1,7 +1,7 @@
 const icons: string[] = [];
 const modules = import.meta.glob('./../../assets/icons/svg/*.svg');
 for (const path in modules) {
-	const p = path.split('assets/icons/svg/')[1].split('.svg')[0];
-	icons.push(p);
+  const p = path.split('assets/icons/svg/')[1].split('.svg')[0];
+  icons.push(p);
 }
 export default icons;
diff --git a/src/components/ImagePreview/index.vue b/src/components/ImagePreview/index.vue
index 45f8326..9b244f8 100644
--- a/src/components/ImagePreview/index.vue
+++ b/src/components/ImagePreview/index.vue
@@ -44,13 +44,13 @@
 </script>
 
 <template>
-	<el-image :src="`${realSrc}`" fit="cover" :style="`width:${realWidth};height:${realHeight};`" :preview-src-list="realSrcList" preview-teleported>
-		<template #error>
-			<div class="image-slot">
-				<el-icon><picture-filled /></el-icon>
-			</div>
-		</template>
-	</el-image>
+  <el-image :src="`${realSrc}`" fit="cover" :style="`width:${realWidth};height:${realHeight};`" :preview-src-list="realSrcList" preview-teleported>
+    <template #error>
+      <div class="image-slot">
+        <el-icon><picture-filled /></el-icon>
+      </div>
+    </template>
+  </el-image>
 </template>
 
 <style lang="scss" scoped>
diff --git a/src/components/ImageUpload/index.vue b/src/components/ImageUpload/index.vue
index 9753d0c..57697fa 100644
--- a/src/components/ImageUpload/index.vue
+++ b/src/components/ImageUpload/index.vue
@@ -1,3 +1,42 @@
+<template>
+  <div class="component-upload-image">
+    <el-upload
+      multiple
+      :action="uploadImgUrl"
+      list-type="picture-card"
+      :on-success="handleUploadSuccess"
+      :before-upload="handleBeforeUpload"
+      :limit="limit"
+      :on-error="handleUploadError"
+      :on-exceed="handleExceed"
+      ref="imageUpload"
+      :before-remove="handleDelete"
+      :show-file-list="true"
+      :headers="headers"
+      :file-list="fileList"
+      :on-preview="handlePictureCardPreview"
+      :class="{ hide: fileList.length >= limit }"
+    >
+      <el-icon class="avatar-uploader-icon"><plus /></el-icon>
+    </el-upload>
+    <!-- 涓婁紶鎻愮ず -->
+    <div class="el-upload__tip" v-if="showTip">
+      璇蜂笂浼�
+      <template v-if="fileSize">
+        澶у皬涓嶈秴杩� <b style="color: #f56c6c">{{ fileSize }}MB</b>
+      </template>
+      <template v-if="fileType">
+        鏍煎紡涓� <b style="color: #f56c6c">{{ fileType.join("/") }}</b>
+      </template>
+      鐨勬枃浠�
+    </div>
+
+    <el-dialog v-model="dialogVisible" title="棰勮" width="800px" append-to-body>
+      <img :src="dialogImageUrl" style="display: block; max-width: 100%; margin: 0 auto" />
+    </el-dialog>
+  </div>
+</template>
+
 <script setup lang="ts">
 import { getToken } from "@/utils/auth";
 import { listByIds, delOss } from "@/api/system/oss";
@@ -6,27 +45,27 @@
 import { ElUpload, UploadFile } from "element-plus";
 
 const props = defineProps({
-  modelValue: [String, Object, Array],
-  // 鍥剧墖鏁伴噺闄愬埗
-  limit: {
-    type: Number,
-    default: 5,
-  },
-  // 澶у皬闄愬埗(MB)
-  fileSize: {
-    type: Number,
-    default: 5,
-  },
-  // 鏂囦欢绫诲瀷, 渚嬪['png', 'jpg', 'jpeg']
-  fileType: {
-    type: Array as PropType<string[]>,
-    default: () => ["png", "jpg", "jpeg"],
-  },
-  // 鏄惁鏄剧ず鎻愮ず
-  isShowTip: {
-    type: Boolean,
-    default: true
-  },
+    modelValue: [String, Object, Array],
+    // 鍥剧墖鏁伴噺闄愬埗
+    limit: {
+        type: Number,
+        default: 5,
+    },
+    // 澶у皬闄愬埗(MB)
+    fileSize: {
+        type: Number,
+        default: 5,
+    },
+    // 鏂囦欢绫诲瀷, 渚嬪['png', 'jpg', 'jpeg']
+    fileType: {
+        type: Array as PropType<string[]>,
+        default: () => ["png", "jpg", "jpeg"],
+    },
+    // 鏄惁鏄剧ず鎻愮ず
+    isShowTip: {
+        type: Boolean,
+        default: true
+    },
 });
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
@@ -42,178 +81,139 @@
 
 const fileList = ref<any[]>([]);
 const showTip = computed(
-  () => props.isShowTip && (props.fileType || props.fileSize)
+    () => props.isShowTip && (props.fileType || props.fileSize)
 );
 
 const imageUploadRef = ref(ElUpload);
 
 watch(() => props.modelValue, async val => {
-  if (val) {
-    // 棣栧厛灏嗗�艰浆涓烘暟缁�
-    let list:OssVO[] = [];
-    if (Array.isArray(val)) {
-      list = val as OssVO[];
+    if (val) {
+        // 棣栧厛灏嗗�艰浆涓烘暟缁�
+        let list:OssVO[] = [];
+        if (Array.isArray(val)) {
+            list = val as OssVO[];
+        } else {
+            const res = await listByIds(val as string)
+            list = res.data
+        }
+        // 鐒跺悗灏嗘暟缁勮浆涓哄璞℃暟缁�
+        fileList.value = list.map(item => {
+            // 瀛楃涓插洖鏄惧鐞� 濡傛灉姝ゅ瀛樼殑鏄痷rl鍙洿鎺ュ洖鏄� 濡傛灉瀛樼殑鏄痠d闇�瑕佽皟鐢ㄦ帴鍙f煡鍑烘潵
+            let itemData;
+            if (typeof item === "string") {
+                itemData = { name: item, url: item };
+            } else {
+                // 姝ゅname浣跨敤ossId 闃叉鍒犻櫎鍑虹幇閲嶅悕
+                itemData = { name: item.ossId, url: item.url, ossId: item.ossId };
+            }
+            return itemData;
+        });
     } else {
-      const res = await listByIds(val as string)
-      list = res.data
+        fileList.value = [];
+        return [];
     }
-    // 鐒跺悗灏嗘暟缁勮浆涓哄璞℃暟缁�
-    fileList.value = list.map(item => {
-      // 瀛楃涓插洖鏄惧鐞� 濡傛灉姝ゅ瀛樼殑鏄痷rl鍙洿鎺ュ洖鏄� 濡傛灉瀛樼殑鏄痠d闇�瑕佽皟鐢ㄦ帴鍙f煡鍑烘潵
-      let itemData;
-      if (typeof item === "string") {
-        itemData = { name: item, url: item };
-      } else {
-        // 姝ゅname浣跨敤ossId 闃叉鍒犻櫎鍑虹幇閲嶅悕
-        itemData = { name: item.ossId, url: item.url, ossId: item.ossId };
-      }
-      return itemData;
-    });
-  } else {
-    fileList.value = [];
-    return [];
-  }
 },{ deep: true, immediate: true });
 
 /** 涓婁紶鍓峫oading鍔犺浇 */
 const handleBeforeUpload = (file: any) => {
-  let isImg = false;
-  if (props.fileType.length) {
-    let fileExtension = "";
-    if (file.name.lastIndexOf(".") > -1) {
-      fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
+    let isImg = false;
+    if (props.fileType.length) {
+        let fileExtension = "";
+        if (file.name.lastIndexOf(".") > -1) {
+            fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
+        }
+        isImg = props.fileType.some((type) => {
+            if (file.type.indexOf(type) > -1) return true;
+            if (fileExtension && fileExtension.indexOf(type) > -1) return true;
+            return false;
+        });
+    } else {
+        isImg = file.type.indexOf("image") > -1;
     }
-    isImg = props.fileType.some((type) => {
-      if (file.type.indexOf(type) > -1) return true;
-      if (fileExtension && fileExtension.indexOf(type) > -1) return true;
-      return false;
-    });
-  } else {
-    isImg = file.type.indexOf("image") > -1;
-  }
-  if (!isImg) {
-    proxy?.$modal.msgError(
-      `鏂囦欢鏍煎紡涓嶆纭�, 璇蜂笂浼�${props.fileType.join("/")}鍥剧墖鏍煎紡鏂囦欢!`
-    );
-    return false;
-  }
-  if (props.fileSize) {
-    const isLt = file.size / 1024 / 1024 < props.fileSize;
-    if (!isLt) {
-      proxy?.$modal.msgError(`涓婁紶澶村儚鍥剧墖澶у皬涓嶈兘瓒呰繃 ${props.fileSize} MB!`);
-      return false;
+    if (!isImg) {
+        proxy?.$modal.msgError(
+            `鏂囦欢鏍煎紡涓嶆纭�, 璇蜂笂浼�${props.fileType.join("/")}鍥剧墖鏍煎紡鏂囦欢!`
+        );
+        return false;
     }
-  }
-  proxy?.$modal.loading("姝e湪涓婁紶鍥剧墖锛岃绋嶅��...");
-  number.value++;
+    if (props.fileSize) {
+        const isLt = file.size / 1024 / 1024 < props.fileSize;
+        if (!isLt) {
+            proxy?.$modal.msgError(`涓婁紶澶村儚鍥剧墖澶у皬涓嶈兘瓒呰繃 ${props.fileSize} MB!`);
+            return false;
+        }
+    }
+    proxy?.$modal.loading("姝e湪涓婁紶鍥剧墖锛岃绋嶅��...");
+    number.value++;
 }
 
 // 鏂囦欢涓暟瓒呭嚭
 const handleExceed = () => {
-  proxy?.$modal.msgError(`涓婁紶鏂囦欢鏁伴噺涓嶈兘瓒呰繃 ${props.limit} 涓�!`);
+    proxy?.$modal.msgError(`涓婁紶鏂囦欢鏁伴噺涓嶈兘瓒呰繃 ${props.limit} 涓�!`);
 }
 
 // 涓婁紶鎴愬姛鍥炶皟
 const handleUploadSuccess = (res: any, file: UploadFile) => {
-  if (res.code === 200) {
-    uploadList.value.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId });
-    uploadedSuccessfully();
-  } else {
-    number.value--;
-    proxy?.$modal.closeLoading();
-    proxy?.$modal.msgError(res.msg);
-    imageUploadRef.value.handleRemove(file);
-    uploadedSuccessfully();
-  }
+    if (res.code === 200) {
+        uploadList.value.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId });
+        uploadedSuccessfully();
+    } else {
+        number.value--;
+        proxy?.$modal.closeLoading();
+        proxy?.$modal.msgError(res.msg);
+        imageUploadRef.value.handleRemove(file);
+        uploadedSuccessfully();
+    }
 }
 
 // 鍒犻櫎鍥剧墖
 const handleDelete = (file: UploadFile): boolean => {
-  const findex = fileList.value.map(f => f.name).indexOf(file.name);
-  if (findex > -1 && uploadList.value.length === number.value) {
-    let ossId = fileList.value[findex].ossId;
-    delOss(ossId);
-    fileList.value.splice(findex, 1);
-    emit("update:modelValue", listToString(fileList.value));
-    return false;
-  }
-  return true;
+    const findex = fileList.value.map(f => f.name).indexOf(file.name);
+    if (findex > -1 && uploadList.value.length === number.value) {
+        let ossId = fileList.value[findex].ossId;
+        delOss(ossId);
+        fileList.value.splice(findex, 1);
+        emit("update:modelValue", listToString(fileList.value));
+        return false;
+    }
+    return true;
 }
 
 // 涓婁紶缁撴潫澶勭悊
 const uploadedSuccessfully = () => {
-  if (number.value > 0 && uploadList.value.length === number.value) {
-    fileList.value = fileList.value.filter(f => f.url !== undefined).concat(uploadList.value);
-    uploadList.value = [];
-    number.value = 0;
-    emit("update:modelValue", listToString(fileList.value));
-    proxy?.$modal.closeLoading();
-  }
+    if (number.value > 0 && uploadList.value.length === number.value) {
+        fileList.value = fileList.value.filter(f => f.url !== undefined).concat(uploadList.value);
+        uploadList.value = [];
+        number.value = 0;
+        emit("update:modelValue", listToString(fileList.value));
+        proxy?.$modal.closeLoading();
+    }
 }
 
 // 涓婁紶澶辫触
 const handleUploadError = () => {
-  proxy?.$modal.msgError("涓婁紶鍥剧墖澶辫触");
-  proxy?.$modal.closeLoading();
+    proxy?.$modal.msgError("涓婁紶鍥剧墖澶辫触");
+    proxy?.$modal.closeLoading();
 }
 
 // 棰勮
 const handlePictureCardPreview = (file: any) => {
-  dialogImageUrl.value = file.url;
-  dialogVisible.value = true;
+    dialogImageUrl.value = file.url;
+    dialogVisible.value = true;
 }
 
 // 瀵硅薄杞垚鎸囧畾瀛楃涓插垎闅�
 const listToString = (list: any[], separator?: string) => {
-  let strs = "";
-  separator = separator || ",";
-  for (let i in list) {
-    if(undefined !== list[i].ossId && list[i].url.indexOf("blob:") !== 0) {
-      strs += list[i].ossId + separator;
+    let strs = "";
+    separator = separator || ",";
+    for (let i in list) {
+        if(undefined !== list[i].ossId && list[i].url.indexOf("blob:") !== 0) {
+            strs += list[i].ossId + separator;
+        }
     }
-  }
-  return strs != "" ? strs.substring(0, strs.length - 1) : "";
+    return strs != "" ? strs.substring(0, strs.length - 1) : "";
 }
 </script>
-
-<template>
-	<div class="component-upload-image">
-		<el-upload
-			multiple
-			:action="uploadImgUrl"
-			list-type="picture-card"
-			:on-success="handleUploadSuccess"
-			:before-upload="handleBeforeUpload"
-			:limit="limit"
-			:on-error="handleUploadError"
-			:on-exceed="handleExceed"
-			ref="imageUpload"
-			:before-remove="handleDelete"
-			:show-file-list="true"
-			:headers="headers"
-			:file-list="fileList"
-			:on-preview="handlePictureCardPreview"
-			:class="{ hide: fileList.length >= limit }"
-		>
-			<el-icon class="avatar-uploader-icon"><plus /></el-icon>
-		</el-upload>
-		<!-- 涓婁紶鎻愮ず -->
-		<div class="el-upload__tip" v-if="showTip">
-			璇蜂笂浼�
-			<template v-if="fileSize">
-				澶у皬涓嶈秴杩� <b style="color: #f56c6c">{{ fileSize }}MB</b>
-			</template>
-			<template v-if="fileType">
-				鏍煎紡涓� <b style="color: #f56c6c">{{ fileType.join("/") }}</b>
-			</template>
-			鐨勬枃浠�
-		</div>
-
-		<el-dialog v-model="dialogVisible" title="棰勮" width="800px" append-to-body>
-			<img :src="dialogImageUrl" style="display: block; max-width: 100%; margin: 0 auto" />
-		</el-dialog>
-	</div>
-</template>
 
 <style scoped lang="scss">
 // .el-upload--picture-card 鎺у埗鍔犲彿閮ㄥ垎
diff --git a/src/components/Pagination/index.vue b/src/components/Pagination/index.vue
index 40bc584..de7b02c 100644
--- a/src/components/Pagination/index.vue
+++ b/src/components/Pagination/index.vue
@@ -1,6 +1,22 @@
+<template>
+  <div :class="{ 'hidden': hidden }" class="pagination-container">
+    <el-pagination
+      :background="background"
+      v-model:current-page="currentPage"
+      v-model:page-size="pageSize"
+      :layout="layout"
+      :page-sizes="pageSizes"
+      :pager-count="pagerCount"
+      :total="total"
+      @size-change="handleSizeChange"
+      @current-change="handleCurrentChange"
+    />
+  </div>
+</template>
+
 <script lang="ts">
 export default {
-  name: 'Pagination'
+    name: 'Pagination'
 }
 </script>
 
@@ -9,100 +25,84 @@
 import { PropType } from "vue";
 
 const props = defineProps({
-  total: {
-    required: true,
-    type: Number
-  },
-  page: {
-    type: Number,
-    default: 1
-  },
-  limit: {
-    type: Number,
-    default: 20
-  },
-  pageSizes: {
-    type: Array as PropType<number[]>,
-    default() {
-      return [10, 20, 30, 50]
+    total: {
+        required: true,
+        type: Number
+    },
+    page: {
+        type: Number,
+        default: 1
+    },
+    limit: {
+        type: Number,
+        default: 20
+    },
+    pageSizes: {
+        type: Array as PropType<number[]>,
+        default() {
+            return [10, 20, 30, 50]
+        }
+    },
+    // 绉诲姩绔〉鐮佹寜閽殑鏁伴噺绔粯璁ゅ��5
+    pagerCount: {
+        type: Number,
+        default: document.body.clientWidth < 992 ? 5 : 7
+    },
+    layout: {
+        type: String,
+        default: 'total, sizes, prev, pager, next, jumper'
+    },
+    background: {
+        type: Boolean,
+        default: true
+    },
+    autoScroll: {
+        type: Boolean,
+        default: true
+    },
+    hidden: {
+        type: Boolean,
+        default: false
+    },
+    float: {
+        type: String,
+        default: 'right'
     }
-  },
-  // 绉诲姩绔〉鐮佹寜閽殑鏁伴噺绔粯璁ゅ��5
-  pagerCount: {
-    type: Number,
-    default: document.body.clientWidth < 992 ? 5 : 7
-  },
-  layout: {
-    type: String,
-    default: 'total, sizes, prev, pager, next, jumper'
-  },
-  background: {
-    type: Boolean,
-    default: true
-  },
-  autoScroll: {
-    type: Boolean,
-    default: true
-  },
-  hidden: {
-    type: Boolean,
-    default: false
-  },
-  float: {
-    type: String,
-    default: 'right'
-  }
 })
 
 const emit = defineEmits(['update:page', 'update:limit', 'pagination']);
 const currentPage = computed({
-  get() {
-    return props.page
-  },
-  set(val) {
-    emit('update:page', val)
-  }
+    get() {
+        return props.page
+    },
+    set(val) {
+        emit('update:page', val)
+    }
 })
 const pageSize = computed({
-  get() {
-    return props.limit
-  },
-  set(val){
-    emit('update:limit', val)
-  }
+    get() {
+        return props.limit
+    },
+    set(val){
+        emit('update:limit', val)
+    }
 })
 function handleSizeChange(val: number) {
-  if (currentPage.value * val > props.total) {
-    currentPage.value = 1
-  }
-  emit('pagination', { page: currentPage.value, limit: val })
-  if (props.autoScroll) {
-    scrollTo(0, 800)
-  }
+    if (currentPage.value * val > props.total) {
+        currentPage.value = 1
+    }
+    emit('pagination', { page: currentPage.value, limit: val })
+    if (props.autoScroll) {
+        scrollTo(0, 800)
+    }
 }
 function handleCurrentChange(val: number) {
-  emit('pagination', { page: val, limit: pageSize.value })
-  if (props.autoScroll) {
-    scrollTo(0, 800)
-  }
+    emit('pagination', { page: val, limit: pageSize.value })
+    if (props.autoScroll) {
+        scrollTo(0, 800)
+    }
 }
 </script>
-
-<template>
-	<div :class="{ 'hidden': hidden }" class="pagination-container">
-		<el-pagination
-			:background="background"
-			v-model:current-page="currentPage"
-			v-model:page-size="pageSize"
-			:layout="layout"
-			:page-sizes="pageSizes"
-			:pager-count="pagerCount"
-			:total="total"
-			@size-change="handleSizeChange"
-			@current-change="handleCurrentChange"
-		/>
-	</div>
-</template>
 
 <style lang="scss" scoped>
 .pagination-container {
diff --git a/src/components/ParentView/index.vue b/src/components/ParentView/index.vue
index 4437b0a..98240ae 100644
--- a/src/components/ParentView/index.vue
+++ b/src/components/ParentView/index.vue
@@ -1,3 +1,3 @@
 <template>
-	<router-view />
+  <router-view />
 </template>
diff --git a/src/components/RightToolbar/index.vue b/src/components/RightToolbar/index.vue
index fd94360..20226d8 100644
--- a/src/components/RightToolbar/index.vue
+++ b/src/components/RightToolbar/index.vue
@@ -1,23 +1,42 @@
+<template>
+  <div class="top-right-btn" :style="style">
+    <el-row>
+      <el-tooltip class="item" effect="dark" :content="showSearch ? '闅愯棌鎼滅储' : '鏄剧ず鎼滅储'" placement="top" v-if="search">
+        <el-button circle icon="Search" @click="toggleSearch()" />
+      </el-tooltip>
+      <el-tooltip class="item" effect="dark" content="鍒锋柊" placement="top">
+        <el-button circle icon="Refresh" @click="refresh()" />
+      </el-tooltip>
+      <el-tooltip class="item" effect="dark" content="鏄鹃殣鍒�" placement="top" v-if="columns">
+        <el-button circle icon="Menu" @click="showColumn()" />
+      </el-tooltip>
+    </el-row>
+    <el-dialog :title="title" v-model="open" append-to-body>
+      <el-transfer :titles="['鏄剧ず', '闅愯棌']" v-model="value" :data="columns" @change="dataChange"></el-transfer>
+    </el-dialog>
+  </div>
+</template>
+
 <script setup lang="ts">
 import { TransferKey } from "element-plus";
 import { PropType } from "vue";
 
 const props = defineProps({
-  showSearch: {
-    type: Boolean,
-    default: true,
-  },
-  columns: {
-    type: Array as PropType<FieldOption[]>,
-  },
-  search: {
-    type: Boolean,
-    default: true,
-  },
-  gutter: {
-    type: Number,
-    default: 10,
-  },
+    showSearch: {
+        type: Boolean,
+        default: true,
+    },
+    columns: {
+        type: Array as PropType<FieldOption[]>,
+    },
+    search: {
+        type: Boolean,
+        default: true,
+    },
+    gutter: {
+        type: Number,
+        default: 10,
+    },
 })
 
 const emits = defineEmits(['update:showSearch', 'queryTable']);
@@ -30,63 +49,44 @@
 const open = ref(false);
 
 const style = computed(() => {
-  const ret: any = {};
-  if (props.gutter) {
-    ret.marginRight = `${props.gutter / 2}px`;
-  }
-  return ret;
+    const ret: any = {};
+    if (props.gutter) {
+        ret.marginRight = `${props.gutter / 2}px`;
+    }
+    return ret;
 });
 
 // 鎼滅储
 function toggleSearch() {
-  emits("update:showSearch", !props.showSearch);
+    emits("update:showSearch", !props.showSearch);
 }
 
 // 鍒锋柊
 function refresh() {
-  emits("queryTable");
+    emits("queryTable");
 }
 
 // 鍙充晶鍒楄〃鍏冪礌鍙樺寲
 function dataChange(data: TransferKey[]) {
-  props.columns?.forEach((item) => {
-    item.visible = !data.includes(item.key);
-  })
+    props.columns?.forEach((item) => {
+        item.visible = !data.includes(item.key);
+    })
 }
 
 // 鎵撳紑鏄鹃殣鍒梔ialog
 const showColumn = () => {
-  open.value = true;
+    open.value = true;
 }
 
 // 鏄鹃殣鍒楀垵濮嬮粯璁ら殣钘忓垪
 onMounted(() => {
-  props.columns?.forEach((item) => {
-    if (!item.visible) {
-      value.value.push(item.key);
-    }
-  })
+    props.columns?.forEach((item) => {
+        if (!item.visible) {
+            value.value.push(item.key);
+        }
+    })
 })
 </script>
-
-<template>
-	<div class="top-right-btn" :style="style">
-		<el-row>
-			<el-tooltip class="item" effect="dark" :content="showSearch ? '闅愯棌鎼滅储' : '鏄剧ず鎼滅储'" placement="top" v-if="search">
-				<el-button circle icon="Search" @click="toggleSearch()" />
-			</el-tooltip>
-			<el-tooltip class="item" effect="dark" content="鍒锋柊" placement="top">
-				<el-button circle icon="Refresh" @click="refresh()" />
-			</el-tooltip>
-			<el-tooltip class="item" effect="dark" content="鏄鹃殣鍒�" placement="top" v-if="columns">
-				<el-button circle icon="Menu" @click="showColumn()" />
-			</el-tooltip>
-		</el-row>
-		<el-dialog :title="title" v-model="open" append-to-body>
-			<el-transfer :titles="['鏄剧ず', '闅愯棌']" v-model="value" :data="columns" @change="dataChange"></el-transfer>
-		</el-dialog>
-	</div>
-</template>
 
 <style lang="scss" scoped>
 :deep(.el-transfer__button) {
diff --git a/src/components/RuoYiDoc/index.vue b/src/components/RuoYiDoc/index.vue
index 9dc9c5f..6dad85c 100644
--- a/src/components/RuoYiDoc/index.vue
+++ b/src/components/RuoYiDoc/index.vue
@@ -1,7 +1,7 @@
 <template>
-	<div>
-		<svg-icon icon-class="question" @click="goto" />
-	</div>
+  <div>
+    <svg-icon icon-class="question" @click="goto" />
+  </div>
 </template>
 
 <script setup>
diff --git a/src/components/RuoYiGit/index.vue b/src/components/RuoYiGit/index.vue
index 3682250..82393eb 100644
--- a/src/components/RuoYiGit/index.vue
+++ b/src/components/RuoYiGit/index.vue
@@ -1,7 +1,7 @@
 <template>
-	<div>
-		<svg-icon icon-class="github" @click="goto" />
-	</div>
+  <div>
+    <svg-icon icon-class="github" @click="goto" />
+  </div>
 </template>
 
 <script setup>
diff --git a/src/components/Screenfull/index.vue b/src/components/Screenfull/index.vue
index 3922f58..2089e30 100644
--- a/src/components/Screenfull/index.vue
+++ b/src/components/Screenfull/index.vue
@@ -1,7 +1,7 @@
 <template>
-	<div>
-		<svg-icon :icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'" @click="toggle" />
-	</div>
+  <div>
+    <svg-icon :icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'" @click="toggle" />
+  </div>
 </template>
 
 <script setup lang="ts">
diff --git a/src/components/SizeSelect/index.vue b/src/components/SizeSelect/index.vue
index fb28e05..268a836 100644
--- a/src/components/SizeSelect/index.vue
+++ b/src/components/SizeSelect/index.vue
@@ -16,20 +16,20 @@
 </script>
 
 <template>
-	<div>
-		<el-dropdown trigger="click" @command="handleSetSize">
-			<div class="size-icon--style">
-				<svg-icon class-name="size-icon" icon-class="size" />
-			</div>
-			<template #dropdown>
-				<el-dropdown-menu>
-					<el-dropdown-item v-for="item of sizeOptions" :key="item.value" :disabled="size === item.value" :command="item.value">
-						{{ item.label }}
-					</el-dropdown-item>
-				</el-dropdown-menu>
-			</template>
-		</el-dropdown>
-	</div>
+  <div>
+    <el-dropdown trigger="click" @command="handleSetSize">
+      <div class="size-icon--style">
+        <svg-icon class-name="size-icon" icon-class="size" />
+      </div>
+      <template #dropdown>
+        <el-dropdown-menu>
+          <el-dropdown-item v-for="item of sizeOptions" :key="item.value" :disabled="size === item.value" :command="item.value">
+            {{ item.label }}
+          </el-dropdown-item>
+        </el-dropdown-menu>
+      </template>
+    </el-dropdown>
+  </div>
 </template>
 
 <style lang="scss" scoped>
diff --git a/src/components/SvgIcon/index.vue b/src/components/SvgIcon/index.vue
index 661ae51..4a858bd 100644
--- a/src/components/SvgIcon/index.vue
+++ b/src/components/SvgIcon/index.vue
@@ -23,9 +23,9 @@
 </script>
 
 <template>
-	<svg :class="svgClass" aria-hidden="true">
-		<use :xlink:href="iconName" :fill="color" />
-	</svg>
+  <svg :class="svgClass" aria-hidden="true">
+    <use :xlink:href="iconName" :fill="color" />
+  </svg>
 </template>
 
 <style scope lang="scss">
diff --git a/src/components/TopNav/index.vue b/src/components/TopNav/index.vue
index ea16377..41e3a11 100644
--- a/src/components/TopNav/index.vue
+++ b/src/components/TopNav/index.vue
@@ -1,3 +1,23 @@
+<template>
+    <el-menu :default-active="activeMenu" mode="horizontal" @select="handleSelect" :ellipsis="false">
+        <template v-for="(item, index) in topMenus">
+            <el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber"
+            ><svg-icon :icon-class="item.meta ? item.meta.icon : '' " /> {{ item.meta?.title }}</el-menu-item
+            >
+        </template>
+
+        <!-- 椤堕儴鑿滃崟瓒呭嚭鏁伴噺鎶樺彔 -->
+        <el-sub-menu :style="{'--theme': theme}" index="more" v-if="topMenus.length > visibleNumber">
+            <template #title>鏇村鑿滃崟</template>
+            <template v-for="(item, index) in topMenus">
+                <el-menu-item :index="item.path" :key="index" v-if="index >= visibleNumber"
+                ><svg-icon :icon-class="item.meta ? item.meta.icon : '' " /> {{ item.meta?.title }}</el-menu-item
+                >
+            </template>
+        </el-sub-menu>
+    </el-menu>
+</template>
+
 <script setup lang="ts">
 import { constantRoutes } from '@/router';
 import { isHttp } from '@/utils/validate';
@@ -129,26 +149,6 @@
   setVisibleNumber()
 })
 </script>
-
-<template>
-	<el-menu :default-active="activeMenu" mode="horizontal" @select="handleSelect" :ellipsis="false">
-		<template v-for="(item, index) in topMenus">
-			<el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber"
-				><svg-icon :icon-class="item.meta ? item.meta.icon : '' " /> {{ item.meta?.title }}</el-menu-item
-			>
-		</template>
-
-		<!-- 椤堕儴鑿滃崟瓒呭嚭鏁伴噺鎶樺彔 -->
-		<el-sub-menu :style="{'--theme': theme}" index="more" v-if="topMenus.length > visibleNumber">
-			<template #title>鏇村鑿滃崟</template>
-			<template v-for="(item, index) in topMenus">
-				<el-menu-item :index="item.path" :key="index" v-if="index >= visibleNumber"
-					><svg-icon :icon-class="item.meta ? item.meta.icon : '' " /> {{ item.meta?.title }}</el-menu-item
-				>
-			</template>
-		</el-sub-menu>
-	</el-menu>
-</template>
 
 <style lang="scss">
 .topmenu-container.el-menu--horizontal > .el-menu-item {
diff --git a/src/components/TreeSelect/index.vue b/src/components/TreeSelect/index.vue
index 8e5f567..0df87f0 100644
--- a/src/components/TreeSelect/index.vue
+++ b/src/components/TreeSelect/index.vue
@@ -128,31 +128,31 @@
 </style>
 
 <template>
-	<div class="el-tree-select">
-		<el-select
-			style="width: 100%"
-			v-model="valueId"
-			ref="treeSelect"
-			:filterable="true"
-			:clearable="true"
-			@clear="clearHandle"
-			:filter-method="selectFilterData"
-			:placeholder="placeholder"
-		>
-			<el-option :value="valueId" :label="valueTitle">
-				<el-tree
-					id="tree-option"
-					ref="selectTree"
-					:accordion="accordion"
-					:data="options"
-					:props="objMap"
-					:node-key="objMap.value"
-					:expand-on-click-node="false"
-					:default-expanded-keys="defaultExpandedKey"
-					:filter-node-method="filterNode"
-					@node-click="handleNodeClick"
-				></el-tree>
-			</el-option>
-		</el-select>
-	</div>
+  <div class="el-tree-select">
+    <el-select
+      style="width: 100%"
+      v-model="valueId"
+      ref="treeSelect"
+      :filterable="true"
+      :clearable="true"
+      @clear="clearHandle"
+      :filter-method="selectFilterData"
+      :placeholder="placeholder"
+    >
+      <el-option :value="valueId" :label="valueTitle">
+        <el-tree
+          id="tree-option"
+          ref="selectTree"
+          :accordion="accordion"
+          :data="options"
+          :props="objMap"
+          :node-key="objMap.value"
+          :expand-on-click-node="false"
+          :default-expanded-keys="defaultExpandedKey"
+          :filter-node-method="filterNode"
+          @node-click="handleNodeClick"
+        ></el-tree>
+      </el-option>
+    </el-select>
+  </div>
 </template>
diff --git a/src/components/iFrame/index.vue b/src/components/iFrame/index.vue
index aff55e7..94d7b28 100644
--- a/src/components/iFrame/index.vue
+++ b/src/components/iFrame/index.vue
@@ -21,7 +21,7 @@
 </script>
 
 <template>
-	<div v-loading="loading" :style="'height:' + height">
-		<iframe :src="url" frameborder="no" style="width: 100%; height: 100%" scrolling="auto" />
-	</div>
+  <div v-loading="loading" :style="'height:' + height">
+    <iframe :src="url" frameborder="no" style="width: 100%; height: 100%" scrolling="auto" />
+  </div>
 </template>
diff --git a/src/directive/common/copyText.ts b/src/directive/common/copyText.ts
index b924b8f..b6805f8 100644
--- a/src/directive/common/copyText.ts
+++ b/src/directive/common/copyText.ts
@@ -4,63 +4,63 @@
  */
 
 export default {
-	beforeMount(el: any, { value, arg }: any) {
-		if (arg === 'callback') {
-			el.$copyCallback = value;
-		} else {
-			el.$copyValue = value;
-			const handler = () => {
-				copyTextToClipboard(el.$copyValue);
-				if (el.$copyCallback) {
-					el.$copyCallback(el.$copyValue);
-				}
-			};
-			el.addEventListener('click', handler);
-			el.$destroyCopy = () => el.removeEventListener('click', handler);
-		}
-	}
+  beforeMount(el: any, { value, arg }: any) {
+    if (arg === 'callback') {
+      el.$copyCallback = value;
+    } else {
+      el.$copyValue = value;
+      const handler = () => {
+        copyTextToClipboard(el.$copyValue);
+        if (el.$copyCallback) {
+          el.$copyCallback(el.$copyValue);
+        }
+      };
+      el.addEventListener('click', handler);
+      el.$destroyCopy = () => el.removeEventListener('click', handler);
+    }
+  }
 };
 
 function copyTextToClipboard(input: string, { target = document.body } = {}) {
-	const element = document.createElement('textarea');
-	const previouslyFocusedElement = document.activeElement as HTMLInputElement;
-	element.value = input;
-	// Prevent keyboard from showing on mobile
-	element.setAttribute('readonly', '');
+  const element = document.createElement('textarea');
+  const previouslyFocusedElement = document.activeElement as HTMLInputElement;
+  element.value = input;
+  // Prevent keyboard from showing on mobile
+  element.setAttribute('readonly', '');
 
-	element.style.contain = 'strict';
-	element.style.position = 'absolute';
-	element.style.left = '-9999px';
-	element.style.fontSize = '12pt'; // Prevent zooming on iOS
+  element.style.contain = 'strict';
+  element.style.position = 'absolute';
+  element.style.left = '-9999px';
+  element.style.fontSize = '12pt'; // Prevent zooming on iOS
 
-	const selection = document.getSelection();
-	let originalRange;
-	if (selection) {
-		originalRange = selection?.rangeCount > 0 && selection.getRangeAt(0);
-	}
-	target.append(element);
-	element.select();
+  const selection = document.getSelection();
+  let originalRange;
+  if (selection) {
+    originalRange = selection?.rangeCount > 0 && selection.getRangeAt(0);
+  }
+  target.append(element);
+  element.select();
 
-	// Explicit selection workaround for iOS
-	element.selectionStart = 0;
-	element.selectionEnd = input.length;
+  // Explicit selection workaround for iOS
+  element.selectionStart = 0;
+  element.selectionEnd = input.length;
 
-	let isSuccess = false;
-	try {
-		isSuccess = document.execCommand('copy');
-	} catch (err) {
-		console.error(err);
-	}
-	element.remove();
+  let isSuccess = false;
+  try {
+    isSuccess = document.execCommand('copy');
+  } catch (err) {
+    console.error(err);
+  }
+  element.remove();
 
-	if (originalRange) {
-		selection?.removeAllRanges();
-		selection?.addRange(originalRange);
-	}
+  if (originalRange) {
+    selection?.removeAllRanges();
+    selection?.addRange(originalRange);
+  }
 
-	// Get the focus back on the previously focused element, if any
-	if (previouslyFocusedElement) {
-		previouslyFocusedElement.focus();
-	}
-	return isSuccess;
+  // Get the focus back on the previously focused element, if any
+  if (previouslyFocusedElement) {
+    previouslyFocusedElement.focus();
+  }
+  return isSuccess;
 }
diff --git a/src/directive/index.ts b/src/directive/index.ts
index 500cf12..ef25ee8 100644
--- a/src/directive/index.ts
+++ b/src/directive/index.ts
@@ -3,7 +3,7 @@
 import { App } from 'vue';
 
 export default (app: App) => {
-	app.directive('copyText', copyText);
-	app.directive('hasPermi', hasPermi);
-	app.directive('hasRoles', hasRoles);
+  app.directive('copyText', copyText);
+  app.directive('hasPermi', hasPermi);
+  app.directive('hasRoles', hasRoles);
 };
diff --git a/src/directive/permission/index.ts b/src/directive/permission/index.ts
index c52b949..0bdc1c7 100644
--- a/src/directive/permission/index.ts
+++ b/src/directive/permission/index.ts
@@ -4,41 +4,41 @@
  * 鎿嶄綔鏉冮檺澶勭悊
  */
 export const hasPermi: Directive = {
-	mounted(el: HTMLElement, binding: DirectiveBinding) {
-		const { permissions } = useUserStore();
-		// 銆屽叾浠栬鑹层�嶆寜閽潈闄愭牎楠�
-		const { value } = binding;
-		if (value && value instanceof Array && value.length > 0) {
-			const hasPermission = permissions.some((permi) => {
-				return permi === '*:*:*' || value.includes(permi);
-			});
-			if (!hasPermission) {
-				el.parentNode && el.parentNode.removeChild(el);
-				return false;
-			}
-		} else {
-			throw new Error("check perms! Like v-has-permi=\"['sys:user:add','sys:user:edit']\"");
-		}
-	}
+  mounted(el: HTMLElement, binding: DirectiveBinding) {
+    const { permissions } = useUserStore();
+    // 銆屽叾浠栬鑹层�嶆寜閽潈闄愭牎楠�
+    const { value } = binding;
+    if (value && value instanceof Array && value.length > 0) {
+      const hasPermission = permissions.some((permi) => {
+        return permi === '*:*:*' || value.includes(permi);
+      });
+      if (!hasPermission) {
+        el.parentNode && el.parentNode.removeChild(el);
+        return false;
+      }
+    } else {
+      throw new Error("check perms! Like v-has-permi=\"['sys:user:add','sys:user:edit']\"");
+    }
+  }
 };
 
 /**
  * 瑙掕壊鏉冮檺澶勭悊
  */
 export const hasRoles: Directive = {
-	mounted(el: HTMLElement, binding: DirectiveBinding) {
-		const { value } = binding;
-		const { roles } = useUserStore();
-		if (value && value instanceof Array && value.length > 0) {
-			const hasRole = roles.some((role) => {
-				return role === 'admin' || value.includes(role);
-			});
-			if (!hasRole) {
-				el.parentNode && el.parentNode.removeChild(el);
-				return false;
-			}
-		} else {
-			throw new Error("check roles! Like v-has-roles=\"['admin','test']\"");
-		}
-	}
+  mounted(el: HTMLElement, binding: DirectiveBinding) {
+    const { value } = binding;
+    const { roles } = useUserStore();
+    if (value && value instanceof Array && value.length > 0) {
+      const hasRole = roles.some((role) => {
+        return role === 'admin' || value.includes(role);
+      });
+      if (!hasRole) {
+        el.parentNode && el.parentNode.removeChild(el);
+        return false;
+      }
+    } else {
+      throw new Error("check roles! Like v-has-roles=\"['admin','test']\"");
+    }
+  }
 };
diff --git a/src/enums/MenuTypeEnum.ts b/src/enums/MenuTypeEnum.ts
index ceb22fb..cecebd2 100644
--- a/src/enums/MenuTypeEnum.ts
+++ b/src/enums/MenuTypeEnum.ts
@@ -1,15 +1,15 @@
 export enum MenuTypeEnum {
-	/**
-	 * 鐩綍
-	 */
-	M = 'M',
-	/**
-	 * 鑿滃崟
-	 */
-	C = 'C',
+  /**
+   * 鐩綍
+   */
+  M = 'M',
+  /**
+   * 鑿滃崟
+   */
+  C = 'C',
 
-	/**
-	 * 鎸夐挳
-	 */
-	F = 'F'
+  /**
+   * 鎸夐挳
+   */
+  F = 'F'
 }
diff --git a/src/enums/RespEnum.ts b/src/enums/RespEnum.ts
index e723fa8..ce60a51 100644
--- a/src/enums/RespEnum.ts
+++ b/src/enums/RespEnum.ts
@@ -1,90 +1,90 @@
 export enum HttpStatus {
-	/**
-	 * 鎿嶄綔鎴愬姛
-	 */
-	SUCCESS = 200,
-	/**
-	 * 瀵硅薄鍒涘缓鎴愬姛
-	 */
-	CREATED = 201,
-	/**
-	 * 璇锋眰宸茬粡琚帴鍙�
-	 */
-	ACCEPTED = 202,
-	/**
-	 * 鎿嶄綔宸茬粡鎵ц鎴愬姛锛屼絾鏄病鏈夎繑鍥炴暟鎹�
-	 */
-	NO_CONTENT = 204,
-	/**
-	 * 璧勬簮宸茬粡琚Щ闄�
-	 */
-	MOVED_PERM = 301,
-	/**
-	 * 閲嶅畾鍚�
-	 */
-	SEE_OTHER = 303,
-	/**
-	 * 璧勬簮娌℃湁琚慨鏀�
-	 */
-	NOT_MODIFIED = 304,
-	/**
-	 * 鍙傛暟鍒楄〃閿欒锛堢己灏戯紝鏍煎紡涓嶅尮閰嶏級
-	 */
-	PARAM_ERROR = 400,
-	/**
-	 * 鏈巿鏉�
-	 */
-	UNAUTHORIZED = 401,
-	/**
-	 * 璁块棶鍙楅檺锛屾巿鏉冭繃鏈�
-	 */
-	FORBIDDEN = 403,
-	/**
-	 * 璧勬簮锛屾湇鍔℃湭鎵惧埌
-	 */
-	NOT_FOUND = 404,
-	/**
-	 * 涓嶅厑璁哥殑http鏂规硶
-	 */
-	BAD_METHOD = 405,
-	/**
-	 * 璧勬簮鍐茬獊锛屾垨鑰呰祫婧愯閿�
-	 */
-	CONFLICT = 409,
-	/**
-	 * 涓嶆敮鎸佺殑鏁版嵁锛屽獟浣撶被鍨�
-	 */
-	UNSUPPORTED_TYPE = 415,
-	/**
-	 * 绯荤粺鍐呴儴閿欒
-	 */
-	SERVER_ERROR = 500,
-	/**
-	 * 鎺ュ彛鏈疄鐜�
-	 */
-	NOT_IMPLEMENTED = 501,
-	/**
-	 * 鏈嶅姟涓嶅彲鐢紝杩囪浇鎴栬�呯淮鎶�
-	 */
-	BAD_GATEWAY = 502,
-	/**
-	 * 缃戝叧瓒呮椂
-	 */
-	GATEWAY_TIMEOUT = 504,
-	/**
-	 * 鏈煡閿欒
-	 */
-	UNKNOWN_ERROR = 520,
-	/**
-	 * 鏈嶅姟鏈煡閿欒
-	 */
-	SERVICE_ERROR = 521,
-	/**
-	 * 鏁版嵁搴撴湭鐭ラ敊璇�
-	 */
-	DATABASE_ERROR = 522,
-	/**
-	 * 绯荤粺璀﹀憡娑堟伅
-	 */
-	WARN = 601
+  /**
+   * 鎿嶄綔鎴愬姛
+   */
+  SUCCESS = 200,
+  /**
+   * 瀵硅薄鍒涘缓鎴愬姛
+   */
+  CREATED = 201,
+  /**
+   * 璇锋眰宸茬粡琚帴鍙�
+   */
+  ACCEPTED = 202,
+  /**
+   * 鎿嶄綔宸茬粡鎵ц鎴愬姛锛屼絾鏄病鏈夎繑鍥炴暟鎹�
+   */
+  NO_CONTENT = 204,
+  /**
+   * 璧勬簮宸茬粡琚Щ闄�
+   */
+  MOVED_PERM = 301,
+  /**
+   * 閲嶅畾鍚�
+   */
+  SEE_OTHER = 303,
+  /**
+   * 璧勬簮娌℃湁琚慨鏀�
+   */
+  NOT_MODIFIED = 304,
+  /**
+   * 鍙傛暟鍒楄〃閿欒锛堢己灏戯紝鏍煎紡涓嶅尮閰嶏級
+   */
+  PARAM_ERROR = 400,
+  /**
+   * 鏈巿鏉�
+   */
+  UNAUTHORIZED = 401,
+  /**
+   * 璁块棶鍙楅檺锛屾巿鏉冭繃鏈�
+   */
+  FORBIDDEN = 403,
+  /**
+   * 璧勬簮锛屾湇鍔℃湭鎵惧埌
+   */
+  NOT_FOUND = 404,
+  /**
+   * 涓嶅厑璁哥殑http鏂规硶
+   */
+  BAD_METHOD = 405,
+  /**
+   * 璧勬簮鍐茬獊锛屾垨鑰呰祫婧愯閿�
+   */
+  CONFLICT = 409,
+  /**
+   * 涓嶆敮鎸佺殑鏁版嵁锛屽獟浣撶被鍨�
+   */
+  UNSUPPORTED_TYPE = 415,
+  /**
+   * 绯荤粺鍐呴儴閿欒
+   */
+  SERVER_ERROR = 500,
+  /**
+   * 鎺ュ彛鏈疄鐜�
+   */
+  NOT_IMPLEMENTED = 501,
+  /**
+   * 鏈嶅姟涓嶅彲鐢紝杩囪浇鎴栬�呯淮鎶�
+   */
+  BAD_GATEWAY = 502,
+  /**
+   * 缃戝叧瓒呮椂
+   */
+  GATEWAY_TIMEOUT = 504,
+  /**
+   * 鏈煡閿欒
+   */
+  UNKNOWN_ERROR = 520,
+  /**
+   * 鏈嶅姟鏈煡閿欒
+   */
+  SERVICE_ERROR = 521,
+  /**
+   * 鏁版嵁搴撴湭鐭ラ敊璇�
+   */
+  DATABASE_ERROR = 522,
+  /**
+   * 绯荤粺璀﹀憡娑堟伅
+   */
+  WARN = 601
 }
diff --git a/src/enums/SettingTypeEnum.ts b/src/enums/SettingTypeEnum.ts
index 6589b37..bf4ec43 100644
--- a/src/enums/SettingTypeEnum.ts
+++ b/src/enums/SettingTypeEnum.ts
@@ -1,16 +1,16 @@
 export enum SettingTypeEnum {
-	TITLE = 'title',
-	THEME = 'theme',
-	SIDE_THEME = 'sideTheme',
-	SHOW_SETTINGS = 'showSettings',
-	TOP_NAV = 'topNav',
-	TAGS_VIEW = 'tagsView',
-	FIXED_HEADER = 'fixedHeader',
-	SIDEBAR_LOGO = 'sidebarLogo',
-	DYNAMIC_TITLE = 'dynamicTitle',
-	ANIMATION_ENABLE = 'animationEnable',
-	LAYOUT = 'layout',
-	DARK = 'dark',
+  TITLE = 'title',
+  THEME = 'theme',
+  SIDE_THEME = 'sideTheme',
+  SHOW_SETTINGS = 'showSettings',
+  TOP_NAV = 'topNav',
+  TAGS_VIEW = 'tagsView',
+  FIXED_HEADER = 'fixedHeader',
+  SIDEBAR_LOGO = 'sidebarLogo',
+  DYNAMIC_TITLE = 'dynamicTitle',
+  ANIMATION_ENABLE = 'animationEnable',
+  LAYOUT = 'layout',
+  DARK = 'dark',
 
-	LAYOUT_SETTING = 'layout-setting'
+  LAYOUT_SETTING = 'layout-setting'
 }
diff --git a/src/enums/layout/LayoutEnum.ts b/src/enums/layout/LayoutEnum.ts
index 4c26219..0aa601b 100644
--- a/src/enums/layout/LayoutEnum.ts
+++ b/src/enums/layout/LayoutEnum.ts
@@ -1,4 +1,4 @@
 export enum ThemeEnum {
-	DARK = 'theme-dark',
-	LIGHT = 'theme-light'
+  DARK = 'theme-dark',
+  LIGHT = 'theme-light'
 }
diff --git a/src/lang/en.ts b/src/lang/en.ts
index 37dfed6..64318e7 100644
--- a/src/lang/en.ts
+++ b/src/lang/en.ts
@@ -1,25 +1,25 @@
 export default {
-	// 璺敱鍥介檯鍖�
-	route: {
-		dashboard: 'Dashboard',
-		document: 'Document'
-	},
-	// 鐧诲綍椤甸潰鍥介檯鍖�
-	login: {
-		title: 'vue3-element-admin',
-		username: 'Username',
-		password: 'Password',
-		login: 'Login',
-		code: 'Verification Code',
-		copyright: '',
-		icp: '',
-		thirdPartyLogin: 'third-party login'
-	},
-	// 瀵艰埅鏍忓浗闄呭寲
-	navbar: {
-		dashboard: 'Dashboard',
-		logout: 'Logout',
-		document: 'Document',
-		gitee: 'Gitee'
-	}
+  // 璺敱鍥介檯鍖�
+  route: {
+    dashboard: 'Dashboard',
+    document: 'Document'
+  },
+  // 鐧诲綍椤甸潰鍥介檯鍖�
+  login: {
+    title: 'vue3-element-admin',
+    username: 'Username',
+    password: 'Password',
+    login: 'Login',
+    code: 'Verification Code',
+    copyright: '',
+    icp: '',
+    thirdPartyLogin: 'third-party login'
+  },
+  // 瀵艰埅鏍忓浗闄呭寲
+  navbar: {
+    dashboard: 'Dashboard',
+    logout: 'Logout',
+    document: 'Document',
+    gitee: 'Gitee'
+  }
 };
diff --git a/src/lang/index.ts b/src/lang/index.ts
index 1048211..8ed51e9 100644
--- a/src/lang/index.ts
+++ b/src/lang/index.ts
@@ -6,12 +6,12 @@
 import zhCnLocale from './zh-cn';
 
 const messages = {
-	'zh-cn': {
-		...zhCnLocale
-	},
-	en: {
-		...enLocale
-	}
+  'zh-cn': {
+    ...zhCnLocale
+  },
+  en: {
+    ...enLocale
+  }
 };
 
 /**
@@ -20,26 +20,26 @@
  * @returns zh-cn|en ...
  */
 export const getLanguage = () => {
-	// 鏈湴缂撳瓨鑾峰彇
-	let language = localStorage.getItem('language');
-	if (language) {
-		return language;
-	}
-	// 娴忚鍣ㄤ娇鐢ㄨ瑷�
-	language = navigator.language.toLowerCase();
-	const locales = Object.keys(messages);
-	for (const locale of locales) {
-		if (language.indexOf(locale) > -1) {
-			return locale;
-		}
-	}
-	return 'zh-cn';
+  // 鏈湴缂撳瓨鑾峰彇
+  let language = localStorage.getItem('language');
+  if (language) {
+    return language;
+  }
+  // 娴忚鍣ㄤ娇鐢ㄨ瑷�
+  language = navigator.language.toLowerCase();
+  const locales = Object.keys(messages);
+  for (const locale of locales) {
+    if (language.indexOf(locale) > -1) {
+      return locale;
+    }
+  }
+  return 'zh-cn';
 };
 
 const i18n = createI18n({
-	legacy: false,
-	locale: getLanguage(),
-	messages: messages
+  legacy: false,
+  locale: getLanguage(),
+  messages: messages
 });
 
 export default i18n;
diff --git a/src/lang/zh-cn.ts b/src/lang/zh-cn.ts
index 5f7d5b3..1c91526 100644
--- a/src/lang/zh-cn.ts
+++ b/src/lang/zh-cn.ts
@@ -1,24 +1,24 @@
 export default {
-	// 璺敱鍥介檯鍖�
-	route: {
-		dashboard: '棣栭〉',
-		document: '椤圭洰鏂囨。'
-	},
-	// 鐧诲綍椤甸潰鍥介檯鍖�
-	login: {
-		title: 'vue3-element-admin',
-		username: '鐢ㄦ埛鍚�',
-		password: '瀵嗙爜',
-		login: '鐧� 褰�',
-		code: '璇疯緭鍏ラ獙璇佺爜',
-		copyright: '',
-		icp: '',
-		thirdPartyLogin: '绗笁鏂圭櫥褰�'
-	},
-	navbar: {
-		dashboard: '棣栭〉',
-		logout: '娉ㄩ攢',
-		document: '椤圭洰鏂囨。',
-		gitee: '鐮佷簯'
-	}
+  // 璺敱鍥介檯鍖�
+  route: {
+    dashboard: '棣栭〉',
+    document: '椤圭洰鏂囨。'
+  },
+  // 鐧诲綍椤甸潰鍥介檯鍖�
+  login: {
+    title: 'vue3-element-admin',
+    username: '鐢ㄦ埛鍚�',
+    password: '瀵嗙爜',
+    login: '鐧� 褰�',
+    code: '璇疯緭鍏ラ獙璇佺爜',
+    copyright: '',
+    icp: '',
+    thirdPartyLogin: '绗笁鏂圭櫥褰�'
+  },
+  navbar: {
+    dashboard: '棣栭〉',
+    logout: '娉ㄩ攢',
+    document: '椤圭洰鏂囨。',
+    gitee: '鐮佷簯'
+  }
 };
diff --git a/src/layout/components/AppMain.vue b/src/layout/components/AppMain.vue
index e600479..5649fac 100644
--- a/src/layout/components/AppMain.vue
+++ b/src/layout/components/AppMain.vue
@@ -1,6 +1,19 @@
+<template>
+  <section class="app-main">
+    <router-view v-slot="{ Component, route }">
+      <transition :enter-active-class="animante" mode="out-in">
+        <keep-alive :include="tagsViewStore.cachedViews">
+          <component v-if="!route.meta.link" :is="Component" :key="route.path" />
+        </keep-alive>
+      </transition>
+    </router-view>
+    <iframe-toggle />
+  </section>
+</template>
+
 <script lang="ts">
 export default {
-  name: 'AppMin'
+    name: 'AppMin'
 }
 </script>
 
@@ -16,27 +29,14 @@
 const animante = ref<string>('');
 const animationEnable = ref(useSettingsStore().animationEnable);
 watch(()=> useSettingsStore().animationEnable, (val) => {
-  animationEnable.value = val;
-  if (val) {
-    animante.value = proxy?.animate.animateList[Math.round(Math.random() * proxy?.animate.animateList.length)] as string;
-  } else {
-    animante.value = proxy?.animate.defaultAnimate as string;
-  }
+    animationEnable.value = val;
+    if (val) {
+        animante.value = proxy?.animate.animateList[Math.round(Math.random() * proxy?.animate.animateList.length)] as string;
+    } else {
+        animante.value = proxy?.animate.defaultAnimate as string;
+    }
 }, { immediate: true });
 </script>
-
-<template>
-	<section class="app-main">
-		<router-view v-slot="{ Component, route }">
-			<transition :enter-active-class="animante" mode="out-in">
-				<keep-alive :include="tagsViewStore.cachedViews">
-					<component v-if="!route.meta.link" :is="Component" :key="route.path" />
-				</keep-alive>
-			</transition>
-		</router-view>
-		<iframe-toggle />
-	</section>
-</template>
 
 <style lang="scss" scoped>
 .app-main {
diff --git a/src/layout/components/IframeToggle/index.vue b/src/layout/components/IframeToggle/index.vue
index f5d167c..e6e131e 100644
--- a/src/layout/components/IframeToggle/index.vue
+++ b/src/layout/components/IframeToggle/index.vue
@@ -7,13 +7,13 @@
 </script>
 
 <template>
-	<transition-group name="fade-transform" mode="out-in">
-		<inner-link
-			v-for="(item, index) in tagsViewStore.iframeViews"
-			:key="item.path"
-			:iframeId="'iframe' + index"
-			v-show="route.path === item.path"
-			:src="item.meta ? item.meta.link : ''"
-		></inner-link>
-	</transition-group>
+  <transition-group name="fade-transform" mode="out-in">
+    <inner-link
+      v-for="(item, index) in tagsViewStore.iframeViews"
+      :key="item.path"
+      :iframeId="'iframe' + index"
+      v-show="route.path === item.path"
+      :src="item.meta ? item.meta.link : ''"
+    ></inner-link>
+  </transition-group>
 </template>
diff --git a/src/layout/components/InnerLink/index.vue b/src/layout/components/InnerLink/index.vue
index c1b8bbb..31050fd 100644
--- a/src/layout/components/InnerLink/index.vue
+++ b/src/layout/components/InnerLink/index.vue
@@ -1,18 +1,18 @@
+<template>
+  <div :style="'height:' + height">
+    <iframe :id="iframeId" style="width: 100%; height: 100%" :src="src" frameborder="no"></iframe>
+  </div>
+</template>
+
 <script setup lang="ts">
 const props = defineProps({
-  src: {
-    type: String,
-    default: "/"
-  },
-  iframeId: {
-    type: String
-  }
+    src: {
+        type: String,
+        default: "/"
+    },
+    iframeId: {
+        type: String
+    }
 });
 const height = ref(document.documentElement.clientHeight - 94.5 + "px");
-</script>
-
-<template>
-	<div :style="'height:' + height">
-		<iframe :id="iframeId" style="width: 100%; height: 100%" :src="src" frameborder="no"></iframe>
-	</div>
-</template>
+</script>
\ No newline at end of file
diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue
index 483800d..9e4f470 100644
--- a/src/layout/components/Navbar.vue
+++ b/src/layout/components/Navbar.vue
@@ -1,3 +1,68 @@
+<template>
+  <div class="navbar">
+    <hamburger id="hamburger-container" :is-active="appStore.sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
+    <breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!settingsStore.topNav" />
+    <top-nav id="topmenu-container" class="topmenu-container" v-if="settingsStore.topNav" />
+
+    <div class="right-menu flex align-center">
+      <template v-if="appStore.device !== 'mobile'">
+        <el-select
+          v-model="companyName"
+          clearable
+          filterable
+          reserve-keyword
+          placeholder="璇烽�夋嫨绉熸埛"
+          v-if="userId === 1 && tenantEnabled"
+          @change="dynamicTenantEvent"
+          @clear="dynamicClearEvent"
+        >
+          <el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId"> </el-option>
+          <template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template>
+        </el-select>
+
+        <header-search id="header-search" class="right-menu-item" />
+
+        <el-tooltip content="婧愮爜鍦板潃" effect="dark" placement="bottom">
+          <ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
+        </el-tooltip>
+
+        <el-tooltip content="鏂囨。鍦板潃" effect="dark" placement="bottom">
+          <ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" />
+        </el-tooltip>
+
+        <el-tooltip content="鍏ㄥ睆" effect="dark" placement="bottom">
+          <screenfull id="screenfull" class="right-menu-item hover-effect" />
+        </el-tooltip>
+
+        <el-tooltip content="甯冨眬澶у皬" effect="dark" placement="bottom">
+          <size-select id="size-select" class="right-menu-item hover-effect" />
+        </el-tooltip>
+      </template>
+      <div class="avatar-container">
+        <el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click">
+          <div class="avatar-wrapper">
+            <img :src="userStore.avatar" class="user-avatar" />
+            <el-icon><caret-bottom /></el-icon>
+          </div>
+          <template #dropdown>
+            <el-dropdown-menu>
+              <router-link to="/user/profile" v-if="!dynamic">
+                <el-dropdown-item>涓汉涓績</el-dropdown-item>
+              </router-link>
+              <el-dropdown-item command="setLayout">
+                <span>甯冨眬璁剧疆</span>
+              </el-dropdown-item>
+              <el-dropdown-item divided command="logout">
+                <span>閫�鍑虹櫥褰�</span>
+              </el-dropdown-item>
+            </el-dropdown-menu>
+          </template>
+        </el-dropdown>
+      </div>
+    </div>
+  </div>
+</template>
+
 <script setup lang="ts">
 import useAppStore from '@/store/modules/app'
 import useUserStore from '@/store/modules/user'
@@ -23,129 +88,64 @@
 
 // 鍔ㄦ�佸垏鎹�
 const dynamicTenantEvent = async (tenantId: string) => {
-  if (companyName.value != null && companyName.value !== '') {
-    await dynamicTenant(tenantId);
-    dynamic.value = true;
-    proxy?.$tab.closeAllPage();
-    proxy?.$router.push('/');
-  }
+    if (companyName.value != null && companyName.value !== '') {
+        await dynamicTenant(tenantId);
+        dynamic.value = true;
+        proxy?.$tab.closeAllPage();
+        proxy?.$router.push('/');
+    }
 }
 
 const dynamicClearEvent = async () => {
-  await dynamicClear();
-  dynamic.value = false;
-  proxy?.$tab.closeAllPage();
-  proxy?.$router.push('/')
+    await dynamicClear();
+    dynamic.value = false;
+    proxy?.$tab.closeAllPage();
+    proxy?.$router.push('/')
 }
 
 /** 绉熸埛鍒楄〃 */
 const initTenantList = async () => {
-  const { data } = await getTenantList();
-  tenantEnabled.value = data.tenantEnabled === undefined ? true : data.tenantEnabled;
-  if (tenantEnabled.value) {
-      tenantList.value = data.voList;
-  }
+    const { data } = await getTenantList();
+    tenantEnabled.value = data.tenantEnabled === undefined ? true : data.tenantEnabled;
+    if (tenantEnabled.value) {
+        tenantList.value = data.voList;
+    }
 }
 
 defineExpose({
-  initTenantList,
+    initTenantList,
 })
 
 const toggleSideBar = () => {
-  appStore.toggleSideBar()
+    appStore.toggleSideBar()
 }
 
 const logout = async () => {
-  await ElMessageBox.confirm('纭畾娉ㄩ攢骞堕��鍑虹郴缁熷悧锛�', '鎻愮ず', {
-    confirmButtonText: '纭畾',
-    cancelButtonText: '鍙栨秷',
-    type: 'warning'
-  })
-  await userStore.logout()
-  location.href = import.meta.env.VITE_APP_CONTEXT_PATH + 'index';
+    await ElMessageBox.confirm('纭畾娉ㄩ攢骞堕��鍑虹郴缁熷悧锛�', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+    })
+    await userStore.logout()
+    location.href = import.meta.env.VITE_APP_CONTEXT_PATH + 'index';
 }
 
 const emits = defineEmits(['setLayout'])
 const setLayout = () => {
-  emits('setLayout');
+    emits('setLayout');
 }
 // 瀹氫箟Command鏂规硶瀵硅薄 閫氳繃key鐩存帴璋冪敤鏂规硶
 const commandMap: {[key: string]: any} = {
-  setLayout,
-  logout
+    setLayout,
+    logout
 };
 const handleCommand = (command: string) => {
-  // 鍒ゆ柇鏄惁瀛樺湪璇ユ柟娉�
-  if (commandMap[command]) {
-    commandMap[command]();
-  }
+    // 鍒ゆ柇鏄惁瀛樺湪璇ユ柟娉�
+    if (commandMap[command]) {
+        commandMap[command]();
+    }
 }
 </script>
-
-<template>
-	<div class="navbar">
-		<hamburger id="hamburger-container" :is-active="appStore.sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
-		<breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!settingsStore.topNav" />
-		<top-nav id="topmenu-container" class="topmenu-container" v-if="settingsStore.topNav" />
-
-		<div class="right-menu flex align-center">
-			<template v-if="appStore.device !== 'mobile'">
-				<el-select
-					v-model="companyName"
-					clearable
-					filterable
-					reserve-keyword
-					placeholder="璇烽�夋嫨绉熸埛"
-					v-if="userId === 1 && tenantEnabled"
-					@change="dynamicTenantEvent"
-					@clear="dynamicClearEvent"
-				>
-					<el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId"> </el-option>
-					<template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template>
-				</el-select>
-
-				<header-search id="header-search" class="right-menu-item" />
-
-				<el-tooltip content="婧愮爜鍦板潃" effect="dark" placement="bottom">
-					<ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
-				</el-tooltip>
-
-				<el-tooltip content="鏂囨。鍦板潃" effect="dark" placement="bottom">
-					<ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" />
-				</el-tooltip>
-
-				<el-tooltip content="鍏ㄥ睆" effect="dark" placement="bottom">
-					<screenfull id="screenfull" class="right-menu-item hover-effect" />
-				</el-tooltip>
-
-				<el-tooltip content="甯冨眬澶у皬" effect="dark" placement="bottom">
-					<size-select id="size-select" class="right-menu-item hover-effect" />
-				</el-tooltip>
-			</template>
-			<div class="avatar-container">
-				<el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click">
-					<div class="avatar-wrapper">
-						<img :src="userStore.avatar" class="user-avatar" />
-						<el-icon><caret-bottom /></el-icon>
-					</div>
-					<template #dropdown>
-						<el-dropdown-menu>
-							<router-link to="/user/profile" v-if="!dynamic">
-								<el-dropdown-item>涓汉涓績</el-dropdown-item>
-							</router-link>
-							<el-dropdown-item command="setLayout">
-								<span>甯冨眬璁剧疆</span>
-							</el-dropdown-item>
-							<el-dropdown-item divided command="logout">
-								<span>閫�鍑虹櫥褰�</span>
-							</el-dropdown-item>
-						</el-dropdown-menu>
-					</template>
-				</el-dropdown>
-			</div>
-		</div>
-	</div>
-</template>
 
 <style lang="scss" scoped>
 
diff --git a/src/layout/components/Settings/index.vue b/src/layout/components/Settings/index.vue
index 9bd345f..7e9d8b3 100644
--- a/src/layout/components/Settings/index.vue
+++ b/src/layout/components/Settings/index.vue
@@ -101,86 +101,86 @@
 </script>
 
 <template>
-	<el-drawer v-model="showSettings" :withHeader="false" direction="rtl" size="300px" close-on-click-modal>
-		<div class="setting-drawer-title">
-			<h3 class="drawer-title">涓婚椋庢牸璁剧疆</h3>
-		</div>
-		<div class="setting-drawer-block-checbox">
-			<div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-dark')">
-				<img src="@/assets/images/dark.svg" alt="dark" />
-				<div v-if="sideTheme === 'theme-dark'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
-					<i aria-label="鍥炬爣: check" class="anticon anticon-check">
-						<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class>
-							<path
-								d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"
-							/>
-						</svg>
-					</i>
-				</div>
-			</div>
-			<div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-light')">
-				<img src="@/assets/images/light.svg" alt="light" />
-				<div v-if="sideTheme === 'theme-light'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
-					<i aria-label="鍥炬爣: check" class="anticon anticon-check">
-						<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class>
-							<path
-								d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"
-							/>
-						</svg>
-					</i>
-				</div>
-			</div>
-		</div>
-		<div class="drawer-item">
-			<span>涓婚棰滆壊</span>
-			<span class="comp-style">
-				<el-color-picker v-model="theme" :predefine="predefineColors" @change="themeChange" />
-			</span>
-		</div>
-		<el-divider />
+  <el-drawer v-model="showSettings" :withHeader="false" direction="rtl" size="300px" close-on-click-modal>
+    <div class="setting-drawer-title">
+      <h3 class="drawer-title">涓婚椋庢牸璁剧疆</h3>
+    </div>
+    <div class="setting-drawer-block-checbox">
+      <div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-dark')">
+        <img src="@/assets/images/dark.svg" alt="dark" />
+        <div v-if="sideTheme === 'theme-dark'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
+          <i aria-label="鍥炬爣: check" class="anticon anticon-check">
+            <svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class>
+              <path
+                d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"
+              />
+            </svg>
+          </i>
+        </div>
+      </div>
+      <div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-light')">
+        <img src="@/assets/images/light.svg" alt="light" />
+        <div v-if="sideTheme === 'theme-light'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
+          <i aria-label="鍥炬爣: check" class="anticon anticon-check">
+            <svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class>
+              <path
+                d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"
+              />
+            </svg>
+          </i>
+        </div>
+      </div>
+    </div>
+    <div class="drawer-item">
+      <span>涓婚棰滆壊</span>
+      <span class="comp-style">
+        <el-color-picker v-model="theme" :predefine="predefineColors" @change="themeChange" />
+      </span>
+    </div>
+    <el-divider />
 
-		<h3 class="drawer-title">绯荤粺甯冨眬閰嶇疆</h3>
+    <h3 class="drawer-title">绯荤粺甯冨眬閰嶇疆</h3>
 
-		<div class="drawer-item">
-			<span>寮�鍚� TopNav</span>
-			<span class="comp-style">
-				<el-switch v-model="topNav" class="drawer-switch" />
-			</span>
-		</div>
+    <div class="drawer-item">
+      <span>寮�鍚� TopNav</span>
+      <span class="comp-style">
+        <el-switch v-model="topNav" class="drawer-switch" />
+      </span>
+    </div>
 
-		<div class="drawer-item">
-			<span>寮�鍚� Tags-Views</span>
-			<span class="comp-style">
-				<el-switch v-model="tagsView" class="drawer-switch" />
-			</span>
-		</div>
+    <div class="drawer-item">
+      <span>寮�鍚� Tags-Views</span>
+      <span class="comp-style">
+        <el-switch v-model="tagsView" class="drawer-switch" />
+      </span>
+    </div>
 
-		<div class="drawer-item">
-			<span>鍥哄畾 Header</span>
-			<span class="comp-style">
-				<el-switch v-model="fixedHeader" class="drawer-switch" />
-			</span>
-		</div>
+    <div class="drawer-item">
+      <span>鍥哄畾 Header</span>
+      <span class="comp-style">
+        <el-switch v-model="fixedHeader" class="drawer-switch" />
+      </span>
+    </div>
 
-		<div class="drawer-item">
-			<span>鏄剧ず Logo</span>
-			<span class="comp-style">
-				<el-switch v-model="sidebarLogo" class="drawer-switch" />
-			</span>
-		</div>
+    <div class="drawer-item">
+      <span>鏄剧ず Logo</span>
+      <span class="comp-style">
+        <el-switch v-model="sidebarLogo" class="drawer-switch" />
+      </span>
+    </div>
 
-		<div class="drawer-item">
-			<span>鍔ㄦ�佹爣棰�</span>
-			<span class="comp-style">
-				<el-switch v-model="dynamicTitle" class="drawer-switch" />
-			</span>
-		</div>
+    <div class="drawer-item">
+      <span>鍔ㄦ�佹爣棰�</span>
+      <span class="comp-style">
+        <el-switch v-model="dynamicTitle" class="drawer-switch" />
+      </span>
+    </div>
 
-		<el-divider />
+    <el-divider />
 
-		<el-button type="primary" plain icon="DocumentAdd" @click="saveSetting">淇濆瓨閰嶇疆</el-button>
-		<el-button plain icon="Refresh" @click="resetSetting">閲嶇疆閰嶇疆</el-button>
-	</el-drawer>
+    <el-button type="primary" plain icon="DocumentAdd" @click="saveSetting">淇濆瓨閰嶇疆</el-button>
+    <el-button plain icon="Refresh" @click="resetSetting">閲嶇疆閰嶇疆</el-button>
+  </el-drawer>
 </template>
 
 <style lang="scss" scoped>
diff --git a/src/layout/components/Sidebar/Link.vue b/src/layout/components/Sidebar/Link.vue
index 02f0307..c1c276f 100644
--- a/src/layout/components/Sidebar/Link.vue
+++ b/src/layout/components/Sidebar/Link.vue
@@ -34,7 +34,7 @@
 </script>
 
 <template>
-	<component :is="type" v-bind="linkProps()">
-		<slot />
-	</component>
+  <component :is="type" v-bind="linkProps()">
+    <slot />
+  </component>
 </template>
diff --git a/src/layout/components/Sidebar/Logo.vue b/src/layout/components/Sidebar/Logo.vue
index 66df720..4e6ec7a 100644
--- a/src/layout/components/Sidebar/Logo.vue
+++ b/src/layout/components/Sidebar/Logo.vue
@@ -18,26 +18,26 @@
 </script>
 
 <template>
-	<div
-		class="sidebar-logo-container"
-		:class="{ 'collapse': collapse }"
-		:style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }"
-	>
-		<transition :enter-active-class="proxy?.animate.logoAnimate.enter" mode="out-in">
-			<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
-				<img v-if="logo" :src="logo" class="sidebar-logo" />
-				<h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">
-					{{ title }}
-				</h1>
-			</router-link>
-			<router-link v-else key="expand" class="sidebar-logo-link" to="/">
-				<img v-if="logo" :src="logo" class="sidebar-logo" />
-				<h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">
-					{{ title }}
-				</h1>
-			</router-link>
-		</transition>
-	</div>
+  <div
+    class="sidebar-logo-container"
+    :class="{ 'collapse': collapse }"
+    :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }"
+  >
+    <transition :enter-active-class="proxy?.animate.logoAnimate.enter" mode="out-in">
+      <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
+        <img v-if="logo" :src="logo" class="sidebar-logo" />
+        <h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">
+          {{ title }}
+        </h1>
+      </router-link>
+      <router-link v-else key="expand" class="sidebar-logo-link" to="/">
+        <img v-if="logo" :src="logo" class="sidebar-logo" />
+        <h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">
+          {{ title }}
+        </h1>
+      </router-link>
+    </transition>
+  </div>
 </template>
 
 <style lang="scss" scoped>
diff --git a/src/layout/components/Sidebar/SidebarItem.vue b/src/layout/components/Sidebar/SidebarItem.vue
index 0c5831f..f803f13 100644
--- a/src/layout/components/Sidebar/SidebarItem.vue
+++ b/src/layout/components/Sidebar/SidebarItem.vue
@@ -1,3 +1,34 @@
+<template>
+  <div v-if="!item.hidden">
+    <template v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && !item.alwaysShow">
+      <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path, onlyOneChild.query)">
+        <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{ 'submenu-title-noDropdown': !isNest }">
+          <svg-icon :icon-class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)" />
+          <template #title>
+            <span class="menu-title" :title="hasTitle(onlyOneChild.meta.title)">{{ onlyOneChild.meta.title }}</span>
+          </template>
+        </el-menu-item>
+      </app-link>
+    </template>
+
+    <el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" teleported>
+      <template v-if="item.meta" #title>
+        <svg-icon :icon-class="item.meta ? item.meta.icon : '' " />
+        <span class="menu-title" :title="hasTitle(item.meta?.title)">{{ item.meta?.title }}</span>
+      </template>
+
+      <sidebar-item
+        v-for="child in item.children"
+        :key="child.path"
+        :is-nest="true"
+        :item="child as RouteOption"
+        :base-path="resolvePath(child.path)"
+        class="nest-menu"
+      />
+    </el-sub-menu>
+  </div>
+</template>
+
 <script setup lang="ts">
 import { isExternal } from '@/utils/validate'
 import AppLink from './Link.vue'
@@ -6,100 +37,69 @@
 import { PropType } from "vue";
 
 const props = defineProps({
-  // route object
-  item: {
-    type: Object as PropType<RouteOption>,
-    required: true
-  },
-  isNest: {
-    type: Boolean,
-    default: false
-  },
-  basePath: {
-    type: String,
-    default: ''
-  }
+    // route object
+    item: {
+        type: Object as PropType<RouteOption>,
+        required: true
+    },
+    isNest: {
+        type: Boolean,
+        default: false
+    },
+    basePath: {
+        type: String,
+        default: ''
+    }
 })
 
 const onlyOneChild = ref<any>({});
 
 const hasOneShowingChild = (children:RouteOption[] = [], parent: RouteOption) => {
-  if (!children) {
-    children = [];
-  }
-  const showingChildren = children.filter(item => {
-    if (item.hidden) {
-      return false
-    } else {
-      // Temp set(will be used if only has one showing child)
-      onlyOneChild.value = item
-      return true
+    if (!children) {
+        children = [];
     }
-  })
+    const showingChildren = children.filter(item => {
+        if (item.hidden) {
+            return false
+        } else {
+            // Temp set(will be used if only has one showing child)
+            onlyOneChild.value = item
+            return true
+        }
+    })
 
-  // When there is only one child router, the child router is displayed by default
-  if (showingChildren.length === 1) {
-    return true
-  }
+    // When there is only one child router, the child router is displayed by default
+    if (showingChildren.length === 1) {
+        return true
+    }
 
-  // Show parent if there are no child router to display
-  if (showingChildren.length === 0) {
-    onlyOneChild.value = { ...parent, path: '', noShowingChildren: true }
-    return true
-  }
+    // Show parent if there are no child router to display
+    if (showingChildren.length === 0) {
+        onlyOneChild.value = { ...parent, path: '', noShowingChildren: true }
+        return true
+    }
 
-  return false
+    return false
 };
 
 const resolvePath = (routePath:string, routeQuery?:string): any => {
-  if (isExternal(routePath)) {
-    return routePath
-  }
-  if (isExternal(props.basePath)) {
-    return props.basePath
-  }
-  if (routeQuery) {
-    let query = JSON.parse(routeQuery);
-    return { path: getNormalPath(props.basePath + '/' + routePath), query: query }
-  }
-  return getNormalPath(props.basePath + '/' + routePath)
+    if (isExternal(routePath)) {
+        return routePath
+    }
+    if (isExternal(props.basePath)) {
+        return props.basePath
+    }
+    if (routeQuery) {
+        let query = JSON.parse(routeQuery);
+        return { path: getNormalPath(props.basePath + '/' + routePath), query: query }
+    }
+    return getNormalPath(props.basePath + '/' + routePath)
 }
 
 const hasTitle = (title: string | undefined): string => {
-  if(!title || title.length <= 5) {
-    return "";
-  }
-  return title;
+    if(!title || title.length <= 5) {
+        return "";
+    }
+    return title;
 }
 </script>
-
-<template>
-	<div v-if="!item.hidden">
-		<template v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && !item.alwaysShow">
-			<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path, onlyOneChild.query)">
-				<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{ 'submenu-title-noDropdown': !isNest }">
-					<svg-icon :icon-class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)" />
-					<template #title>
-						<span class="menu-title" :title="hasTitle(onlyOneChild.meta.title)">{{ onlyOneChild.meta.title }}</span>
-					</template>
-				</el-menu-item>
-			</app-link>
-		</template>
-
-		<el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" teleported>
-			<template v-if="item.meta" #title>
-				<svg-icon :icon-class="item.meta ? item.meta.icon : '' " />
-				<span class="menu-title" :title="hasTitle(item.meta?.title)">{{ item.meta?.title }}</span>
-			</template>
-
-			<sidebar-item
-				v-for="child in item.children"
-				:key="child.path"
-				:is-nest="true"
-				:item="child as RouteOption"
-				:base-path="resolvePath(child.path)"
-				class="nest-menu"
-			/>
-		</el-sub-menu>
-	</div>
-</template>
diff --git a/src/layout/components/Sidebar/index.vue b/src/layout/components/Sidebar/index.vue
index fad0d02..a568c71 100644
--- a/src/layout/components/Sidebar/index.vue
+++ b/src/layout/components/Sidebar/index.vue
@@ -24,7 +24,7 @@
   // if set path, the sidebar will highlight the path you set
   if (meta.activeMenu) {
     return meta.activeMenu;
-	}
+  }
   return path;
 })
 
@@ -33,23 +33,23 @@
 </script>
 
 <template>
-	<div :class="{ 'has-logo': showLogo }" :style="{ backgroundColor: bgColor }">
-		<logo v-if="showLogo" :collapse="isCollapse" />
-		<el-scrollbar :class="sideTheme" wrap-class="scrollbar-wrapper">
-			<transition :enter-active-class="proxy?.animate.menuSearchAnimate.enter" mode="out-in">
-				<el-menu
-					:default-active="activeMenu as string"
-					:collapse="isCollapse"
-					:background-color="bgColor"
-					:text-color="textColor"
-					:unique-opened="true"
-					:active-text-color="theme"
-					:collapse-transition="false"
-					mode="vertical"
-				>
-					<sidebar-item v-for="(route, index) in sidebarRouters" :key="route.path + index" :item="route" :base-path="route.path" />
-				</el-menu>
-			</transition>
-		</el-scrollbar>
-	</div>
+  <div :class="{ 'has-logo': showLogo }" :style="{ backgroundColor: bgColor }">
+    <logo v-if="showLogo" :collapse="isCollapse" />
+    <el-scrollbar :class="sideTheme" wrap-class="scrollbar-wrapper">
+      <transition :enter-active-class="proxy?.animate.menuSearchAnimate.enter" mode="out-in">
+        <el-menu
+          :default-active="activeMenu as string"
+          :collapse="isCollapse"
+          :background-color="bgColor"
+          :text-color="textColor"
+          :unique-opened="true"
+          :active-text-color="theme"
+          :collapse-transition="false"
+          mode="vertical"
+        >
+          <sidebar-item v-for="(route, index) in sidebarRouters" :key="route.path + index" :item="route" :base-path="route.path" />
+        </el-menu>
+      </transition>
+    </el-scrollbar>
+  </div>
 </template>
diff --git a/src/layout/components/TagsView/ScrollPane.vue b/src/layout/components/TagsView/ScrollPane.vue
index b5b4b6d..6a96f75 100644
--- a/src/layout/components/TagsView/ScrollPane.vue
+++ b/src/layout/components/TagsView/ScrollPane.vue
@@ -81,9 +81,9 @@
 </script>
 
 <template>
-	<el-scrollbar ref="scrollContainerRef" :vertical="false" class="scroll-container" @wheel.prevent="handleScroll">
-		<slot />
-	</el-scrollbar>
+  <el-scrollbar ref="scrollContainerRef" :vertical="false" class="scroll-container" @wheel.prevent="handleScroll">
+    <slot />
+  </el-scrollbar>
 </template>
 
 <style lang="scss" scoped>
diff --git a/src/layout/components/TagsView/index.vue b/src/layout/components/TagsView/index.vue
index 9f4db62..43b122f 100644
--- a/src/layout/components/TagsView/index.vue
+++ b/src/layout/components/TagsView/index.vue
@@ -1,3 +1,34 @@
+<template>
+  <div id="tags-view-container" class="tags-view-container">
+    <scroll-pane ref="scrollPaneRef" class="tags-view-wrapper" @scroll="handleScroll">
+      <router-link
+        v-for="tag in visitedViews"
+        :key="tag.path"
+        :data-path="tag.path"
+        :class="isActive(tag) ? 'active' : ''"
+        :to="{ path: tag.path ? tag.path : '', query: tag.query, fullPath: tag.fullPath ? tag.fullPath : '' }"
+        class="tags-view-item"
+        :style="activeStyle(tag)"
+        @click.middle="!isAffix(tag) ? closeSelectedTag(tag) : ''"
+        @contextmenu.prevent="openMenu(tag, $event)"
+      >
+        {{ tag.title }}
+        <span v-if="!isAffix(tag)" @click.prevent.stop="closeSelectedTag(tag)">
+          <close class="el-icon-close" style="width: 1em; height: 1em;vertical-align: middle;" />
+        </span>
+      </router-link>
+    </scroll-pane>
+    <ul v-show="visible" :style="{ left: left + 'px', top: top + 'px' }" class="contextmenu">
+      <li @click="refreshSelectedTag(selectedTag)"><refresh-right style="width: 1em; height: 1em;" /> 鍒锋柊椤甸潰</li>
+      <li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)"><close style="width: 1em; height: 1em;" /> 鍏抽棴褰撳墠</li>
+      <li @click="closeOthersTags"><circle-close style="width: 1em; height: 1em;" /> 鍏抽棴鍏朵粬</li>
+      <li v-if="!isFirstView()" @click="closeLeftTags"><back style="width: 1em; height: 1em;" /> 鍏抽棴宸︿晶</li>
+      <li v-if="!isLastView()" @click="closeRightTags"><right style="width: 1em; height: 1em;" /> 鍏抽棴鍙充晶</li>
+      <li @click="closeAllTags(selectedTag)"><circle-close style="width: 1em; height: 1em;" /> 鍏ㄩ儴鍏抽棴</li>
+    </ul>
+  </div>
+</template>
+
 <script setup lang="ts">
 import ScrollPane from './ScrollPane.vue'
 import { getNormalPath } from '@/utils/ruoyi'
@@ -23,215 +54,184 @@
 const theme = computed(() => useSettingsStore().theme);
 
 watch(route, () => {
-  addTags();
-  moveToCurrentTag();
+    addTags();
+    moveToCurrentTag();
 })
 watch(visible, (value) => {
-  if (value) {
-    document.body.addEventListener('click', closeMenu);
-  } else {
-    document.body.removeEventListener('click', closeMenu);
-  }
+    if (value) {
+        document.body.addEventListener('click', closeMenu);
+    } else {
+        document.body.removeEventListener('click', closeMenu);
+    }
 })
 
 const isActive = (r: TagView): boolean => {
-  return r.path === route.path;
+    return r.path === route.path;
 }
 const activeStyle = (tag: TagView) => {
-  if (!isActive(tag)) return {};
-  return {
-    "background-color": theme.value,
-    "border-color": theme.value
-  };
+    if (!isActive(tag)) return {};
+    return {
+        "background-color": theme.value,
+        "border-color": theme.value
+    };
 }
 const isAffix = (tag: TagView) => {
-  return tag.meta && tag.meta.affix;
+    return tag.meta && tag.meta.affix;
 }
 const isFirstView = () => {
-  try {
-    return selectedTag.value.fullPath === '/index' || selectedTag.value.fullPath === visitedViews.value[1].fullPath;
-  } catch (err) {
-    return false;
-  }
+    try {
+        return selectedTag.value.fullPath === '/index' || selectedTag.value.fullPath === visitedViews.value[1].fullPath;
+    } catch (err) {
+        return false;
+    }
 }
 const isLastView = () => {
-  try {
-    return selectedTag.value.fullPath === visitedViews.value[visitedViews.value.length - 1].fullPath;
-  } catch (err) {
-    return false;
-  }
+    try {
+        return selectedTag.value.fullPath === visitedViews.value[visitedViews.value.length - 1].fullPath;
+    } catch (err) {
+        return false;
+    }
 }
 const filterAffixTags = (routes:RouteOption [], basePath = '') => {
-  let tags:TagView[] = []
-  routes.forEach(route => {
-    if (route.meta && route.meta.affix) {
-      const tagPath = getNormalPath(basePath + '/' + route.path);
-      tags.push({
-        fullPath: tagPath,
-        path: tagPath,
-        name: route.name,
-        meta: { ...route.meta }
-      })
-    }
-    if (route.children) {
-      const tempTags = filterAffixTags(route.children, route.path);
-      if (tempTags.length >= 1) {
-        tags = [...tags, ...tempTags];
-      }
-    }
-  })
-  return tags
+    let tags:TagView[] = []
+    routes.forEach(route => {
+        if (route.meta && route.meta.affix) {
+            const tagPath = getNormalPath(basePath + '/' + route.path);
+            tags.push({
+                fullPath: tagPath,
+                path: tagPath,
+                name: route.name,
+                meta: { ...route.meta }
+            })
+        }
+        if (route.children) {
+            const tempTags = filterAffixTags(route.children, route.path);
+            if (tempTags.length >= 1) {
+                tags = [...tags, ...tempTags];
+            }
+        }
+    })
+    return tags
 }
 const initTags = () => {
-  const res = filterAffixTags(routes.value);
-  affixTags.value = res;
-  for (const tag of res) {
-    // Must have tag name
-    if (tag.name) {
-      useTagsViewStore().addVisitedView(tag);
+    const res = filterAffixTags(routes.value);
+    affixTags.value = res;
+    for (const tag of res) {
+        // Must have tag name
+        if (tag.name) {
+            useTagsViewStore().addVisitedView(tag);
+        }
     }
-  }
 }
 const addTags = () => {
-  const { name } = route;
-  if (name) {
-    useTagsViewStore().addView(route);
-    if (route.meta.link) {
-      useTagsViewStore().addIframeView(route);
+    const { name } = route;
+    if (name) {
+        useTagsViewStore().addView(route);
+        if (route.meta.link) {
+            useTagsViewStore().addIframeView(route);
+        }
     }
-  }
-  return false
+    return false
 }
 const moveToCurrentTag = () => {
-  nextTick(() => {
-    for (const r of visitedViews.value) {
-      if (r.path === route.path) {
-        scrollPaneRef.value.moveToTarget(r);
-        // when query is different then update
-        if (r.fullPath !== route.fullPath) {
-          useTagsViewStore().updateVisitedView(route);
+    nextTick(() => {
+        for (const r of visitedViews.value) {
+            if (r.path === route.path) {
+                scrollPaneRef.value.moveToTarget(r);
+                // when query is different then update
+                if (r.fullPath !== route.fullPath) {
+                    useTagsViewStore().updateVisitedView(route);
+                }
+            }
         }
-      }
-    }
-  })
+    })
 }
 const refreshSelectedTag = (view: TagView) => {
-  proxy?.$tab.refreshPage(view);
-  if (route.meta.link) {
-    useTagsViewStore().delIframeView(route);
-  }
+    proxy?.$tab.refreshPage(view);
+    if (route.meta.link) {
+        useTagsViewStore().delIframeView(route);
+    }
 }
 const closeSelectedTag = (view: TagView) => {
-  proxy?.$tab.closePage(view).then(({ visitedViews }: any) => {
-    if (isActive(view)) {
-      toLastView(visitedViews, view);
-    }
-  })
+    proxy?.$tab.closePage(view).then(({ visitedViews }: any) => {
+        if (isActive(view)) {
+            toLastView(visitedViews, view);
+        }
+    })
 }
 const closeRightTags = () => {
-  proxy?.$tab.closeRightPage(selectedTag.value).then(visitedViews => {
-    if (!visitedViews.find(i => i.fullPath === route.fullPath)) {
-      toLastView(visitedViews);
-    }
-  })
+    proxy?.$tab.closeRightPage(selectedTag.value).then(visitedViews => {
+        if (!visitedViews.find(i => i.fullPath === route.fullPath)) {
+            toLastView(visitedViews);
+        }
+    })
 }
 const closeLeftTags = () => {
-  proxy?.$tab.closeLeftPage(selectedTag.value).then(visitedViews => {
-    if (!visitedViews.find(i => i.fullPath === route.fullPath)) {
-      toLastView(visitedViews);
-    }
-  })
+    proxy?.$tab.closeLeftPage(selectedTag.value).then(visitedViews => {
+        if (!visitedViews.find(i => i.fullPath === route.fullPath)) {
+            toLastView(visitedViews);
+        }
+    })
 }
 const closeOthersTags = () => {
-  router.push(selectedTag.value as RouteLocationRaw).catch(() => { });
-  proxy?.$tab.closeOtherPage(selectedTag.value).then(() => {
-    moveToCurrentTag();
-  })
+    router.push(selectedTag.value as RouteLocationRaw).catch(() => { });
+    proxy?.$tab.closeOtherPage(selectedTag.value).then(() => {
+        moveToCurrentTag();
+    })
 }
 const closeAllTags = (view: TagView) => {
-  proxy?.$tab.closeAllPage().then(({ visitedViews }) => {
-    if (affixTags.value.some(tag => tag.path === route.path)) {
-      return;
-    }
-    toLastView(visitedViews, view);
-  })
+    proxy?.$tab.closeAllPage().then(({ visitedViews }) => {
+        if (affixTags.value.some(tag => tag.path === route.path)) {
+            return;
+        }
+        toLastView(visitedViews, view);
+    })
 }
 const toLastView = (visitedViews:TagView[], view?: TagView) => {
-  const latestView = visitedViews.slice(-1)[0];
-  if (latestView) {
-    router.push(latestView.fullPath as string);
-  } else {
-    // now the default is to redirect to the home page if there is no tags-view,
-    // you can adjust it according to your needs.
-    if (view?.name === 'Dashboard') {
-      // to reload home page
-      router.replace({ path: '/redirect' + view?.fullPath });
+    const latestView = visitedViews.slice(-1)[0];
+    if (latestView) {
+        router.push(latestView.fullPath as string);
     } else {
-      router.push('/');
+        // now the default is to redirect to the home page if there is no tags-view,
+        // you can adjust it according to your needs.
+        if (view?.name === 'Dashboard') {
+            // to reload home page
+            router.replace({ path: '/redirect' + view?.fullPath });
+        } else {
+            router.push('/');
+        }
     }
-  }
 }
 const openMenu = (tag: TagView, e: MouseEvent) => {
-  const menuMinWidth = 105;
-  const offsetLeft = proxy?.$el.getBoundingClientRect().left; // container margin left
-  const offsetWidth = proxy?.$el.offsetWidth; // container width
-  const maxLeft = offsetWidth - menuMinWidth; // left boundary
-  const l = e.clientX - offsetLeft + 15; // 15: margin right
+    const menuMinWidth = 105;
+    const offsetLeft = proxy?.$el.getBoundingClientRect().left; // container margin left
+    const offsetWidth = proxy?.$el.offsetWidth; // container width
+    const maxLeft = offsetWidth - menuMinWidth; // left boundary
+    const l = e.clientX - offsetLeft + 15; // 15: margin right
 
-  if (l > maxLeft) {
-    left.value = maxLeft;
-  } else {
-    left.value = l;
-  }
+    if (l > maxLeft) {
+        left.value = maxLeft;
+    } else {
+        left.value = l;
+    }
 
-  top.value = e.clientY
-  visible.value = true;
-  selectedTag.value = tag;
+    top.value = e.clientY
+    visible.value = true;
+    selectedTag.value = tag;
 }
 const closeMenu = () => {
-  visible.value = false;
+    visible.value = false;
 }
 const handleScroll = () => {
-  closeMenu();
+    closeMenu();
 }
 
 
 onMounted(() => {
-  initTags();
-  addTags();
+    initTags();
+    addTags();
 })
 </script>
-
-<template>
-	<div id="tags-view-container" class="tags-view-container">
-		<scroll-pane ref="scrollPaneRef" class="tags-view-wrapper" @scroll="handleScroll">
-			<router-link
-				v-for="tag in visitedViews"
-				:key="tag.path"
-				:data-path="tag.path"
-				:class="isActive(tag) ? 'active' : ''"
-				:to="{ path: tag.path ? tag.path : '', query: tag.query, fullPath: tag.fullPath ? tag.fullPath : '' }"
-				class="tags-view-item"
-				:style="activeStyle(tag)"
-				@click.middle="!isAffix(tag) ? closeSelectedTag(tag) : ''"
-				@contextmenu.prevent="openMenu(tag, $event)"
-			>
-				{{ tag.title }}
-				<span v-if="!isAffix(tag)" @click.prevent.stop="closeSelectedTag(tag)">
-					<close class="el-icon-close" style="width: 1em; height: 1em;vertical-align: middle;" />
-				</span>
-			</router-link>
-		</scroll-pane>
-		<ul v-show="visible" :style="{ left: left + 'px', top: top + 'px' }" class="contextmenu">
-			<li @click="refreshSelectedTag(selectedTag)"><refresh-right style="width: 1em; height: 1em;" /> 鍒锋柊椤甸潰</li>
-			<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)"><close style="width: 1em; height: 1em;" /> 鍏抽棴褰撳墠</li>
-			<li @click="closeOthersTags"><circle-close style="width: 1em; height: 1em;" /> 鍏抽棴鍏朵粬</li>
-			<li v-if="!isFirstView()" @click="closeLeftTags"><back style="width: 1em; height: 1em;" /> 鍏抽棴宸︿晶</li>
-			<li v-if="!isLastView()" @click="closeRightTags"><right style="width: 1em; height: 1em;" /> 鍏抽棴鍙充晶</li>
-			<li @click="closeAllTags(selectedTag)"><circle-close style="width: 1em; height: 1em;" /> 鍏ㄩ儴鍏抽棴</li>
-		</ul>
-	</div>
-</template>
 
 <style lang="scss" scoped>
 .tags-view-container {
diff --git a/src/layout/index.vue b/src/layout/index.vue
index 673b0fd..8bc1c8b 100644
--- a/src/layout/index.vue
+++ b/src/layout/index.vue
@@ -52,18 +52,18 @@
 </script>
 
 <template>
-	<div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme }">
-		<div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
-		<side-bar v-if="!sidebar.hide" class="sidebar-container" />
-		<div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container">
-			<div :class="{ 'fixed-header': fixedHeader }">
-				<navbar ref="navbarRef" @setLayout="setLayout" />
-				<tags-view v-if="needTagsView" />
-			</div>
-			<app-main />
-			<settings ref="settingRef" />
-		</div>
-	</div>
+  <div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme }">
+    <div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
+    <side-bar v-if="!sidebar.hide" class="sidebar-container" />
+    <div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container">
+      <div :class="{ 'fixed-header': fixedHeader }">
+        <navbar ref="navbarRef" @setLayout="setLayout" />
+        <tags-view v-if="needTagsView" />
+      </div>
+      <app-main />
+      <settings ref="settingRef" />
+    </div>
+  </div>
 </template>
 
 <style lang="scss" scoped>
diff --git a/src/permission.ts b/src/permission.ts
index 3c76965..4713383 100644
--- a/src/permission.ts
+++ b/src/permission.ts
@@ -13,49 +13,49 @@
 const whiteList = ['/login', '/register'];
 
 router.beforeEach(async (to, from, next) => {
-	NProgress.start();
-	if (getToken()) {
-		to.meta.title && useSettingsStore().setTitle(to.meta.title as string);
-		/* has token*/
-		if (to.path === '/login') {
-			next({ path: '/' });
-			NProgress.done();
-		} else {
-			if (useUserStore().roles.length === 0) {
-				isRelogin.show = true;
-				// 鍒ゆ柇褰撳墠鐢ㄦ埛鏄惁宸叉媺鍙栧畬user_info淇℃伅
-				const [err] = await tos(useUserStore().getInfo());
-				if (err) {
-					await useUserStore().logout();
-					ElMessage.error(err);
-					next({ path: '/' });
-				} else {
-					isRelogin.show = false;
-					const accessRoutes = await usePermissionStore().generateRoutes();
-					// 鏍规嵁roles鏉冮檺鐢熸垚鍙闂殑璺敱琛�
-					accessRoutes.forEach((route) => {
-						if (!isHttp(route.path)) {
-							router.addRoute(route); // 鍔ㄦ�佹坊鍔犲彲璁块棶璺敱琛�
-						}
-					});
-					next({ ...to, replace: true }); // hack鏂规硶 纭繚addRoutes宸插畬鎴�
-				}
-			} else {
-				next();
-			}
-		}
-	} else {
-		// 娌℃湁token
-		if (whiteList.indexOf(to.path) !== -1) {
-			// 鍦ㄥ厤鐧诲綍鐧藉悕鍗曪紝鐩存帴杩涘叆
-			next();
-		} else {
-			next(`/login?redirect=${to.fullPath}`); // 鍚﹀垯鍏ㄩ儴閲嶅畾鍚戝埌鐧诲綍椤�
-			NProgress.done();
-		}
-	}
+  NProgress.start();
+  if (getToken()) {
+    to.meta.title && useSettingsStore().setTitle(to.meta.title as string);
+    /* has token*/
+    if (to.path === '/login') {
+      next({ path: '/' });
+      NProgress.done();
+    } else {
+      if (useUserStore().roles.length === 0) {
+        isRelogin.show = true;
+        // 鍒ゆ柇褰撳墠鐢ㄦ埛鏄惁宸叉媺鍙栧畬user_info淇℃伅
+        const [err] = await tos(useUserStore().getInfo());
+        if (err) {
+          await useUserStore().logout();
+          ElMessage.error(err);
+          next({ path: '/' });
+        } else {
+          isRelogin.show = false;
+          const accessRoutes = await usePermissionStore().generateRoutes();
+          // 鏍规嵁roles鏉冮檺鐢熸垚鍙闂殑璺敱琛�
+          accessRoutes.forEach((route) => {
+            if (!isHttp(route.path)) {
+              router.addRoute(route); // 鍔ㄦ�佹坊鍔犲彲璁块棶璺敱琛�
+            }
+          });
+          next({ ...to, replace: true }); // hack鏂规硶 纭繚addRoutes宸插畬鎴�
+        }
+      } else {
+        next();
+      }
+    }
+  } else {
+    // 娌℃湁token
+    if (whiteList.indexOf(to.path) !== -1) {
+      // 鍦ㄥ厤鐧诲綍鐧藉悕鍗曪紝鐩存帴杩涘叆
+      next();
+    } else {
+      next(`/login?redirect=${to.fullPath}`); // 鍚﹀垯鍏ㄩ儴閲嶅畾鍚戝埌鐧诲綍椤�
+      NProgress.done();
+    }
+  }
 });
 
 router.afterEach(() => {
-	NProgress.done();
+  NProgress.done();
 });
diff --git a/src/plugins/auth.ts b/src/plugins/auth.ts
index f9e63b7..74c91ee 100644
--- a/src/plugins/auth.ts
+++ b/src/plugins/auth.ts
@@ -1,60 +1,60 @@
 import useUserStore from '@/store/modules/user';
 
 const authPermission = (permission: string): boolean => {
-	const all_permission = '*:*:*';
-	const permissions: string[] = useUserStore().permissions;
-	if (permission && permission.length > 0) {
-		return permissions.some((v) => {
-			return all_permission === v || v === permission;
-		});
-	} else {
-		return false;
-	}
+  const all_permission = '*:*:*';
+  const permissions: string[] = useUserStore().permissions;
+  if (permission && permission.length > 0) {
+    return permissions.some((v) => {
+      return all_permission === v || v === permission;
+    });
+  } else {
+    return false;
+  }
 };
 
 const authRole = (role: string): boolean => {
-	const super_admin = 'admin';
-	const roles = useUserStore().roles;
-	if (role && role.length > 0) {
-		return roles.some((v) => {
-			return super_admin === v || v === role;
-		});
-	} else {
-		return false;
-	}
+  const super_admin = 'admin';
+  const roles = useUserStore().roles;
+  if (role && role.length > 0) {
+    return roles.some((v) => {
+      return super_admin === v || v === role;
+    });
+  } else {
+    return false;
+  }
 };
 
 export default {
-	// 楠岃瘉鐢ㄦ埛鏄惁鍏峰鏌愭潈闄�
-	hasPermi(permission: string): boolean {
-		return authPermission(permission);
-	},
-	// 楠岃瘉鐢ㄦ埛鏄惁鍚湁鎸囧畾鏉冮檺锛屽彧闇�鍖呭惈鍏朵腑涓�涓�
-	hasPermiOr(permissions: string[]): boolean {
-		return permissions.some((item) => {
-			return authPermission(item);
-		});
-	},
-	// 楠岃瘉鐢ㄦ埛鏄惁鍚湁鎸囧畾鏉冮檺锛屽繀椤诲叏閮ㄦ嫢鏈�
-	hasPermiAnd(permissions: string[]): boolean {
-		return permissions.every((item) => {
-			return authPermission(item);
-		});
-	},
-	// 楠岃瘉鐢ㄦ埛鏄惁鍏峰鏌愯鑹�
-	hasRole(role: string): boolean {
-		return authRole(role);
-	},
-	// 楠岃瘉鐢ㄦ埛鏄惁鍚湁鎸囧畾瑙掕壊锛屽彧闇�鍖呭惈鍏朵腑涓�涓�
-	hasRoleOr(roles: string[]): boolean {
-		return roles.some((item) => {
-			return authRole(item);
-		});
-	},
-	// 楠岃瘉鐢ㄦ埛鏄惁鍚湁鎸囧畾瑙掕壊锛屽繀椤诲叏閮ㄦ嫢鏈�
-	hasRoleAnd(roles: string[]): boolean {
-		return roles.every((item) => {
-			return authRole(item);
-		});
-	}
+  // 楠岃瘉鐢ㄦ埛鏄惁鍏峰鏌愭潈闄�
+  hasPermi(permission: string): boolean {
+    return authPermission(permission);
+  },
+  // 楠岃瘉鐢ㄦ埛鏄惁鍚湁鎸囧畾鏉冮檺锛屽彧闇�鍖呭惈鍏朵腑涓�涓�
+  hasPermiOr(permissions: string[]): boolean {
+    return permissions.some((item) => {
+      return authPermission(item);
+    });
+  },
+  // 楠岃瘉鐢ㄦ埛鏄惁鍚湁鎸囧畾鏉冮檺锛屽繀椤诲叏閮ㄦ嫢鏈�
+  hasPermiAnd(permissions: string[]): boolean {
+    return permissions.every((item) => {
+      return authPermission(item);
+    });
+  },
+  // 楠岃瘉鐢ㄦ埛鏄惁鍏峰鏌愯鑹�
+  hasRole(role: string): boolean {
+    return authRole(role);
+  },
+  // 楠岃瘉鐢ㄦ埛鏄惁鍚湁鎸囧畾瑙掕壊锛屽彧闇�鍖呭惈鍏朵腑涓�涓�
+  hasRoleOr(roles: string[]): boolean {
+    return roles.some((item) => {
+      return authRole(item);
+    });
+  },
+  // 楠岃瘉鐢ㄦ埛鏄惁鍚湁鎸囧畾瑙掕壊锛屽繀椤诲叏閮ㄦ嫢鏈�
+  hasRoleAnd(roles: string[]): boolean {
+    return roles.every((item) => {
+      return authRole(item);
+    });
+  }
 };
diff --git a/src/plugins/cache.ts b/src/plugins/cache.ts
index c3cc7eb..cf43680 100644
--- a/src/plugins/cache.ts
+++ b/src/plugins/cache.ts
@@ -1,77 +1,77 @@
 const sessionCache = {
-	set(key: string, value: any) {
-		if (!sessionStorage) {
-			return;
-		}
-		if (key != null && value != null) {
-			sessionStorage.setItem(key, value);
-		}
-	},
-	get(key: string) {
-		if (!sessionStorage) {
-			return null;
-		}
-		if (key == null) {
-			return null;
-		}
-		return sessionStorage.getItem(key);
-	},
-	setJSON(key: string, jsonValue: any) {
-		if (jsonValue != null) {
-			this.set(key, JSON.stringify(jsonValue));
-		}
-	},
-	getJSON(key: string) {
-		const value = this.get(key);
-		if (value != null) {
-			return JSON.parse(value);
-		}
-	},
-	remove(key: string) {
-		sessionStorage.removeItem(key);
-	}
+  set(key: string, value: any) {
+    if (!sessionStorage) {
+      return;
+    }
+    if (key != null && value != null) {
+      sessionStorage.setItem(key, value);
+    }
+  },
+  get(key: string) {
+    if (!sessionStorage) {
+      return null;
+    }
+    if (key == null) {
+      return null;
+    }
+    return sessionStorage.getItem(key);
+  },
+  setJSON(key: string, jsonValue: any) {
+    if (jsonValue != null) {
+      this.set(key, JSON.stringify(jsonValue));
+    }
+  },
+  getJSON(key: string) {
+    const value = this.get(key);
+    if (value != null) {
+      return JSON.parse(value);
+    }
+  },
+  remove(key: string) {
+    sessionStorage.removeItem(key);
+  }
 };
 const localCache = {
-	set(key: string, value: any) {
-		if (!localStorage) {
-			return;
-		}
-		if (key != null && value != null) {
-			localStorage.setItem(key, value);
-		}
-	},
-	get(key: string) {
-		if (!localStorage) {
-			return null;
-		}
-		if (key == null) {
-			return null;
-		}
-		return localStorage.getItem(key);
-	},
-	setJSON(key: string, jsonValue: any) {
-		if (jsonValue != null) {
-			this.set(key, JSON.stringify(jsonValue));
-		}
-	},
-	getJSON(key: string) {
-		const value = this.get(key);
-		if (value != null) {
-			return JSON.parse(value);
-		}
-	},
-	remove(key: string) {
-		localStorage.removeItem(key);
-	}
+  set(key: string, value: any) {
+    if (!localStorage) {
+      return;
+    }
+    if (key != null && value != null) {
+      localStorage.setItem(key, value);
+    }
+  },
+  get(key: string) {
+    if (!localStorage) {
+      return null;
+    }
+    if (key == null) {
+      return null;
+    }
+    return localStorage.getItem(key);
+  },
+  setJSON(key: string, jsonValue: any) {
+    if (jsonValue != null) {
+      this.set(key, JSON.stringify(jsonValue));
+    }
+  },
+  getJSON(key: string) {
+    const value = this.get(key);
+    if (value != null) {
+      return JSON.parse(value);
+    }
+  },
+  remove(key: string) {
+    localStorage.removeItem(key);
+  }
 };
 
 export default {
-	/**
-	 * 浼氳瘽绾х紦瀛�
-	 */
-	session: sessionCache,
-	/**
-	 * 鏈湴缂撳瓨
-	 */
-	local: localCache
+  /**
+   * 浼氳瘽绾х紦瀛�
+   */
+  session: sessionCache,
+  /**
+   * 鏈湴缂撳瓨
+   */
+  local: localCache
 };
diff --git a/src/plugins/download.ts b/src/plugins/download.ts
index 3e963a7..2640763 100644
--- a/src/plugins/download.ts
+++ b/src/plugins/download.ts
@@ -8,53 +8,53 @@
 const baseURL = import.meta.env.VITE_APP_BASE_API;
 let downloadLoadingInstance: LoadingInstance;
 export default {
-	async oss(ossId: string | number) {
-		const url = baseURL + '/system/oss/download/' + ossId;
-		downloadLoadingInstance = ElLoading.service({ text: '姝e湪涓嬭浇鏁版嵁锛岃绋嶅��', background: 'rgba(0, 0, 0, 0.7)' });
-		try {
-			const res = await axios({
-				method: 'get',
-				url: url,
-				responseType: 'blob',
-				headers: { Authorization: 'Bearer ' + getToken() }
-			});
-			const isBlob = blobValidate(res.data);
-			if (isBlob) {
-				const blob = new Blob([res.data], { type: 'application/octet-stream' });
-				FileSaver.saveAs(blob, decodeURIComponent(res.headers['download-filename'] as string));
-			} else {
-				this.printErrMsg(res.data);
-			}
-			downloadLoadingInstance.close();
-		} catch (r) {
-			console.error(r);
-			ElMessage.error('涓嬭浇鏂囦欢鍑虹幇閿欒锛岃鑱旂郴绠$悊鍛橈紒');
-			downloadLoadingInstance.close();
-		}
-	},
-	async zip(url: string, name: string) {
-		url = baseURL + url;
-		const res = await axios({
-			method: 'get',
-			url: url,
-			responseType: 'blob',
-			headers: {
-				Authorization: 'Bearer ' + getToken(),
-				datasource: localStorage.getItem('dataName')
-			}
-		});
-		const isBlob = blobValidate(res.data);
-		if (isBlob) {
-			const blob = new Blob([res.data], { type: 'application/zip' });
-			FileSaver.saveAs(blob, name);
-		} else {
-			this.printErrMsg(res.data);
-		}
-	},
-	async printErrMsg(data: any) {
-		const resText = await data.text();
-		const rspObj = JSON.parse(resText);
-		const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'];
-		ElMessage.error(errMsg);
-	}
+  async oss(ossId: string | number) {
+    const url = baseURL + '/system/oss/download/' + ossId;
+    downloadLoadingInstance = ElLoading.service({ text: '姝e湪涓嬭浇鏁版嵁锛岃绋嶅��', background: 'rgba(0, 0, 0, 0.7)' });
+    try {
+      const res = await axios({
+        method: 'get',
+        url: url,
+        responseType: 'blob',
+        headers: { Authorization: 'Bearer ' + getToken() }
+      });
+      const isBlob = blobValidate(res.data);
+      if (isBlob) {
+        const blob = new Blob([res.data], { type: 'application/octet-stream' });
+        FileSaver.saveAs(blob, decodeURIComponent(res.headers['download-filename'] as string));
+      } else {
+        this.printErrMsg(res.data);
+      }
+      downloadLoadingInstance.close();
+    } catch (r) {
+      console.error(r);
+      ElMessage.error('涓嬭浇鏂囦欢鍑虹幇閿欒锛岃鑱旂郴绠$悊鍛橈紒');
+      downloadLoadingInstance.close();
+    }
+  },
+  async zip(url: string, name: string) {
+    url = baseURL + url;
+    const res = await axios({
+      method: 'get',
+      url: url,
+      responseType: 'blob',
+      headers: {
+        Authorization: 'Bearer ' + getToken(),
+        datasource: localStorage.getItem('dataName')
+      }
+    });
+    const isBlob = blobValidate(res.data);
+    if (isBlob) {
+      const blob = new Blob([res.data], { type: 'application/zip' });
+      FileSaver.saveAs(blob, name);
+    } else {
+      this.printErrMsg(res.data);
+    }
+  },
+  async printErrMsg(data: any) {
+    const resText = await data.text();
+    const rspObj = JSON.parse(resText);
+    const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'];
+    ElMessage.error(errMsg);
+  }
 };
diff --git a/src/plugins/index.ts b/src/plugins/index.ts
index dc49340..09d550a 100644
--- a/src/plugins/index.ts
+++ b/src/plugins/index.ts
@@ -7,18 +7,18 @@
 import { App } from 'vue';
 
 export default function installPlugin(app: App) {
-	// 椤电鎿嶄綔
-	app.config.globalProperties.$tab = tab;
+  // 椤电鎿嶄綔
+  app.config.globalProperties.$tab = tab;
 
-	// 妯℃�佹瀵硅薄
-	app.config.globalProperties.$modal = modal;
+  // 妯℃�佹瀵硅薄
+  app.config.globalProperties.$modal = modal;
 
-	// 缂撳瓨瀵硅薄
-	app.config.globalProperties.$cache = cache;
+  // 缂撳瓨瀵硅薄
+  app.config.globalProperties.$cache = cache;
 
-	// 涓嬭浇鏂囦欢
-	app.config.globalProperties.$download = download;
+  // 涓嬭浇鏂囦欢
+  app.config.globalProperties.$download = download;
 
-	// 璁よ瘉瀵硅薄
-	app.config.globalProperties.$auth = auth;
+  // 璁よ瘉瀵硅薄
+  app.config.globalProperties.$auth = auth;
 }
diff --git a/src/plugins/modal.ts b/src/plugins/modal.ts
index c18cb0b..9526623 100644
--- a/src/plugins/modal.ts
+++ b/src/plugins/modal.ts
@@ -2,80 +2,80 @@
 import { LoadingInstance } from 'element-plus/es/components/loading/src/loading';
 let loadingInstance: LoadingInstance;
 export default {
-	// 娑堟伅鎻愮ず
-	msg(content: string) {
-		ElMessage.info(content);
-	},
-	// 閿欒娑堟伅
-	msgError(content: string) {
-		ElMessage.error(content);
-	},
-	// 鎴愬姛娑堟伅
-	msgSuccess(content: string) {
-		ElMessage.success(content);
-	},
-	// 璀﹀憡娑堟伅
-	msgWarning(content: string) {
-		ElMessage.warning(content);
-	},
-	// 寮瑰嚭鎻愮ず
-	alert(content: string) {
-		ElMessageBox.alert(content, '绯荤粺鎻愮ず');
-	},
-	// 閿欒鎻愮ず
-	alertError(content: string) {
-		ElMessageBox.alert(content, '绯荤粺鎻愮ず', { type: 'error' });
-	},
-	// 鎴愬姛鎻愮ず
-	alertSuccess(content: string, s: string, p: { dangerouslyUseHTMLString: boolean }) {
-		ElMessageBox.alert(content, '绯荤粺鎻愮ず', { type: 'success' });
-	},
-	// 璀﹀憡鎻愮ず
-	alertWarning(content: string) {
-		ElMessageBox.alert(content, '绯荤粺鎻愮ず', { type: 'warning' });
-	},
-	// 閫氱煡鎻愮ず
-	notify(content: string) {
-		ElNotification.info(content);
-	},
-	// 閿欒閫氱煡
-	notifyError(content: string) {
-		ElNotification.error(content);
-	},
-	// 鎴愬姛閫氱煡
-	notifySuccess(content: string) {
-		ElNotification.success(content);
-	},
-	// 璀﹀憡閫氱煡
-	notifyWarning(content: string) {
-		ElNotification.warning(content);
-	},
-	// 纭绐椾綋
-	confirm(content: string): Promise<MessageBoxData> {
-		return ElMessageBox.confirm(content, '绯荤粺鎻愮ず', {
-			confirmButtonText: '纭畾',
-			cancelButtonText: '鍙栨秷',
-			type: 'warning'
-		});
-	},
-	// 鎻愪氦鍐呭
-	prompt(content: string) {
-		return ElMessageBox.prompt(content, '绯荤粺鎻愮ず', {
-			confirmButtonText: '纭畾',
-			cancelButtonText: '鍙栨秷',
-			type: 'warning'
-		});
-	},
-	// 鎵撳紑閬僵灞�
-	loading(content: string) {
-		loadingInstance = ElLoading.service({
-			lock: true,
-			text: content,
-			background: 'rgba(0, 0, 0, 0.7)'
-		});
-	},
-	// 鍏抽棴閬僵灞�
-	closeLoading() {
-		loadingInstance.close();
-	}
+  // 娑堟伅鎻愮ず
+  msg(content: string) {
+    ElMessage.info(content);
+  },
+  // 閿欒娑堟伅
+  msgError(content: string) {
+    ElMessage.error(content);
+  },
+  // 鎴愬姛娑堟伅
+  msgSuccess(content: string) {
+    ElMessage.success(content);
+  },
+  // 璀﹀憡娑堟伅
+  msgWarning(content: string) {
+    ElMessage.warning(content);
+  },
+  // 寮瑰嚭鎻愮ず
+  alert(content: string) {
+    ElMessageBox.alert(content, '绯荤粺鎻愮ず');
+  },
+  // 閿欒鎻愮ず
+  alertError(content: string) {
+    ElMessageBox.alert(content, '绯荤粺鎻愮ず', { type: 'error' });
+  },
+  // 鎴愬姛鎻愮ず
+  alertSuccess(content: string, s: string, p: { dangerouslyUseHTMLString: boolean }) {
+    ElMessageBox.alert(content, '绯荤粺鎻愮ず', { type: 'success' });
+  },
+  // 璀﹀憡鎻愮ず
+  alertWarning(content: string) {
+    ElMessageBox.alert(content, '绯荤粺鎻愮ず', { type: 'warning' });
+  },
+  // 閫氱煡鎻愮ず
+  notify(content: string) {
+    ElNotification.info(content);
+  },
+  // 閿欒閫氱煡
+  notifyError(content: string) {
+    ElNotification.error(content);
+  },
+  // 鎴愬姛閫氱煡
+  notifySuccess(content: string) {
+    ElNotification.success(content);
+  },
+  // 璀﹀憡閫氱煡
+  notifyWarning(content: string) {
+    ElNotification.warning(content);
+  },
+  // 纭绐椾綋
+  confirm(content: string): Promise<MessageBoxData> {
+    return ElMessageBox.confirm(content, '绯荤粺鎻愮ず', {
+      confirmButtonText: '纭畾',
+      cancelButtonText: '鍙栨秷',
+      type: 'warning'
+    });
+  },
+  // 鎻愪氦鍐呭
+  prompt(content: string) {
+    return ElMessageBox.prompt(content, '绯荤粺鎻愮ず', {
+      confirmButtonText: '纭畾',
+      cancelButtonText: '鍙栨秷',
+      type: 'warning'
+    });
+  },
+  // 鎵撳紑閬僵灞�
+  loading(content: string) {
+    loadingInstance = ElLoading.service({
+      lock: true,
+      text: content,
+      background: 'rgba(0, 0, 0, 0.7)'
+    });
+  },
+  // 鍏抽棴閬僵灞�
+  closeLoading() {
+    loadingInstance.close();
+  }
 };
diff --git a/src/plugins/svgicon.ts b/src/plugins/svgicon.ts
index 2975b0e..8c68609 100644
--- a/src/plugins/svgicon.ts
+++ b/src/plugins/svgicon.ts
@@ -2,9 +2,9 @@
 import { App } from 'vue';
 
 export default {
-	install: (app: App) => {
-		for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
-			app.component(key, component);
-		}
-	}
+  install: (app: App) => {
+    for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
+      app.component(key, component);
+    }
+  }
 };
diff --git a/src/plugins/tab.ts b/src/plugins/tab.ts
index ad6f1c3..bc4128c 100644
--- a/src/plugins/tab.ts
+++ b/src/plugins/tab.ts
@@ -3,63 +3,63 @@
 import { TagView, RouteLocationRaw } from 'vue-router';
 
 export default {
-	// 鍒锋柊褰撳墠tab椤电
-	async refreshPage(obj: TagView): Promise<void> {
-		const { path, query, matched } = router.currentRoute.value;
-		if (obj === undefined) {
-			matched.forEach((m) => {
-				if (m.components && m.components.default && m.components.default.name) {
-					if (!['Layout', 'ParentView'].includes(m.components.default.name)) {
-						obj = { name: m.components.default.name, path: path, query: query };
-					}
-				}
-			});
-		}
-		// prettier-ignore
-		await useTagsViewStore().delCachedView(obj)
-		router.replace({
-			path: '/redirect' + obj.path,
-			query: obj.query
-		});
-	},
-	// 鍏抽棴褰撳墠tab椤电锛屾墦寮�鏂伴〉绛�
-	closeOpenPage(obj: RouteLocationRaw): void {
-		useTagsViewStore().delView(router.currentRoute.value);
-		if (obj !== undefined) {
-			router.push(obj);
-		}
-	},
-	// 鍏抽棴鎸囧畾tab椤电
-	async closePage(obj?: TagView): Promise<{ visitedViews: TagView[]; cachedViews: string[] } | any> {
-		if (obj === undefined) {
-			// prettier-ignore
-			const { lastPath } = await useTagsViewStore().delView(router.currentRoute.value) as any
-			return router.push(lastPath || '/index');
-		}
-		return useTagsViewStore().delView(obj);
-	},
-	// 鍏抽棴鎵�鏈塼ab椤电
-	closeAllPage() {
-		return useTagsViewStore().delAllViews();
-	},
-	// 鍏抽棴宸︿晶tab椤电
-	closeLeftPage(obj: TagView) {
-		return useTagsViewStore().delLeftTags(obj || router.currentRoute.value);
-	},
-	// 鍏抽棴鍙充晶tab椤电
-	closeRightPage(obj: TagView) {
-		return useTagsViewStore().delRightTags(obj || router.currentRoute.value);
-	},
-	// 鍏抽棴鍏朵粬tab椤电
-	closeOtherPage(obj: TagView) {
-		return useTagsViewStore().delOthersViews(obj || router.currentRoute.value);
-	},
-	// 鎵撳紑tab椤电
-	openPage(url: RouteLocationRaw) {
-		return router.push(url);
-	},
-	// 淇敼tab椤电
-	updatePage(obj: TagView) {
-		return useTagsViewStore().updateVisitedView(obj);
-	}
+  // 鍒锋柊褰撳墠tab椤电
+  async refreshPage(obj: TagView): Promise<void> {
+    const { path, query, matched } = router.currentRoute.value;
+    if (obj === undefined) {
+      matched.forEach((m) => {
+        if (m.components && m.components.default && m.components.default.name) {
+          if (!['Layout', 'ParentView'].includes(m.components.default.name)) {
+            obj = { name: m.components.default.name, path: path, query: query };
+          }
+        }
+      });
+    }
+    // prettier-ignore
+    await useTagsViewStore().delCachedView(obj)
+    router.replace({
+      path: '/redirect' + obj.path,
+      query: obj.query
+    });
+  },
+  // 鍏抽棴褰撳墠tab椤电锛屾墦寮�鏂伴〉绛�
+  closeOpenPage(obj: RouteLocationRaw): void {
+    useTagsViewStore().delView(router.currentRoute.value);
+    if (obj !== undefined) {
+      router.push(obj);
+    }
+  },
+  // 鍏抽棴鎸囧畾tab椤电
+  async closePage(obj?: TagView): Promise<{ visitedViews: TagView[]; cachedViews: string[] } | any> {
+    if (obj === undefined) {
+      // prettier-ignore
+      const { lastPath } = await useTagsViewStore().delView(router.currentRoute.value) as any
+      return router.push(lastPath || '/index');
+    }
+    return useTagsViewStore().delView(obj);
+  },
+  // 鍏抽棴鎵�鏈塼ab椤电
+  closeAllPage() {
+    return useTagsViewStore().delAllViews();
+  },
+  // 鍏抽棴宸︿晶tab椤电
+  closeLeftPage(obj: TagView) {
+    return useTagsViewStore().delLeftTags(obj || router.currentRoute.value);
+  },
+  // 鍏抽棴鍙充晶tab椤电
+  closeRightPage(obj: TagView) {
+    return useTagsViewStore().delRightTags(obj || router.currentRoute.value);
+  },
+  // 鍏抽棴鍏朵粬tab椤电
+  closeOtherPage(obj: TagView) {
+    return useTagsViewStore().delOthersViews(obj || router.currentRoute.value);
+  },
+  // 鎵撳紑tab椤电
+  openPage(url: RouteLocationRaw) {
+    return router.push(url);
+  },
+  // 淇敼tab椤电
+  updatePage(obj: TagView) {
+    return useTagsViewStore().updateVisitedView(obj);
+  }
 };
diff --git a/src/router/index.ts b/src/router/index.ts
index 5c5388c..bbfc448 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -26,154 +26,154 @@
 
 // 鍏叡璺敱
 export const constantRoutes: RouteOption[] = [
-	{
-		path: '/redirect',
-		component: Layout,
-		hidden: true,
-		children: [
-			{
-				path: '/redirect/:path(.*)',
-				component: () => import('@/views/redirect/index.vue')
-			}
-		]
-	},
-	{
-		path: '/login',
-		component: () => import('@/views/login.vue'),
-		hidden: true
-	},
-	{
-		path: '/register',
-		component: () => import('@/views/register.vue'),
-		hidden: true
-	},
-	{
-		path: '/:pathMatch(.*)*',
-		component: () => import('@/views/error/404.vue'),
-		hidden: true
-	},
-	{
-		path: '/401',
-		component: () => import('@/views/error/401.vue'),
-		hidden: true
-	},
-	{
-		path: '',
-		component: Layout,
-		redirect: '/index',
-		children: [
-			{
-				path: '/index',
-				component: () => import('@/views/index.vue'),
-				name: 'Index',
-				meta: { title: '棣栭〉', icon: 'dashboard', affix: true }
-			}
-		]
-	},
-	{
-		path: '/user',
-		component: Layout,
-		hidden: true,
-		redirect: 'noredirect',
-		children: [
-			{
-				path: 'profile',
-				component: () => import('@/views/system/user/profile/index.vue'),
-				name: 'Profile',
-				meta: { title: '涓汉涓績', icon: 'user' }
-			}
-		]
-	}
+  {
+    path: '/redirect',
+    component: Layout,
+    hidden: true,
+    children: [
+      {
+        path: '/redirect/:path(.*)',
+        component: () => import('@/views/redirect/index.vue')
+      }
+    ]
+  },
+  {
+    path: '/login',
+    component: () => import('@/views/login.vue'),
+    hidden: true
+  },
+  {
+    path: '/register',
+    component: () => import('@/views/register.vue'),
+    hidden: true
+  },
+  {
+    path: '/:pathMatch(.*)*',
+    component: () => import('@/views/error/404.vue'),
+    hidden: true
+  },
+  {
+    path: '/401',
+    component: () => import('@/views/error/401.vue'),
+    hidden: true
+  },
+  {
+    path: '',
+    component: Layout,
+    redirect: '/index',
+    children: [
+      {
+        path: '/index',
+        component: () => import('@/views/index.vue'),
+        name: 'Index',
+        meta: { title: '棣栭〉', icon: 'dashboard', affix: true }
+      }
+    ]
+  },
+  {
+    path: '/user',
+    component: Layout,
+    hidden: true,
+    redirect: 'noredirect',
+    children: [
+      {
+        path: 'profile',
+        component: () => import('@/views/system/user/profile/index.vue'),
+        name: 'Profile',
+        meta: { title: '涓汉涓績', icon: 'user' }
+      }
+    ]
+  }
 ];
 
 // 鍔ㄦ�佽矾鐢憋紝鍩轰簬鐢ㄦ埛鏉冮檺鍔ㄦ�佸幓鍔犺浇
 export const dynamicRoutes: RouteOption[] = [
-	{
-		path: '/system/user-auth',
-		component: Layout,
-		hidden: true,
-		permissions: ['system:user:edit'],
-		children: [
-			{
-				path: 'role/:userId(\\d+)',
-				component: () => import('@/views/system/user/authRole.vue'),
-				name: 'AuthRole',
-				meta: { title: '鍒嗛厤瑙掕壊', activeMenu: '/system/user', icon: '' }
-			}
-		]
-	},
-	{
-		path: '/system/role-auth',
-		component: Layout,
-		hidden: true,
-		permissions: ['system:role:edit'],
-		children: [
-			{
-				path: 'user/:roleId(\\d+)',
-				component: () => import('@/views/system/role/authUser.vue'),
-				name: 'AuthUser',
-				meta: { title: '鍒嗛厤鐢ㄦ埛', activeMenu: '/system/role', icon: '' }
-			}
-		]
-	},
-	{
-		path: '/system/dict-data',
-		component: Layout,
-		hidden: true,
-		permissions: ['system:dict:list'],
-		children: [
-			{
-				path: 'index/:dictId(\\d+)',
-				component: () => import('@/views/system/dict/data.vue'),
-				name: 'Data',
-				meta: { title: '瀛楀吀鏁版嵁', activeMenu: '/system/dict', icon: '' }
-			}
-		]
-	},
-	{
-		path: '/system/oss-config',
-		component: Layout,
-		hidden: true,
-		permissions: ['monitor:job:list'],
-		children: [
-			{
-				path: 'index',
-				component: () => import('@/views/system/oss/config.vue'),
-				name: 'OssConfig',
-				meta: { title: '閰嶇疆绠$悊', activeMenu: '/system/oss', icon: '' }
-			}
-		]
-	},
-	{
-		path: '/tool/gen-edit',
-		component: Layout,
-		hidden: true,
-		permissions: ['tool:gen:edit'],
-		children: [
-			{
-				path: 'index/:tableId(\\d+)',
-				component: () => import('@/views/tool/gen/editTable.vue'),
-				name: 'GenEdit',
-				meta: { title: '淇敼鐢熸垚閰嶇疆', activeMenu: '/tool/gen', icon: '' }
-			}
-		]
-	}
+  {
+    path: '/system/user-auth',
+    component: Layout,
+    hidden: true,
+    permissions: ['system:user:edit'],
+    children: [
+      {
+        path: 'role/:userId(\\d+)',
+        component: () => import('@/views/system/user/authRole.vue'),
+        name: 'AuthRole',
+        meta: { title: '鍒嗛厤瑙掕壊', activeMenu: '/system/user', icon: '' }
+      }
+    ]
+  },
+  {
+    path: '/system/role-auth',
+    component: Layout,
+    hidden: true,
+    permissions: ['system:role:edit'],
+    children: [
+      {
+        path: 'user/:roleId(\\d+)',
+        component: () => import('@/views/system/role/authUser.vue'),
+        name: 'AuthUser',
+        meta: { title: '鍒嗛厤鐢ㄦ埛', activeMenu: '/system/role', icon: '' }
+      }
+    ]
+  },
+  {
+    path: '/system/dict-data',
+    component: Layout,
+    hidden: true,
+    permissions: ['system:dict:list'],
+    children: [
+      {
+        path: 'index/:dictId(\\d+)',
+        component: () => import('@/views/system/dict/data.vue'),
+        name: 'Data',
+        meta: { title: '瀛楀吀鏁版嵁', activeMenu: '/system/dict', icon: '' }
+      }
+    ]
+  },
+  {
+    path: '/system/oss-config',
+    component: Layout,
+    hidden: true,
+    permissions: ['monitor:job:list'],
+    children: [
+      {
+        path: 'index',
+        component: () => import('@/views/system/oss/config.vue'),
+        name: 'OssConfig',
+        meta: { title: '閰嶇疆绠$悊', activeMenu: '/system/oss', icon: '' }
+      }
+    ]
+  },
+  {
+    path: '/tool/gen-edit',
+    component: Layout,
+    hidden: true,
+    permissions: ['tool:gen:edit'],
+    children: [
+      {
+        path: 'index/:tableId(\\d+)',
+        component: () => import('@/views/tool/gen/editTable.vue'),
+        name: 'GenEdit',
+        meta: { title: '淇敼鐢熸垚閰嶇疆', activeMenu: '/tool/gen', icon: '' }
+      }
+    ]
+  }
 ];
 
 /**
  * 鍒涘缓璺敱
  */
 const router = createRouter({
-	history: createWebHistory(import.meta.env.VITE_APP_CONTEXT_PATH),
-	routes: constantRoutes,
-	// 鍒锋柊鏃讹紝婊氬姩鏉′綅缃繕鍘�
-	scrollBehavior(to, from, savedPosition) {
-		if (savedPosition) {
-			return savedPosition;
-		} else {
-			return { top: 0 };
-		}
-	}
+  history: createWebHistory(import.meta.env.VITE_APP_CONTEXT_PATH),
+  routes: constantRoutes,
+  // 鍒锋柊鏃讹紝婊氬姩鏉′綅缃繕鍘�
+  scrollBehavior(to, from, savedPosition) {
+    if (savedPosition) {
+      return savedPosition;
+    } else {
+      return { top: 0 };
+    }
+  }
 });
 
 export default router;
diff --git a/src/settings.ts b/src/settings.ts
index 25f7995..dd171e7 100644
--- a/src/settings.ts
+++ b/src/settings.ts
@@ -1,55 +1,55 @@
 const setting: DefaultSettings = {
-	/**
-	 * 缃戦〉鏍囬
-	 */
-	title: import.meta.env.VITE_APP_TITLE,
+  /**
+   * 缃戦〉鏍囬
+   */
+  title: import.meta.env.VITE_APP_TITLE,
 
-	theme: '#409EFF',
+  theme: '#409EFF',
 
-	/**
-	 * 渚ц竟鏍忎富棰� 娣辫壊涓婚theme-dark锛屾祬鑹蹭富棰榯heme-light
-	 */
-	sideTheme: 'theme-dark',
-	/**
-	 * 鏄惁绯荤粺甯冨眬閰嶇疆
-	 */
-	showSettings: false,
+  /**
+   * 渚ц竟鏍忎富棰� 娣辫壊涓婚theme-dark锛屾祬鑹蹭富棰榯heme-light
+   */
+  sideTheme: 'theme-dark',
+  /**
+   * 鏄惁绯荤粺甯冨眬閰嶇疆
+   */
+  showSettings: false,
 
-	/**
-	 * 鏄惁鏄剧ず椤堕儴瀵艰埅
-	 */
-	topNav: false,
+  /**
+   * 鏄惁鏄剧ず椤堕儴瀵艰埅
+   */
+  topNav: false,
 
-	/**
-	 * 鏄惁鏄剧ず tagsView
-	 */
-	tagsView: true,
+  /**
+   * 鏄惁鏄剧ず tagsView
+   */
+  tagsView: true,
 
-	/**
-	 * 鏄惁鍥哄畾澶撮儴
-	 */
-	fixedHeader: false,
+  /**
+   * 鏄惁鍥哄畾澶撮儴
+   */
+  fixedHeader: false,
 
-	/**
-	 * 鏄惁鏄剧ずlogo
-	 */
-	sidebarLogo: true,
+  /**
+   * 鏄惁鏄剧ずlogo
+   */
+  sidebarLogo: true,
 
-	/**
-	 * 鏄惁鏄剧ず鍔ㄦ�佹爣棰�
-	 */
-	dynamicTitle: false,
+  /**
+   * 鏄惁鏄剧ず鍔ㄦ�佹爣棰�
+   */
+  dynamicTitle: false,
 
-	/**
-	 * @type {string | array} 'production' | ['production', 'development']
-	 * @description Need show err logs component.
-	 * The default is only used in the production env
-	 * If you want to also use it in dev, you can pass ['production', 'development']
-	 */
-	errorLog: 'production',
+  /**
+   * @type {string | array} 'production' | ['production', 'development']
+   * @description Need show err logs component.
+   * The default is only used in the production env
+   * If you want to also use it in dev, you can pass ['production', 'development']
+   */
+  errorLog: 'production',
 
-	animationEnable: false,
+  animationEnable: false,
 
-	dark: false
+  dark: false
 };
 export default setting;
diff --git a/src/store/modules/app.ts b/src/store/modules/app.ts
index b53dbad..fd47c82 100644
--- a/src/store/modules/app.ts
+++ b/src/store/modules/app.ts
@@ -3,71 +3,71 @@
 import en from 'element-plus/es/locale/lang/en';
 
 export const useAppStore = defineStore('app', () => {
-	const sidebarStatus = Cookies.get('sidebarStatus');
-	const sidebar = reactive({
-		opened: sidebarStatus ? !!+sidebarStatus : true,
-		withoutAnimation: false,
-		hide: false
-	});
-	const device = ref<string>('desktop');
-	const size = ref(Cookies.get('size') || 'default');
-	// 璇█
-	const language = ref(Cookies.get('language'));
-	const locale = computed(() => {
-		if (language?.value == 'en') {
-			return en;
-		} else {
-			return zhCn;
-		}
-	});
+  const sidebarStatus = Cookies.get('sidebarStatus');
+  const sidebar = reactive({
+    opened: sidebarStatus ? !!+sidebarStatus : true,
+    withoutAnimation: false,
+    hide: false
+  });
+  const device = ref<string>('desktop');
+  const size = ref(Cookies.get('size') || 'default');
+  // 璇█
+  const language = ref(Cookies.get('language'));
+  const locale = computed(() => {
+    if (language?.value == 'en') {
+      return en;
+    } else {
+      return zhCn;
+    }
+  });
 
-	const toggleSideBar = (withoutAnimation?: boolean) => {
-		if (sidebar.hide) {
-			return false;
-		}
+  const toggleSideBar = (withoutAnimation?: boolean) => {
+    if (sidebar.hide) {
+      return false;
+    }
 
-		sidebar.opened = !sidebar.opened;
-		sidebar.withoutAnimation = withoutAnimation as boolean;
-		if (sidebar.opened) {
-			Cookies.set('sidebarStatus', '1');
-		} else {
-			Cookies.set('sidebarStatus', '0');
-		}
-	};
+    sidebar.opened = !sidebar.opened;
+    sidebar.withoutAnimation = withoutAnimation as boolean;
+    if (sidebar.opened) {
+      Cookies.set('sidebarStatus', '1');
+    } else {
+      Cookies.set('sidebarStatus', '0');
+    }
+  };
 
-	const closeSideBar = ({ withoutAnimation }: any): void => {
-		Cookies.set('sidebarStatus', '0');
-		sidebar.opened = false;
-		sidebar.withoutAnimation = withoutAnimation;
-	};
-	const toggleDevice = (d: string): void => {
-		device.value = d;
-	};
-	const setSize = (s: string): void => {
-		size.value = s;
-		Cookies.set('size', s);
-	};
-	const toggleSideBarHide = (status: boolean): void => {
-		sidebar.hide = status;
-	};
+  const closeSideBar = ({ withoutAnimation }: any): void => {
+    Cookies.set('sidebarStatus', '0');
+    sidebar.opened = false;
+    sidebar.withoutAnimation = withoutAnimation;
+  };
+  const toggleDevice = (d: string): void => {
+    device.value = d;
+  };
+  const setSize = (s: string): void => {
+    size.value = s;
+    Cookies.set('size', s);
+  };
+  const toggleSideBarHide = (status: boolean): void => {
+    sidebar.hide = status;
+  };
 
-	const changeLanguage = (val: string): void => {
-		language.value = val;
-	};
+  const changeLanguage = (val: string): void => {
+    language.value = val;
+  };
 
-	return {
-		device,
-		sidebar,
-		language,
-		locale,
-		size,
-		changeLanguage,
-		toggleSideBar,
-		closeSideBar,
-		toggleDevice,
-		setSize,
-		toggleSideBarHide
-	};
+  return {
+    device,
+    sidebar,
+    language,
+    locale,
+    size,
+    changeLanguage,
+    toggleSideBar,
+    closeSideBar,
+    toggleDevice,
+    setSize,
+    toggleSideBarHide
+  };
 });
 
 export default useAppStore;
diff --git a/src/store/modules/dict.ts b/src/store/modules/dict.ts
index 50b8871..2f937b9 100644
--- a/src/store/modules/dict.ts
+++ b/src/store/modules/dict.ts
@@ -1,78 +1,78 @@
 export const useDictStore = defineStore('dict', () => {
-	const dict = ref<
-		Array<{
-			key: string;
-			value: DictDataOption[];
-		}>
-	>([]);
+  const dict = ref<
+    Array<{
+      key: string;
+      value: DictDataOption[];
+    }>
+  >([]);
 
-	/**
-	 * 鑾峰彇瀛楀吀
-	 * @param _key 瀛楀吀key
-	 */
-	const getDict = (_key: string): DictDataOption[] | null => {
-		if (_key == null && _key == '') {
-			return null;
-		}
-		try {
-			for (let i = 0; i < dict.value.length; i++) {
-				if (dict.value[i].key == _key) {
-					return dict.value[i].value;
-				}
-			}
-		} catch (e) {
-			return null;
-		}
-		return null;
-	};
+  /**
+   * 鑾峰彇瀛楀吀
+   * @param _key 瀛楀吀key
+   */
+  const getDict = (_key: string): DictDataOption[] | null => {
+    if (_key == null && _key == '') {
+      return null;
+    }
+    try {
+      for (let i = 0; i < dict.value.length; i++) {
+        if (dict.value[i].key == _key) {
+          return dict.value[i].value;
+        }
+      }
+    } catch (e) {
+      return null;
+    }
+    return null;
+  };
 
-	/**
-	 * 璁剧疆瀛楀吀
-	 * @param _key 瀛楀吀key
-	 * @param _value 瀛楀吀value
-	 */
-	const setDict = (_key: string, _value: DictDataOption[]) => {
-		if (_key !== null && _key !== '') {
-			dict.value.push({
-				key: _key,
-				value: _value
-			});
-		}
-	};
+  /**
+   * 璁剧疆瀛楀吀
+   * @param _key 瀛楀吀key
+   * @param _value 瀛楀吀value
+   */
+  const setDict = (_key: string, _value: DictDataOption[]) => {
+    if (_key !== null && _key !== '') {
+      dict.value.push({
+        key: _key,
+        value: _value
+      });
+    }
+  };
 
-	/**
-	 * 鍒犻櫎瀛楀吀
-	 * @param _key
-	 */
-	const removeDict = (_key: string): boolean => {
-		let bln = false;
-		try {
-			for (let i = 0; i < dict.value.length; i++) {
-				if (dict.value[i].key == _key) {
-					dict.value.splice(i, 1);
-					return true;
-				}
-			}
-		} catch (e) {
-			bln = false;
-		}
-		return bln;
-	};
+  /**
+   * 鍒犻櫎瀛楀吀
+   * @param _key
+   */
+  const removeDict = (_key: string): boolean => {
+    let bln = false;
+    try {
+      for (let i = 0; i < dict.value.length; i++) {
+        if (dict.value[i].key == _key) {
+          dict.value.splice(i, 1);
+          return true;
+        }
+      }
+    } catch (e) {
+      bln = false;
+    }
+    return bln;
+  };
 
-	/**
-	 * 娓呯┖瀛楀吀
-	 */
-	const cleanDict = (): void => {
-		dict.value = [];
-	};
+  /**
+   * 娓呯┖瀛楀吀
+   */
+  const cleanDict = (): void => {
+    dict.value = [];
+  };
 
-	return {
-		dict,
-		getDict,
-		setDict,
-		removeDict,
-		cleanDict
-	};
+  return {
+    dict,
+    getDict,
+    setDict,
+    removeDict,
+    cleanDict
+  };
 });
 
 export default useDictStore;
diff --git a/src/store/modules/permission.ts b/src/store/modules/permission.ts
index 271518e..dcb3cd4 100644
--- a/src/store/modules/permission.ts
+++ b/src/store/modules/permission.ts
@@ -11,134 +11,134 @@
 const modules = import.meta.glob('./../../views/**/*.vue');
 
 export const usePermissionStore = defineStore('permission', () => {
-	const routes = ref<RouteOption[]>([]);
-	const addRoutes = ref<RouteOption[]>([]);
-	const defaultRoutes = ref<RouteOption[]>([]);
-	const topbarRouters = ref<RouteOption[]>([]);
-	const sidebarRouters = ref<RouteOption[]>([]);
+  const routes = ref<RouteOption[]>([]);
+  const addRoutes = ref<RouteOption[]>([]);
+  const defaultRoutes = ref<RouteOption[]>([]);
+  const topbarRouters = ref<RouteOption[]>([]);
+  const sidebarRouters = ref<RouteOption[]>([]);
 
-	const setRoutes = (newRoutes: RouteOption[]): void => {
-		addRoutes.value = newRoutes;
-		routes.value = constantRoutes.concat(newRoutes);
-	};
-	const setDefaultRoutes = (routes: RouteOption[]): void => {
-		defaultRoutes.value = constantRoutes.concat(routes);
-	};
-	const setTopbarRoutes = (routes: RouteOption[]): void => {
-		topbarRouters.value = routes;
-	};
-	const setSidebarRouters = (routes: RouteOption[]): void => {
-		sidebarRouters.value = routes;
-	};
-	const generateRoutes = async (): Promise<RouteOption[]> => {
-		const res = await getRouters();
-		const { data } = res;
-		const sdata = JSON.parse(JSON.stringify(data));
-		const rdata = JSON.parse(JSON.stringify(data));
-		const defaultData = JSON.parse(JSON.stringify(data));
-		const sidebarRoutes = filterAsyncRouter(sdata);
-		const rewriteRoutes = filterAsyncRouter(rdata, undefined, true);
-		const defaultRoutes = filterAsyncRouter(defaultData);
-		const asyncRoutes = filterDynamicRoutes(dynamicRoutes);
-		asyncRoutes.forEach((route) => {
-			router.addRoute(route);
-		});
-		setRoutes(rewriteRoutes);
-		setSidebarRouters(constantRoutes.concat(sidebarRoutes));
-		setDefaultRoutes(sidebarRoutes);
-		setTopbarRoutes(defaultRoutes);
-		return new Promise<RouteOption[]>((resolve) => resolve(rewriteRoutes));
-	};
+  const setRoutes = (newRoutes: RouteOption[]): void => {
+    addRoutes.value = newRoutes;
+    routes.value = constantRoutes.concat(newRoutes);
+  };
+  const setDefaultRoutes = (routes: RouteOption[]): void => {
+    defaultRoutes.value = constantRoutes.concat(routes);
+  };
+  const setTopbarRoutes = (routes: RouteOption[]): void => {
+    topbarRouters.value = routes;
+  };
+  const setSidebarRouters = (routes: RouteOption[]): void => {
+    sidebarRouters.value = routes;
+  };
+  const generateRoutes = async (): Promise<RouteOption[]> => {
+    const res = await getRouters();
+    const { data } = res;
+    const sdata = JSON.parse(JSON.stringify(data));
+    const rdata = JSON.parse(JSON.stringify(data));
+    const defaultData = JSON.parse(JSON.stringify(data));
+    const sidebarRoutes = filterAsyncRouter(sdata);
+    const rewriteRoutes = filterAsyncRouter(rdata, undefined, true);
+    const defaultRoutes = filterAsyncRouter(defaultData);
+    const asyncRoutes = filterDynamicRoutes(dynamicRoutes);
+    asyncRoutes.forEach((route) => {
+      router.addRoute(route);
+    });
+    setRoutes(rewriteRoutes);
+    setSidebarRouters(constantRoutes.concat(sidebarRoutes));
+    setDefaultRoutes(sidebarRoutes);
+    setTopbarRoutes(defaultRoutes);
+    return new Promise<RouteOption[]>((resolve) => resolve(rewriteRoutes));
+  };
 
-	/**
-	 * 閬嶅巻鍚庡彴浼犳潵鐨勮矾鐢卞瓧绗︿覆锛岃浆鎹负缁勪欢瀵硅薄
-	 * @param asyncRouterMap 鍚庡彴浼犳潵鐨勮矾鐢卞瓧绗︿覆
-	 * @param lastRouter 涓婁竴绾ц矾鐢�
-	 * @param type 鏄惁鏄噸鍐欒矾鐢�
-	 */
-	const filterAsyncRouter = (asyncRouterMap: RouteOption[], lastRouter?: RouteOption, type = false): RouteOption[] => {
-		return asyncRouterMap.filter((route) => {
-			if (type && route.children) {
-				route.children = filterChildren(route.children, undefined);
-			}
-			if (route.component) {
-				// Layout ParentView 缁勪欢鐗规畩澶勭悊
-				if (route.component === 'Layout') {
-					route.component = Layout;
-				} else if (route.component === 'ParentView') {
-					route.component = ParentView;
-				} else if (route.component === 'InnerLink') {
-					route.component = InnerLink;
-				} else {
-					route.component = loadView(route.component);
-				}
-			}
-			if (route.children != null && route.children && route.children.length) {
-				route.children = filterAsyncRouter(route.children, route, type);
-			} else {
-				delete route.children;
-				delete route.redirect;
-			}
-			return true;
-		});
-	};
-	const filterChildren = (childrenMap: RouteOption[], lastRouter?: RouteOption): RouteOption[] => {
-		let children: RouteOption[] = [];
-		childrenMap.forEach((el) => {
-			if (el.children && el.children.length) {
-				if (el.component === 'ParentView' && !lastRouter) {
-					el.children.forEach((c) => {
-						c.path = el.path + '/' + c.path;
-						if (c.children && c.children.length) {
-							children = children.concat(filterChildren(c.children, c));
-							return;
-						}
-						children.push(c);
-					});
-					return;
-				}
-			}
-			if (lastRouter) {
-				el.path = lastRouter.path + '/' + el.path;
-			}
-			children = children.concat(el);
-		});
-		return children;
-	};
-	return { routes, setRoutes, generateRoutes, setSidebarRouters, topbarRouters, sidebarRouters, defaultRoutes };
+  /**
+   * 閬嶅巻鍚庡彴浼犳潵鐨勮矾鐢卞瓧绗︿覆锛岃浆鎹负缁勪欢瀵硅薄
+   * @param asyncRouterMap 鍚庡彴浼犳潵鐨勮矾鐢卞瓧绗︿覆
+   * @param lastRouter 涓婁竴绾ц矾鐢�
+   * @param type 鏄惁鏄噸鍐欒矾鐢�
+   */
+  const filterAsyncRouter = (asyncRouterMap: RouteOption[], lastRouter?: RouteOption, type = false): RouteOption[] => {
+    return asyncRouterMap.filter((route) => {
+      if (type && route.children) {
+        route.children = filterChildren(route.children, undefined);
+      }
+      if (route.component) {
+        // Layout ParentView 缁勪欢鐗规畩澶勭悊
+        if (route.component === 'Layout') {
+          route.component = Layout;
+        } else if (route.component === 'ParentView') {
+          route.component = ParentView;
+        } else if (route.component === 'InnerLink') {
+          route.component = InnerLink;
+        } else {
+          route.component = loadView(route.component);
+        }
+      }
+      if (route.children != null && route.children && route.children.length) {
+        route.children = filterAsyncRouter(route.children, route, type);
+      } else {
+        delete route.children;
+        delete route.redirect;
+      }
+      return true;
+    });
+  };
+  const filterChildren = (childrenMap: RouteOption[], lastRouter?: RouteOption): RouteOption[] => {
+    let children: RouteOption[] = [];
+    childrenMap.forEach((el) => {
+      if (el.children && el.children.length) {
+        if (el.component === 'ParentView' && !lastRouter) {
+          el.children.forEach((c) => {
+            c.path = el.path + '/' + c.path;
+            if (c.children && c.children.length) {
+              children = children.concat(filterChildren(c.children, c));
+              return;
+            }
+            children.push(c);
+          });
+          return;
+        }
+      }
+      if (lastRouter) {
+        el.path = lastRouter.path + '/' + el.path;
+      }
+      children = children.concat(el);
+    });
+    return children;
+  };
+  return { routes, setRoutes, generateRoutes, setSidebarRouters, topbarRouters, sidebarRouters, defaultRoutes };
 });
 
 // 鍔ㄦ�佽矾鐢遍亶鍘嗭紝楠岃瘉鏄惁鍏峰鏉冮檺
 export const filterDynamicRoutes = (routes: RouteOption[]) => {
-	const res: RouteOption[] = [];
-	routes.forEach((route) => {
-		if (route.permissions) {
-			if (auth.hasPermiOr(route.permissions)) {
-				res.push(route);
-			}
-		} else if (route.roles) {
-			if (auth.hasRoleOr(route.roles)) {
-				res.push(route);
-			}
-		}
-	});
-	return res;
+  const res: RouteOption[] = [];
+  routes.forEach((route) => {
+    if (route.permissions) {
+      if (auth.hasPermiOr(route.permissions)) {
+        res.push(route);
+      }
+    } else if (route.roles) {
+      if (auth.hasRoleOr(route.roles)) {
+        res.push(route);
+      }
+    }
+  });
+  return res;
 };
 
 export const loadView = (view: any) => {
-	let res;
-	for (const path in modules) {
-		const dir = path.split('views/')[1].split('.vue')[0];
-		if (dir === view) {
-			res = () => modules[path]();
-		}
-	}
-	return res;
+  let res;
+  for (const path in modules) {
+    const dir = path.split('views/')[1].split('.vue')[0];
+    if (dir === view) {
+      res = () => modules[path]();
+    }
+  }
+  return res;
 };
 
 // 闈瀞etup
 export const usePermissionStoreHook = () => {
-	return usePermissionStore(store);
+  return usePermissionStore(store);
 };
 
 export default usePermissionStore;
diff --git a/src/store/modules/settings.ts b/src/store/modules/settings.ts
index 32119cd..b9a5730 100644
--- a/src/store/modules/settings.ts
+++ b/src/store/modules/settings.ts
@@ -5,50 +5,50 @@
 import { Ref } from 'vue';
 
 export const useSettingsStore = defineStore('setting', () => {
-	const storageSetting = JSON.parse(localStorage.getItem('layout-setting') || '{}');
+  const storageSetting = JSON.parse(localStorage.getItem('layout-setting') || '{}');
 
-	const prop: { [key: string]: Ref<any> } = {
-		title: ref<string>(''),
-		theme: ref<string>(storageSetting.theme || defaultSettings.theme),
-		sideTheme: ref<string>(storageSetting.sideTheme || defaultSettings.sideTheme),
-		showSettings: ref<boolean>(storageSetting.showSettings),
-		topNav: ref<boolean>(storageSetting.topNav || defaultSettings.topNav),
-		tagsView: ref<boolean>(storageSetting.tagsView || defaultSettings.tagsView),
-		fixedHeader: ref<boolean>(storageSetting.fixedHeader || defaultSettings.fixedHeader),
-		sidebarLogo: ref<boolean>(storageSetting.sidebarLogo || defaultSettings.sidebarLogo),
-		dynamicTitle: ref<boolean>(storageSetting.dynamicTitle || defaultSettings.dynamicTitle),
-		animationEnable: ref<boolean>(storageSetting.animationEnable || defaultSettings.animationEnable),
-		dark: ref<boolean>(storageSetting.dark || defaultSettings.dark)
-	};
+  const prop: { [key: string]: Ref<any> } = {
+    title: ref<string>(''),
+    theme: ref<string>(storageSetting.theme || defaultSettings.theme),
+    sideTheme: ref<string>(storageSetting.sideTheme || defaultSettings.sideTheme),
+    showSettings: ref<boolean>(storageSetting.showSettings),
+    topNav: ref<boolean>(storageSetting.topNav || defaultSettings.topNav),
+    tagsView: ref<boolean>(storageSetting.tagsView || defaultSettings.tagsView),
+    fixedHeader: ref<boolean>(storageSetting.fixedHeader || defaultSettings.fixedHeader),
+    sidebarLogo: ref<boolean>(storageSetting.sidebarLogo || defaultSettings.sidebarLogo),
+    dynamicTitle: ref<boolean>(storageSetting.dynamicTitle || defaultSettings.dynamicTitle),
+    animationEnable: ref<boolean>(storageSetting.animationEnable || defaultSettings.animationEnable),
+    dark: ref<boolean>(storageSetting.dark || defaultSettings.dark)
+  };
 
-	const { title, theme, sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle, animationEnable, dark } = prop;
+  const { title, theme, sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle, animationEnable, dark } = prop;
 
-	// actions
-	const changeSetting = (param: { key: SettingTypeEnum; value: any }) => {
-		const { key, value } = param;
-		if (key in prop) {
-			prop[key].value = value;
-		}
-	};
-	const setTitle = (value: string) => {
-		title.value = value;
-		useDynamicTitle();
-	};
-	return {
-		title,
-		theme,
-		sideTheme,
-		showSettings,
-		topNav,
-		tagsView,
-		fixedHeader,
-		sidebarLogo,
-		dynamicTitle,
-		animationEnable,
-		dark,
-		changeSetting,
-		setTitle
-	};
+  // actions
+  const changeSetting = (param: { key: SettingTypeEnum; value: any }) => {
+    const { key, value } = param;
+    if (key in prop) {
+      prop[key].value = value;
+    }
+  };
+  const setTitle = (value: string) => {
+    title.value = value;
+    useDynamicTitle();
+  };
+  return {
+    title,
+    theme,
+    sideTheme,
+    showSettings,
+    topNav,
+    tagsView,
+    fixedHeader,
+    sidebarLogo,
+    dynamicTitle,
+    animationEnable,
+    dark,
+    changeSetting,
+    setTitle
+  };
 });
 
 export default useSettingsStore;
diff --git a/src/store/modules/tagsView.ts b/src/store/modules/tagsView.ts
index c0fdf5d..af980ef 100644
--- a/src/store/modules/tagsView.ts
+++ b/src/store/modules/tagsView.ts
@@ -1,198 +1,198 @@
 import { TagView } from 'vue-router';
 
 export const useTagsViewStore = defineStore('tagsView', () => {
-	const visitedViews = ref<TagView[]>([]);
-	const cachedViews = ref<string[]>([]);
-	const iframeViews = ref<TagView[]>([]);
+  const visitedViews = ref<TagView[]>([]);
+  const cachedViews = ref<string[]>([]);
+  const iframeViews = ref<TagView[]>([]);
 
-	const addView = (view: TagView) => {
-		addVisitedView(view);
-		addCachedView(view);
-	};
+  const addView = (view: TagView) => {
+    addVisitedView(view);
+    addCachedView(view);
+  };
 
-	const addIframeView = (view: TagView): void => {
-		if (iframeViews.value.some((v) => v.path === view.path)) return;
-		iframeViews.value.push(
-			Object.assign({}, view, {
-				title: view.meta?.title || 'no-name'
-			})
-		);
-	};
-	const delIframeView = (view: TagView): Promise<TagView[]> => {
-		return new Promise((resolve) => {
-			iframeViews.value = iframeViews.value.filter((item) => item.path !== view.path);
-			resolve([...iframeViews.value]);
-		});
-	};
-	const addVisitedView = (view: TagView): void => {
-		if (visitedViews.value.some((v) => v.path === view.path)) return;
-		visitedViews.value.push(
-			Object.assign({}, view, {
-				title: view.meta?.title || 'no-name'
-			})
-		);
-	};
-	const delView = (view: TagView): Promise<{ visitedViews: TagView[]; cachedViews: string[] }> => {
-		return new Promise((resolve) => {
-			delVisitedView(view);
-			delCachedView(view);
-			resolve({
-				visitedViews: [...visitedViews.value],
-				cachedViews: [...cachedViews.value]
-			});
-		});
-	};
+  const addIframeView = (view: TagView): void => {
+    if (iframeViews.value.some((v) => v.path === view.path)) return;
+    iframeViews.value.push(
+      Object.assign({}, view, {
+        title: view.meta?.title || 'no-name'
+      })
+    );
+  };
+  const delIframeView = (view: TagView): Promise<TagView[]> => {
+    return new Promise((resolve) => {
+      iframeViews.value = iframeViews.value.filter((item) => item.path !== view.path);
+      resolve([...iframeViews.value]);
+    });
+  };
+  const addVisitedView = (view: TagView): void => {
+    if (visitedViews.value.some((v) => v.path === view.path)) return;
+    visitedViews.value.push(
+      Object.assign({}, view, {
+        title: view.meta?.title || 'no-name'
+      })
+    );
+  };
+  const delView = (view: TagView): Promise<{ visitedViews: TagView[]; cachedViews: string[] }> => {
+    return new Promise((resolve) => {
+      delVisitedView(view);
+      delCachedView(view);
+      resolve({
+        visitedViews: [...visitedViews.value],
+        cachedViews: [...cachedViews.value]
+      });
+    });
+  };
 
-	const delVisitedView = (view: TagView): Promise<TagView[]> => {
-		return new Promise((resolve) => {
-			for (const [i, v] of visitedViews.value.entries()) {
-				if (v.path === view.path) {
-					visitedViews.value.splice(i, 1);
-					break;
-				}
-			}
-			resolve([...visitedViews.value]);
-		});
-	};
-	const delCachedView = (view: TagView): Promise<string[]> => {
-		const viewName = view.name as string;
-		return new Promise((resolve) => {
-			const index = cachedViews.value.indexOf(viewName);
-			index > -1 && cachedViews.value.splice(index, 1);
-			resolve([...cachedViews.value]);
-		});
-	};
-	const delOthersViews = (view: TagView): Promise<{ visitedViews: TagView[]; cachedViews: string[] }> => {
-		return new Promise((resolve) => {
-			delOthersVisitedViews(view);
-			delOthersCachedViews(view);
-			resolve({
-				visitedViews: [...visitedViews.value],
-				cachedViews: [...cachedViews.value]
-			});
-		});
-	};
+  const delVisitedView = (view: TagView): Promise<TagView[]> => {
+    return new Promise((resolve) => {
+      for (const [i, v] of visitedViews.value.entries()) {
+        if (v.path === view.path) {
+          visitedViews.value.splice(i, 1);
+          break;
+        }
+      }
+      resolve([...visitedViews.value]);
+    });
+  };
+  const delCachedView = (view: TagView): Promise<string[]> => {
+    const viewName = view.name as string;
+    return new Promise((resolve) => {
+      const index = cachedViews.value.indexOf(viewName);
+      index > -1 && cachedViews.value.splice(index, 1);
+      resolve([...cachedViews.value]);
+    });
+  };
+  const delOthersViews = (view: TagView): Promise<{ visitedViews: TagView[]; cachedViews: string[] }> => {
+    return new Promise((resolve) => {
+      delOthersVisitedViews(view);
+      delOthersCachedViews(view);
+      resolve({
+        visitedViews: [...visitedViews.value],
+        cachedViews: [...cachedViews.value]
+      });
+    });
+  };
 
-	const delOthersVisitedViews = (view: TagView): Promise<TagView[]> => {
-		return new Promise((resolve) => {
-			visitedViews.value = visitedViews.value.filter((v) => {
-				return v.meta?.affix || v.path === view.path;
-			});
-			resolve([...visitedViews.value]);
-		});
-	};
-	const delOthersCachedViews = (view: TagView): Promise<string[]> => {
-		const viewName = view.name as string;
-		return new Promise((resolve) => {
-			const index = cachedViews.value.indexOf(viewName);
-			if (index > -1) {
-				cachedViews.value = cachedViews.value.slice(index, index + 1);
-			} else {
-				cachedViews.value = [];
-			}
-			resolve([...cachedViews.value]);
-		});
-	};
+  const delOthersVisitedViews = (view: TagView): Promise<TagView[]> => {
+    return new Promise((resolve) => {
+      visitedViews.value = visitedViews.value.filter((v) => {
+        return v.meta?.affix || v.path === view.path;
+      });
+      resolve([...visitedViews.value]);
+    });
+  };
+  const delOthersCachedViews = (view: TagView): Promise<string[]> => {
+    const viewName = view.name as string;
+    return new Promise((resolve) => {
+      const index = cachedViews.value.indexOf(viewName);
+      if (index > -1) {
+        cachedViews.value = cachedViews.value.slice(index, index + 1);
+      } else {
+        cachedViews.value = [];
+      }
+      resolve([...cachedViews.value]);
+    });
+  };
 
-	const delAllViews = (): Promise<{ visitedViews: TagView[]; cachedViews: string[] }> => {
-		return new Promise((resolve) => {
-			delAllVisitedViews();
-			delAllCachedViews();
-			resolve({
-				visitedViews: [...visitedViews.value],
-				cachedViews: [...cachedViews.value]
-			});
-		});
-	};
-	const delAllVisitedViews = (): Promise<TagView[]> => {
-		return new Promise((resolve) => {
-			visitedViews.value = visitedViews.value.filter((tag) => tag.meta?.affix);
-			resolve([...visitedViews.value]);
-		});
-	};
+  const delAllViews = (): Promise<{ visitedViews: TagView[]; cachedViews: string[] }> => {
+    return new Promise((resolve) => {
+      delAllVisitedViews();
+      delAllCachedViews();
+      resolve({
+        visitedViews: [...visitedViews.value],
+        cachedViews: [...cachedViews.value]
+      });
+    });
+  };
+  const delAllVisitedViews = (): Promise<TagView[]> => {
+    return new Promise((resolve) => {
+      visitedViews.value = visitedViews.value.filter((tag) => tag.meta?.affix);
+      resolve([...visitedViews.value]);
+    });
+  };
 
-	const delAllCachedViews = (): Promise<string[]> => {
-		return new Promise((resolve) => {
-			cachedViews.value = [];
-			resolve([...cachedViews.value]);
-		});
-	};
+  const delAllCachedViews = (): Promise<string[]> => {
+    return new Promise((resolve) => {
+      cachedViews.value = [];
+      resolve([...cachedViews.value]);
+    });
+  };
 
-	const updateVisitedView = (view: TagView): void => {
-		for (let v of visitedViews.value) {
-			if (v.path === view.path) {
-				v = Object.assign(v, view);
-				break;
-			}
-		}
-	};
-	const delRightTags = (view: TagView): Promise<TagView[]> => {
-		return new Promise((resolve) => {
-			const index = visitedViews.value.findIndex((v) => v.path === view.path);
-			if (index === -1) {
-				return;
-			}
-			visitedViews.value = visitedViews.value.filter((item, idx) => {
-				if (idx <= index || (item.meta && item.meta.affix)) {
-					return true;
-				}
-				const i = cachedViews.value.indexOf(item.name as string);
-				if (i > -1) {
-					cachedViews.value.splice(i, 1);
-				}
-				return false;
-			});
-			resolve([...visitedViews.value]);
-		});
-	};
-	const delLeftTags = (view: TagView): Promise<TagView[]> => {
-		return new Promise((resolve) => {
-			const index = visitedViews.value.findIndex((v) => v.path === view.path);
-			if (index === -1) {
-				return;
-			}
-			visitedViews.value = visitedViews.value.filter((item, idx) => {
-				if (idx >= index || (item.meta && item.meta.affix)) {
-					return true;
-				}
-				const i = cachedViews.value.indexOf(item.name as string);
-				if (i > -1) {
-					cachedViews.value.splice(i, 1);
-				}
-				return false;
-			});
-			resolve([...visitedViews.value]);
-		});
-	};
+  const updateVisitedView = (view: TagView): void => {
+    for (let v of visitedViews.value) {
+      if (v.path === view.path) {
+        v = Object.assign(v, view);
+        break;
+      }
+    }
+  };
+  const delRightTags = (view: TagView): Promise<TagView[]> => {
+    return new Promise((resolve) => {
+      const index = visitedViews.value.findIndex((v) => v.path === view.path);
+      if (index === -1) {
+        return;
+      }
+      visitedViews.value = visitedViews.value.filter((item, idx) => {
+        if (idx <= index || (item.meta && item.meta.affix)) {
+          return true;
+        }
+        const i = cachedViews.value.indexOf(item.name as string);
+        if (i > -1) {
+          cachedViews.value.splice(i, 1);
+        }
+        return false;
+      });
+      resolve([...visitedViews.value]);
+    });
+  };
+  const delLeftTags = (view: TagView): Promise<TagView[]> => {
+    return new Promise((resolve) => {
+      const index = visitedViews.value.findIndex((v) => v.path === view.path);
+      if (index === -1) {
+        return;
+      }
+      visitedViews.value = visitedViews.value.filter((item, idx) => {
+        if (idx >= index || (item.meta && item.meta.affix)) {
+          return true;
+        }
+        const i = cachedViews.value.indexOf(item.name as string);
+        if (i > -1) {
+          cachedViews.value.splice(i, 1);
+        }
+        return false;
+      });
+      resolve([...visitedViews.value]);
+    });
+  };
 
-	const addCachedView = (view: TagView): void => {
-		const viewName = view.name as string;
-		if (cachedViews.value.includes(viewName)) return;
-		if (!view.meta?.noCache) {
-			cachedViews.value.push(viewName);
-		}
-	};
+  const addCachedView = (view: TagView): void => {
+    const viewName = view.name as string;
+    if (cachedViews.value.includes(viewName)) return;
+    if (!view.meta?.noCache) {
+      cachedViews.value.push(viewName);
+    }
+  };
 
-	return {
-		visitedViews,
-		cachedViews,
-		iframeViews,
-		addVisitedView,
-		addCachedView,
-		delVisitedView,
-		delCachedView,
-		updateVisitedView,
-		addView,
-		delView,
-		delAllViews,
-		delAllVisitedViews,
-		delAllCachedViews,
-		delOthersViews,
-		delRightTags,
-		delLeftTags,
-		addIframeView,
-		delIframeView
-	};
+  return {
+    visitedViews,
+    cachedViews,
+    iframeViews,
+    addVisitedView,
+    addCachedView,
+    delVisitedView,
+    delCachedView,
+    updateVisitedView,
+    addView,
+    delView,
+    delAllViews,
+    delAllVisitedViews,
+    delAllCachedViews,
+    delOthersViews,
+    delRightTags,
+    delLeftTags,
+    addIframeView,
+    delIframeView
+  };
 });
 
 export default useTagsViewStore;
diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts
index dafec8b..6f30437 100644
--- a/src/store/modules/user.ts
+++ b/src/store/modules/user.ts
@@ -6,78 +6,78 @@
 import { LoginData } from '@/api/types';
 
 export const useUserStore = defineStore('user', () => {
-	const token = ref(getToken());
-	const name = ref('');
-	const nickname = ref('');
-	const userId = ref<string | number>('');
-	const avatar = ref('');
-	const roles = ref<Array<string>>([]); // 鐢ㄦ埛瑙掕壊缂栫爜闆嗗悎 鈫� 鍒ゆ柇璺敱鏉冮檺
-	const permissions = ref<Array<string>>([]); // 鐢ㄦ埛鏉冮檺缂栫爜闆嗗悎 鈫� 鍒ゆ柇鎸夐挳鏉冮檺
+  const token = ref(getToken());
+  const name = ref('');
+  const nickname = ref('');
+  const userId = ref<string | number>('');
+  const avatar = ref('');
+  const roles = ref<Array<string>>([]); // 鐢ㄦ埛瑙掕壊缂栫爜闆嗗悎 鈫� 鍒ゆ柇璺敱鏉冮檺
+  const permissions = ref<Array<string>>([]); // 鐢ㄦ埛鏉冮檺缂栫爜闆嗗悎 鈫� 鍒ゆ柇鎸夐挳鏉冮檺
 
-	/**
-	 * 鐧诲綍
-	 * @param userInfo
-	 * @returns
-	 */
-	const login = async (userInfo: LoginData): Promise<void> => {
-		const [err, res] = await to(loginApi(userInfo));
-		if (res) {
-			const data = res.data;
-			setToken(data.token);
-			token.value = data.token;
-			return Promise.resolve();
-		}
-		return Promise.reject(err);
-	};
+  /**
+   * 鐧诲綍
+   * @param userInfo
+   * @returns
+   */
+  const login = async (userInfo: LoginData): Promise<void> => {
+    const [err, res] = await to(loginApi(userInfo));
+    if (res) {
+      const data = res.data;
+      setToken(data.token);
+      token.value = data.token;
+      return Promise.resolve();
+    }
+    return Promise.reject(err);
+  };
 
-	// 鑾峰彇鐢ㄦ埛淇℃伅
-	const getInfo = async (): Promise<void> => {
-		const [err, res] = await to(getUserInfo());
-		if (res) {
-			const data = res.data;
-			const user = data.user;
-			const profile = user.avatar == '' || user.avatar == null ? defAva : user.avatar;
+  // 鑾峰彇鐢ㄦ埛淇℃伅
+  const getInfo = async (): Promise<void> => {
+    const [err, res] = await to(getUserInfo());
+    if (res) {
+      const data = res.data;
+      const user = data.user;
+      const profile = user.avatar == '' || user.avatar == null ? defAva : user.avatar;
 
-			if (data.roles && data.roles.length > 0) {
-				// 楠岃瘉杩斿洖鐨剅oles鏄惁鏄竴涓潪绌烘暟缁�
-				roles.value = data.roles;
-				permissions.value = data.permissions;
-			} else {
-				roles.value = ['ROLE_DEFAULT'];
-			}
-			name.value = user.userName;
-			nickname.value = user.nickName;
-			avatar.value = profile;
-			userId.value = user.userId;
-			return Promise.resolve();
-		}
-		return Promise.reject(err);
-	};
+      if (data.roles && data.roles.length > 0) {
+        // 楠岃瘉杩斿洖鐨剅oles鏄惁鏄竴涓潪绌烘暟缁�
+        roles.value = data.roles;
+        permissions.value = data.permissions;
+      } else {
+        roles.value = ['ROLE_DEFAULT'];
+      }
+      name.value = user.userName;
+      nickname.value = user.nickName;
+      avatar.value = profile;
+      userId.value = user.userId;
+      return Promise.resolve();
+    }
+    return Promise.reject(err);
+  };
 
-	// 娉ㄩ攢
-	const logout = async (): Promise<void> => {
-		await logoutApi();
-		token.value = '';
-		roles.value = [];
-		permissions.value = [];
-		removeToken();
-	};
+  // 娉ㄩ攢
+  const logout = async (): Promise<void> => {
+    await logoutApi();
+    token.value = '';
+    roles.value = [];
+    permissions.value = [];
+    removeToken();
+  };
 
-	return {
-		userId,
-		token,
-		nickname,
-		avatar,
-		roles,
-		permissions,
-		login,
-		getInfo,
-		logout
-	};
+  return {
+    userId,
+    token,
+    nickname,
+    avatar,
+    roles,
+    permissions,
+    login,
+    getInfo,
+    logout
+  };
 });
 
 export default useUserStore;
 // 闈瀞etup
 export function useUserStoreHook() {
-	return useUserStore(store);
+  return useUserStore(store);
 }
diff --git a/src/types/auto-imports.d.ts b/src/types/auto-imports.d.ts
index ae42063..13b0bf9 100644
--- a/src/types/auto-imports.d.ts
+++ b/src/types/auto-imports.d.ts
@@ -2,13 +2,11 @@
 export {}
 declare global {
   const EffectScope: typeof import('vue')['EffectScope']
-  const ElForm: typeof import('element-plus/es')['ElForm']
   const ElLoading: typeof import('element-plus/es')['ElLoading']
   const ElMessage: typeof import('element-plus/es')['ElMessage']
   const ElMessageBox: typeof import('element-plus/es')['ElMessageBox']
   const ElNotification: typeof import('element-plus/es')['ElNotification']
   const ElSelect: typeof import('element-plus/es')['ElSelect']
-  const ElTable: typeof import('element-plus/es')['ElTable']
   const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
   const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
   const autoResetRef: typeof import('@vueuse/core')['autoResetRef']
@@ -288,13 +286,11 @@
 declare module 'vue' {
   interface ComponentCustomProperties {
     readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
-    readonly ElForm: UnwrapRef<typeof import('element-plus/es')['ElForm']>
     readonly ElLoading: UnwrapRef<typeof import('element-plus/es')['ElLoading']>
     readonly ElMessage: UnwrapRef<typeof import('element-plus/es')['ElMessage']>
     readonly ElMessageBox: UnwrapRef<typeof import('element-plus/es')['ElMessageBox']>
     readonly ElNotification: UnwrapRef<typeof import('element-plus/es')['ElNotification']>
     readonly ElSelect: UnwrapRef<typeof import('element-plus/es')['ElSelect']>
-    readonly ElTable: UnwrapRef<typeof import('element-plus/es')['ElTable']>
     readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
     readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']>
     readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']>
diff --git a/src/types/axios.d.ts b/src/types/axios.d.ts
index 54237d4..36a9f8f 100644
--- a/src/types/axios.d.ts
+++ b/src/types/axios.d.ts
@@ -1,10 +1,10 @@
 import axios from 'axios';
 
 declare module 'axios' {
-	export interface AxiosResponse<T = any> {
-		code: number;
-		msg: string;
-		rows: T;
-		total: number;
-	}
+  export interface AxiosResponse<T = any> {
+    code: number;
+    msg: string;
+    rows: T;
+    total: number;
+  }
 }
diff --git a/src/types/components.d.ts b/src/types/components.d.ts
index 9f02c4b..f3c749a 100644
--- a/src/types/components.d.ts
+++ b/src/types/components.d.ts
@@ -14,7 +14,6 @@
     ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
     ElButton: typeof import('element-plus/es')['ElButton']
     ElCard: typeof import('element-plus/es')['ElCard']
-    ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
     ElCol: typeof import('element-plus/es')['ElCol']
     ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
     ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
@@ -25,42 +24,26 @@
     ElDropdown: typeof import('element-plus/es')['ElDropdown']
     ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
     ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
-    ElForm: typeof import('element-plus/es')['ElForm']
     ElFormItem: typeof import('element-plus/es')['ElFormItem']
     ElIcon: typeof import('element-plus/es')['ElIcon']
-    ElImage: typeof import('element-plus/es')['ElImage']
     ElInput: typeof import('element-plus/es')['ElInput']
-    ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
-    ElLink: typeof import('element-plus/es')['ElLink']
     ElMenu: typeof import('element-plus/es')['ElMenu']
     ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
     ElOption: typeof import('element-plus/es')['ElOption']
-    ElPagination: typeof import('element-plus/es')['ElPagination']
-    ElPopover: typeof import('element-plus/es')['ElPopover']
-    ElRadio: typeof import('element-plus/es')['ElRadio']
-    ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
     ElRow: typeof import('element-plus/es')['ElRow']
     ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
     ElSelect: typeof import('element-plus/es')['ElSelect']
     ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
     ElSwitch: typeof import('element-plus/es')['ElSwitch']
-    ElTable: typeof import('element-plus/es')['ElTable']
     ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
-    ElTabPane: typeof import('element-plus/es')['ElTabPane']
-    ElTabs: typeof import('element-plus/es')['ElTabs']
     ElTag: typeof import('element-plus/es')['ElTag']
     ElTooltip: typeof import('element-plus/es')['ElTooltip']
     ElTransfer: typeof import('element-plus/es')['ElTransfer']
-    ElTree: typeof import('element-plus/es')['ElTree']
     ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
-    ElUpload: typeof import('element-plus/es')['ElUpload']
     FileUpload: typeof import('./../components/FileUpload/index.vue')['default']
     Hamburger: typeof import('./../components/Hamburger/index.vue')['default']
     HeaderSearch: typeof import('./../components/HeaderSearch/index.vue')['default']
     IconSelect: typeof import('./../components/IconSelect/index.vue')['default']
-    IEpCaretBottom: typeof import('~icons/ep/caret-bottom')['default']
-    IEpCaretTop: typeof import('~icons/ep/caret-top')['default']
-    IEpUploadFilled: typeof import('~icons/ep/upload-filled')['default']
     IFrame: typeof import('./../components/iFrame/index.vue')['default']
     ImagePreview: typeof import('./../components/ImagePreview/index.vue')['default']
     ImageUpload: typeof import('./../components/ImageUpload/index.vue')['default']
diff --git a/src/types/env.d.ts b/src/types/env.d.ts
index 33b3450..7e5134a 100644
--- a/src/types/env.d.ts
+++ b/src/types/env.d.ts
@@ -1,74 +1,74 @@
 declare module '*.vue' {
-	import { DefineComponent } from 'vue';
-	const component: DefineComponent<{}, {}, any>;
-	export default component;
+  import { DefineComponent } from 'vue';
+  const component: DefineComponent<{}, {}, any>;
+  export default component;
 }
 declare module '*.avif' {
-	const src: string;
-	export default src;
+  const src: string;
+  export default src;
 }
 
 declare module '*.bmp' {
-	const src: string;
-	export default src;
+  const src: string;
+  export default src;
 }
 
 declare module '*.gif' {
-	const src: string;
-	export default src;
+  const src: string;
+  export default src;
 }
 
 declare module '*.jpg' {
-	const src: string;
-	export default src;
+  const src: string;
+  export default src;
 }
 
 declare module '*.jpeg' {
-	const src: string;
-	export default src;
+  const src: string;
+  export default src;
 }
 
 declare module '*.png' {
-	const src: string;
-	export default src;
+  const src: string;
+  export default src;
 }
 
 declare module '*.webp' {
-	const src: string;
-	export default src;
+  const src: string;
+  export default src;
 }
 
 declare module '*.svg' {
-	const src: string;
-	export default src;
+  const src: string;
+  export default src;
 }
 
 declare module '*.module.css' {
-	const classes: { readonly [key: string]: string };
-	export default classes;
+  const classes: { readonly [key: string]: string };
+  export default classes;
 }
 
 declare module '*.module.scss' {
-	const classes: { readonly [key: string]: string };
-	export default classes;
+  const classes: { readonly [key: string]: string };
+  export default classes;
 }
 
 declare module '*.module.sass' {
-	const classes: { readonly [key: string]: string };
-	export default classes;
+  const classes: { readonly [key: string]: string };
+  export default classes;
 }
 // 鐜鍙橀噺
 interface ImportMetaEnv {
-	VITE_APP_TITLE: string;
-	VITE_APP_PORT: number;
-	VITE_APP_BASE_API: string;
-	VITE_APP_BASE_URL: string;
-	VITE_APP_CONTEXT_PATH: string;
-	VITE_APP_MONITRO_ADMIN: string;
-	VITE_APP_XXL_JOB_ADMIN: string;
-	VITE_APP_ENV: string;
+  VITE_APP_TITLE: string;
+  VITE_APP_PORT: number;
+  VITE_APP_BASE_API: string;
+  VITE_APP_BASE_URL: string;
+  VITE_APP_CONTEXT_PATH: string;
+  VITE_APP_MONITRO_ADMIN: string;
+  VITE_APP_XXL_JOB_ADMIN: string;
+  VITE_APP_ENV: string;
 }
 interface ImportMeta {
-	readonly env: ImportMetaEnv;
-	// readonly glob: any;
+  readonly env: ImportMetaEnv;
+  // readonly glob: any;
 }
diff --git a/src/types/global.d.ts b/src/types/global.d.ts
index 81bc816..2083d4b 100644
--- a/src/types/global.d.ts
+++ b/src/types/global.d.ts
@@ -1,83 +1,83 @@
 import { FormRules } from 'element-plus';
 declare global {
-	/**
-	 * 鐣岄潰瀛楁闅愯棌灞炴��
-	 */
-	interface FieldOption {
-		key: number;
-		label: string;
-		visible: boolean;
-	}
+  /**
+   * 鐣岄潰瀛楁闅愯棌灞炴��
+   */
+  interface FieldOption {
+    key: number;
+    label: string;
+    visible: boolean;
+  }
 
-	/**
-	 * 寮圭獥灞炴��
-	 */
-	interface DialogOption {
-		/**
-		 * 寮圭獥鏍囬
-		 */
-		title?: string;
-		/**
-		 * 鏄惁鏄剧ず
-		 */
-		visible: boolean;
-	}
+  /**
+   * 寮圭獥灞炴��
+   */
+  interface DialogOption {
+    /**
+     * 寮圭獥鏍囬
+     */
+    title?: string;
+    /**
+     * 鏄惁鏄剧ず
+     */
+    visible: boolean;
+  }
 
-	interface UploadOption {
-		/** 璁剧疆涓婁紶鐨勮姹傚ご閮� */
-		headers: { [key: string]: any };
+  interface UploadOption {
+    /** 璁剧疆涓婁紶鐨勮姹傚ご閮� */
+    headers: { [key: string]: any };
 
-		/** 涓婁紶鐨勫湴鍧� */
-		url: string;
-	}
+    /** 涓婁紶鐨勫湴鍧� */
+    url: string;
+  }
 
-	/**
-	 * 瀵煎叆灞炴��
-	 */
-	interface ImportOption extends UploadOption {
-		/** 鏄惁鏄剧ず寮瑰嚭灞� */
-		open: boolean;
-		/** 寮瑰嚭灞傛爣棰� */
-		title: string;
-		/** 鏄惁绂佺敤涓婁紶 */
-		isUploading: boolean;
+  /**
+   * 瀵煎叆灞炴��
+   */
+  interface ImportOption extends UploadOption {
+    /** 鏄惁鏄剧ず寮瑰嚭灞� */
+    open: boolean;
+    /** 寮瑰嚭灞傛爣棰� */
+    title: string;
+    /** 鏄惁绂佺敤涓婁紶 */
+    isUploading: boolean;
 
-		/** 鍏朵粬鍙傛暟 */
-		[key: string]: any;
-	}
-	/**
-	 * 瀛楀吀鏁版嵁  鏁版嵁閰嶇疆
-	 */
-	interface DictDataOption {
-		label: string;
-		value: string;
-		elTagType?: ElTagType;
-		elTagClass?: string;
-	}
+    /** 鍏朵粬鍙傛暟 */
+    [key: string]: any;
+  }
+  /**
+   * 瀛楀吀鏁版嵁  鏁版嵁閰嶇疆
+   */
+  interface DictDataOption {
+    label: string;
+    value: string;
+    elTagType?: ElTagType;
+    elTagClass?: string;
+  }
 
-	interface BaseEntity {
-		createBy?: any;
-		createTime?: string;
-		updateBy?: any;
-		updateTime?: any;
-	}
+  interface BaseEntity {
+    createBy?: any;
+    createTime?: string;
+    updateBy?: any;
+    updateTime?: any;
+  }
 
-	/**
-	 * 鍒嗛〉鏁版嵁
-	 * T : 琛ㄥ崟鏁版嵁
-	 * D : 鏌ヨ鍙傛暟
-	 */
-	interface PageData<T, D> {
-		form: T;
-		queryParams: D;
-		rules: FormRules;
-	}
-	/**
-	 * 鍒嗛〉鏌ヨ鍙傛暟
-	 */
-	interface PageQuery {
-		pageNum: number;
-		pageSize: number;
-	}
+  /**
+   * 鍒嗛〉鏁版嵁
+   * T : 琛ㄥ崟鏁版嵁
+   * D : 鏌ヨ鍙傛暟
+   */
+  interface PageData<T, D> {
+    form: T;
+    queryParams: D;
+    rules: FormRules;
+  }
+  /**
+   * 鍒嗛〉鏌ヨ鍙傛暟
+   */
+  interface PageQuery {
+    pageNum: number;
+    pageSize: number;
+  }
 }
 export {};
diff --git a/src/types/module.d.ts b/src/types/module.d.ts
index 82ff47f..b99bc44 100644
--- a/src/types/module.d.ts
+++ b/src/types/module.d.ts
@@ -8,21 +8,21 @@
 import animate from '@/animate';
 
 declare module 'vue' {
-	export interface ComponentCustomProperties {
-		// 鍏ㄥ眬鏂规硶澹版槑
-		$modal: typeof modal;
-		$tab: typeof tab;
-		$download: typeof download;
-		animate: typeof animate;
+  export interface ComponentCustomProperties {
+    // 鍏ㄥ眬鏂规硶澹版槑
+    $modal: typeof modal;
+    $tab: typeof tab;
+    $download: typeof download;
+    animate: typeof animate;
 
-		useDict: typeof useDict;
-		addDateRange: typeof addDateRange;
-		download: typeof download1;
-		handleTree: typeof handleTree;
-		getConfigKey: typeof getConfigKey;
-		updateConfigByKey: typeof updateConfigByKey;
-		selectDictLabel: typeof selectDictLabel;
-		selectDictLabels: typeof selectDictLabels;
-		parseTime: typeof parseTime;
-	}
+    useDict: typeof useDict;
+    addDateRange: typeof addDateRange;
+    download: typeof download1;
+    handleTree: typeof handleTree;
+    getConfigKey: typeof getConfigKey;
+    updateConfigByKey: typeof updateConfigByKey;
+    selectDictLabel: typeof selectDictLabel;
+    selectDictLabels: typeof selectDictLabels;
+    parseTime: typeof parseTime;
+  }
 }
diff --git a/src/types/router.d.ts b/src/types/router.d.ts
index 07d177f..0f2b026 100644
--- a/src/types/router.d.ts
+++ b/src/types/router.d.ts
@@ -1,35 +1,35 @@
 import { RouteRecordRaw } from 'vue-router';
 
 declare module 'vue-router' {
-	type RouteOption = {
-		hidden?: boolean;
-		permissions?: string[];
-		roles?: string[];
-		component?: any;
-		children?: RouteOption[];
-		alwaysShow?: boolean;
-		parentPath?: string;
-		meta?: {
-			title: string;
-			icon: string;
-		};
-	} & RouteRecordRaw;
+  type RouteOption = {
+    hidden?: boolean;
+    permissions?: string[];
+    roles?: string[];
+    component?: any;
+    children?: RouteOption[];
+    alwaysShow?: boolean;
+    parentPath?: string;
+    meta?: {
+      title: string;
+      icon: string;
+    };
+  } & RouteRecordRaw;
 
-	interface _RouteLocationBase {
-		children?: RouteOption[];
-	}
+  interface _RouteLocationBase {
+    children?: RouteOption[];
+  }
 
-	interface RouteLocationOptions {
-		fullPath?: string;
-	}
+  interface RouteLocationOptions {
+    fullPath?: string;
+  }
 
-	interface TagView extends Partial<_RouteLocationBase> {
-		title?: string;
-		meta?: {
-			link?: string;
-			title?: string;
-			affix?: boolean;
-			noCache?: boolean;
-		};
-	}
+  interface TagView extends Partial<_RouteLocationBase> {
+    title?: string;
+    meta?: {
+      link?: string;
+      title?: string;
+      affix?: boolean;
+      noCache?: boolean;
+    };
+  }
 }
diff --git a/src/types/setting.d.ts b/src/types/setting.d.ts
index 0d936a1..1b5f9fd 100644
--- a/src/types/setting.d.ts
+++ b/src/types/setting.d.ts
@@ -1,70 +1,70 @@
 declare type DefaultSettings = {
-	/**
-	 * 缃戦〉鏍囬
-	 */
-	title?: string;
+  /**
+   * 缃戦〉鏍囬
+   */
+  title?: string;
 
-	/**
-	 * 渚ц竟鏍忎富棰� theme-dark | theme-light
-	 */
-	sideTheme?: string;
+  /**
+   * 渚ц竟鏍忎富棰� theme-dark | theme-light
+   */
+  sideTheme?: string;
 
-	/**
-	 * 鏄惁鏄剧ず绯荤粺甯冨眬璁剧疆
-	 */
-	showSettings?: boolean;
+  /**
+   * 鏄惁鏄剧ず绯荤粺甯冨眬璁剧疆
+   */
+  showSettings?: boolean;
 
-	/**
-	 * 鏄惁鏄剧ず椤堕儴瀵艰埅
-	 */
-	topNav?: boolean;
+  /**
+   * 鏄惁鏄剧ず椤堕儴瀵艰埅
+   */
+  topNav?: boolean;
 
-	/**
-	 * 鏄惁鏄剧ず澶氭爣绛惧鑸�
-	 */
-	tagsView?: boolean;
-	/**
-	 * 鏄惁鍥哄畾澶撮儴
-	 */
-	fixedHeader?: boolean;
-	/**
-	 * 鏄惁鏄剧ず渚ц竟鏍廘ogo
-	 */
-	sidebarLogo?: boolean;
-	/**
-	 * 瀵艰埅鏍忓竷灞�
-	 */
-	layout?: string;
-	/**
-	 * 涓婚妯″紡
-	 */
-	theme?: string;
+  /**
+   * 鏄惁鏄剧ず澶氭爣绛惧鑸�
+   */
+  tagsView?: boolean;
+  /**
+   * 鏄惁鍥哄畾澶撮儴
+   */
+  fixedHeader?: boolean;
+  /**
+   * 鏄惁鏄剧ず渚ц竟鏍廘ogo
+   */
+  sidebarLogo?: boolean;
+  /**
+   * 瀵艰埅鏍忓竷灞�
+   */
+  layout?: string;
+  /**
+   * 涓婚妯″紡
+   */
+  theme?: string;
 
-	/**
-	 * 甯冨眬澶у皬
-	 */
-	size?: string;
+  /**
+   * 甯冨眬澶у皬
+   */
+  size?: string;
 
-	/**
-	 * 璇█
-	 */
-	language?: string;
+  /**
+   * 璇█
+   */
+  language?: string;
 
-	/**
-	 * 鏄惁鏄剧ず鍔ㄦ�佹爣棰�
-	 */
-	dynamicTitle?: boolean;
-	/**
-	 * 鏄惁鍚敤鍔ㄧ敾鏁堟灉
-	 */
-	animationEnable?: boolean;
-	/**
-	 *  鏄惁鍚敤鏆楅粦妯″紡
-	 *
-	 * true:鏆楅粦妯″紡
-	 * false: 鏄庝寒妯″紡
-	 */
-	dark?: boolean;
+  /**
+   * 鏄惁鏄剧ず鍔ㄦ�佹爣棰�
+   */
+  dynamicTitle?: boolean;
+  /**
+   * 鏄惁鍚敤鍔ㄧ敾鏁堟灉
+   */
+  animationEnable?: boolean;
+  /**
+   *  鏄惁鍚敤鏆楅粦妯″紡
+   *
+   * true:鏆楅粦妯″紡
+   * false: 鏄庝寒妯″紡
+   */
+  dark?: boolean;
 
-	errorLog?: string;
+  errorLog?: string;
 };
diff --git a/src/utils/dict.ts b/src/utils/dict.ts
index 23948e5..0575072 100644
--- a/src/utils/dict.ts
+++ b/src/utils/dict.ts
@@ -4,24 +4,24 @@
  * 鑾峰彇瀛楀吀鏁版嵁
  */
 export const useDict = (...args: string[]): { [key: string]: DictDataOption[] } => {
-	const res = ref<{
-		[key: string]: DictDataOption[];
-	}>({});
-	return (() => {
-		args.forEach(async (dictType) => {
-			res.value[dictType] = [];
-			const dicts = useDictStore().getDict(dictType);
-			if (dicts) {
-				res.value[dictType] = dicts;
-			} else {
-				await getDicts(dictType).then((resp) => {
-					res.value[dictType] = resp.data.map(
-						(p): DictDataOption => ({ label: p.dictLabel, value: p.dictValue, elTagType: p.listClass, elTagClass: p.cssClass })
-					);
-					useDictStore().setDict(dictType, res.value[dictType]);
-				});
-			}
-		});
-		return res.value;
-	})();
+  const res = ref<{
+    [key: string]: DictDataOption[];
+  }>({});
+  return (() => {
+    args.forEach(async (dictType) => {
+      res.value[dictType] = [];
+      const dicts = useDictStore().getDict(dictType);
+      if (dicts) {
+        res.value[dictType] = dicts;
+      } else {
+        await getDicts(dictType).then((resp) => {
+          res.value[dictType] = resp.data.map(
+            (p): DictDataOption => ({ label: p.dictLabel, value: p.dictValue, elTagType: p.listClass, elTagClass: p.cssClass })
+          );
+          useDictStore().setDict(dictType, res.value[dictType]);
+        });
+      }
+    });
+    return res.value;
+  })();
 };
diff --git a/src/utils/dynamicTitle.ts b/src/utils/dynamicTitle.ts
index f6ba1d9..8e23ef8 100644
--- a/src/utils/dynamicTitle.ts
+++ b/src/utils/dynamicTitle.ts
@@ -5,10 +5,10 @@
  * 鍔ㄦ�佷慨鏀规爣棰�
  */
 export const useDynamicTitle = () => {
-	const settingsStore = useSettingsStore();
-	if (settingsStore.dynamicTitle) {
-		document.title = settingsStore.title + ' - ' + import.meta.env.VITE_APP_TITLE;
-	} else {
-		document.title = defaultSettings.title as string;
-	}
+  const settingsStore = useSettingsStore();
+  if (settingsStore.dynamicTitle) {
+    document.title = settingsStore.title + ' - ' + import.meta.env.VITE_APP_TITLE;
+  } else {
+    document.title = defaultSettings.title as string;
+  }
 };
diff --git a/src/utils/errorCode.ts b/src/utils/errorCode.ts
index f541b21..d85914e 100644
--- a/src/utils/errorCode.ts
+++ b/src/utils/errorCode.ts
@@ -1,7 +1,7 @@
 export const errorCode: any = {
-	'401': '璁よ瘉澶辫触锛屾棤娉曡闂郴缁熻祫婧�',
-	'403': '褰撳墠鎿嶄綔娌℃湁鏉冮檺',
-	'404': '璁块棶璧勬簮涓嶅瓨鍦�',
-	default: '绯荤粺鏈煡閿欒锛岃鍙嶉缁欑鐞嗗憳'
+  '401': '璁よ瘉澶辫触锛屾棤娉曡闂郴缁熻祫婧�',
+  '403': '褰撳墠鎿嶄綔娌℃湁鏉冮檺',
+  '404': '璁块棶璧勬簮涓嶅瓨鍦�',
+  default: '绯荤粺鏈煡閿欒锛岃鍙嶉缁欑鐞嗗憳'
 };
 export default errorCode;
diff --git a/src/utils/i18n.ts b/src/utils/i18n.ts
index 758c847..481010a 100644
--- a/src/utils/i18n.ts
+++ b/src/utils/i18n.ts
@@ -2,11 +2,11 @@
 import i18n from '@/lang/index';
 
 export const translateRouteTitleI18n = (title: string): string => {
-	// 鍒ゆ柇鏄惁瀛樺湪鍥介檯鍖栭厤缃紝濡傛灉娌℃湁鍘熺敓杩斿洖
-	const hasKey = i18n.global.te('route.' + title);
-	if (hasKey) {
-		const translatedTitle = i18n.global.t('route.' + title);
-		return translatedTitle;
-	}
-	return title;
+  // 鍒ゆ柇鏄惁瀛樺湪鍥介檯鍖栭厤缃紝濡傛灉娌℃湁鍘熺敓杩斿洖
+  const hasKey = i18n.global.te('route.' + title);
+  if (hasKey) {
+    const translatedTitle = i18n.global.t('route.' + title);
+    return translatedTitle;
+  }
+  return title;
 };
diff --git a/src/utils/index.ts b/src/utils/index.ts
index fb1a97b..f474462 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -4,15 +4,15 @@
  * 琛ㄦ牸鏃堕棿鏍煎紡鍖�
  */
 export const formatDate = (cellValue: string) => {
-	if (cellValue == null || cellValue == '') return '';
-	const date = new Date(cellValue);
-	const year = date.getFullYear();
-	const month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1;
-	const day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
-	const hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours();
-	const minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes();
-	const seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
-	return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
+  if (cellValue == null || cellValue == '') return '';
+  const date = new Date(cellValue);
+  const year = date.getFullYear();
+  const month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1;
+  const day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
+  const hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours();
+  const minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes();
+  const seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
+  return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
 };
 
 /**
@@ -21,32 +21,32 @@
  * @returns {string}
  */
 export const formatTime = (time: string, option: string) => {
-	let t: number;
-	if (('' + time).length === 10) {
-		t = parseInt(time) * 1000;
-	} else {
-		t = +time;
-	}
-	const d: any = new Date(t);
-	const now = Date.now();
+  let t: number;
+  if (('' + time).length === 10) {
+    t = parseInt(time) * 1000;
+  } else {
+    t = +time;
+  }
+  const d: any = new Date(t);
+  const now = Date.now();
 
-	const diff = (now - d) / 1000;
+  const diff = (now - d) / 1000;
 
-	if (diff < 30) {
-		return '鍒氬垰';
-	} else if (diff < 3600) {
-		// less 1 hour
-		return Math.ceil(diff / 60) + '鍒嗛挓鍓�';
-	} else if (diff < 3600 * 24) {
-		return Math.ceil(diff / 3600) + '灏忔椂鍓�';
-	} else if (diff < 3600 * 24 * 2) {
-		return '1澶╁墠';
-	}
-	if (option) {
-		return parseTime(t, option);
-	} else {
-		return d.getMonth() + 1 + '鏈�' + d.getDate() + '鏃�' + d.getHours() + '鏃�' + d.getMinutes() + '鍒�';
-	}
+  if (diff < 30) {
+    return '鍒氬垰';
+  } else if (diff < 3600) {
+    // less 1 hour
+    return Math.ceil(diff / 60) + '鍒嗛挓鍓�';
+  } else if (diff < 3600 * 24) {
+    return Math.ceil(diff / 3600) + '灏忔椂鍓�';
+  } else if (diff < 3600 * 24 * 2) {
+    return '1澶╁墠';
+  }
+  if (option) {
+    return parseTime(t, option);
+  } else {
+    return d.getMonth() + 1 + '鏈�' + d.getDate() + '鏃�' + d.getHours() + '鏃�' + d.getMinutes() + '鍒�';
+  }
 };
 
 /**
@@ -54,18 +54,18 @@
  * @returns {Object}
  */
 export const getQueryObject = (url: string) => {
-	url = url == null ? window.location.href : url;
-	const search = url.substring(url.lastIndexOf('?') + 1);
-	const obj: { [key: string]: string } = {};
-	const reg = /([^?&=]+)=([^?&=]*)/g;
-	search.replace(reg, (rs, $1, $2) => {
-		const name = decodeURIComponent($1);
-		let val = decodeURIComponent($2);
-		val = String(val);
-		obj[name] = val;
-		return rs;
-	});
-	return obj;
+  url = url == null ? window.location.href : url;
+  const search = url.substring(url.lastIndexOf('?') + 1);
+  const obj: { [key: string]: string } = {};
+  const reg = /([^?&=]+)=([^?&=]*)/g;
+  search.replace(reg, (rs, $1, $2) => {
+    const name = decodeURIComponent($1);
+    let val = decodeURIComponent($2);
+    val = String(val);
+    obj[name] = val;
+    return rs;
+  });
+  return obj;
 };
 
 /**
@@ -73,15 +73,15 @@
  * @returns {number} output value
  */
 export const byteLength = (str: string) => {
-	// returns the byte length of an utf8 string
-	let s = str.length;
-	for (let i = str.length - 1; i >= 0; i--) {
-		const code = str.charCodeAt(i);
-		if (code > 0x7f && code <= 0x7ff) s++;
-		else if (code > 0x7ff && code <= 0xffff) s += 2;
-		if (code >= 0xdc00 && code <= 0xdfff) i--;
-	}
-	return s;
+  // returns the byte length of an utf8 string
+  let s = str.length;
+  for (let i = str.length - 1; i >= 0; i--) {
+    const code = str.charCodeAt(i);
+    if (code > 0x7f && code <= 0x7ff) s++;
+    else if (code > 0x7ff && code <= 0xffff) s += 2;
+    if (code >= 0xdc00 && code <= 0xdfff) i--;
+  }
+  return s;
 };
 
 /**
@@ -89,13 +89,13 @@
  * @returns {Array}
  */
 export const cleanArray = (actual: Array<any>) => {
-	const newArray = [];
-	for (let i = 0; i < actual.length; i++) {
-		if (actual[i]) {
-			newArray.push(actual[i]);
-		}
-	}
-	return newArray;
+  const newArray = [];
+  for (let i = 0; i < actual.length; i++) {
+    if (actual[i]) {
+      newArray.push(actual[i]);
+    }
+  }
+  return newArray;
 };
 
 /**
@@ -103,13 +103,13 @@
  * @returns {Array}
  */
 export const param = (json: any) => {
-	if (!json) return '';
-	return cleanArray(
-		Object.keys(json).map((key) => {
-			if (json[key] === undefined) return '';
-			return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]);
-		})
-	).join('&');
+  if (!json) return '';
+  return cleanArray(
+    Object.keys(json).map((key) => {
+      if (json[key] === undefined) return '';
+      return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]);
+    })
+  ).join('&');
 };
 
 /**
@@ -117,21 +117,21 @@
  * @returns {Object}
  */
 export const param2Obj = (url: string) => {
-	const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ');
-	if (!search) {
-		return {};
-	}
-	const obj: any = {};
-	const searchArr = search.split('&');
-	searchArr.forEach((v) => {
-		const index = v.indexOf('=');
-		if (index !== -1) {
-			const name = v.substring(0, index);
-			const val = v.substring(index + 1, v.length);
-			obj[name] = val;
-		}
-	});
-	return obj;
+  const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ');
+  if (!search) {
+    return {};
+  }
+  const obj: any = {};
+  const searchArr = search.split('&');
+  searchArr.forEach((v) => {
+    const index = v.indexOf('=');
+    if (index !== -1) {
+      const name = v.substring(0, index);
+      const val = v.substring(index + 1, v.length);
+      obj[name] = val;
+    }
+  });
+  return obj;
 };
 
 /**
@@ -139,9 +139,9 @@
  * @returns {string}
  */
 export const html2Text = (val: string) => {
-	const div = document.createElement('div');
-	div.innerHTML = val;
-	return div.textContent || div.innerText;
+  const div = document.createElement('div');
+  div.innerHTML = val;
+  return div.textContent || div.innerText;
 };
 
 /**
@@ -151,21 +151,21 @@
  * @returns {Object}
  */
 export const objectMerge = (target: any, source: any | any[]) => {
-	if (typeof target !== 'object') {
-		target = {};
-	}
-	if (Array.isArray(source)) {
-		return source.slice();
-	}
-	Object.keys(source).forEach((property) => {
-		const sourceProperty = source[property];
-		if (typeof sourceProperty === 'object') {
-			target[property] = objectMerge(target[property], sourceProperty);
-		} else {
-			target[property] = sourceProperty;
-		}
-	});
-	return target;
+  if (typeof target !== 'object') {
+    target = {};
+  }
+  if (Array.isArray(source)) {
+    return source.slice();
+  }
+  Object.keys(source).forEach((property) => {
+    const sourceProperty = source[property];
+    if (typeof sourceProperty === 'object') {
+      target[property] = objectMerge(target[property], sourceProperty);
+    } else {
+      target[property] = sourceProperty;
+    }
+  });
+  return target;
 };
 
 /**
@@ -173,17 +173,17 @@
  * @param {string} className
  */
 export const toggleClass = (element: HTMLElement, className: string) => {
-	if (!element || !className) {
-		return;
-	}
-	let classString = element.className;
-	const nameIndex = classString.indexOf(className);
-	if (nameIndex === -1) {
-		classString += '' + className;
-	} else {
-		classString = classString.substring(0, nameIndex) + classString.substring(nameIndex + className.length);
-	}
-	element.className = classString;
+  if (!element || !className) {
+    return;
+  }
+  let classString = element.className;
+  const nameIndex = classString.indexOf(className);
+  if (nameIndex === -1) {
+    classString += '' + className;
+  } else {
+    classString = classString.substring(0, nameIndex) + classString.substring(nameIndex + className.length);
+  }
+  element.className = classString;
 };
 
 /**
@@ -191,11 +191,11 @@
  * @returns {Date}
  */
 export const getTime = (type: string) => {
-	if (type === 'start') {
-		return new Date().getTime() - 3600 * 1000 * 24 * 90;
-	} else {
-		return new Date(new Date().toDateString());
-	}
+  if (type === 'start') {
+    return new Date().getTime() - 3600 * 1000 * 24 * 90;
+  } else {
+    return new Date(new Date().toDateString());
+  }
 };
 
 /**
@@ -205,37 +205,37 @@
  * @return {*}
  */
 export const debounce = (func: any, wait: number, immediate: boolean) => {
-	let timeout: any, args: any, context: any, timestamp: any, result: any;
+  let timeout: any, args: any, context: any, timestamp: any, result: any;
 
-	const later = function () {
-		// 鎹笂涓�娆¤Е鍙戞椂闂撮棿闅�
-		const last = +new Date() - timestamp;
+  const later = function () {
+    // 鎹笂涓�娆¤Е鍙戞椂闂撮棿闅�
+    const last = +new Date() - timestamp;
 
-		// 涓婃琚寘瑁呭嚱鏁拌璋冪敤鏃堕棿闂撮殧 last 灏忎簬璁惧畾鏃堕棿闂撮殧 wait
-		if (last < wait && last > 0) {
-			timeout = setTimeout(later, wait - last);
-		} else {
-			timeout = null;
-			// 濡傛灉璁惧畾涓篿mmediate===true锛屽洜涓哄紑濮嬭竟鐣屽凡缁忚皟鐢ㄨ繃浜嗘澶勬棤闇�璋冪敤
-			if (!immediate) {
-				result = func.apply(context, args);
-				if (!timeout) context = args = null;
-			}
-		}
-	};
+    // 涓婃琚寘瑁呭嚱鏁拌璋冪敤鏃堕棿闂撮殧 last 灏忎簬璁惧畾鏃堕棿闂撮殧 wait
+    if (last < wait && last > 0) {
+      timeout = setTimeout(later, wait - last);
+    } else {
+      timeout = null;
+      // 濡傛灉璁惧畾涓篿mmediate===true锛屽洜涓哄紑濮嬭竟鐣屽凡缁忚皟鐢ㄨ繃浜嗘澶勬棤闇�璋冪敤
+      if (!immediate) {
+        result = func.apply(context, args);
+        if (!timeout) context = args = null;
+      }
+    }
+  };
 
-	return (...args: any) => {
-		context = this;
-		timestamp = +new Date();
-		const callNow = immediate && !timeout;
-		// 濡傛灉寤舵椂涓嶅瓨鍦紝閲嶆柊璁惧畾寤舵椂
-		if (!timeout) timeout = setTimeout(later, wait);
-		if (callNow) {
-			result = func.apply(context, args);
-			context = args = null;
-		}
-		return result;
-	};
+  return (...args: any) => {
+    context = this;
+    timestamp = +new Date();
+    const callNow = immediate && !timeout;
+    // 濡傛灉寤舵椂涓嶅瓨鍦紝閲嶆柊璁惧畾寤舵椂
+    if (!timeout) timeout = setTimeout(later, wait);
+    if (callNow) {
+      result = func.apply(context, args);
+      context = args = null;
+    }
+    return result;
+  };
 };
 
 /**
@@ -246,18 +246,18 @@
  * @returns {Object}
  */
 export const deepClone = (source: any) => {
-	if (!source && typeof source !== 'object') {
-		throw new Error('error arguments', 'deepClone' as any);
-	}
-	const targetObj: any = source.constructor === Array ? [] : {};
-	Object.keys(source).forEach((keys) => {
-		if (source[keys] && typeof source[keys] === 'object') {
-			targetObj[keys] = deepClone(source[keys]);
-		} else {
-			targetObj[keys] = source[keys];
-		}
-	});
-	return targetObj;
+  if (!source && typeof source !== 'object') {
+    throw new Error('error arguments', 'deepClone' as any);
+  }
+  const targetObj: any = source.constructor === Array ? [] : {};
+  Object.keys(source).forEach((keys) => {
+    if (source[keys] && typeof source[keys] === 'object') {
+      targetObj[keys] = deepClone(source[keys]);
+    } else {
+      targetObj[keys] = source[keys];
+    }
+  });
+  return targetObj;
 };
 
 /**
@@ -265,17 +265,17 @@
  * @returns {Array}
  */
 export const uniqueArr = (arr: any) => {
-	return Array.from(new Set(arr));
+  return Array.from(new Set(arr));
 };
 
 /**
  * @returns {string}
  */
 export const createUniqueString = (): string => {
-	const timestamp = +new Date() + '';
-	const num = (1 + Math.random()) * 65536;
-	const randomNum = parseInt(num + '');
-	return (+(randomNum + timestamp)).toString(32);
+  const timestamp = +new Date() + '';
+  const num = (1 + Math.random()) * 65536;
+  const randomNum = parseInt(num + '');
+  return (+(randomNum + timestamp)).toString(32);
 };
 
 /**
@@ -285,7 +285,7 @@
  * @returns {boolean}
  */
 export const hasClass = (ele: HTMLElement, cls: string): boolean => {
-	return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
+  return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
 };
 
 /**
@@ -294,7 +294,7 @@
  * @param {string} cls
  */
 export const addClass = (ele: HTMLElement, cls: string) => {
-	if (!hasClass(ele, cls)) ele.className += ' ' + cls;
+  if (!hasClass(ele, cls)) ele.className += ' ' + cls;
 };
 
 /**
@@ -303,10 +303,10 @@
  * @param {string} cls
  */
 export const removeClass = (ele: HTMLElement, cls: string) => {
-	if (hasClass(ele, cls)) {
-		const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
-		ele.className = ele.className.replace(reg, ' ');
-	}
+  if (hasClass(ele, cls)) {
+    const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
+    ele.className = ele.className.replace(reg, ' ');
+  }
 };
 
 /**
@@ -314,5 +314,5 @@
  * @returns {Boolean}
  */
 export const isExternal = (path: string) => {
-	return /^(https?:|http?:|mailto:|tel:)/.test(path);
+  return /^(https?:|http?:|mailto:|tel:)/.test(path);
 };
diff --git a/src/utils/jsencrypt.ts b/src/utils/jsencrypt.ts
index d26209b..18493ad 100644
--- a/src/utils/jsencrypt.ts
+++ b/src/utils/jsencrypt.ts
@@ -2,28 +2,28 @@
 // 瀵嗛挜瀵圭敓鎴� http://web.chacuo.net/netrsakeypair
 
 const publicKey =
-	'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' + 'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==';
+  'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' + 'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==';
 
 const privateKey =
-	'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' +
-	'7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' +
-	'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' +
-	'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' +
-	'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' +
-	'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' +
-	'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' +
-	'UP8iWi1Qw0Y=';
+  'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' +
+  '7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' +
+  'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' +
+  'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' +
+  'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' +
+  'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' +
+  'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' +
+  'UP8iWi1Qw0Y=';
 
 // 鍔犲瘑
 export const encrypt = (txt: string) => {
-	const encryptor = new JSEncrypt();
-	encryptor.setPublicKey(publicKey); // 璁剧疆鍏挜
-	return encryptor.encrypt(txt); // 瀵规暟鎹繘琛屽姞瀵�
+  const encryptor = new JSEncrypt();
+  encryptor.setPublicKey(publicKey); // 璁剧疆鍏挜
+  return encryptor.encrypt(txt); // 瀵规暟鎹繘琛屽姞瀵�
 };
 
 // 瑙e瘑
 export const decrypt = (txt: string) => {
-	const encryptor = new JSEncrypt();
-	encryptor.setPrivateKey(privateKey); // 璁剧疆绉侀挜
-	return encryptor.decrypt(txt); // 瀵规暟鎹繘琛岃В瀵�
+  const encryptor = new JSEncrypt();
+  encryptor.setPrivateKey(privateKey); // 璁剧疆绉侀挜
+  return encryptor.decrypt(txt); // 瀵规暟鎹繘琛岃В瀵�
 };
diff --git a/src/utils/permission.ts b/src/utils/permission.ts
index 7b51dbc..eb3838a 100644
--- a/src/utils/permission.ts
+++ b/src/utils/permission.ts
@@ -6,23 +6,23 @@
  * @returns {Boolean}
  */
 export const checkPermi = (value: any) => {
-	if (value && value instanceof Array && value.length > 0) {
-		const permissions = useUserStore().permissions;
-		const permissionDatas = value;
-		const all_permission = '*:*:*';
+  if (value && value instanceof Array && value.length > 0) {
+    const permissions = useUserStore().permissions;
+    const permissionDatas = value;
+    const all_permission = '*:*:*';
 
-		const hasPermission = permissions.some((permission) => {
-			return all_permission === permission || permissionDatas.includes(permission);
-		});
+    const hasPermission = permissions.some((permission) => {
+      return all_permission === permission || permissionDatas.includes(permission);
+    });
 
-		if (!hasPermission) {
-			return false;
-		}
-		return true;
-	} else {
-		console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`);
-		return false;
-	}
+    if (!hasPermission) {
+      return false;
+    }
+    return true;
+  } else {
+    console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`);
+    return false;
+  }
 };
 
 /**
@@ -31,21 +31,21 @@
  * @returns {Boolean}
  */
 export const checkRole = (value: any): boolean => {
-	if (value && value instanceof Array && value.length > 0) {
-		const roles = useUserStore().roles;
-		const permissionRoles = value;
-		const super_admin = 'admin';
+  if (value && value instanceof Array && value.length > 0) {
+    const roles = useUserStore().roles;
+    const permissionRoles = value;
+    const super_admin = 'admin';
 
-		const hasRole = roles.some((role) => {
-			return super_admin === role || permissionRoles.includes(role);
-		});
+    const hasRole = roles.some((role) => {
+      return super_admin === role || permissionRoles.includes(role);
+    });
 
-		if (!hasRole) {
-			return false;
-		}
-		return true;
-	} else {
-		console.error(`need roles! Like checkRole="['admin','editor']"`);
-		return false;
-	}
+    if (!hasRole) {
+      return false;
+    }
+    return true;
+  } else {
+    console.error(`need roles! Like checkRole="['admin','editor']"`);
+    return false;
+  }
 };
diff --git a/src/utils/request.ts b/src/utils/request.ts
index 1376fbd..5fe8f11 100644
--- a/src/utils/request.ts
+++ b/src/utils/request.ts
@@ -17,143 +17,143 @@
 axios.defaults.headers['Content-Language'] = 'zh_CN';
 // 鍒涘缓 axios 瀹炰緥
 const service = axios.create({
-	baseURL: import.meta.env.VITE_APP_BASE_API,
-	timeout: 50000
+  baseURL: import.meta.env.VITE_APP_BASE_API,
+  timeout: 50000
 });
 
 // 璇锋眰鎷︽埅鍣�
 service.interceptors.request.use(
-	(config: InternalAxiosRequestConfig) => {
-		const isToken = (config.headers || {}).isToken === false;
-		// 鏄惁闇�瑕侀槻姝㈡暟鎹噸澶嶆彁浜�
-		const isRepeatSubmit = !(config.headers || {}).repeatSubmit;
-		if (getToken() && !isToken) {
-			config.headers['Authorization'] = 'Bearer ' + getToken(); // 璁╂瘡涓姹傛惡甯﹁嚜瀹氫箟token 璇锋牴鎹疄闄呮儏鍐佃嚜琛屼慨鏀�
-		}
-		// get璇锋眰鏄犲皠params鍙傛暟
-		if (config.method === 'get' && config.params) {
-			let url = config.url + '?' + tansParams(config.params);
-			url = url.slice(0, -1);
-			config.params = {};
-			config.url = url;
-		}
+  (config: InternalAxiosRequestConfig) => {
+    const isToken = (config.headers || {}).isToken === false;
+    // 鏄惁闇�瑕侀槻姝㈡暟鎹噸澶嶆彁浜�
+    const isRepeatSubmit = !(config.headers || {}).repeatSubmit;
+    if (getToken() && !isToken) {
+      config.headers['Authorization'] = 'Bearer ' + getToken(); // 璁╂瘡涓姹傛惡甯﹁嚜瀹氫箟token 璇锋牴鎹疄闄呮儏鍐佃嚜琛屼慨鏀�
+    }
+    // get璇锋眰鏄犲皠params鍙傛暟
+    if (config.method === 'get' && config.params) {
+      let url = config.url + '?' + tansParams(config.params);
+      url = url.slice(0, -1);
+      config.params = {};
+      config.url = url;
+    }
 
-		if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
-			const requestObj = {
-				url: config.url,
-				data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
-				time: new Date().getTime()
-			};
-			const sessionObj = cache.session.getJSON('sessionObj');
-			if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
-				cache.session.setJSON('sessionObj', requestObj);
-			} else {
-				const s_url = sessionObj.url; // 璇锋眰鍦板潃
-				const s_data = sessionObj.data; // 璇锋眰鏁版嵁
-				const s_time = sessionObj.time; // 璇锋眰鏃堕棿
-				const interval = 500; // 闂撮殧鏃堕棿(ms)锛屽皬浜庢鏃堕棿瑙嗕负閲嶅鎻愪氦
-				if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
-					const message = '鏁版嵁姝e湪澶勭悊锛岃鍕块噸澶嶆彁浜�';
-					console.warn(`[${s_url}]: ` + message);
-					return Promise.reject(new Error(message));
-				} else {
-					cache.session.setJSON('sessionObj', requestObj);
-				}
-			}
-		}
-		return config;
-	},
-	(error: any) => {
-		console.log(error);
-		return Promise.reject(error);
-	}
+    if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
+      const requestObj = {
+        url: config.url,
+        data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
+        time: new Date().getTime()
+      };
+      const sessionObj = cache.session.getJSON('sessionObj');
+      if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
+        cache.session.setJSON('sessionObj', requestObj);
+      } else {
+        const s_url = sessionObj.url; // 璇锋眰鍦板潃
+        const s_data = sessionObj.data; // 璇锋眰鏁版嵁
+        const s_time = sessionObj.time; // 璇锋眰鏃堕棿
+        const interval = 500; // 闂撮殧鏃堕棿(ms)锛屽皬浜庢鏃堕棿瑙嗕负閲嶅鎻愪氦
+        if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
+          const message = '鏁版嵁姝e湪澶勭悊锛岃鍕块噸澶嶆彁浜�';
+          console.warn(`[${s_url}]: ` + message);
+          return Promise.reject(new Error(message));
+        } else {
+          cache.session.setJSON('sessionObj', requestObj);
+        }
+      }
+    }
+    return config;
+  },
+  (error: any) => {
+    console.log(error);
+    return Promise.reject(error);
+  }
 );
 
 // 鍝嶅簲鎷︽埅鍣�
 service.interceptors.response.use(
-	(res) => {
-		// 鏈缃姸鎬佺爜鍒欓粯璁ゆ垚鍔熺姸鎬�
-		const code = res.data.code || HttpStatus.SUCCESS;
-		// 鑾峰彇閿欒淇℃伅
-		const msg = errorCode[code] || res.data.msg || errorCode['default'];
-		// 浜岃繘鍒舵暟鎹垯鐩存帴杩斿洖
-		if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
-			return res.data;
-		}
-		if (code === 401) {
-			// prettier-ignore
-			if (!isRelogin.show) {
-				isRelogin.show = true;
-				ElMessageBox.confirm('鐧诲綍鐘舵�佸凡杩囨湡锛屾偍鍙互缁х画鐣欏湪璇ラ〉闈紝鎴栬�呴噸鏂扮櫥褰�', '绯荤粺鎻愮ず', {
-					confirmButtonText: '閲嶆柊鐧诲綍',
-					cancelButtonText: '鍙栨秷',
-					type: 'warning'
-				}).then(() => {
-					isRelogin.show = false;
-					useUserStore().logout().then(() => {
-							location.href = import.meta.env.VITE_APP_CONTEXT_PATH + 'index';
-						});
-				}).catch(() => {
-					isRelogin.show = false;
-				});
-			}
-			return Promise.reject('鏃犳晥鐨勪細璇濓紝鎴栬�呬細璇濆凡杩囨湡锛岃閲嶆柊鐧诲綍銆�');
-		} else if (code === HttpStatus.SERVER_ERROR) {
-			console.log(msg);
-			ElMessage({ message: msg, type: 'error' });
-			return Promise.reject(new Error(msg));
-		} else if (code === HttpStatus.WARN) {
-			ElMessage({ message: msg, type: 'warning' });
-			return Promise.reject(new Error(msg));
-		} else if (code !== HttpStatus.SUCCESS) {
-			ElNotification.error({ title: msg });
-			return Promise.reject('error');
-		} else {
-			return Promise.resolve(res.data);
-		}
-	},
-	(error) => {
-		let { message } = error;
-		if (message == 'Network Error') {
-			message = '鍚庣鎺ュ彛杩炴帴寮傚父';
-		} else if (message.includes('timeout')) {
-			message = '绯荤粺鎺ュ彛璇锋眰瓒呮椂';
-		} else if (message.includes('Request failed with status code')) {
-			message = '绯荤粺鎺ュ彛' + message.substr(message.length - 3) + '寮傚父';
-		}
-		ElMessage({ message: message, type: 'error', duration: 5 * 1000 });
-		return Promise.reject(error);
-	}
+  (res) => {
+    // 鏈缃姸鎬佺爜鍒欓粯璁ゆ垚鍔熺姸鎬�
+    const code = res.data.code || HttpStatus.SUCCESS;
+    // 鑾峰彇閿欒淇℃伅
+    const msg = errorCode[code] || res.data.msg || errorCode['default'];
+    // 浜岃繘鍒舵暟鎹垯鐩存帴杩斿洖
+    if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
+      return res.data;
+    }
+    if (code === 401) {
+      // prettier-ignore
+      if (!isRelogin.show) {
+        isRelogin.show = true;
+        ElMessageBox.confirm('鐧诲綍鐘舵�佸凡杩囨湡锛屾偍鍙互缁х画鐣欏湪璇ラ〉闈紝鎴栬�呴噸鏂扮櫥褰�', '绯荤粺鎻愮ず', {
+          confirmButtonText: '閲嶆柊鐧诲綍',
+          cancelButtonText: '鍙栨秷',
+          type: 'warning'
+        }).then(() => {
+          isRelogin.show = false;
+          useUserStore().logout().then(() => {
+              location.href = import.meta.env.VITE_APP_CONTEXT_PATH + 'index';
+            });
+        }).catch(() => {
+          isRelogin.show = false;
+        });
+      }
+      return Promise.reject('鏃犳晥鐨勪細璇濓紝鎴栬�呬細璇濆凡杩囨湡锛岃閲嶆柊鐧诲綍銆�');
+    } else if (code === HttpStatus.SERVER_ERROR) {
+      console.log(msg);
+      ElMessage({ message: msg, type: 'error' });
+      return Promise.reject(new Error(msg));
+    } else if (code === HttpStatus.WARN) {
+      ElMessage({ message: msg, type: 'warning' });
+      return Promise.reject(new Error(msg));
+    } else if (code !== HttpStatus.SUCCESS) {
+      ElNotification.error({ title: msg });
+      return Promise.reject('error');
+    } else {
+      return Promise.resolve(res.data);
+    }
+  },
+  (error) => {
+    let { message } = error;
+    if (message == 'Network Error') {
+      message = '鍚庣鎺ュ彛杩炴帴寮傚父';
+    } else if (message.includes('timeout')) {
+      message = '绯荤粺鎺ュ彛璇锋眰瓒呮椂';
+    } else if (message.includes('Request failed with status code')) {
+      message = '绯荤粺鎺ュ彛' + message.substr(message.length - 3) + '寮傚父';
+    }
+    ElMessage({ message: message, type: 'error', duration: 5 * 1000 });
+    return Promise.reject(error);
+  }
 );
 // 閫氱敤涓嬭浇鏂规硶
 export function download(url: string, params: any, fileName: string) {
-	downloadLoadingInstance = ElLoading.service({ text: '姝e湪涓嬭浇鏁版嵁锛岃绋嶅��', background: 'rgba(0, 0, 0, 0.7)' });
-	// prettier-ignore
-	return service.post(url, params, {
-			transformRequest: [
-				(params) => {
-					return tansParams(params);
-				}
-			],
-			headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
-			responseType: 'blob'
-		}).then(async (resp) => {
-			const isLogin = blobValidate(resp);
-			if (isLogin) {
-				const blob = new Blob([resp as any]);
+  downloadLoadingInstance = ElLoading.service({ text: '姝e湪涓嬭浇鏁版嵁锛岃绋嶅��', background: 'rgba(0, 0, 0, 0.7)' });
+  // prettier-ignore
+  return service.post(url, params, {
+      transformRequest: [
+        (params) => {
+          return tansParams(params);
+        }
+      ],
+      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+      responseType: 'blob'
+    }).then(async (resp) => {
+      const isLogin = blobValidate(resp);
+      if (isLogin) {
+        const blob = new Blob([resp as any]);
         FileSaver.saveAs(blob, fileName);
-			} else {
-				const resText = await resp.data.text();
-				const rspObj = JSON.parse(resText);
-				const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'];
-				ElMessage.error(errMsg);
-			}
-			downloadLoadingInstance.close();
-		}).catch((r) => {
-			console.error(r);
-			ElMessage.error('涓嬭浇鏂囦欢鍑虹幇閿欒锛岃鑱旂郴绠$悊鍛橈紒');
-			downloadLoadingInstance.close();
-		});
+      } else {
+        const resText = await resp.data.text();
+        const rspObj = JSON.parse(resText);
+        const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'];
+        ElMessage.error(errMsg);
+      }
+      downloadLoadingInstance.close();
+    }).catch((r) => {
+      console.error(r);
+      ElMessage.error('涓嬭浇鏂囦欢鍑虹幇閿欒锛岃鑱旂郴绠$悊鍛橈紒');
+      downloadLoadingInstance.close();
+    });
 }
 // 瀵煎嚭 axios 瀹炰緥
 export default service;
diff --git a/src/utils/ruoyi.ts b/src/utils/ruoyi.ts
index 05691d8..a116b52 100644
--- a/src/utils/ruoyi.ts
+++ b/src/utils/ruoyi.ts
@@ -1,46 +1,46 @@
 // 鏃ユ湡鏍煎紡鍖�
 export function parseTime(time: any, pattern?: string) {
-	if (arguments.length === 0 || !time) {
-		return null;
-	}
-	const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}';
-	let date;
-	if (typeof time === 'object') {
-		date = time;
-	} else {
-		if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
-			time = parseInt(time);
-		} else if (typeof time === 'string') {
-			time = time
-				.replace(new RegExp(/-/gm), '/')
-				.replace('T', ' ')
-				.replace(new RegExp(/\.[\d]{3}/gm), '');
-		}
-		if (typeof time === 'number' && time.toString().length === 10) {
-			time = time * 1000;
-		}
-		date = new Date(time);
-	}
-	const formatObj: { [key: string]: any } = {
-		y: date.getFullYear(),
-		m: date.getMonth() + 1,
-		d: date.getDate(),
-		h: date.getHours(),
-		i: date.getMinutes(),
-		s: date.getSeconds(),
-		a: date.getDay()
-	};
-	return format.replace(/{(y|m|d|h|i|s|a)+}/g, (result: string, key: string) => {
-		let value = formatObj[key];
-		// Note: getDay() returns 0 on Sunday
-		if (key === 'a') {
-			return ['鏃�', '涓�', '浜�', '涓�', '鍥�', '浜�', '鍏�'][value];
-		}
-		if (result.length > 0 && value < 10) {
-			value = '0' + value;
-		}
-		return value || 0;
-	});
+  if (arguments.length === 0 || !time) {
+    return null;
+  }
+  const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}';
+  let date;
+  if (typeof time === 'object') {
+    date = time;
+  } else {
+    if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
+      time = parseInt(time);
+    } else if (typeof time === 'string') {
+      time = time
+        .replace(new RegExp(/-/gm), '/')
+        .replace('T', ' ')
+        .replace(new RegExp(/\.[\d]{3}/gm), '');
+    }
+    if (typeof time === 'number' && time.toString().length === 10) {
+      time = time * 1000;
+    }
+    date = new Date(time);
+  }
+  const formatObj: { [key: string]: any } = {
+    y: date.getFullYear(),
+    m: date.getMonth() + 1,
+    d: date.getDate(),
+    h: date.getHours(),
+    i: date.getMinutes(),
+    s: date.getSeconds(),
+    a: date.getDay()
+  };
+  return format.replace(/{(y|m|d|h|i|s|a)+}/g, (result: string, key: string) => {
+    let value = formatObj[key];
+    // Note: getDay() returns 0 on Sunday
+    if (key === 'a') {
+      return ['鏃�', '涓�', '浜�', '涓�', '鍥�', '浜�', '鍏�'][value];
+    }
+    if (result.length > 0 && value < 10) {
+      value = '0' + value;
+    }
+    return value || 0;
+  });
 }
 
 /**
@@ -50,102 +50,102 @@
  * @param propName
  */
 export const addDateRange = (params: any, dateRange: any[], propName?: string) => {
-	const search = params;
-	search.params = typeof search.params === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {};
-	dateRange = Array.isArray(dateRange) ? dateRange : [];
-	if (typeof propName === 'undefined') {
-		search.params['beginTime'] = dateRange[0];
-		search.params['endTime'] = dateRange[1];
-	} else {
-		search.params['begin' + propName] = dateRange[0];
-		search.params['end' + propName] = dateRange[1];
-	}
-	return search;
+  const search = params;
+  search.params = typeof search.params === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {};
+  dateRange = Array.isArray(dateRange) ? dateRange : [];
+  if (typeof propName === 'undefined') {
+    search.params['beginTime'] = dateRange[0];
+    search.params['endTime'] = dateRange[1];
+  } else {
+    search.params['begin' + propName] = dateRange[0];
+    search.params['end' + propName] = dateRange[1];
+  }
+  return search;
 };
 
 // 鍥炴樉鏁版嵁瀛楀吀
 export const selectDictLabel = (datas: any, value: number | string) => {
-	if (value === undefined) {
-		return '';
-	}
-	const actions = [];
-	Object.keys(datas).some((key) => {
-		if (datas[key].value == '' + value) {
-			actions.push(datas[key].label);
-			return true;
-		}
-	});
-	if (actions.length === 0) {
-		actions.push(value);
-	}
-	return actions.join('');
+  if (value === undefined) {
+    return '';
+  }
+  const actions = [];
+  Object.keys(datas).some((key) => {
+    if (datas[key].value == '' + value) {
+      actions.push(datas[key].label);
+      return true;
+    }
+  });
+  if (actions.length === 0) {
+    actions.push(value);
+  }
+  return actions.join('');
 };
 
 // 鍥炴樉鏁版嵁瀛楀吀锛堝瓧绗︿覆鏁扮粍锛�
 export const selectDictLabels = (datas: any, value: any, separator: any) => {
-	if (value === undefined || value.length === 0) {
-		return '';
-	}
-	if (Array.isArray(value)) {
-		value = value.join(',');
-	}
-	const actions: any[] = [];
-	const currentSeparator = undefined === separator ? ',' : separator;
-	const temp = value.split(currentSeparator);
-	Object.keys(value.split(currentSeparator)).some((val) => {
-		let match = false;
-		Object.keys(datas).some((key) => {
-			if (datas[key].value == '' + temp[val]) {
-				actions.push(datas[key].label + currentSeparator);
-				match = true;
-			}
-		});
-		if (!match) {
-			actions.push(temp[val] + currentSeparator);
-		}
-	});
-	return actions.join('').substring(0, actions.join('').length - 1);
+  if (value === undefined || value.length === 0) {
+    return '';
+  }
+  if (Array.isArray(value)) {
+    value = value.join(',');
+  }
+  const actions: any[] = [];
+  const currentSeparator = undefined === separator ? ',' : separator;
+  const temp = value.split(currentSeparator);
+  Object.keys(value.split(currentSeparator)).some((val) => {
+    let match = false;
+    Object.keys(datas).some((key) => {
+      if (datas[key].value == '' + temp[val]) {
+        actions.push(datas[key].label + currentSeparator);
+        match = true;
+      }
+    });
+    if (!match) {
+      actions.push(temp[val] + currentSeparator);
+    }
+  });
+  return actions.join('').substring(0, actions.join('').length - 1);
 };
 
 // 瀛楃涓叉牸寮忓寲(%s )
 export function sprintf(str: string) {
-	if (arguments.length !== 0) {
-		let flag = true,
-			i = 1;
-		str = str.replace(/%s/g, function () {
-			const arg = arguments[i++];
-			if (typeof arg === 'undefined') {
-				flag = false;
-				return '';
-			}
-			return arg;
-		});
-		return flag ? str : '';
-	}
+  if (arguments.length !== 0) {
+    let flag = true,
+      i = 1;
+    str = str.replace(/%s/g, function () {
+      const arg = arguments[i++];
+      if (typeof arg === 'undefined') {
+        flag = false;
+        return '';
+      }
+      return arg;
+    });
+    return flag ? str : '';
+  }
 }
 
 // 杞崲瀛楃涓诧紝undefined,null绛夎浆鍖栦负""
 export const parseStrEmpty = (str: any) => {
-	if (!str || str == 'undefined' || str == 'null') {
-		return '';
-	}
-	return str;
+  if (!str || str == 'undefined' || str == 'null') {
+    return '';
+  }
+  return str;
 };
 
 // 鏁版嵁鍚堝苟
 export const mergeRecursive = (source: any, target: any) => {
-	for (const p in target) {
-		try {
-			if (target[p].constructor == Object) {
-				source[p] = mergeRecursive(source[p], target[p]);
-			} else {
-				source[p] = target[p];
-			}
-		} catch (e) {
-			source[p] = target[p];
-		}
-	}
-	return source;
+  for (const p in target) {
+    try {
+      if (target[p].constructor == Object) {
+        source[p] = mergeRecursive(source[p], target[p]);
+      } else {
+        source[p] = target[p];
+      }
+    } catch (e) {
+      source[p] = target[p];
+    }
+  }
+  return source;
 };
 
 /**
@@ -156,51 +156,51 @@
  * @param {*} children 瀛╁瓙鑺傜偣瀛楁 榛樿 'children'
  */
 export const handleTree = <T>(data: any[], id?: string, parentId?: string, children?: string): T[] => {
-	const config: {
-		id: string;
-		parentId: string;
-		childrenList: string;
-	} = {
-		id: id || 'id',
-		parentId: parentId || 'parentId',
-		childrenList: children || 'children'
-	};
+  const config: {
+    id: string;
+    parentId: string;
+    childrenList: string;
+  } = {
+    id: id || 'id',
+    parentId: parentId || 'parentId',
+    childrenList: children || 'children'
+  };
 
-	const childrenListMap: any = {};
-	const nodeIds: any = {};
-	const tree: T[] = [];
+  const childrenListMap: any = {};
+  const nodeIds: any = {};
+  const tree: T[] = [];
 
-	for (const d of data) {
-		const parentId = d[config.parentId];
-		if (childrenListMap[parentId] == null) {
-			childrenListMap[parentId] = [];
-		}
-		nodeIds[d[config.id]] = d;
-		childrenListMap[parentId].push(d);
-	}
+  for (const d of data) {
+    const parentId = d[config.parentId];
+    if (childrenListMap[parentId] == null) {
+      childrenListMap[parentId] = [];
+    }
+    nodeIds[d[config.id]] = d;
+    childrenListMap[parentId].push(d);
+  }
 
-	for (const d of data) {
-		const parentId = d[config.parentId];
-		if (nodeIds[parentId] == null) {
-			tree.push(d);
-		}
-	}
-	const adaptToChildrenList = (o: any) => {
-		if (childrenListMap[o[config.id]] !== null) {
-			o[config.childrenList] = childrenListMap[o[config.id]];
-		}
-		if (o[config.childrenList]) {
-			for (const c of o[config.childrenList]) {
-				adaptToChildrenList(c);
-			}
-		}
-	};
+  for (const d of data) {
+    const parentId = d[config.parentId];
+    if (nodeIds[parentId] == null) {
+      tree.push(d);
+    }
+  }
+  const adaptToChildrenList = (o: any) => {
+    if (childrenListMap[o[config.id]] !== null) {
+      o[config.childrenList] = childrenListMap[o[config.id]];
+    }
+    if (o[config.childrenList]) {
+      for (const c of o[config.childrenList]) {
+        adaptToChildrenList(c);
+      }
+    }
+  };
 
-	for (const t of tree) {
-		adaptToChildrenList(t);
-	}
+  for (const t of tree) {
+    adaptToChildrenList(t);
+  }
 
-	return tree;
+  return tree;
 };
 
 /**
@@ -208,40 +208,40 @@
  * @param {*} params  鍙傛暟
  */
 export const tansParams = (params: any) => {
-	let result = '';
-	for (const propName of Object.keys(params)) {
-		const value = params[propName];
-		const part = encodeURIComponent(propName) + '=';
-		if (value !== null && value !== '' && typeof value !== 'undefined') {
-			if (typeof value === 'object') {
-				for (const key of Object.keys(value)) {
-					if (value[key] !== null && value[key] !== '' && typeof value[key] !== 'undefined') {
-						const params = propName + '[' + key + ']';
-						const subPart = encodeURIComponent(params) + '=';
-						result += subPart + encodeURIComponent(value[key]) + '&';
-					}
-				}
-			} else {
-				result += part + encodeURIComponent(value) + '&';
-			}
-		}
-	}
-	return result;
+  let result = '';
+  for (const propName of Object.keys(params)) {
+    const value = params[propName];
+    const part = encodeURIComponent(propName) + '=';
+    if (value !== null && value !== '' && typeof value !== 'undefined') {
+      if (typeof value === 'object') {
+        for (const key of Object.keys(value)) {
+          if (value[key] !== null && value[key] !== '' && typeof value[key] !== 'undefined') {
+            const params = propName + '[' + key + ']';
+            const subPart = encodeURIComponent(params) + '=';
+            result += subPart + encodeURIComponent(value[key]) + '&';
+          }
+        }
+      } else {
+        result += part + encodeURIComponent(value) + '&';
+      }
+    }
+  }
+  return result;
 };
 
 // 杩斿洖椤圭洰璺緞
 export const getNormalPath = (p: string): string => {
-	if (p.length === 0 || !p || p === 'undefined') {
-		return p;
-	}
-	const res = p.replace('//', '/');
-	if (res[res.length - 1] === '/') {
-		return res.slice(0, res.length - 1);
-	}
-	return res;
+  if (p.length === 0 || !p || p === 'undefined') {
+    return p;
+  }
+  const res = p.replace('//', '/');
+  if (res[res.length - 1] === '/') {
+    return res.slice(0, res.length - 1);
+  }
+  return res;
 };
 
 // 楠岃瘉鏄惁涓篵lob鏍煎紡
 export const blobValidate = (data: any) => {
-	return data.type !== 'application/json';
+  return data.type !== 'application/json';
 };
diff --git a/src/utils/scroll-to.ts b/src/utils/scroll-to.ts
index bbb4709..c2fa379 100644
--- a/src/utils/scroll-to.ts
+++ b/src/utils/scroll-to.ts
@@ -1,22 +1,22 @@
 const easeInOutQuad = (t: number, b: number, c: number, d: number) => {
-	t /= d / 2;
-	if (t < 1) {
-		return (c / 2) * t * t + b;
-	}
-	t--;
-	return (-c / 2) * (t * (t - 2) - 1) + b;
+  t /= d / 2;
+  if (t < 1) {
+    return (c / 2) * t * t + b;
+  }
+  t--;
+  return (-c / 2) * (t * (t - 2) - 1) + b;
 };
 
 // requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
 const requestAnimFrame = (function () {
-	return (
-		window.requestAnimationFrame ||
-		(window as any).webkitRequestAnimationFrame ||
-		(window as any).mozRequestAnimationFrame ||
-		function (callback) {
-			window.setTimeout(callback, 1000 / 60);
-		}
-	);
+  return (
+    window.requestAnimationFrame ||
+    (window as any).webkitRequestAnimationFrame ||
+    (window as any).mozRequestAnimationFrame ||
+    function (callback) {
+      window.setTimeout(callback, 1000 / 60);
+    }
+  );
 })();
 
 /**
@@ -24,13 +24,13 @@
  * @param {number} amount
  */
 const move = (amount: number) => {
-	document.documentElement.scrollTop = amount;
-	(document.body.parentNode as HTMLElement).scrollTop = amount;
-	document.body.scrollTop = amount;
+  document.documentElement.scrollTop = amount;
+  (document.body.parentNode as HTMLElement).scrollTop = amount;
+  document.body.scrollTop = amount;
 };
 
 const position = () => {
-	return document.documentElement.scrollTop || (document.body.parentNode as HTMLElement).scrollTop || document.body.scrollTop;
+  return document.documentElement.scrollTop || (document.body.parentNode as HTMLElement).scrollTop || document.body.scrollTop;
 };
 
 /**
@@ -39,27 +39,27 @@
  * @param {Function} callback
  */
 export const scrollTo = (to: number, duration: number, callback?: any) => {
-	const start = position();
-	const change = to - start;
-	const increment = 20;
-	let currentTime = 0;
-	duration = typeof duration === 'undefined' ? 500 : duration;
-	const animateScroll = function () {
-		// increment the time
-		currentTime += increment;
-		// find the value with the quadratic in-out easing function
-		const val = easeInOutQuad(currentTime, start, change, duration);
-		// move the document.body
-		move(val);
-		// do the animation unless its over
-		if (currentTime < duration) {
-			requestAnimFrame(animateScroll);
-		} else {
-			if (callback && typeof callback === 'function') {
-				// the animation is done so lets callback
-				callback();
-			}
-		}
-	};
-	animateScroll();
+  const start = position();
+  const change = to - start;
+  const increment = 20;
+  let currentTime = 0;
+  duration = typeof duration === 'undefined' ? 500 : duration;
+  const animateScroll = function () {
+    // increment the time
+    currentTime += increment;
+    // find the value with the quadratic in-out easing function
+    const val = easeInOutQuad(currentTime, start, change, duration);
+    // move the document.body
+    move(val);
+    // do the animation unless its over
+    if (currentTime < duration) {
+      requestAnimFrame(animateScroll);
+    } else {
+      if (callback && typeof callback === 'function') {
+        // the animation is done so lets callback
+        callback();
+      }
+    }
+  };
+  animateScroll();
 };
diff --git a/src/utils/theme.ts b/src/utils/theme.ts
index 2ec6187..3936248 100644
--- a/src/utils/theme.ts
+++ b/src/utils/theme.ts
@@ -1,52 +1,52 @@
 // 澶勭悊涓婚鏍峰紡
 export const handleThemeStyle = (theme: string) => {
-	document.documentElement.style.setProperty('--el-color-primary', theme);
-	for (let i = 1; i <= 9; i++) {
-		document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, `${getLightColor(theme, i / 10)}`);
-	}
-	for (let i = 1; i <= 9; i++) {
-		document.documentElement.style.setProperty(`--el-color-primary-dark-${i}`, `${getDarkColor(theme, i / 10)}`);
-	}
+  document.documentElement.style.setProperty('--el-color-primary', theme);
+  for (let i = 1; i <= 9; i++) {
+    document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, `${getLightColor(theme, i / 10)}`);
+  }
+  for (let i = 1; i <= 9; i++) {
+    document.documentElement.style.setProperty(`--el-color-primary-dark-${i}`, `${getDarkColor(theme, i / 10)}`);
+  }
 };
 
 // hex棰滆壊杞瑀gb棰滆壊
 export const hexToRgb = (str: string): string[] => {
-	str = str.replace('#', '');
-	const hexs = str.match(/../g);
-	for (let i = 0; i < 3; i++) {
-		if (hexs) {
-			hexs[i] = String(parseInt(hexs[i], 16));
-		}
-	}
-	return hexs ? hexs : [];
+  str = str.replace('#', '');
+  const hexs = str.match(/../g);
+  for (let i = 0; i < 3; i++) {
+    if (hexs) {
+      hexs[i] = String(parseInt(hexs[i], 16));
+    }
+  }
+  return hexs ? hexs : [];
 };
 
 // rgb棰滆壊杞琀ex棰滆壊
 export const rgbToHex = (r: string, g: string, b: string) => {
-	const hexs = [Number(r).toString(16), Number(g).toString(16), Number(b).toString(16)];
-	for (let i = 0; i < 3; i++) {
-		if (hexs[i].length == 1) {
-			hexs[i] = `0${hexs[i]}`;
-		}
-	}
-	return `#${hexs.join('')}`;
+  const hexs = [Number(r).toString(16), Number(g).toString(16), Number(b).toString(16)];
+  for (let i = 0; i < 3; i++) {
+    if (hexs[i].length == 1) {
+      hexs[i] = `0${hexs[i]}`;
+    }
+  }
+  return `#${hexs.join('')}`;
 };
 
 // 鍙樻祬棰滆壊鍊�
 export const getLightColor = (color: string, level: number) => {
-	const rgb = hexToRgb(color);
-	for (let i = 0; i < 3; i++) {
-		const s = (255 - Number(rgb[i])) * level + Number(rgb[i]);
-		rgb[i] = String(Math.floor(s));
-	}
-	return rgbToHex(rgb[0], rgb[1], rgb[2]);
+  const rgb = hexToRgb(color);
+  for (let i = 0; i < 3; i++) {
+    const s = (255 - Number(rgb[i])) * level + Number(rgb[i]);
+    rgb[i] = String(Math.floor(s));
+  }
+  return rgbToHex(rgb[0], rgb[1], rgb[2]);
 };
 
 // 鍙樻繁棰滆壊鍊�
 export const getDarkColor = (color: string, level: number) => {
-	const rgb = hexToRgb(color);
-	for (let i = 0; i < 3; i++) {
-		rgb[i] = String(Math.floor(Number(rgb[i]) * (1 - level)));
-	}
-	return rgbToHex(rgb[0], rgb[1], rgb[2]);
+  const rgb = hexToRgb(color);
+  for (let i = 0; i < 3; i++) {
+    rgb[i] = String(Math.floor(Number(rgb[i]) * (1 - level)));
+  }
+  return rgbToHex(rgb[0], rgb[1], rgb[2]);
 };
diff --git a/src/utils/validate.ts b/src/utils/validate.ts
index c1752fa..f2da87b 100644
--- a/src/utils/validate.ts
+++ b/src/utils/validate.ts
@@ -4,7 +4,7 @@
  * @param url
  */
 export const isHttp = (url: string): boolean => {
-	return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1;
+  return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1;
 };
 
 /**
@@ -13,7 +13,7 @@
  * @returns {Boolean}
  */
 export const isExternal = (path: string) => {
-	return /^(https?:|mailto:|tel:)/.test(path);
+  return /^(https?:|mailto:|tel:)/.test(path);
 };
 
 /**
@@ -21,8 +21,8 @@
  * @returns {Boolean}
  */
 export const validUsername = (str: string) => {
-	const valid_map = ['admin', 'editor'];
-	return valid_map.indexOf(str.trim()) >= 0;
+  const valid_map = ['admin', 'editor'];
+  return valid_map.indexOf(str.trim()) >= 0;
 };
 
 /**
@@ -30,9 +30,9 @@
  * @returns {Boolean}
  */
 export const validURL = (url: string) => {
-	const reg =
-		/^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/;
-	return reg.test(url);
+  const reg =
+    /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/;
+  return reg.test(url);
 };
 
 /**
@@ -40,8 +40,8 @@
  * @returns {Boolean}
  */
 export const validLowerCase = (str: string) => {
-	const reg = /^[a-z]+$/;
-	return reg.test(str);
+  const reg = /^[a-z]+$/;
+  return reg.test(str);
 };
 
 /**
@@ -49,8 +49,8 @@
  * @returns {Boolean}
  */
 export const validUpperCase = (str: string) => {
-	const reg = /^[A-Z]+$/;
-	return reg.test(str);
+  const reg = /^[A-Z]+$/;
+  return reg.test(str);
 };
 
 /**
@@ -58,8 +58,8 @@
  * @returns {Boolean}
  */
 export const validAlphabets = (str: string) => {
-	const reg = /^[A-Za-z]+$/;
-	return reg.test(str);
+  const reg = /^[A-Za-z]+$/;
+  return reg.test(str);
 };
 
 /**
@@ -67,9 +67,9 @@
  * @returns {Boolean}
  */
 export const validEmail = (email: string) => {
-	const reg =
-		/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
-	return reg.test(email);
+  const reg =
+    /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
+  return reg.test(email);
 };
 
 /**
@@ -77,7 +77,7 @@
  * @returns {Boolean}
  */
 export const isString = (str: any) => {
-	return typeof str === 'string' || str instanceof String;
+  return typeof str === 'string' || str instanceof String;
 };
 
 /**
@@ -85,8 +85,8 @@
  * @returns {Boolean}
  */
 export const isArray = (arg: string | string[]) => {
-	if (typeof Array.isArray === 'undefined') {
-		return Object.prototype.toString.call(arg) === '[object Array]';
-	}
-	return Array.isArray(arg);
+  if (typeof Array.isArray === 'undefined') {
+    return Object.prototype.toString.call(arg) === '[object Array]';
+  }
+  return Array.isArray(arg);
 };
diff --git a/src/views/demo/demo/index.vue b/src/views/demo/demo/index.vue
index 17c5be8..71cc1fc 100644
--- a/src/views/demo/demo/index.vue
+++ b/src/views/demo/demo/index.vue
@@ -1,3 +1,150 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+          <el-form-item label="key閿�" prop="testKey">
+            <el-input v-model="queryParams.testKey" placeholder="璇疯緭鍏ey閿�" clearable style="width: 200px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鍊�" prop="value">
+            <el-input v-model="queryParams.value" placeholder="璇疯緭鍏ュ��" clearable style="width: 200px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鍒涘缓鏃堕棿">
+            <el-date-picker
+              v-model="daterangeCreateTime"
+              value-format="YYYY-MM-DD HH:mm:ss"
+              type="daterange"
+              range-separator="-"
+              start-placeholder="寮�濮嬫棩鏈�"
+              end-placeholder="缁撴潫鏃ユ湡"
+              :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
+            ></el-date-picker>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="search" @click="handleQuery">鎼滅储</el-button>
+            <el-button type="primary" icon="search" @click="handlePage">鎼滅储(鑷畾涔夊垎椤垫帴鍙�)</el-button>
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['demo:demo:add']">鏂板</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['demo:demo:edit']">淇敼</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['demo:demo:remove']">
+              鍒犻櫎
+            </el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="info" plain icon="Upload" @click="handleImport" v-hasPermi="['demo:demo:import']">瀵煎叆(鏍¢獙)</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['demo:demo:export']">瀵煎嚭</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table v-loading="loading" :data="demoList" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="涓婚敭" align="center" prop="id" v-if="columns[0].visible" />
+        <el-table-column label="閮ㄩ棬id" align="center" prop="deptId" v-if="columns[1].visible" />
+        <el-table-column label="鐢ㄦ埛id" align="center" prop="userId" v-if="columns[2].visible" />
+        <el-table-column label="鎺掑簭鍙�" align="center" prop="orderNum" v-if="columns[3].visible" />
+        <el-table-column label="key閿�" align="center" prop="testKey" v-if="columns[4].visible" />
+        <el-table-column label="鍊�" align="center" prop="value" v-if="columns[5].visible" />
+        <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" v-if="columns[6].visible" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鍒涘缓浜�" align="center" prop="createByName" v-if="columns[7].visible" />
+        <el-table-column label="鏇存柊鏃堕棿" align="center" prop="updateTime" v-if="columns[8].visible" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d}') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鏇存柊浜�" align="center" prop="updateByName" v-if="columns[9].visible" />
+        <el-table-column label="鎿嶄綔" fixed="right" align="center" width="150" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-tooltip content="淇敼" placement="top">
+              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['demo:demo:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="淇敼" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['demo:demo:remove']"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+    </el-card>
+
+    <!-- 娣诲姞鎴栦慨鏀规祴璇曞崟琛ㄥ璇濇 -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
+      <el-form ref="demoFormRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="閮ㄩ棬id" prop="deptId">
+          <el-input v-model="form.deptId" placeholder="璇疯緭鍏ラ儴闂╥d" />
+        </el-form-item>
+        <el-form-item label="鐢ㄦ埛id" prop="userId">
+          <el-input v-model="form.userId" placeholder="璇疯緭鍏ョ敤鎴穒d" />
+        </el-form-item>
+        <el-form-item label="鎺掑簭鍙�" prop="orderNum">
+          <el-input v-model="form.orderNum" placeholder="璇疯緭鍏ユ帓搴忓彿" />
+        </el-form-item>
+        <el-form-item label="key閿�" prop="testKey">
+          <el-input v-model="form.testKey" placeholder="璇疯緭鍏ey閿�" />
+        </el-form-item>
+        <el-form-item label="鍊�" prop="value">
+          <el-input v-model="form.value" placeholder="璇疯緭鍏ュ��" />
+        </el-form-item>
+        <el-form-item label="鍒涘缓鏃堕棿" prop="createTime">
+          <el-date-picker clearable v-model="form.createTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="閫夋嫨鍒涘缓鏃堕棿">
+          </el-date-picker>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <!-- 鐢ㄦ埛瀵煎叆瀵硅瘽妗� -->
+    <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
+      <el-upload
+        ref="uploadRef"
+        :limit="1"
+        accept=".xlsx, .xls"
+        :headers="upload.headers"
+        :action="upload.url + '?updateSupport=' + upload.updateSupport"
+        :disabled="upload.isUploading"
+        :on-progress="handleFileUploadProgress"
+        :on-success="handleFileSuccess"
+        :auto-upload="false"
+        drag
+      >
+        <i class="el-icon-upload"></i>
+        <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+      </el-upload>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
+          <el-button @click="upload.open = false">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
 <script setup name="Demo" lang="ts">
 import { listDemo, pageDemo, getDemo, delDemo, addDemo, updateDemo } from "@/api/demo/demo";
 import { getToken } from "@/utils/auth";
@@ -22,336 +169,189 @@
 const uploadRef = ref(ElUpload);
 
 const dialog = reactive<DialogOption>({
-	visible: false,
-	title: ''
+    visible: false,
+    title: ''
 });
 
 /** 鐢ㄦ埛瀵煎叆鍙傛暟 */
 const upload = reactive<ImportOption>({
-	// 鏄惁鏄剧ず寮瑰嚭灞傦紙鐢ㄦ埛瀵煎叆锛�
-	open: false,
-	// 寮瑰嚭灞傛爣棰橈紙鐢ㄦ埛瀵煎叆锛�
-	title: "",
-	// 鏄惁绂佺敤涓婁紶
-	isUploading: false,
-	// 璁剧疆涓婁紶鐨勮姹傚ご閮�
-	headers: { Authorization: "Bearer " + getToken() },
-	// 涓婁紶鐨勫湴鍧�
-	url: import.meta.env.VITE_APP_BASE_API + "demo/demo/importData"
+    // 鏄惁鏄剧ず寮瑰嚭灞傦紙鐢ㄦ埛瀵煎叆锛�
+    open: false,
+    // 寮瑰嚭灞傛爣棰橈紙鐢ㄦ埛瀵煎叆锛�
+    title: "",
+    // 鏄惁绂佺敤涓婁紶
+    isUploading: false,
+    // 璁剧疆涓婁紶鐨勮姹傚ご閮�
+    headers: { Authorization: "Bearer " + getToken() },
+    // 涓婁紶鐨勫湴鍧�
+    url: import.meta.env.VITE_APP_BASE_API + "demo/demo/importData"
 })
 
 // 鍒楁樉闅愪俊鎭�
 const columns = ref<FieldOption[]>([
-	{ key: 0, label: `涓婚敭`, visible: false },
-	{ key: 1, label: `閮ㄩ棬id`, visible: true },
-	{ key: 2, label: `鐢ㄦ埛id`, visible: true },
-	{ key: 3, label: `鎺掑簭鍙穈, visible: true },
-	{ key: 4, label: `key閿甡, visible: true },
-	{ key: 5, label: `鍊糮, visible: true },
-	{ key: 6, label: `鍒涘缓鏃堕棿`, visible: true },
-	{ key: 7, label: `鍒涘缓浜篳, visible: true },
-	{ key: 8, label: `鏇存柊鏃堕棿`, visible: true },
-	{ key: 9, label: `鏇存柊浜篳, visible: true }
+    { key: 0, label: `涓婚敭`, visible: false },
+    { key: 1, label: `閮ㄩ棬id`, visible: true },
+    { key: 2, label: `鐢ㄦ埛id`, visible: true },
+    { key: 3, label: `鎺掑簭鍙穈, visible: true },
+    { key: 4, label: `key閿甡, visible: true },
+    { key: 5, label: `鍊糮, visible: true },
+    { key: 6, label: `鍒涘缓鏃堕棿`, visible: true },
+    { key: 7, label: `鍒涘缓浜篳, visible: true },
+    { key: 8, label: `鏇存柊鏃堕棿`, visible: true },
+    { key: 9, label: `鏇存柊浜篳, visible: true }
 ]);
 
 const initDataForm: DemoForm = {
-	id: undefined,
-	deptId: undefined,
-	userId: undefined,
-	orderNum: 0,
-	testKey: '',
-	value: '',
-	version: '',
-	ossConfigId: undefined,
+    id: undefined,
+    deptId: undefined,
+    userId: undefined,
+    orderNum: 0,
+    testKey: '',
+    value: '',
+    version: '',
+    ossConfigId: undefined,
 }
 const data = reactive<PageData<DemoForm, DemoQuery>>({
-	form: { ...initDataForm },
-	queryParams: {
-		pageNum: 1,
-		pageSize: 10,
-		testKey: '',
-		value: '',
-		createTime: '',
-	},
-	rules: {
-		testKey: [{ required: true, message: "key閿笉鑳戒负绌�", trigger: "blur" }],
-		value: [{ required: true, message: "鍊间笉鑳戒负绌�", trigger: "blur" }],
-	}
+    form: { ...initDataForm },
+    queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        testKey: '',
+        value: '',
+        createTime: '',
+    },
+    rules: {
+        testKey: [{ required: true, message: "key閿笉鑳戒负绌�", trigger: "blur" }],
+        value: [{ required: true, message: "鍊间笉鑳戒负绌�", trigger: "blur" }],
+    }
 });
 
 const { queryParams, form, rules } = toRefs(data);
 
 /** 鏌ヨOSS瀵硅薄瀛樺偍鍒楄〃 */
 const getList = async () => {
-	loading.value = true;
-	const res = await listDemo(proxy?.addDateRange(queryParams.value, daterangeCreateTime.value, "CreateTime"));
-	demoList.value = res.rows;
-	total.value = res.total;
-	loading.value = false;
+    loading.value = true;
+    const res = await listDemo(proxy?.addDateRange(queryParams.value, daterangeCreateTime.value, "CreateTime"));
+    demoList.value = res.rows;
+    total.value = res.total;
+    loading.value = false;
 }
 /** 鑷畾涔夊垎椤垫煡璇� */
 const getPage = async () => {
-	loading.value = true;
-	const res = await pageDemo(proxy?.addDateRange(queryParams.value, daterangeCreateTime.value, "CreateTime"));
-	demoList.value = res.rows;
-	total.value = res.total;
-	loading.value = false;
+    loading.value = true;
+    const res = await pageDemo(proxy?.addDateRange(queryParams.value, daterangeCreateTime.value, "CreateTime"));
+    demoList.value = res.rows;
+    total.value = res.total;
+    loading.value = false;
 }
 /** 鍙栨秷鎸夐挳 */
 const cancel = () => {
-	reset();
-	dialog.visible = false;
+    reset();
+    dialog.visible = false;
 }
 /** 琛ㄥ崟閲嶇疆 */
 const reset = () => {
-	form.value = { ...initDataForm };
-	demoFormRef.value.resetFields();
+    form.value = { ...initDataForm };
+    demoFormRef.value.resetFields();
 }
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-	queryParams.value.pageNum = 1;
-	getList();
+    queryParams.value.pageNum = 1;
+    getList();
 }
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handlePage = () => {
-	queryParams.value.pageNum = 1;
-	getList();
+    queryParams.value.pageNum = 1;
+    getList();
 }
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 const resetQuery = () => {
-	daterangeCreateTime.value = ['', ''];
-	queryFormRef.value.resetFields();
-	handleQuery();
+    daterangeCreateTime.value = ['', ''];
+    queryFormRef.value.resetFields();
+    handleQuery();
 }
 /** 閫夋嫨鏉℃暟  */
 const handleSelectionChange = (selection: DemoVO[]) => {
-	ids.value = selection.map(item => item.id);
-	single.value = selection.length != 1;
-	multiple.value = !selection.length;
+    ids.value = selection.map(item => item.id);
+    single.value = selection.length != 1;
+    multiple.value = !selection.length;
 }
 /** 鏂板鎸夐挳鎿嶄綔 */
 const handleAdd = () => {
-	dialog.visible = true;
-	dialog.title = "娣诲姞娴嬭瘯鍗曡〃";
-	nextTick(() => {
-		reset();
-	})
+    dialog.visible = true;
+    dialog.title = "娣诲姞娴嬭瘯鍗曡〃";
+    nextTick(() => {
+        reset();
+    })
 }
 /** 淇敼鎸夐挳鎿嶄綔 */
 const handleUpdate = async (row?: DemoVO) => {
-	loading.value = true;
-	dialog.visible = true;
-	dialog.title = "淇敼娴嬭瘯鍗曡〃";
-	const _ids = row?.id || ids.value[0];
-	const res = await getDemo(_ids);
-	nextTick(() => {
-		reset();
-		Object.assign(form.value, res.data)
-		loading.value = false;
-	})
+    loading.value = true;
+    dialog.visible = true;
+    dialog.title = "淇敼娴嬭瘯鍗曡〃";
+    const _ids = row?.id || ids.value[0];
+    const res = await getDemo(_ids);
+    nextTick(() => {
+        reset();
+        Object.assign(form.value, res.data)
+        loading.value = false;
+    })
 }
 /** 鎻愪氦鎸夐挳 */
 const submitForm = () => {
-	demoFormRef.value.validate(async (valid: boolean) => {
-		if (valid) {
-			buttonLoading.value = true;
-			if (form.value.ossConfigId) {
-				await updateDemo(form.value).finally(() => buttonLoading.value = false);
-			} else {
-				await addDemo(form.value).finally(() => buttonLoading.value = false);
-			}
-			proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛");
-			dialog.visible = false;
-			getList();
-		}
-	});
+    demoFormRef.value.validate(async (valid: boolean) => {
+        if (valid) {
+            buttonLoading.value = true;
+            if (form.value.ossConfigId) {
+                await updateDemo(form.value).finally(() => buttonLoading.value = false);
+            } else {
+                await addDemo(form.value).finally(() => buttonLoading.value = false);
+            }
+            proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛");
+            dialog.visible = false;
+            getList();
+        }
+    });
 }
 /** 鍒犻櫎鎸夐挳鎿嶄綔 */
 const handleDelete = async (row?: DemoVO) => {
-	const _ids = row?.id || ids.value;
-	await proxy?.$modal.confirm('鏄惁纭鍒犻櫎娴嬭瘯鍗曡〃缂栧彿涓�"' + _ids + '"鐨勬暟鎹」?');
-	await delDemo(_ids).finally(() => loading.value = false);
-	loading.value = false;
-	getList();
-	proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    const _ids = row?.id || ids.value;
+    await proxy?.$modal.confirm('鏄惁纭鍒犻櫎娴嬭瘯鍗曡〃缂栧彿涓�"' + _ids + '"鐨勬暟鎹」?');
+    await delDemo(_ids).finally(() => loading.value = false);
+    loading.value = false;
+    getList();
+    proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
 }
 /** 瀵煎叆鎸夐挳鎿嶄綔 */
 const handleImport = () => {
-	upload.title = "娴嬭瘯瀵煎叆";
-	upload.open = true;
+    upload.title = "娴嬭瘯瀵煎叆";
+    upload.open = true;
 }
 /** 瀵煎嚭鎸夐挳鎿嶄綔 */
 const handleExport = () => {
-	proxy?.download("demo/demo/export", {
-		...queryParams.value,
-	}, `demo_${new Date().getTime()}.xlsx`);
+    proxy?.download("demo/demo/export", {
+        ...queryParams.value,
+    }, `demo_${new Date().getTime()}.xlsx`);
 }
 /**鏂囦欢涓婁紶涓鐞� */
 const handleFileUploadProgress = () => {
-	upload.isUploading = true;
+    upload.isUploading = true;
 }
 /** 鏂囦欢涓婁紶鎴愬姛澶勭悊 */
 const handleFileSuccess = (res: any, file: UploadFile, fileList: UploadFiles) => {
-	upload.open = false;
-	upload.isUploading = false;
-	uploadRef.value.clearFiles();
-	ElMessageBox.alert(res.msg, "瀵煎叆缁撴灉", { dangerouslyUseHTMLString: true });
-	getList();
+    upload.open = false;
+    upload.isUploading = false;
+    uploadRef.value.clearFiles();
+    ElMessageBox.alert(res.msg, "瀵煎叆缁撴灉", { dangerouslyUseHTMLString: true });
+    getList();
 }
 /** 鎻愪氦涓婁紶鏂囦欢 */
 function submitFileForm() {
-	uploadRef.value.submit();
+    uploadRef.value.submit();
 }
 
 onMounted(() => {
-	getList()
-	getPage()
+    getList()
+    getPage()
 })
 </script>
-
-<template>
-	<div class="p-2">
-		<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-			<div class="search" v-show="showSearch">
-				<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
-					<el-form-item label="key閿�" prop="testKey">
-						<el-input v-model="queryParams.testKey" placeholder="璇疯緭鍏ey閿�" clearable style="width: 200px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鍊�" prop="value">
-						<el-input v-model="queryParams.value" placeholder="璇疯緭鍏ュ��" clearable style="width: 200px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鍒涘缓鏃堕棿">
-						<el-date-picker
-							v-model="daterangeCreateTime"
-							value-format="YYYY-MM-DD HH:mm:ss"
-							type="daterange"
-							range-separator="-"
-							start-placeholder="寮�濮嬫棩鏈�"
-							end-placeholder="缁撴潫鏃ユ湡"
-							:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
-						></el-date-picker>
-					</el-form-item>
-					<el-form-item>
-						<el-button type="primary" icon="search" @click="handleQuery">鎼滅储</el-button>
-						<el-button type="primary" icon="search" @click="handlePage">鎼滅储(鑷畾涔夊垎椤垫帴鍙�)</el-button>
-						<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-					</el-form-item>
-				</el-form>
-			</div>
-		</transition>
-
-		<el-card shadow="never">
-			<template #header>
-				<el-row :gutter="10" class="mb8">
-					<el-col :span="1.5">
-						<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['demo:demo:add']">鏂板</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['demo:demo:edit']">淇敼</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['demo:demo:remove']">
-							鍒犻櫎
-						</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="info" plain icon="Upload" @click="handleImport" v-hasPermi="['demo:demo:import']">瀵煎叆(鏍¢獙)</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['demo:demo:export']">瀵煎嚭</el-button>
-					</el-col>
-					<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-				</el-row>
-			</template>
-
-			<el-table v-loading="loading" :data="demoList" @selection-change="handleSelectionChange">
-				<el-table-column type="selection" width="55" align="center" />
-				<el-table-column label="涓婚敭" align="center" prop="id" v-if="columns[0].visible" />
-				<el-table-column label="閮ㄩ棬id" align="center" prop="deptId" v-if="columns[1].visible" />
-				<el-table-column label="鐢ㄦ埛id" align="center" prop="userId" v-if="columns[2].visible" />
-				<el-table-column label="鎺掑簭鍙�" align="center" prop="orderNum" v-if="columns[3].visible" />
-				<el-table-column label="key閿�" align="center" prop="testKey" v-if="columns[4].visible" />
-				<el-table-column label="鍊�" align="center" prop="value" v-if="columns[5].visible" />
-				<el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" v-if="columns[6].visible" width="180">
-					<template #default="scope">
-						<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
-					</template>
-				</el-table-column>
-				<el-table-column label="鍒涘缓浜�" align="center" prop="createByName" v-if="columns[7].visible" />
-				<el-table-column label="鏇存柊鏃堕棿" align="center" prop="updateTime" v-if="columns[8].visible" width="180">
-					<template #default="scope">
-						<span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d}') }}</span>
-					</template>
-				</el-table-column>
-				<el-table-column label="鏇存柊浜�" align="center" prop="updateByName" v-if="columns[9].visible" />
-				<el-table-column label="鎿嶄綔" fixed="right" align="center" width="150" class-name="small-padding fixed-width">
-					<template #default="scope">
-						<el-tooltip content="淇敼" placement="top">
-							<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['demo:demo:edit']"></el-button>
-						</el-tooltip>
-						<el-tooltip content="淇敼" placement="top">
-							<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['demo:demo:remove']"></el-button>
-						</el-tooltip>
-					</template>
-				</el-table-column>
-			</el-table>
-
-			<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
-		</el-card>
-
-		<!-- 娣诲姞鎴栦慨鏀规祴璇曞崟琛ㄥ璇濇 -->
-		<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
-			<el-form ref="demoFormRef" :model="form" :rules="rules" label-width="80px">
-				<el-form-item label="閮ㄩ棬id" prop="deptId">
-					<el-input v-model="form.deptId" placeholder="璇疯緭鍏ラ儴闂╥d" />
-				</el-form-item>
-				<el-form-item label="鐢ㄦ埛id" prop="userId">
-					<el-input v-model="form.userId" placeholder="璇疯緭鍏ョ敤鎴穒d" />
-				</el-form-item>
-				<el-form-item label="鎺掑簭鍙�" prop="orderNum">
-					<el-input v-model="form.orderNum" placeholder="璇疯緭鍏ユ帓搴忓彿" />
-				</el-form-item>
-				<el-form-item label="key閿�" prop="testKey">
-					<el-input v-model="form.testKey" placeholder="璇疯緭鍏ey閿�" />
-				</el-form-item>
-				<el-form-item label="鍊�" prop="value">
-					<el-input v-model="form.value" placeholder="璇疯緭鍏ュ��" />
-				</el-form-item>
-				<el-form-item label="鍒涘缓鏃堕棿" prop="createTime">
-					<el-date-picker clearable v-model="form.createTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="閫夋嫨鍒涘缓鏃堕棿">
-					</el-date-picker>
-				</el-form-item>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
-					<el-button @click="cancel">鍙� 娑�</el-button>
-				</div>
-			</template>
-		</el-dialog>
-		<!-- 鐢ㄦ埛瀵煎叆瀵硅瘽妗� -->
-		<el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
-			<el-upload
-				ref="uploadRef"
-				:limit="1"
-				accept=".xlsx, .xls"
-				:headers="upload.headers"
-				:action="upload.url + '?updateSupport=' + upload.updateSupport"
-				:disabled="upload.isUploading"
-				:on-progress="handleFileUploadProgress"
-				:on-success="handleFileSuccess"
-				:auto-upload="false"
-				drag
-			>
-				<i class="el-icon-upload"></i>
-				<div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
-			</el-upload>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
-					<el-button @click="upload.open = false">鍙� 娑�</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</div>
-</template>
diff --git a/src/views/demo/tree/index.vue b/src/views/demo/tree/index.vue
index f3f13e1..e46f3c5 100644
--- a/src/views/demo/tree/index.vue
+++ b/src/views/demo/tree/index.vue
@@ -1,3 +1,110 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form :model="queryParams" ref="qeuryFormRef" :inline="true" label-width="68px">
+          <el-form-item label="鏍戣妭鐐瑰悕" prop="treeName">
+            <el-input v-model="queryParams.treeName" placeholder="璇疯緭鍏ユ爲鑺傜偣鍚�" clearable style="width: 200px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鍒涘缓鏃堕棿">
+            <el-date-picker
+              v-model="daterangeCreateTime"
+              value-format="YYYY-MM-DD HH:mm:ss"
+              type="daterange"
+              range-separator="-"
+              start-placeholder="寮�濮嬫棩鏈�"
+              end-placeholder="缁撴潫鏃ユ湡"
+              :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
+            ></el-date-picker>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="search" @click="handleQuery">鎼滅储</el-button>
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['demo:tree:add']">鏂板</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">灞曞紑/鎶樺彔</el-button>
+          </el-col>
+          <right-toolbar :columns="columns" v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table
+        v-if="refreshTable"
+        v-loading="loading"
+        :data="treeList"
+        row-key="id"
+        :default-expand-all="isExpandAll"
+        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
+        ref="demoTreeTableRef"
+      >
+        <el-table-column label="鐖秈d" prop="parentId" v-if="columns[0].visible" />
+        <el-table-column label="閮ㄩ棬id" align="center" prop="deptId" v-if="columns[1].visible" />
+        <el-table-column label="鐢ㄦ埛id" align="center" prop="userId" v-if="columns[2].visible" />
+        <el-table-column label="鏍戣妭鐐瑰悕" align="center" prop="treeName" v-if="columns[3].visible" />
+        <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" v-if="columns[4].visible" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" fixed="right" align="center" width="150" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-tooltip content="淇敼" placement="top">
+              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['demo:tree:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="鏂板" placement="top">
+              <el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['demo:tree:add']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="鍒犻櫎" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['demo:tree:remove']"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+
+    <!-- 娣诲姞鎴栦慨鏀规祴璇曟爲琛ㄥ璇濇 -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
+      <el-form ref="treeRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="鐖秈d" prop="parentId">
+          <el-tree-select
+            v-model="form.parentId"
+            :data="treeOptions"
+            :props="{ value: 'id', label: 'treeName', children: 'children' }"
+            value-key="id"
+            check-strictly
+            placeholder="璇烽�夋嫨鐖秈d"
+          />
+        </el-form-item>
+        <el-form-item label="閮ㄩ棬id" prop="deptId">
+          <el-input v-model="form.deptId" placeholder="璇疯緭鍏ラ儴闂╥d" />
+        </el-form-item>
+        <el-form-item label="鐢ㄦ埛id" prop="userId">
+          <el-input v-model="form.userId" placeholder="璇疯緭鍏ョ敤鎴穒d" />
+        </el-form-item>
+        <el-form-item label="鏍戣妭鐐瑰悕" prop="treeName">
+          <el-input v-model="form.treeName" placeholder="璇疯緭鍏ユ爲鑺傜偣鍚�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
 <script setup name="Tree" lang="ts">
 import { listTree, getTree, delTree, addTree, updateTree } from '@/api/demo/tree';
 import { DemoTreeVO, DemoTreeForm, DemoTreeOptionsType, DemoTreeQuery } from '@/api/demo/types';
@@ -20,274 +127,167 @@
 const demoTreeTableRef = ref(ElTable)
 
 const dialog = reactive<DialogOption>({
-  visible: false,
-  title: ''
+    visible: false,
+    title: ''
 });
 
 // 鍒楁樉闅愪俊鎭�
 const columns = ref<FieldOption[]>([
-  { key: 0, label: `鐖秈d`, visible: false },
-  { key: 1, label: `閮ㄩ棬id`, visible: true },
-  { key: 2, label: `鐢ㄦ埛id`, visible: true },
-  { key: 3, label: `鏍戣妭鐐瑰悕`, visible: true },
-  { key: 4, label: `鍒涘缓鏃堕棿`, visible: true }
+    { key: 0, label: `鐖秈d`, visible: false },
+    { key: 1, label: `閮ㄩ棬id`, visible: true },
+    { key: 2, label: `鐢ㄦ埛id`, visible: true },
+    { key: 3, label: `鏍戣妭鐐瑰悕`, visible: true },
+    { key: 4, label: `鍒涘缓鏃堕棿`, visible: true }
 ]);
 
 const initFormData = {
-  id: undefined,
-  parentId: undefined,
-  deptId: undefined,
-  userId: undefined,
-  treeName: ''
+    id: undefined,
+    parentId: undefined,
+    deptId: undefined,
+    userId: undefined,
+    treeName: ''
 }
 
 const data = reactive<PageData<DemoTreeForm, DemoTreeQuery>>({
-  // 鏌ヨ鍙傛暟
-  queryParams: {
-    treeName: '',
-    createTime: '',
-  },
-  // 琛ㄥ崟鍙傛暟
-  form: {...initFormData},
-  // 琛ㄥ崟鏍¢獙
-  rules: {
-    treeName: [{ required: true, message: "鏍戣妭鐐瑰悕涓嶈兘涓虹┖", trigger: "blur" }],
-  }
+    // 鏌ヨ鍙傛暟
+    queryParams: {
+        treeName: '',
+        createTime: '',
+    },
+    // 琛ㄥ崟鍙傛暟
+    form: {...initFormData},
+    // 琛ㄥ崟鏍¢獙
+    rules: {
+        treeName: [{ required: true, message: "鏍戣妭鐐瑰悕涓嶈兘涓虹┖", trigger: "blur" }],
+    }
 });
 
 const { queryParams, form, rules } = toRefs(data);
 /** 鏌ヨ娴嬭瘯鏍戣〃鍒楄〃 */
 const getList = () => {
-  loading.value = true;
-  listTree(proxy?.addDateRange(queryParams.value, daterangeCreateTime.value, "CreateTime")).then(res => {
-    const data = proxy?.handleTree<DemoTreeVO>(res.data, "id", "parentId");
-    if (data) {
-      treeList.value = data
-    }
-    loading.value = false;
-  });
+    loading.value = true;
+    listTree(proxy?.addDateRange(queryParams.value, daterangeCreateTime.value, "CreateTime")).then(res => {
+        const data = proxy?.handleTree<DemoTreeVO>(res.data, "id", "parentId");
+        if (data) {
+            treeList.value = data
+        }
+        loading.value = false;
+    });
 }
 
 /** 鏌ヨ閮ㄩ棬涓嬫媺鏍戠粨鏋� */
 const getTreeSelect = async () => {
-  listTree(proxy?.addDateRange(queryParams.value, daterangeCreateTime.value, "CreateTime")).then(res => {
-  const topData: DemoTreeOptionsType = { id: 0, treeName: '椤剁骇鑺傜偣', children: [] };
-  topData.children = proxy?.handleTree<DemoTreeOptionsType>(res.data, "id", "parentId");
-  treeOptions.value.push(topData);
-  });
+    listTree(proxy?.addDateRange(queryParams.value, daterangeCreateTime.value, "CreateTime")).then(res => {
+        const topData: DemoTreeOptionsType = { id: 0, treeName: '椤剁骇鑺傜偣', children: [] };
+        topData.children = proxy?.handleTree<DemoTreeOptionsType>(res.data, "id", "parentId");
+        treeOptions.value.push(topData);
+    });
 }
 /** 鍙栨秷鎸夐挳 */
 const cancel = () => {
-  reset();
-  dialog.visible = false;
+    reset();
+    dialog.visible = false;
 }
 /** 琛ㄥ崟閲嶇疆 */
 const reset = () => {
-  form.value = {...initFormData}
-  treeRef.value.resetFields();
+    form.value = {...initFormData}
+    treeRef.value.resetFields();
 }
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-  getList();
+    getList();
 }
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 const resetQuery = () => {
-  daterangeCreateTime.value = ['', ''];
-  qeuryFormRef.value.resetFields();
-  handleQuery();
+    daterangeCreateTime.value = ['', ''];
+    qeuryFormRef.value.resetFields();
+    handleQuery();
 }
 /** 鏂板鎸夐挳鎿嶄綔 */
 const handleAdd = (row?: DemoTreeVO) => {
-  dialog.visible = true;
-  dialog.title = "娣诲姞娴嬭瘯鏍戣〃";
-  nextTick(() => {
-    reset();
-    getTreeSelect();
-    if (row != null && row.id) {
-      form.value.parentId = row.id;
-    } else {
-      form.value.parentId = 0;
-    }
-  })
+    dialog.visible = true;
+    dialog.title = "娣诲姞娴嬭瘯鏍戣〃";
+    nextTick(() => {
+        reset();
+        getTreeSelect();
+        if (row != null && row.id) {
+            form.value.parentId = row.id;
+        } else {
+            form.value.parentId = 0;
+        }
+    })
 }
 
 /** 灞曞紑/鎶樺彔鎿嶄綔 */
 const handleToggleExpandAll = () => {
-  isExpandAll.value = !isExpandAll.value;
-  toggleExpandAll(treeList.value, isExpandAll.value)
+    isExpandAll.value = !isExpandAll.value;
+    toggleExpandAll(treeList.value, isExpandAll.value)
 }
 /** 灞曞紑/鎶樺彔鎵�鏈� */
 const toggleExpandAll = (data: DemoTreeVO[], status: boolean) => {
-  data.forEach((item) => {
-    demoTreeTableRef.value.toggleRowExpansion(item, status)
-    if(item.children && item.children.length > 0) toggleExpandAll(item.children, status)
-  })
+    data.forEach((item) => {
+        demoTreeTableRef.value.toggleRowExpansion(item, status)
+        if(item.children && item.children.length > 0) toggleExpandAll(item.children, status)
+    })
 }
 
 /** 淇敼鎸夐挳鎿嶄綔 */
 const handleUpdate = async (row: DemoTreeVO) => {
-  loading.value = true;
-  dialog.visible = true;
-  dialog.title = "淇敼娴嬭瘯鏍戣〃";
-  nextTick(async () => {
-    reset();
-    getTreeSelect();
-    if (row) {
-      form.value.parentId = row.id;
-    }
-    getTree(row.id).then((response) => {
-      loading.value = false;
-      form.value = response.data;
+    loading.value = true;
+    dialog.visible = true;
+    dialog.title = "淇敼娴嬭瘯鏍戣〃";
+    nextTick(async () => {
+        reset();
+        getTreeSelect();
+        if (row) {
+            form.value.parentId = row.id;
+        }
+        getTree(row.id).then((response) => {
+            loading.value = false;
+            form.value = response.data;
 
-    });
-  })
+        });
+    })
 }
 /** 鎻愪氦鎸夐挳 */
 const submitForm = () => {
-  treeRef.value.validate((valid: boolean) => {
-    if (valid) {
-      buttonLoading.value = true;
-      if (form.value.id != null) {
-        updateTree(form.value).then(() => {
-          proxy?.$modal.msgSuccess("淇敼鎴愬姛");
-          dialog.visible = false;
-          getList();
-        }).finally(() => {
-          buttonLoading.value = false;
-        });
-      } else {
-        addTree(form.value).then(() => {
-          proxy?.$modal.msgSuccess("鏂板鎴愬姛");
-          dialog.visible = false;
-          getList();
-        }).finally(() => {
-          buttonLoading.value = false;
-        });
-      }
-    }
-  });
+    treeRef.value.validate((valid: boolean) => {
+        if (valid) {
+            buttonLoading.value = true;
+            if (form.value.id != null) {
+                updateTree(form.value).then(() => {
+                    proxy?.$modal.msgSuccess("淇敼鎴愬姛");
+                    dialog.visible = false;
+                    getList();
+                }).finally(() => {
+                    buttonLoading.value = false;
+                });
+            } else {
+                addTree(form.value).then(() => {
+                    proxy?.$modal.msgSuccess("鏂板鎴愬姛");
+                    dialog.visible = false;
+                    getList();
+                }).finally(() => {
+                    buttonLoading.value = false;
+                });
+            }
+        }
+    });
 }
 /** 鍒犻櫎鎸夐挳鎿嶄綔 */
 const handleDelete = (row: DemoTreeVO) => {
-  proxy?.$modal.confirm('鏄惁纭鍒犻櫎娴嬭瘯鍗曡〃缂栧彿涓�"' + row.id + '"鐨勬暟鎹」?').then(() => {
-    loading.value = true;
-    return delTree(row.id);
-  }).then(() => {
-    loading.value = false;
-    getList();
-    proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-  }).finally(() => {
-    loading.value = false;
-  });
+    proxy?.$modal.confirm('鏄惁纭鍒犻櫎娴嬭瘯鍗曡〃缂栧彿涓�"' + row.id + '"鐨勬暟鎹」?').then(() => {
+        loading.value = true;
+        return delTree(row.id);
+    }).then(() => {
+        loading.value = false;
+        getList();
+        proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    }).finally(() => {
+        loading.value = false;
+    });
 }
 onMounted(() => {
-  getList()
+    getList()
 })
 </script>
-
-<template>
-	<div class="p-2">
-		<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-			<div class="search" v-show="showSearch">
-				<el-form :model="queryParams" ref="qeuryFormRef" :inline="true" label-width="68px">
-					<el-form-item label="鏍戣妭鐐瑰悕" prop="treeName">
-						<el-input v-model="queryParams.treeName" placeholder="璇疯緭鍏ユ爲鑺傜偣鍚�" clearable style="width: 200px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鍒涘缓鏃堕棿">
-						<el-date-picker
-							v-model="daterangeCreateTime"
-							value-format="YYYY-MM-DD HH:mm:ss"
-							type="daterange"
-							range-separator="-"
-							start-placeholder="寮�濮嬫棩鏈�"
-							end-placeholder="缁撴潫鏃ユ湡"
-							:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
-						></el-date-picker>
-					</el-form-item>
-					<el-form-item>
-						<el-button type="primary" icon="search" @click="handleQuery">鎼滅储</el-button>
-						<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-					</el-form-item>
-				</el-form>
-			</div>
-		</transition>
-
-		<el-card shadow="never">
-			<template #header>
-				<el-row :gutter="10">
-					<el-col :span="1.5">
-						<el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['demo:tree:add']">鏂板</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">灞曞紑/鎶樺彔</el-button>
-					</el-col>
-					<right-toolbar :columns="columns" v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-				</el-row>
-			</template>
-
-			<el-table
-				v-if="refreshTable"
-				v-loading="loading"
-				:data="treeList"
-				row-key="id"
-				:default-expand-all="isExpandAll"
-				:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
-				ref="demoTreeTableRef"
-			>
-				<el-table-column label="鐖秈d" prop="parentId" v-if="columns[0].visible" />
-				<el-table-column label="閮ㄩ棬id" align="center" prop="deptId" v-if="columns[1].visible" />
-				<el-table-column label="鐢ㄦ埛id" align="center" prop="userId" v-if="columns[2].visible" />
-				<el-table-column label="鏍戣妭鐐瑰悕" align="center" prop="treeName" v-if="columns[3].visible" />
-				<el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" v-if="columns[4].visible" width="180">
-					<template #default="scope">
-						<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
-					</template>
-				</el-table-column>
-				<el-table-column label="鎿嶄綔" fixed="right" align="center" width="150" class-name="small-padding fixed-width">
-					<template #default="scope">
-						<el-tooltip content="淇敼" placement="top">
-							<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['demo:tree:edit']"></el-button>
-						</el-tooltip>
-						<el-tooltip content="鏂板" placement="top">
-							<el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['demo:tree:add']"></el-button>
-						</el-tooltip>
-						<el-tooltip content="鍒犻櫎" placement="top">
-							<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['demo:tree:remove']"></el-button>
-						</el-tooltip>
-					</template>
-				</el-table-column>
-			</el-table>
-		</el-card>
-
-		<!-- 娣诲姞鎴栦慨鏀规祴璇曟爲琛ㄥ璇濇 -->
-		<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
-			<el-form ref="treeRef" :model="form" :rules="rules" label-width="80px">
-				<el-form-item label="鐖秈d" prop="parentId">
-					<el-tree-select
-						v-model="form.parentId"
-						:data="treeOptions"
-						:props="{ value: 'id', label: 'treeName', children: 'children' }"
-						value-key="id"
-						check-strictly
-						placeholder="璇烽�夋嫨鐖秈d"
-					/>
-				</el-form-item>
-				<el-form-item label="閮ㄩ棬id" prop="deptId">
-					<el-input v-model="form.deptId" placeholder="璇疯緭鍏ラ儴闂╥d" />
-				</el-form-item>
-				<el-form-item label="鐢ㄦ埛id" prop="userId">
-					<el-input v-model="form.userId" placeholder="璇疯緭鍏ョ敤鎴穒d" />
-				</el-form-item>
-				<el-form-item label="鏍戣妭鐐瑰悕" prop="treeName">
-					<el-input v-model="form.treeName" placeholder="璇疯緭鍏ユ爲鑺傜偣鍚�" />
-				</el-form-item>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
-					<el-button @click="cancel">鍙� 娑�</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</div>
-</template>
diff --git a/src/views/error/401.vue b/src/views/error/401.vue
index e163a31..63c03ba 100644
--- a/src/views/error/401.vue
+++ b/src/views/error/401.vue
@@ -1,22 +1,22 @@
 <template>
-	<div class="errPage-container">
-		<el-button icon="arrow-left" class="pan-back-btn" @click="back"> 杩斿洖 </el-button>
-		<el-row>
-			<el-col :span="12">
-				<h1 class="text-jumbo text-ginormous">401閿欒!</h1>
-				<h2>鎮ㄦ病鏈夎闂潈闄愶紒</h2>
-				<h6>瀵逛笉璧凤紝鎮ㄦ病鏈夎闂潈闄愶紝璇蜂笉瑕佽繘琛岄潪娉曟搷浣滐紒鎮ㄥ彲浠ヨ繑鍥炰富椤甸潰</h6>
-				<ul class="list-unstyled">
-					<li class="link-type">
-						<router-link to="/"> 鍥為椤� </router-link>
-					</li>
-				</ul>
-			</el-col>
-			<el-col :span="12">
-				<img :src="errGif" width="313" height="428" alt="Girl has dropped her ice cream." />
-			</el-col>
-		</el-row>
-	</div>
+  <div class="errPage-container">
+    <el-button icon="arrow-left" class="pan-back-btn" @click="back"> 杩斿洖 </el-button>
+    <el-row>
+      <el-col :span="12">
+        <h1 class="text-jumbo text-ginormous">401閿欒!</h1>
+        <h2>鎮ㄦ病鏈夎闂潈闄愶紒</h2>
+        <h6>瀵逛笉璧凤紝鎮ㄦ病鏈夎闂潈闄愶紝璇蜂笉瑕佽繘琛岄潪娉曟搷浣滐紒鎮ㄥ彲浠ヨ繑鍥炰富椤甸潰</h6>
+        <ul class="list-unstyled">
+          <li class="link-type">
+            <router-link to="/"> 鍥為椤� </router-link>
+          </li>
+        </ul>
+      </el-col>
+      <el-col :span="12">
+        <img :src="errGif" width="313" height="428" alt="Girl has dropped her ice cream." />
+      </el-col>
+    </el-row>
+  </div>
 </template>
 
 <script setup lang="ts">
diff --git a/src/views/error/404.vue b/src/views/error/404.vue
index aef1848..94ed936 100644
--- a/src/views/error/404.vue
+++ b/src/views/error/404.vue
@@ -1,24 +1,24 @@
 <template>
-	<div class="wscn-http404-container">
-		<div class="wscn-http404">
-			<div class="pic-404">
-				<img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404" />
-				<img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404" />
-				<img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404" />
-				<img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404" />
-			</div>
-			<div class="bullshit">
-				<div class="bullshit__oops">404閿欒!</div>
-				<div class="bullshit__headline">
-					{{ message }}
-				</div>
-				<div class="bullshit__info">
-					瀵逛笉璧凤紝鎮ㄦ鍦ㄥ鎵剧殑椤甸潰涓嶅瓨鍦ㄣ�傚皾璇曟鏌RL鐨勯敊璇紝鐒跺悗鎸夋祻瑙堝櫒涓婄殑鍒锋柊鎸夐挳鎴栧皾璇曞湪鎴戜滑鐨勫簲鐢ㄧ▼搴忎腑鎵惧埌鍏朵粬鍐呭銆�
-				</div>
-				<router-link to="/index" class="bullshit__return-home"> 杩斿洖棣栭〉 </router-link>
-			</div>
-		</div>
-	</div>
+  <div class="wscn-http404-container">
+    <div class="wscn-http404">
+      <div class="pic-404">
+        <img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404" />
+        <img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404" />
+        <img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404" />
+        <img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404" />
+      </div>
+      <div class="bullshit">
+        <div class="bullshit__oops">404閿欒!</div>
+        <div class="bullshit__headline">
+          {{ message }}
+        </div>
+        <div class="bullshit__info">
+          瀵逛笉璧凤紝鎮ㄦ鍦ㄥ鎵剧殑椤甸潰涓嶅瓨鍦ㄣ�傚皾璇曟鏌RL鐨勯敊璇紝鐒跺悗鎸夋祻瑙堝櫒涓婄殑鍒锋柊鎸夐挳鎴栧皾璇曞湪鎴戜滑鐨勫簲鐢ㄧ▼搴忎腑鎵惧埌鍏朵粬鍐呭銆�
+        </div>
+        <router-link to="/index" class="bullshit__return-home"> 杩斿洖棣栭〉 </router-link>
+      </div>
+    </div>
+  </div>
 </template>
 
 <script setup lang="ts">
diff --git a/src/views/index.vue b/src/views/index.vue
index 8e8c3e0..70912af 100644
--- a/src/views/index.vue
+++ b/src/views/index.vue
@@ -1,98 +1,98 @@
 <template>
-	<div class="app-container home">
-		<el-row :gutter="20">
-			<el-col :sm="24" :lg="12" style="padding-left: 20px">
-				<h2>RuoYi-Vue-Plus澶氱鎴风鐞嗙郴缁�</h2>
-				<p>
-					RuoYi-Vue-Plus 鏄熀浜� RuoYi-Vue 閽堝 鍒嗗竷寮忛泦缇� 鍦烘櫙鍗囩骇(涓嶅吋瀹瑰師妗嗘灦)
-					<br />
-					* 鍓嶇寮�鍙戞鏋� Vue3銆乀S銆丒lement Plus<br />
-					* 鍚庣寮�鍙戞鏋� Spring Boot<br />
-					* 瀹瑰櫒妗嗘灦 Undertow 鍩轰簬 Netty 鐨勯珮鎬ц兘瀹瑰櫒<br />
-					* 鏉冮檺璁よ瘉妗嗘灦 Sa-Token 鏀寔澶氱粓绔璇佺郴缁�<br />
-					* 鍏崇郴鏁版嵁搴� MySQL 閫傞厤 8.X 鏈�浣� 5.7<br />
-					* 缂撳瓨鏁版嵁搴� Redis 閫傞厤 6.X 鏈�浣� 4.X<br />
-					* 鏁版嵁搴撴鏋� Mybatis-Plus 蹇�� CRUD 澧炲姞寮�鍙戞晥鐜�<br />
-					* 鏁版嵁搴撴鏋� p6spy 鏇村己鍔茬殑 SQL 鍒嗘瀽<br />
-					* 澶氭暟鎹簮妗嗘灦 dynamic-datasource 鏀寔涓讳粠涓庡绉嶇被鏁版嵁搴撳紓鏋�<br />
-					* 搴忓垪鍖栨鏋� Jackson 缁熶竴浣跨敤 jackson 楂樻晥鍙潬<br />
-					* Redis瀹㈡埛绔� Redisson 鎬ц兘寮哄姴銆丄PI涓板瘜<br />
-					* 鍒嗗竷寮忛檺娴� Redisson 鍏ㄥ眬銆佽姹侷P銆侀泦缇D 澶氱闄愭祦<br />
-					* 鍒嗗竷寮忛攣 Lock4j 娉ㄨВ閿併�佸伐鍏烽攣 澶氱澶氭牱<br />
-					* 鍒嗗竷寮忓箓绛� Lock4j 鍩轰簬鍒嗗竷寮忛攣瀹炵幇<br />
-					* 鍒嗗竷寮忛摼璺拷韪� SkyWalking 鏀寔閾捐矾杩借釜銆佺綉鏍煎垎鏋愩�佸害閲忚仛鍚堛�佸彲瑙嗗寲<br />
-					* 鍒嗗竷寮忎换鍔¤皟搴� Xxl-Job 楂樻�ц兘 楂樺彲闈� 鏄撴墿灞�<br />
-					* 鏂囦欢瀛樺偍 Minio 鏈湴瀛樺偍<br />
-					* 鏂囦欢瀛樺偍 涓冪墰銆侀樋閲屻�佽吘璁� 浜戝瓨鍌�<br />
-					* 鐩戞帶妗嗘灦 SpringBoot-Admin 鍏ㄦ柟浣嶆湇鍔$洃鎺�<br />
-					* 鏍¢獙妗嗘灦 Validation 澧炲己鎺ュ彛瀹夊叏鎬� 涓ヨ皑鎬�<br />
-					* Excel妗嗘灦 Alibaba EasyExcel 鎬ц兘浼樺紓 鎵╁睍鎬у己<br />
-					* 鏂囨。妗嗘灦 SpringDoc銆乯avadoc 鏃犳敞瑙i浂鍏ヤ镜鍩轰簬java娉ㄩ噴<br />
-					* 宸ュ叿绫绘鏋� Hutool銆丩ombok 鍑忓皯浠g爜鍐椾綑 澧炲姞瀹夊叏鎬�<br />
-					* 浠g爜鐢熸垚鍣� 閫傞厤MP銆丼pringDoc瑙勮寖鍖栦唬鐮� 涓�閿敓鎴愬墠鍚庣浠g爜<br />
-					* 閮ㄧ讲鏂瑰紡 Docker 瀹瑰櫒缂栨帓 涓�閿儴缃蹭笟鍔¢泦缇�<br />
-					* 鍥介檯鍖� SpringMessage Spring鏍囧噯鍥介檯鍖栨柟妗�<br />
-				</p>
-				<p><b>褰撳墠鐗堟湰:</b> <span>v5.0.0</span></p>
-				<p>
-					<el-tag type="danger">&yen;鍏嶈垂寮�婧�</el-tag>
-				</p>
-				<p>
-					<el-button type="primary" icon="Cloudy" plain @click="goTarget('https://gitee.com/dromara/RuoYi-Vue-Plus')">璁块棶鐮佷簯</el-button>
-					<el-button type="primary" icon="Cloudy" plain @click="goTarget('https://github.com/dromara/RuoYi-Vue-Plus')">璁块棶GitHub</el-button>
-					<el-button type="primary" icon="Cloudy" plain @click="goTarget('https://javalionli.gitee.io/plus-doc/#/ruoyi-vue-plus/changlog')"
-						>鏇存柊鏃ュ織</el-button
-					>
-				</p>
-			</el-col>
+  <div class="app-container home">
+    <el-row :gutter="20">
+      <el-col :sm="24" :lg="12" style="padding-left: 20px">
+        <h2>RuoYi-Vue-Plus澶氱鎴风鐞嗙郴缁�</h2>
+        <p>
+          RuoYi-Vue-Plus 鏄熀浜� RuoYi-Vue 閽堝 鍒嗗竷寮忛泦缇� 鍦烘櫙鍗囩骇(涓嶅吋瀹瑰師妗嗘灦)
+          <br />
+          * 鍓嶇寮�鍙戞鏋� Vue3銆乀S銆丒lement Plus<br />
+          * 鍚庣寮�鍙戞鏋� Spring Boot<br />
+          * 瀹瑰櫒妗嗘灦 Undertow 鍩轰簬 Netty 鐨勯珮鎬ц兘瀹瑰櫒<br />
+          * 鏉冮檺璁よ瘉妗嗘灦 Sa-Token 鏀寔澶氱粓绔璇佺郴缁�<br />
+          * 鍏崇郴鏁版嵁搴� MySQL 閫傞厤 8.X 鏈�浣� 5.7<br />
+          * 缂撳瓨鏁版嵁搴� Redis 閫傞厤 6.X 鏈�浣� 4.X<br />
+          * 鏁版嵁搴撴鏋� Mybatis-Plus 蹇�� CRUD 澧炲姞寮�鍙戞晥鐜�<br />
+          * 鏁版嵁搴撴鏋� p6spy 鏇村己鍔茬殑 SQL 鍒嗘瀽<br />
+          * 澶氭暟鎹簮妗嗘灦 dynamic-datasource 鏀寔涓讳粠涓庡绉嶇被鏁版嵁搴撳紓鏋�<br />
+          * 搴忓垪鍖栨鏋� Jackson 缁熶竴浣跨敤 jackson 楂樻晥鍙潬<br />
+          * Redis瀹㈡埛绔� Redisson 鎬ц兘寮哄姴銆丄PI涓板瘜<br />
+          * 鍒嗗竷寮忛檺娴� Redisson 鍏ㄥ眬銆佽姹侷P銆侀泦缇D 澶氱闄愭祦<br />
+          * 鍒嗗竷寮忛攣 Lock4j 娉ㄨВ閿併�佸伐鍏烽攣 澶氱澶氭牱<br />
+          * 鍒嗗竷寮忓箓绛� Lock4j 鍩轰簬鍒嗗竷寮忛攣瀹炵幇<br />
+          * 鍒嗗竷寮忛摼璺拷韪� SkyWalking 鏀寔閾捐矾杩借釜銆佺綉鏍煎垎鏋愩�佸害閲忚仛鍚堛�佸彲瑙嗗寲<br />
+          * 鍒嗗竷寮忎换鍔¤皟搴� Xxl-Job 楂樻�ц兘 楂樺彲闈� 鏄撴墿灞�<br />
+          * 鏂囦欢瀛樺偍 Minio 鏈湴瀛樺偍<br />
+          * 鏂囦欢瀛樺偍 涓冪墰銆侀樋閲屻�佽吘璁� 浜戝瓨鍌�<br />
+          * 鐩戞帶妗嗘灦 SpringBoot-Admin 鍏ㄦ柟浣嶆湇鍔$洃鎺�<br />
+          * 鏍¢獙妗嗘灦 Validation 澧炲己鎺ュ彛瀹夊叏鎬� 涓ヨ皑鎬�<br />
+          * Excel妗嗘灦 Alibaba EasyExcel 鎬ц兘浼樺紓 鎵╁睍鎬у己<br />
+          * 鏂囨。妗嗘灦 SpringDoc銆乯avadoc 鏃犳敞瑙i浂鍏ヤ镜鍩轰簬java娉ㄩ噴<br />
+          * 宸ュ叿绫绘鏋� Hutool銆丩ombok 鍑忓皯浠g爜鍐椾綑 澧炲姞瀹夊叏鎬�<br />
+          * 浠g爜鐢熸垚鍣� 閫傞厤MP銆丼pringDoc瑙勮寖鍖栦唬鐮� 涓�閿敓鎴愬墠鍚庣浠g爜<br />
+          * 閮ㄧ讲鏂瑰紡 Docker 瀹瑰櫒缂栨帓 涓�閿儴缃蹭笟鍔¢泦缇�<br />
+          * 鍥介檯鍖� SpringMessage Spring鏍囧噯鍥介檯鍖栨柟妗�<br />
+        </p>
+        <p><b>褰撳墠鐗堟湰:</b> <span>v5.0.0</span></p>
+        <p>
+          <el-tag type="danger">&yen;鍏嶈垂寮�婧�</el-tag>
+        </p>
+        <p>
+          <el-button type="primary" icon="Cloudy" plain @click="goTarget('https://gitee.com/dromara/RuoYi-Vue-Plus')">璁块棶鐮佷簯</el-button>
+          <el-button type="primary" icon="Cloudy" plain @click="goTarget('https://github.com/dromara/RuoYi-Vue-Plus')">璁块棶GitHub</el-button>
+          <el-button type="primary" icon="Cloudy" plain @click="goTarget('https://javalionli.gitee.io/plus-doc/#/ruoyi-vue-plus/changlog')"
+            >鏇存柊鏃ュ織</el-button
+          >
+        </p>
+      </el-col>
 
-			<el-col :sm="24" :lg="12" style="padding-left: 20px">
-				<h2>RuoYi-Cloud-Plus澶氱鎴峰井鏈嶅姟绠$悊绯荤粺</h2>
-				<p>
-					RuoYi-Cloud-Plus 寰湇鍔¢�氱敤鏉冮檺绠$悊绯荤粺 閲嶅啓 RuoYi-Cloud 鍏ㄦ柟浣嶅崌绾�(涓嶅吋瀹瑰師妗嗘灦)
-					<br />
-					* 鍓嶇寮�鍙戞鏋� Vue3銆乀S銆丒lement UI<br />
-					* 鍚庣寮�鍙戞鏋� Spring Boot<br />
-					* 寰湇鍔″紑鍙戞鏋� Spring Cloud銆丼pring Cloud Alibaba<br />
-					* 瀹瑰櫒妗嗘灦 Undertow 鍩轰簬 XNIO 鐨勯珮鎬ц兘瀹瑰櫒<br />
-					* 鏉冮檺璁よ瘉妗嗘灦 Sa-Token銆丣wt 鏀寔澶氱粓绔璇佺郴缁�<br />
-					* 鍏崇郴鏁版嵁搴� MySQL 閫傞厤 8.X 鏈�浣� 5.7<br />
-					* 鍏崇郴鏁版嵁搴� Oracle 閫傞厤 11g 12c<br />
-					* 鍏崇郴鏁版嵁搴� PostgreSQL 閫傞厤 13 14<br />
-					* 鍏崇郴鏁版嵁搴� SQLServer 閫傞厤 2017 2019<br />
-					* 缂撳瓨鏁版嵁搴� Redis 閫傞厤 6.X 鏈�浣� 5.X<br />
-					* 鍒嗗竷寮忔敞鍐屼腑蹇� Alibaba Nacos 閲囩敤2.X 鍩轰簬GRPC閫氫俊楂樻�ц兘<br />
-					* 鍒嗗竷寮忛厤缃腑蹇� Alibaba Nacos 閲囩敤2.X 鍩轰簬GRPC閫氫俊楂樻�ц兘<br />
-					* 鏈嶅姟缃戝叧 Spring Cloud Gateway 鍝嶅簲寮忛珮鎬ц兘缃戝叧<br />
-					* 璐熻浇鍧囪  Spring Cloud Loadbalancer 璐熻浇鍧囪 澶勭悊<br />
-					* RPC杩滅▼璋冪敤 Apache Dubbo 鍘熺敓鎬佷娇鐢ㄤ綋楠屻�侀珮鎬ц兘<br />
-					* 鍒嗗竷寮忛檺娴佺啍鏂� Alibaba Sentinel 鏃犱镜鍏ャ�侀珮鎵╁睍<br />
-					* 鍒嗗竷寮忎簨鍔� Alibaba Seata 鏃犱镜鍏ャ�侀珮鎵╁睍 鏀寔 鍥涚妯″紡<br />
-					* 鍒嗗竷寮忔秷鎭槦鍒� Spring Cloud Stream 闂ㄩ潰妗嗘灦鍏煎鍚勭MQ闆嗘垚<br />
-					* 鍒嗗竷寮忔秷鎭槦鍒� Apache Kafka 楂樻�ц兘楂橀�熷害<br />
-					* 鍒嗗竷寮忔秷鎭槦鍒� Apache RocketMQ 楂樺彲鐢ㄥ姛鑳藉鏍�<br />
-					* 鍒嗗竷寮忔秷鎭槦鍒� RabbitMQ 鏀寔鍚勭鎵╁睍鎻掍欢鍔熻兘澶氭牱鎬�<br />
-					* 鍒嗗竷寮忔悳绱㈠紩鎿� ElasticSearch 涓氱晫鐭ュ悕<br />
-					* 鍒嗗竷寮忛摼璺拷韪� Apache SkyWalking 閾捐矾杩借釜銆佺綉鏍煎垎鏋愩�佸害閲忚仛鍚堛�佸彲瑙嗗寲<br />
-					* 鍒嗗竷寮忔棩蹇椾腑蹇� ELK 涓氱晫鎴愮啛瑙e喅鏂规<br />
-					* 鍒嗗竷寮忕洃鎺� Prometheus銆丟rafana 鍏ㄦ柟浣嶆�ц兘鐩戞帶<br />
-					* 鍏朵綑涓� Vue 鐗堟湰涓�鑷�<br />
-				</p>
-				<p><b>褰撳墠鐗堟湰:</b> <span>v2.0.0</span></p>
-				<p>
-					<el-tag type="danger">&yen;鍏嶈垂寮�婧�</el-tag>
-				</p>
-				<p>
-					<el-button type="primary" icon="Cloudy" plain @click="goTarget('https://gitee.com/dromara/RuoYi-Cloud-Plus')">璁块棶鐮佷簯</el-button>
-					<el-button type="primary" icon="Cloudy" plain @click="goTarget('https://github.com/dromara/RuoYi-Cloud-Plus')">璁块棶GitHub</el-button>
-					<el-button type="primary" icon="Cloudy" plain @click="goTarget('https://javalionli.gitee.io/plus-doc/#/ruoyi-cloud-plus/changlog')"
-						>鏇存柊鏃ュ織</el-button
-					>
-				</p>
-			</el-col>
-		</el-row>
-		<el-divider />
-	</div>
+      <el-col :sm="24" :lg="12" style="padding-left: 20px">
+        <h2>RuoYi-Cloud-Plus澶氱鎴峰井鏈嶅姟绠$悊绯荤粺</h2>
+        <p>
+          RuoYi-Cloud-Plus 寰湇鍔¢�氱敤鏉冮檺绠$悊绯荤粺 閲嶅啓 RuoYi-Cloud 鍏ㄦ柟浣嶅崌绾�(涓嶅吋瀹瑰師妗嗘灦)
+          <br />
+          * 鍓嶇寮�鍙戞鏋� Vue3銆乀S銆丒lement UI<br />
+          * 鍚庣寮�鍙戞鏋� Spring Boot<br />
+          * 寰湇鍔″紑鍙戞鏋� Spring Cloud銆丼pring Cloud Alibaba<br />
+          * 瀹瑰櫒妗嗘灦 Undertow 鍩轰簬 XNIO 鐨勯珮鎬ц兘瀹瑰櫒<br />
+          * 鏉冮檺璁よ瘉妗嗘灦 Sa-Token銆丣wt 鏀寔澶氱粓绔璇佺郴缁�<br />
+          * 鍏崇郴鏁版嵁搴� MySQL 閫傞厤 8.X 鏈�浣� 5.7<br />
+          * 鍏崇郴鏁版嵁搴� Oracle 閫傞厤 11g 12c<br />
+          * 鍏崇郴鏁版嵁搴� PostgreSQL 閫傞厤 13 14<br />
+          * 鍏崇郴鏁版嵁搴� SQLServer 閫傞厤 2017 2019<br />
+          * 缂撳瓨鏁版嵁搴� Redis 閫傞厤 6.X 鏈�浣� 5.X<br />
+          * 鍒嗗竷寮忔敞鍐屼腑蹇� Alibaba Nacos 閲囩敤2.X 鍩轰簬GRPC閫氫俊楂樻�ц兘<br />
+          * 鍒嗗竷寮忛厤缃腑蹇� Alibaba Nacos 閲囩敤2.X 鍩轰簬GRPC閫氫俊楂樻�ц兘<br />
+          * 鏈嶅姟缃戝叧 Spring Cloud Gateway 鍝嶅簲寮忛珮鎬ц兘缃戝叧<br />
+          * 璐熻浇鍧囪  Spring Cloud Loadbalancer 璐熻浇鍧囪 澶勭悊<br />
+          * RPC杩滅▼璋冪敤 Apache Dubbo 鍘熺敓鎬佷娇鐢ㄤ綋楠屻�侀珮鎬ц兘<br />
+          * 鍒嗗竷寮忛檺娴佺啍鏂� Alibaba Sentinel 鏃犱镜鍏ャ�侀珮鎵╁睍<br />
+          * 鍒嗗竷寮忎簨鍔� Alibaba Seata 鏃犱镜鍏ャ�侀珮鎵╁睍 鏀寔 鍥涚妯″紡<br />
+          * 鍒嗗竷寮忔秷鎭槦鍒� Spring Cloud Stream 闂ㄩ潰妗嗘灦鍏煎鍚勭MQ闆嗘垚<br />
+          * 鍒嗗竷寮忔秷鎭槦鍒� Apache Kafka 楂樻�ц兘楂橀�熷害<br />
+          * 鍒嗗竷寮忔秷鎭槦鍒� Apache RocketMQ 楂樺彲鐢ㄥ姛鑳藉鏍�<br />
+          * 鍒嗗竷寮忔秷鎭槦鍒� RabbitMQ 鏀寔鍚勭鎵╁睍鎻掍欢鍔熻兘澶氭牱鎬�<br />
+          * 鍒嗗竷寮忔悳绱㈠紩鎿� ElasticSearch 涓氱晫鐭ュ悕<br />
+          * 鍒嗗竷寮忛摼璺拷韪� Apache SkyWalking 閾捐矾杩借釜銆佺綉鏍煎垎鏋愩�佸害閲忚仛鍚堛�佸彲瑙嗗寲<br />
+          * 鍒嗗竷寮忔棩蹇椾腑蹇� ELK 涓氱晫鎴愮啛瑙e喅鏂规<br />
+          * 鍒嗗竷寮忕洃鎺� Prometheus銆丟rafana 鍏ㄦ柟浣嶆�ц兘鐩戞帶<br />
+          * 鍏朵綑涓� Vue 鐗堟湰涓�鑷�<br />
+        </p>
+        <p><b>褰撳墠鐗堟湰:</b> <span>v2.0.0</span></p>
+        <p>
+          <el-tag type="danger">&yen;鍏嶈垂寮�婧�</el-tag>
+        </p>
+        <p>
+          <el-button type="primary" icon="Cloudy" plain @click="goTarget('https://gitee.com/dromara/RuoYi-Cloud-Plus')">璁块棶鐮佷簯</el-button>
+          <el-button type="primary" icon="Cloudy" plain @click="goTarget('https://github.com/dromara/RuoYi-Cloud-Plus')">璁块棶GitHub</el-button>
+          <el-button type="primary" icon="Cloudy" plain @click="goTarget('https://javalionli.gitee.io/plus-doc/#/ruoyi-cloud-plus/changlog')"
+            >鏇存柊鏃ュ織</el-button
+          >
+        </p>
+      </el-col>
+    </el-row>
+    <el-divider />
+  </div>
 </template>
 
 <script setup name="Index" lang="ts">
diff --git a/src/views/login.vue b/src/views/login.vue
index 102e483..9559f9b 100644
--- a/src/views/login.vue
+++ b/src/views/login.vue
@@ -1,3 +1,49 @@
+<template>
+  <div class="login">
+    <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
+      <h3 class="title">RuoYi-Vue-Plus澶氱鎴风鐞嗙郴缁�</h3>
+      <el-form-item prop="tenantId" v-if="tenantEnabled">
+        <el-select v-model="loginForm.tenantId" filterable placeholder="璇烽�夋嫨/杈撳叆鍏徃鍚嶇О" style="width: 100%">
+          <el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId"> </el-option>
+          <template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template>
+        </el-select>
+      </el-form-item>
+      <el-form-item prop="username">
+        <el-input v-model="loginForm.username" type="text" size="large" auto-complete="off" placeholder="璐﹀彿">
+          <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
+        </el-input>
+      </el-form-item>
+      <el-form-item prop="password">
+        <el-input v-model="loginForm.password" type="password" size="large" auto-complete="off" placeholder="瀵嗙爜" @keyup.enter="handleLogin">
+          <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
+        </el-input>
+      </el-form-item>
+      <el-form-item prop="code" v-if="captchaEnabled">
+        <el-input v-model="loginForm.code" size="large" auto-complete="off" placeholder="楠岃瘉鐮�" style="width: 63%" @keyup.enter="handleLogin">
+          <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
+        </el-input>
+        <div class="login-code">
+          <img :src="codeUrl" @click="getCode" class="login-code-img" />
+        </div>
+      </el-form-item>
+      <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">璁颁綇瀵嗙爜</el-checkbox>
+      <el-form-item style="width:100%;">
+        <el-button :loading="loading" size="large" type="primary" style="width:100%;" @click.prevent="handleLogin">
+          <span v-if="!loading">鐧� 褰�</span>
+          <span v-else>鐧� 褰� 涓�...</span>
+        </el-button>
+        <div style="float: right;" v-if="register">
+          <router-link class="link-type" :to="'/register'">绔嬪嵆娉ㄥ唽</router-link>
+        </div>
+      </el-form-item>
+    </el-form>
+    <!--  搴曢儴  -->
+    <div class="el-login-footer">
+      <span>Copyright 漏 2018-2023 鐤媯鐨勭嫯瀛怢i All Rights Reserved.</span>
+    </div>
+  </div>
+</template>
+
 <script setup lang="ts">
 import { getCodeImg, getTenantList } from '@/api/login';
 import Cookies from 'js-cookie';
@@ -11,19 +57,19 @@
 const router = useRouter();
 
 const loginForm = ref<LoginData>({
-  tenantId: "000000",
-  username: 'admin',
-  password: 'admin123',
-  rememberMe: false,
-  code: '',
-  uuid: ''
+    tenantId: "000000",
+    username: 'admin',
+    password: 'admin123',
+    rememberMe: false,
+    code: '',
+    uuid: ''
 });
 
 const loginRules: FormRules = {
-  tenantId: [{ required: true, trigger: "blur", message: "璇疯緭鍏ユ偍鐨勭鎴风紪鍙�" }],
-  username: [{ required: true, trigger: 'blur', message: '璇疯緭鍏ユ偍鐨勮处鍙�' }],
-  password: [{ required: true, trigger: 'blur', message: '璇疯緭鍏ユ偍鐨勫瘑鐮�' }],
-  code: [{ required: true, trigger: 'change', message: '璇疯緭鍏ラ獙璇佺爜' }]
+    tenantId: [{ required: true, trigger: "blur", message: "璇疯緭鍏ユ偍鐨勭鎴风紪鍙�" }],
+    username: [{ required: true, trigger: 'blur', message: '璇疯緭鍏ユ偍鐨勮处鍙�' }],
+    password: [{ required: true, trigger: 'blur', message: '璇疯緭鍏ユ偍鐨勫瘑鐮�' }],
+    code: [{ required: true, trigger: 'change', message: '璇疯緭鍏ラ獙璇佺爜' }]
 };
 
 const codeUrl = ref('');
@@ -42,64 +88,64 @@
 const tenantList = ref<TenantVO[]>([]);
 
 const handleLogin = () => {
-  loginRef.value.validate(async (valid:boolean, fields: any) => {
-    if (valid) {
-      loading.value = true;
-      // 鍕鹃�変簡闇�瑕佽浣忓瘑鐮佽缃湪 cookie 涓缃浣忕敤鎴峰悕鍜屽瘑鐮�
-      if (loginForm.value.rememberMe) {
-        Cookies.set("tenantId", loginForm.value.tenantId, { expires: 30 });
-        Cookies.set('username', loginForm.value.username, { expires: 30 });
-        Cookies.set('password', String(encrypt(loginForm.value.password)), { expires: 30 });
-        Cookies.set('rememberMe', String(loginForm.value.rememberMe), { expires: 30 });
-      } else {
-        // 鍚﹀垯绉婚櫎
-        Cookies.remove("tenantId");
-        Cookies.remove('username');
-        Cookies.remove('password');
-        Cookies.remove('rememberMe');
-      }
-      // 璋冪敤action鐨勭櫥褰曟柟娉�
-      // prittier-ignore
-      const [err] = await to(userStore.login(loginForm.value));
-      if (!err) {
-        await router.push({ path: redirect.value || '/' });
-      } else {
-        loading.value = false;
-        // 閲嶆柊鑾峰彇楠岃瘉鐮�
-        if (captchaEnabled.value) {
-          await getCode();
+    loginRef.value.validate(async (valid:boolean, fields: any) => {
+        if (valid) {
+            loading.value = true;
+            // 鍕鹃�変簡闇�瑕佽浣忓瘑鐮佽缃湪 cookie 涓缃浣忕敤鎴峰悕鍜屽瘑鐮�
+            if (loginForm.value.rememberMe) {
+                Cookies.set("tenantId", loginForm.value.tenantId, { expires: 30 });
+                Cookies.set('username', loginForm.value.username, { expires: 30 });
+                Cookies.set('password', String(encrypt(loginForm.value.password)), { expires: 30 });
+                Cookies.set('rememberMe', String(loginForm.value.rememberMe), { expires: 30 });
+            } else {
+                // 鍚﹀垯绉婚櫎
+                Cookies.remove("tenantId");
+                Cookies.remove('username');
+                Cookies.remove('password');
+                Cookies.remove('rememberMe');
+            }
+            // 璋冪敤action鐨勭櫥褰曟柟娉�
+            // prittier-ignore
+            const [err] = await to(userStore.login(loginForm.value));
+            if (!err) {
+                await router.push({ path: redirect.value || '/' });
+            } else {
+                loading.value = false;
+                // 閲嶆柊鑾峰彇楠岃瘉鐮�
+                if (captchaEnabled.value) {
+                    await getCode();
+                }
+            }
+        } else {
+            console.log('error submit!', fields);
         }
-      }
-    } else {
-      console.log('error submit!', fields);
-    }
-  });
+    });
 };
 
 /**
  * 鑾峰彇楠岃瘉鐮�
  */
 const getCode = async () => {
-  const res = await getCodeImg();
-  const { data } = res;
-  captchaEnabled.value = data.captchaEnabled === undefined ? true : data.captchaEnabled;
-  if (captchaEnabled.value) {
-    codeUrl.value = 'data:image/gif;base64,' + data.img;
-    loginForm.value.uuid = data.uuid;
-  }
+    const res = await getCodeImg();
+    const { data } = res;
+    captchaEnabled.value = data.captchaEnabled === undefined ? true : data.captchaEnabled;
+    if (captchaEnabled.value) {
+        codeUrl.value = 'data:image/gif;base64,' + data.img;
+        loginForm.value.uuid = data.uuid;
+    }
 };
 
 const getCookie = () => {
-  const tenantId = Cookies.get("tenantId");
-  const username = Cookies.get('username');
-  const password = Cookies.get('password');
-  const rememberMe = Cookies.get('rememberMe');
-  loginForm.value = {
-    tenantId: tenantId === undefined ? loginForm.value.tenantId : tenantId,
-    username: username === undefined ? loginForm.value.username : username,
-    password: password === undefined ? loginForm.value.password : (decrypt(password) as string),
-    rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
-  };
+    const tenantId = Cookies.get("tenantId");
+    const username = Cookies.get('username');
+    const password = Cookies.get('password');
+    const rememberMe = Cookies.get('rememberMe');
+    loginForm.value = {
+        tenantId: tenantId === undefined ? loginForm.value.tenantId : tenantId,
+        username: username === undefined ? loginForm.value.username : username,
+        password: password === undefined ? loginForm.value.password : (decrypt(password) as string),
+        rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
+    };
 }
 
 
@@ -107,68 +153,22 @@
  * 鑾峰彇绉熸埛鍒楄〃
  */
 const initTenantList = async () => {
-  const { data } = await getTenantList();
-  tenantEnabled.value = data.tenantEnabled === undefined ? true : data.tenantEnabled;
-  if (tenantEnabled.value) {
-    tenantList.value = data.voList;
-    if (tenantList.value != null && tenantList.value.length !== 0) {
-      loginForm.value.tenantId = tenantList.value[0].tenantId;
+    const { data } = await getTenantList();
+    tenantEnabled.value = data.tenantEnabled === undefined ? true : data.tenantEnabled;
+    if (tenantEnabled.value) {
+        tenantList.value = data.voList;
+        if (tenantList.value != null && tenantList.value.length !== 0) {
+            loginForm.value.tenantId = tenantList.value[0].tenantId;
+        }
     }
-  }
 }
 
 onMounted(() => {
-  getCode();
-  initTenantList();
-  getCookie();
+    getCode();
+    initTenantList();
+    getCookie();
 });
 </script>
-
-<template>
-	<div class="login">
-		<el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
-			<h3 class="title">RuoYi-Vue-Plus澶氱鎴风鐞嗙郴缁�</h3>
-			<el-form-item prop="tenantId" v-if="tenantEnabled">
-				<el-select v-model="loginForm.tenantId" filterable placeholder="璇烽�夋嫨/杈撳叆鍏徃鍚嶇О" style="width: 100%">
-					<el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId"> </el-option>
-					<template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template>
-				</el-select>
-			</el-form-item>
-			<el-form-item prop="username">
-				<el-input v-model="loginForm.username" type="text" size="large" auto-complete="off" placeholder="璐﹀彿">
-					<template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
-				</el-input>
-			</el-form-item>
-			<el-form-item prop="password">
-				<el-input v-model="loginForm.password" type="password" size="large" auto-complete="off" placeholder="瀵嗙爜" @keyup.enter="handleLogin">
-					<template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
-				</el-input>
-			</el-form-item>
-			<el-form-item prop="code" v-if="captchaEnabled">
-				<el-input v-model="loginForm.code" size="large" auto-complete="off" placeholder="楠岃瘉鐮�" style="width: 63%" @keyup.enter="handleLogin">
-					<template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
-				</el-input>
-				<div class="login-code">
-					<img :src="codeUrl" @click="getCode" class="login-code-img" />
-				</div>
-			</el-form-item>
-			<el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">璁颁綇瀵嗙爜</el-checkbox>
-			<el-form-item style="width:100%;">
-				<el-button :loading="loading" size="large" type="primary" style="width:100%;" @click.prevent="handleLogin">
-					<span v-if="!loading">鐧� 褰�</span>
-					<span v-else>鐧� 褰� 涓�...</span>
-				</el-button>
-				<div style="float: right;" v-if="register">
-					<router-link class="link-type" :to="'/register'">绔嬪嵆娉ㄥ唽</router-link>
-				</div>
-			</el-form-item>
-		</el-form>
-		<!--  搴曢儴  -->
-		<div class="el-login-footer">
-			<span>Copyright 漏 2018-2023 鐤媯鐨勭嫯瀛怢i All Rights Reserved.</span>
-		</div>
-	</div>
-</template>
 
 <style lang="scss" scoped>
 .login {
diff --git a/src/views/monitor/admin/index.vue b/src/views/monitor/admin/index.vue
index 4f958a1..04c63b5 100644
--- a/src/views/monitor/admin/index.vue
+++ b/src/views/monitor/admin/index.vue
@@ -1,7 +1,7 @@
 <template>
-	<div>
-		<i-frame v-model:src="url"></i-frame>
-	</div>
+  <div>
+    <i-frame v-model:src="url"></i-frame>
+  </div>
 </template>
 
 <script setup lang="ts">
diff --git a/src/views/monitor/cache/index.vue b/src/views/monitor/cache/index.vue
index 65082b0..9af7d50 100644
--- a/src/views/monitor/cache/index.vue
+++ b/src/views/monitor/cache/index.vue
@@ -9,180 +9,180 @@
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 
 const getList = async () => {
-	proxy?.$modal.loading("姝e湪鍔犺浇缂撳瓨鐩戞帶鏁版嵁锛岃绋嶅�欙紒");
-	const res = await getCache();
-	proxy?.$modal.closeLoading();
-	cache.value = res.data;
-	const commandstatsIntance = echarts.init(commandstats.value, "macarons");
-	commandstatsIntance.setOption({
-		tooltip: {
-			trigger: "item",
-			formatter: "{a} <br/>{b} : {c} ({d}%)"
-		},
-		series: [
-			{
-				name: "鍛戒护",
-				type: "pie",
-				roseType: "radius",
-				radius: [15, 95],
-				center: ["50%", "38%"],
-				data: res.data.commandStats,
-				animationEasing: "cubicInOut",
-				animationDuration: 1000
-			}
-		]
-	});
+  proxy?.$modal.loading("姝e湪鍔犺浇缂撳瓨鐩戞帶鏁版嵁锛岃绋嶅�欙紒");
+  const res = await getCache();
+  proxy?.$modal.closeLoading();
+  cache.value = res.data;
+  const commandstatsIntance = echarts.init(commandstats.value, "macarons");
+  commandstatsIntance.setOption({
+    tooltip: {
+      trigger: "item",
+      formatter: "{a} <br/>{b} : {c} ({d}%)"
+    },
+    series: [
+      {
+        name: "鍛戒护",
+        type: "pie",
+        roseType: "radius",
+        radius: [15, 95],
+        center: ["50%", "38%"],
+        data: res.data.commandStats,
+        animationEasing: "cubicInOut",
+        animationDuration: 1000
+      }
+    ]
+  });
 
-	const usedmemoryInstance = echarts.init(usedmemory.value, "macarons");
-	usedmemoryInstance.setOption({
-		tooltip: {
-			formatter: "{b} <br/>{a} : " + cache.value.info.used_memory_human
-		},
-		series: [
-			{
-				name: "宄板��",
-				type: "gauge",
-				min: 0,
-				max: 1000,
-				detail: {
-					formatter: cache.value.info.used_memory_human
-				},
-				data: [
-					{
-						value: parseFloat(cache.value.info.used_memory_human),
-						name: "鍐呭瓨娑堣��"
-					}
-				]
-			}
-		]
-	})
+  const usedmemoryInstance = echarts.init(usedmemory.value, "macarons");
+  usedmemoryInstance.setOption({
+    tooltip: {
+      formatter: "{b} <br/>{a} : " + cache.value.info.used_memory_human
+    },
+    series: [
+      {
+        name: "宄板��",
+        type: "gauge",
+        min: 0,
+        max: 1000,
+        detail: {
+          formatter: cache.value.info.used_memory_human
+        },
+        data: [
+          {
+            value: parseFloat(cache.value.info.used_memory_human),
+            name: "鍐呭瓨娑堣��"
+          }
+        ]
+      }
+    ]
+  })
 }
 
 onMounted(() => {
-	getList();
+  getList();
 })
 </script>
 <template>
-	<div class="p-2">
-		<el-row>
-			<el-col :span="24" class="card-box">
-				<el-card>
-					<template #header>
-						<Monitor style="width: 1em; height: 1em; vertical-align: middle;" />
-						<span style="vertical-align: middle;">鍩烘湰淇℃伅</span>
-					</template>
+  <div class="p-2">
+    <el-row>
+      <el-col :span="24" class="card-box">
+        <el-card>
+          <template #header>
+            <Monitor style="width: 1em; height: 1em; vertical-align: middle;" />
+            <span style="vertical-align: middle;">鍩烘湰淇℃伅</span>
+          </template>
 
-					<div class="el-table el-table--enable-row-hover el-table--medium">
-						<table style="width: 100%">
-							<tbody>
-								<tr>
-									<td class="el-table__cell is-leaf">
-										<div class="cell">Redis鐗堟湰</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell" v-if="cache.info">{{ cache.info.redis_version }}</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell">杩愯妯″紡</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell" v-if="cache.info">{{ cache.info.redis_mode === "standalone" ? "鍗曟満" : "闆嗙兢" }}</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell">绔彛</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell" v-if="cache.info">{{ cache.info.tcp_port }}</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell">瀹㈡埛绔暟</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell" v-if="cache.info">{{ cache.info.connected_clients }}</div>
-									</td>
-								</tr>
-								<tr>
-									<td class="el-table__cell is-leaf">
-										<div class="cell">杩愯鏃堕棿(澶�)</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell" v-if="cache.info">{{ cache.info.uptime_in_days }}</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell">浣跨敤鍐呭瓨</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell" v-if="cache.info">{{ cache.info.used_memory_human }}</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell">浣跨敤CPU</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell" v-if="cache.info">{{ parseFloat(cache.info.used_cpu_user_children).toFixed(2) }}</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell">鍐呭瓨閰嶇疆</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell" v-if="cache.info">{{ cache.info.maxmemory_human }}</div>
-									</td>
-								</tr>
-								<tr>
-									<td class="el-table__cell is-leaf">
-										<div class="cell">AOF鏄惁寮�鍚�</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell" v-if="cache.info">{{ cache.info.aof_enabled === "0" ? "鍚�" : "鏄�" }}</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell">RDB鏄惁鎴愬姛</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell" v-if="cache.info">{{ cache.info.rdb_last_bgsave_status }}</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell">Key鏁伴噺</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell" v-if="cache.dbSize">{{ cache.dbSize }}</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell">缃戠粶鍏ュ彛/鍑哄彛</div>
-									</td>
-									<td class="el-table__cell is-leaf">
-										<div class="cell" v-if="cache.info">
-											{{ cache.info.instantaneous_input_kbps }}kps/{{ cache.info.instantaneous_output_kbps }}kps
-										</div>
-									</td>
-								</tr>
-							</tbody>
-						</table>
-					</div>
-				</el-card>
-			</el-col>
+          <div class="el-table el-table--enable-row-hover el-table--medium">
+            <table style="width: 100%">
+              <tbody>
+                <tr>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell">Redis鐗堟湰</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell" v-if="cache.info">{{ cache.info.redis_version }}</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell">杩愯妯″紡</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell" v-if="cache.info">{{ cache.info.redis_mode === "standalone" ? "鍗曟満" : "闆嗙兢" }}</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell">绔彛</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell" v-if="cache.info">{{ cache.info.tcp_port }}</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell">瀹㈡埛绔暟</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell" v-if="cache.info">{{ cache.info.connected_clients }}</div>
+                  </td>
+                </tr>
+                <tr>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell">杩愯鏃堕棿(澶�)</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell" v-if="cache.info">{{ cache.info.uptime_in_days }}</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell">浣跨敤鍐呭瓨</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell" v-if="cache.info">{{ cache.info.used_memory_human }}</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell">浣跨敤CPU</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell" v-if="cache.info">{{ parseFloat(cache.info.used_cpu_user_children).toFixed(2) }}</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell">鍐呭瓨閰嶇疆</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell" v-if="cache.info">{{ cache.info.maxmemory_human }}</div>
+                  </td>
+                </tr>
+                <tr>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell">AOF鏄惁寮�鍚�</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell" v-if="cache.info">{{ cache.info.aof_enabled === "0" ? "鍚�" : "鏄�" }}</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell">RDB鏄惁鎴愬姛</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell" v-if="cache.info">{{ cache.info.rdb_last_bgsave_status }}</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell">Key鏁伴噺</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell" v-if="cache.dbSize">{{ cache.dbSize }}</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell">缃戠粶鍏ュ彛/鍑哄彛</div>
+                  </td>
+                  <td class="el-table__cell is-leaf">
+                    <div class="cell" v-if="cache.info">
+                      {{ cache.info.instantaneous_input_kbps }}kps/{{ cache.info.instantaneous_output_kbps }}kps
+                    </div>
+                  </td>
+                </tr>
+              </tbody>
+            </table>
+          </div>
+        </el-card>
+      </el-col>
 
-			<el-col :span="12" class="card-box">
-				<el-card>
-					<template #header>
-						<PieChart style="width: 1em; height: 1em; vertical-align: middle;" />
-						<span style="vertical-align: middle;">鍛戒护缁熻</span>
-					</template>
-					<div class="el-table el-table--enable-row-hover el-table--medium">
-						<div ref="commandstats" style="height: 420px" />
-					</div>
-				</el-card>
-			</el-col>
+      <el-col :span="12" class="card-box">
+        <el-card>
+          <template #header>
+            <PieChart style="width: 1em; height: 1em; vertical-align: middle;" />
+            <span style="vertical-align: middle;">鍛戒护缁熻</span>
+          </template>
+          <div class="el-table el-table--enable-row-hover el-table--medium">
+            <div ref="commandstats" style="height: 420px" />
+          </div>
+        </el-card>
+      </el-col>
 
-			<el-col :span="12" class="card-box">
-				<el-card>
-					<template #header>
-						<Odometer style="width: 1em; height: 1em; vertical-align: middle;" /> <span style="vertical-align: middle;">鍐呭瓨淇℃伅</span>
-					</template>
-					<div class="el-table el-table--enable-row-hover el-table--medium">
-						<div ref="usedmemory" style="height: 420px" />
-					</div>
-				</el-card>
-			</el-col>
-		</el-row>
-	</div>
+      <el-col :span="12" class="card-box">
+        <el-card>
+          <template #header>
+            <Odometer style="width: 1em; height: 1em; vertical-align: middle;" /> <span style="vertical-align: middle;">鍐呭瓨淇℃伅</span>
+          </template>
+          <div class="el-table el-table--enable-row-hover el-table--medium">
+            <div ref="usedmemory" style="height: 420px" />
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
 </template>
diff --git a/src/views/monitor/logininfor/index.vue b/src/views/monitor/logininfor/index.vue
index 32e5149..8279363 100644
--- a/src/views/monitor/logininfor/index.vue
+++ b/src/views/monitor/logininfor/index.vue
@@ -1,3 +1,101 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+          <el-form-item label="鐧诲綍鍦板潃" prop="ipaddr">
+            <el-input v-model="queryParams.ipaddr" placeholder="璇疯緭鍏ョ櫥褰曞湴鍧�" clearable style="width: 240px;" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鐢ㄦ埛鍚嶇О" prop="userName">
+            <el-input v-model="queryParams.userName" placeholder="璇疯緭鍏ョ敤鎴峰悕绉�" clearable style="width: 240px;" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鐘舵��" prop="status">
+            <el-select v-model="queryParams.status" placeholder="鐧诲綍鐘舵��" clearable style="width: 240px">
+              <el-option v-for="dict in sys_common_status" :key="dict.value" :label="dict.label" :value="dict.value" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="鐧诲綍鏃堕棿" style="width: 308px">
+            <el-date-picker
+              v-model="dateRange"
+              value-format="YYYY-MM-DD HH:mm:ss"
+              type="daterange"
+              range-separator="-"
+              start-placeholder="寮�濮嬫棩鏈�"
+              end-placeholder="缁撴潫鏃ユ湡"
+              :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
+            ></el-date-picker>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['monitor:logininfor:remove']">
+              鍒犻櫎
+            </el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" @click="handleClean" v-hasPermi="['monitor:logininfor:remove']">娓呯┖</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Unlock" :disabled="single" @click="handleUnlock" v-hasPermi="['monitor:logininfor:unlock']">
+              瑙i攣
+            </el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['monitor:logininfor:export']">瀵煎嚭</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table
+        ref="loginInfoTableRef"
+        v-loading="loading"
+        :data="loginInfoList"
+        @selection-change="handleSelectionChange"
+        :default-sort="defaultSort"
+        @sort-change="handleSortChange"
+      >
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="璁块棶缂栧彿" align="center" prop="infoId" />
+        <el-table-column
+          label="鐢ㄦ埛鍚嶇О"
+          align="center"
+          prop="userName"
+          :show-overflow-tooltip="true"
+          sortable="custom"
+          :sort-orders="['descending', 'ascending']"
+        />
+        <el-table-column label="鍦板潃" align="center" prop="ipaddr" :show-overflow-tooltip="true" />
+        <el-table-column label="鐧诲綍鍦扮偣" align="center" prop="loginLocation" :show-overflow-tooltip="true" />
+        <el-table-column label="鎿嶄綔绯荤粺" align="center" prop="os" :show-overflow-tooltip="true" />
+        <el-table-column label="娴忚鍣�" align="center" prop="browser" :show-overflow-tooltip="true" />
+        <el-table-column label="鐧诲綍鐘舵��" align="center" prop="status">
+          <template #default="scope">
+            <dict-tag :options="sys_common_status" :value="scope.row.status" />
+          </template>
+        </el-table-column>
+        <el-table-column label="鎻忚堪" align="center" prop="msg" :show-overflow-tooltip="true" />
+        <el-table-column label="璁块棶鏃堕棿" align="center" prop="loginTime" sortable="custom" :sort-orders="['descending', 'ascending']" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.loginTime) }}</span>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+    </el-card>
+  </div>
+</template>
+
 <script setup name="Logininfor" lang="ts">
 import { list, delLoginInfo, cleanLoginInfo, unlockLoginInfo } from "@/api/monitor/loginInfo";
 import { ComponentInternalInstance } from "vue";
@@ -22,176 +120,78 @@
 const loginInfoTableRef = ref(ElTable);
 // 鏌ヨ鍙傛暟
 const queryParams = ref<LoginInfoQuery>({
-  pageNum: 1,
-  pageSize: 10,
-  ipaddr: '',
-  userName: '',
-  status: '',
-  orderByColumn: defaultSort.value.prop,
-  isAsc: defaultSort.value.order
+    pageNum: 1,
+    pageSize: 10,
+    ipaddr: '',
+    userName: '',
+    status: '',
+    orderByColumn: defaultSort.value.prop,
+    isAsc: defaultSort.value.order
 });
 
 /** 鏌ヨ鐧诲綍鏃ュ織鍒楄〃 */
 const getList = async () => {
-  loading.value = true;
-	const res = await list(proxy?.addDateRange(queryParams.value, dateRange.value));
-	loginInfoList.value = res.rows;
-	total.value = res.total;
-	loading.value = false;
+    loading.value = true;
+    const res = await list(proxy?.addDateRange(queryParams.value, dateRange.value));
+    loginInfoList.value = res.rows;
+    total.value = res.total;
+    loading.value = false;
 }
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-  queryParams.value.pageNum = 1;
-  getList();
+    queryParams.value.pageNum = 1;
+    getList();
 }
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 const resetQuery = () => {
-  dateRange.value = ['', ''];
-  queryFormRef.value.resetFields();
-  queryParams.value.pageNum = 1;
-  loginInfoTableRef.value.sort(defaultSort.value.prop, defaultSort.value.order);
+    dateRange.value = ['', ''];
+    queryFormRef.value.resetFields();
+    queryParams.value.pageNum = 1;
+    loginInfoTableRef.value.sort(defaultSort.value.prop, defaultSort.value.order);
 }
 /** 澶氶�夋閫変腑鏁版嵁 */
 const handleSelectionChange = (selection: LoginInfoVO[]) => {
-  ids.value = selection.map(item => item.infoId);
-  multiple.value = !selection.length;
-  single.value = selection.length != 1;
-  selectName.value = selection.map(item => item.userName);
+    ids.value = selection.map(item => item.infoId);
+    multiple.value = !selection.length;
+    single.value = selection.length != 1;
+    selectName.value = selection.map(item => item.userName);
 }
 /** 鎺掑簭瑙﹀彂浜嬩欢 */
 const handleSortChange = (column: any) => {
-  queryParams.value.orderByColumn = column.prop;
-  queryParams.value.isAsc = column.order;
-  getList();
+    queryParams.value.orderByColumn = column.prop;
+    queryParams.value.isAsc = column.order;
+    getList();
 }
 /** 鍒犻櫎鎸夐挳鎿嶄綔 */
 const handleDelete = async (row?: LoginInfoVO) => {
-  const infoIds = row?.infoId || ids.value;
-	await proxy?.$modal.confirm('鏄惁纭鍒犻櫎璁块棶缂栧彿涓�"' + infoIds + '"鐨勬暟鎹」?');
-	await delLoginInfo(infoIds);
-	getList();
-	proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    const infoIds = row?.infoId || ids.value;
+    await proxy?.$modal.confirm('鏄惁纭鍒犻櫎璁块棶缂栧彿涓�"' + infoIds + '"鐨勬暟鎹」?');
+    await delLoginInfo(infoIds);
+    getList();
+    proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
 }
 /** 娓呯┖鎸夐挳鎿嶄綔 */
 const handleClean = async () => {
-	await proxy?.$modal.confirm("鏄惁纭娓呯┖鎵�鏈夌櫥褰曟棩蹇楁暟鎹」?");
-	await cleanLoginInfo();
-	getList();
-	proxy?.$modal.msgSuccess("娓呯┖鎴愬姛");
+    await proxy?.$modal.confirm("鏄惁纭娓呯┖鎵�鏈夌櫥褰曟棩蹇楁暟鎹」?");
+    await cleanLoginInfo();
+    getList();
+    proxy?.$modal.msgSuccess("娓呯┖鎴愬姛");
 }
 /** 瑙i攣鎸夐挳鎿嶄綔 */
 const handleUnlock = async () => {
-  const username = selectName.value;
-	await proxy?.$modal.confirm('鏄惁纭瑙i攣鐢ㄦ埛"' + username + '"鏁版嵁椤�?');
-	await unlockLoginInfo(username);
-	proxy?.$modal.msgSuccess("鐢ㄦ埛" + username + "瑙i攣鎴愬姛");
+    const username = selectName.value;
+    await proxy?.$modal.confirm('鏄惁纭瑙i攣鐢ㄦ埛"' + username + '"鏁版嵁椤�?');
+    await unlockLoginInfo(username);
+    proxy?.$modal.msgSuccess("鐢ㄦ埛" + username + "瑙i攣鎴愬姛");
 }
 /** 瀵煎嚭鎸夐挳鎿嶄綔 */
 const handleExport = () => {
-  proxy?.download("monitor/logininfor/export", {
-    ...queryParams.value,
-  }, `config_${new Date().getTime()}.xlsx`);
+    proxy?.download("monitor/logininfor/export", {
+        ...queryParams.value,
+    }, `config_${new Date().getTime()}.xlsx`);
 }
 
 onMounted(() => {
-  getList();
+    getList();
 })
 </script>
-
-<template>
-	<div class="p-2">
-		<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-			<div class="search" v-show="showSearch">
-				<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
-					<el-form-item label="鐧诲綍鍦板潃" prop="ipaddr">
-						<el-input v-model="queryParams.ipaddr" placeholder="璇疯緭鍏ョ櫥褰曞湴鍧�" clearable style="width: 240px;" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鐢ㄦ埛鍚嶇О" prop="userName">
-						<el-input v-model="queryParams.userName" placeholder="璇疯緭鍏ョ敤鎴峰悕绉�" clearable style="width: 240px;" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鐘舵��" prop="status">
-						<el-select v-model="queryParams.status" placeholder="鐧诲綍鐘舵��" clearable style="width: 240px">
-							<el-option v-for="dict in sys_common_status" :key="dict.value" :label="dict.label" :value="dict.value" />
-						</el-select>
-					</el-form-item>
-					<el-form-item label="鐧诲綍鏃堕棿" style="width: 308px">
-						<el-date-picker
-							v-model="dateRange"
-							value-format="YYYY-MM-DD HH:mm:ss"
-							type="daterange"
-							range-separator="-"
-							start-placeholder="寮�濮嬫棩鏈�"
-							end-placeholder="缁撴潫鏃ユ湡"
-							:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
-						></el-date-picker>
-					</el-form-item>
-					<el-form-item>
-						<el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
-						<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-					</el-form-item>
-				</el-form>
-			</div>
-		</transition>
-
-		<el-card shadow="never">
-			<template #header>
-				<el-row :gutter="10" class="mb8">
-					<el-col :span="1.5">
-						<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['monitor:logininfor:remove']">
-							鍒犻櫎
-						</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="danger" plain icon="Delete" @click="handleClean" v-hasPermi="['monitor:logininfor:remove']">娓呯┖</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="primary" plain icon="Unlock" :disabled="single" @click="handleUnlock" v-hasPermi="['monitor:logininfor:unlock']">
-							瑙i攣
-						</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['monitor:logininfor:export']">瀵煎嚭</el-button>
-					</el-col>
-					<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-				</el-row>
-			</template>
-
-			<el-table
-				ref="loginInfoTableRef"
-				v-loading="loading"
-				:data="loginInfoList"
-				@selection-change="handleSelectionChange"
-				:default-sort="defaultSort"
-				@sort-change="handleSortChange"
-			>
-				<el-table-column type="selection" width="55" align="center" />
-				<el-table-column label="璁块棶缂栧彿" align="center" prop="infoId" />
-				<el-table-column
-					label="鐢ㄦ埛鍚嶇О"
-					align="center"
-					prop="userName"
-					:show-overflow-tooltip="true"
-					sortable="custom"
-					:sort-orders="['descending', 'ascending']"
-				/>
-				<el-table-column label="鍦板潃" align="center" prop="ipaddr" :show-overflow-tooltip="true" />
-				<el-table-column label="鐧诲綍鍦扮偣" align="center" prop="loginLocation" :show-overflow-tooltip="true" />
-				<el-table-column label="鎿嶄綔绯荤粺" align="center" prop="os" :show-overflow-tooltip="true" />
-				<el-table-column label="娴忚鍣�" align="center" prop="browser" :show-overflow-tooltip="true" />
-				<el-table-column label="鐧诲綍鐘舵��" align="center" prop="status">
-					<template #default="scope">
-						<dict-tag :options="sys_common_status" :value="scope.row.status" />
-					</template>
-				</el-table-column>
-				<el-table-column label="鎻忚堪" align="center" prop="msg" :show-overflow-tooltip="true" />
-				<el-table-column label="璁块棶鏃堕棿" align="center" prop="loginTime" sortable="custom" :sort-orders="['descending', 'ascending']" width="180">
-					<template #default="scope">
-						<span>{{ parseTime(scope.row.loginTime) }}</span>
-					</template>
-				</el-table-column>
-			</el-table>
-
-			<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
-		</el-card>
-	</div>
-</template>
diff --git a/src/views/monitor/online/index.vue b/src/views/monitor/online/index.vue
index 1084d47..2b56d34 100644
--- a/src/views/monitor/online/index.vue
+++ b/src/views/monitor/online/index.vue
@@ -1,3 +1,57 @@
+<template>
+  <div class="p-2">
+    <div class="search">
+      <el-form :model="queryParams" ref="queryFormRef" :inline="true">
+        <el-form-item label="鐧诲綍鍦板潃" prop="ipaddr">
+          <el-input v-model="queryParams.ipaddr" placeholder="璇疯緭鍏ョ櫥褰曞湴鍧�" clearable style="width: 200px" @keyup.enter="handleQuery" />
+        </el-form-item>
+        <el-form-item label="鐢ㄦ埛鍚嶇О" prop="userName">
+          <el-input v-model="queryParams.userName" placeholder="璇疯緭鍏ョ敤鎴峰悕绉�" clearable style="width: 200px" @keyup.enter="handleQuery" />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+          <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="panel">
+      <el-table
+        v-loading="loading"
+        :data="onlineList.slice((queryParams.pageNum - 1) * queryParams.pageSize, queryParams.pageNum * queryParams.pageSize)"
+        style="width: 100%;"
+      >
+        <el-table-column label="搴忓彿" width="50" type="index" align="center">
+          <template #default="scope">
+            <span>{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="浼氳瘽缂栧彿" align="center" prop="tokenId" :show-overflow-tooltip="true" />
+        <el-table-column label="鐧诲綍鍚嶇О" align="center" prop="userName" :show-overflow-tooltip="true" />
+        <el-table-column label="鎵�灞為儴闂�" align="center" prop="deptName" :show-overflow-tooltip="true" />
+        <el-table-column label="涓绘満" align="center" prop="ipaddr" :show-overflow-tooltip="true" />
+        <el-table-column label="鐧诲綍鍦扮偣" align="center" prop="loginLocation" :show-overflow-tooltip="true" />
+        <el-table-column label="鎿嶄綔绯荤粺" align="center" prop="os" :show-overflow-tooltip="true" />
+        <el-table-column label="娴忚鍣�" align="center" prop="browser" :show-overflow-tooltip="true" />
+        <el-table-column label="鐧诲綍鏃堕棿" align="center" prop="loginTime" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.loginTime) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-tooltip content="寮洪��" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleForceLogout(scope.row)" v-hasPermi="['monitor:online:forceLogout']">
+              </el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" />
+    </div>
+  </div>
+</template>
+
 <script setup name="Online" lang="ts">
 import { forceLogout, list as initData } from "@/api/monitor/online";
 import { ComponentInternalInstance } from "vue";
@@ -12,93 +66,39 @@
 const queryFormRef = ref(ElForm);
 
 const queryParams = ref<OnlineQuery>({
-	pageNum: 1,
-	pageSize: 10,
-	ipaddr: '',
-	userName: ''
+    pageNum: 1,
+    pageSize: 10,
+    ipaddr: '',
+    userName: ''
 });
 
 /** 鏌ヨ鐧诲綍鏃ュ織鍒楄〃 */
 const getList = async () => {
-	loading.value = true;
-	const res = await initData(queryParams.value);
-	onlineList.value = res.rows;
-	total.value = res.total;
-	loading.value = false;
+    loading.value = true;
+    const res = await initData(queryParams.value);
+    onlineList.value = res.rows;
+    total.value = res.total;
+    loading.value = false;
 }
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-	queryParams.value.pageNum = 1;
-	getList();
+    queryParams.value.pageNum = 1;
+    getList();
 }
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 const resetQuery = () => {
-	queryFormRef.value.resetFields();
-	handleQuery();
+    queryFormRef.value.resetFields();
+    handleQuery();
 }
 /** 寮洪��鎸夐挳鎿嶄綔 */
 const handleForceLogout = async (row: OnlineVO) => {
-	await proxy?.$modal.confirm('鏄惁纭寮洪��鍚嶇О涓�"' + row.userName + '"鐨勭敤鎴�?');
-	await forceLogout(row.tokenId);
-	getList();
-	proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    await proxy?.$modal.confirm('鏄惁纭寮洪��鍚嶇О涓�"' + row.userName + '"鐨勭敤鎴�?');
+    await forceLogout(row.tokenId);
+    getList();
+    proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
 }
 
 onMounted(() => {
-	getList();
+    getList();
 })
 </script>
-
-<template>
-	<div class="p-2">
-		<div class="search">
-			<el-form :model="queryParams" ref="queryFormRef" :inline="true">
-				<el-form-item label="鐧诲綍鍦板潃" prop="ipaddr">
-					<el-input v-model="queryParams.ipaddr" placeholder="璇疯緭鍏ョ櫥褰曞湴鍧�" clearable style="width: 200px" @keyup.enter="handleQuery" />
-				</el-form-item>
-				<el-form-item label="鐢ㄦ埛鍚嶇О" prop="userName">
-					<el-input v-model="queryParams.userName" placeholder="璇疯緭鍏ョ敤鎴峰悕绉�" clearable style="width: 200px" @keyup.enter="handleQuery" />
-				</el-form-item>
-				<el-form-item>
-					<el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
-					<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-				</el-form-item>
-			</el-form>
-		</div>
-		<div class="panel">
-			<el-table
-				v-loading="loading"
-				:data="onlineList.slice((queryParams.pageNum - 1) * queryParams.pageSize, queryParams.pageNum * queryParams.pageSize)"
-				style="width: 100%;"
-			>
-				<el-table-column label="搴忓彿" width="50" type="index" align="center">
-					<template #default="scope">
-						<span>{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}</span>
-					</template>
-				</el-table-column>
-				<el-table-column label="浼氳瘽缂栧彿" align="center" prop="tokenId" :show-overflow-tooltip="true" />
-				<el-table-column label="鐧诲綍鍚嶇О" align="center" prop="userName" :show-overflow-tooltip="true" />
-				<el-table-column label="鎵�灞為儴闂�" align="center" prop="deptName" :show-overflow-tooltip="true" />
-				<el-table-column label="涓绘満" align="center" prop="ipaddr" :show-overflow-tooltip="true" />
-				<el-table-column label="鐧诲綍鍦扮偣" align="center" prop="loginLocation" :show-overflow-tooltip="true" />
-				<el-table-column label="鎿嶄綔绯荤粺" align="center" prop="os" :show-overflow-tooltip="true" />
-				<el-table-column label="娴忚鍣�" align="center" prop="browser" :show-overflow-tooltip="true" />
-				<el-table-column label="鐧诲綍鏃堕棿" align="center" prop="loginTime" width="180">
-					<template #default="scope">
-						<span>{{ parseTime(scope.row.loginTime) }}</span>
-					</template>
-				</el-table-column>
-				<el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
-					<template #default="scope">
-						<el-tooltip content="寮洪��" placement="top">
-							<el-button link type="primary" icon="Delete" @click="handleForceLogout(scope.row)" v-hasPermi="['monitor:online:forceLogout']">
-							</el-button>
-						</el-tooltip>
-					</template>
-				</el-table-column>
-			</el-table>
-
-			<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" />
-		</div>
-	</div>
-</template>
diff --git a/src/views/monitor/operlog/index.vue b/src/views/monitor/operlog/index.vue
index 0316c00..086a1aa 100644
--- a/src/views/monitor/operlog/index.vue
+++ b/src/views/monitor/operlog/index.vue
@@ -1,3 +1,168 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+          <el-form-item label="绯荤粺妯″潡" prop="title">
+            <el-input v-model="queryParams.title" placeholder="璇疯緭鍏ョ郴缁熸ā鍧�" clearable style="width: 240px;" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鎿嶄綔浜哄憳" prop="operName">
+            <el-input v-model="queryParams.operName" placeholder="璇疯緭鍏ユ搷浣滀汉鍛�" clearable style="width: 240px;" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="绫诲瀷" prop="businessType">
+            <el-select v-model="queryParams.businessType" placeholder="鎿嶄綔绫诲瀷" clearable style="width: 240px">
+              <el-option v-for="dict in sys_oper_type" :key="dict.value" :label="dict.label" :value="dict.value" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="鐘舵��" prop="status">
+            <el-select v-model="queryParams.status" placeholder="鎿嶄綔鐘舵��" clearable style="width: 240px">
+              <el-option v-for="dict in sys_common_status" :key="dict.value" :label="dict.label" :value="dict.value" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="鎿嶄綔鏃堕棿" style="width: 308px">
+            <el-date-picker
+              v-model="dateRange"
+              value-format="YYYY-MM-DD HH:mm:ss"
+              type="daterange"
+              range-separator="-"
+              start-placeholder="寮�濮嬫棩鏈�"
+              end-placeholder="缁撴潫鏃ユ湡"
+              :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
+            ></el-date-picker>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['monitor:operlog:remove']">
+              鍒犻櫎
+            </el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="WarnTriangleFilled" @click="handleClean" v-hasPermi="['monitor:operlog:remove']">娓呯┖</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['monitor:operlog:export']">瀵煎嚭</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table
+        ref="operLogTableRef"
+        v-loading="loading"
+        :data="operlogList"
+        @selection-change="handleSelectionChange"
+        :default-sort="defaultSort"
+        @sort-change="handleSortChange"
+      >
+        <el-table-column type="selection" width="50" align="center" />
+        <el-table-column label="鏃ュ織缂栧彿" align="center" prop="operId" />
+        <el-table-column label="绯荤粺妯″潡" align="center" prop="title" :show-overflow-tooltip="true" />
+        <el-table-column label="鎿嶄綔绫诲瀷" align="center" prop="businessType">
+          <template #default="scope">
+            <dict-tag :options="sys_oper_type" :value="scope.row.businessType" />
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="鎿嶄綔浜哄憳"
+          align="center"
+          width="110"
+          prop="operName"
+          :show-overflow-tooltip="true"
+          sortable="custom"
+          :sort-orders="['descending', 'ascending']"
+        />
+        <el-table-column label="涓绘満" align="center" prop="operIp" width="130" :show-overflow-tooltip="true" />
+        <el-table-column label="鎿嶄綔鐘舵��" align="center" prop="status">
+          <template #default="scope">
+            <dict-tag :options="sys_common_status" :value="scope.row.status" />
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔鏃ユ湡" align="center" prop="operTime" width="180" sortable="custom" :sort-orders="['descending', 'ascending']">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.operTime) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="娑堣�楁椂闂�"
+          align="center"
+          prop="costTime"
+          width="110"
+          :show-overflow-tooltip="true"
+          sortable="custom"
+          :sort-orders="['descending', 'ascending']"
+        >
+          <template #default="scope">
+            <span>{{ scope.row.costTime }}姣</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" fixed="right" align="center" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-tooltip content="璇︾粏" placement="top">
+              <el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['monitor:operlog:query']"> </el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+    </el-card>
+    <!-- 鎿嶄綔鏃ュ織璇︾粏 -->
+    <el-dialog title="鎿嶄綔鏃ュ織璇︾粏" v-model="dialog.visible" width="700px" append-to-body>
+      <el-form :model="form" label-width="100px">
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="鎿嶄綔妯″潡锛�">{{ form.title }} / {{ typeFormat(form) }}</el-form-item>
+            <el-form-item label="鐧诲綍淇℃伅锛�">{{ form.operName }} / {{ form.operIp }} / {{ form.operLocation }}</el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="璇锋眰鍦板潃锛�">{{ form.operUrl }}</el-form-item>
+            <el-form-item label="璇锋眰鏂瑰紡锛�">{{ form.requestMethod }}</el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="鎿嶄綔鏂规硶锛�">{{ form.method }}</el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="璇锋眰鍙傛暟锛�">{{form.operParam}}</el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="杩斿洖鍙傛暟锛�">{{ form.jsonResult }}</el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="鎿嶄綔鐘舵�侊細">
+              <div v-if="form.status === 0">姝e父</div>
+              <div v-else-if="form.status === 1">澶辫触</div>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="娑堣�楁椂闂达細">{{ form.costTime }}姣</el-form-item>
+          </el-col>
+          <el-col :span="10">
+            <el-form-item label="鎿嶄綔鏃堕棿锛�">{{ parseTime(form.operTime) }}</el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="寮傚父淇℃伅锛�" v-if="form.status === 1">{{ form.errorMsg }}</el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="dialog.visible = false">鍏� 闂�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
 <script setup name="Operlog" lang="ts">
 import { list, delOperlog, cleanOperlog } from '@/api/monitor/operlog';
 import { ComponentInternalInstance } from 'vue';
@@ -20,276 +185,112 @@
 const queryFormRef = ref(ElForm);
 
 const dialog = reactive<DialogOption>({
-  visible: false,
-  title: ''
+    visible: false,
+    title: ''
 });
 
 
 const data = reactive<PageData<OperLogForm, OperLogQuery>>({
-  form: {
-    operId: undefined,
-    tenantId: undefined,
-    title: '',
-    businessType: 0,
-    businessTypes: undefined,
-    method: '',
-    requestMethod: '',
-    operatorType: 0,
-    operName: '',
-    deptName: '',
-    operUrl: '',
-    operIp: '',
-    operLocation: '',
-    operParam: '',
-    jsonResult: '',
-    status: 0,
-    errorMsg: '',
-    operTime: '',
-    costTime: 0
-  },
-  queryParams: {
-    pageNum: 1,
-    pageSize: 10,
-    title: '',
-    operName: '',
-    businessType: '',
-    status: '',
-    orderByColumn: defaultSort.value.prop,
-    isAsc: defaultSort.value.order
-  },
-  rules: {}
+    form: {
+        operId: undefined,
+        tenantId: undefined,
+        title: '',
+        businessType: 0,
+        businessTypes: undefined,
+        method: '',
+        requestMethod: '',
+        operatorType: 0,
+        operName: '',
+        deptName: '',
+        operUrl: '',
+        operIp: '',
+        operLocation: '',
+        operParam: '',
+        jsonResult: '',
+        status: 0,
+        errorMsg: '',
+        operTime: '',
+        costTime: 0
+    },
+    queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        title: '',
+        operName: '',
+        businessType: '',
+        status: '',
+        orderByColumn: defaultSort.value.prop,
+        isAsc: defaultSort.value.order
+    },
+    rules: {}
 });
 
 const { queryParams, form } = toRefs(data);
 
 /** 鏌ヨ鐧诲綍鏃ュ織 */
 const getList = async () => {
-  loading.value = true;
-	const res = await list(proxy?.addDateRange(queryParams.value, dateRange.value));
-	operlogList.value = res.rows;
-	total.value = res.total;
-	loading.value = false;
+    loading.value = true;
+    const res = await list(proxy?.addDateRange(queryParams.value, dateRange.value));
+    operlogList.value = res.rows;
+    total.value = res.total;
+    loading.value = false;
 }
 /** 鎿嶄綔鏃ュ織绫诲瀷瀛楀吀缈昏瘧 */
 const typeFormat = (row: OperLogForm) => {
-  return proxy?.selectDictLabel(sys_oper_type.value, row.businessType);
+    return proxy?.selectDictLabel(sys_oper_type.value, row.businessType);
 }
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-  queryParams.value.pageNum = 1;
-  getList();
+    queryParams.value.pageNum = 1;
+    getList();
 }
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 const resetQuery = () => {
-  dateRange.value = ['', ''];
-  queryFormRef.value.resetFields();
-  queryParams.value.pageNum = 1;
-  operLogTableRef.value.sort(defaultSort.value.prop, defaultSort.value.order);
+    dateRange.value = ['', ''];
+    queryFormRef.value.resetFields();
+    queryParams.value.pageNum = 1;
+    operLogTableRef.value.sort(defaultSort.value.prop, defaultSort.value.order);
 }
 /** 澶氶�夋閫変腑鏁版嵁 */
 const handleSelectionChange = (selection: OperLogVO[]) => {
-  ids.value = selection.map(item => item.operId);
-  multiple.value = !selection.length;
+    ids.value = selection.map(item => item.operId);
+    multiple.value = !selection.length;
 }
 /** 鎺掑簭瑙﹀彂浜嬩欢 */
 const handleSortChange = (column: any) => {
-  queryParams.value.orderByColumn = column.prop;
-  queryParams.value.isAsc = column.order;
-  getList();
+    queryParams.value.orderByColumn = column.prop;
+    queryParams.value.isAsc = column.order;
+    getList();
 }
 /** 璇︾粏鎸夐挳鎿嶄綔 */
 const handleView = (row: OperLogVO) => {
-  dialog.visible = true;
-  form.value = row;
+    dialog.visible = true;
+    form.value = row;
 }
 /** 鍒犻櫎鎸夐挳鎿嶄綔 */
 const handleDelete = async (row?: OperLogVO) => {
-  const operIds = row?.operId || ids.value;
-	await proxy?.$modal.confirm('鏄惁纭鍒犻櫎鏃ュ織缂栧彿涓�"' + operIds + '"鐨勬暟鎹」?');
-	await delOperlog(operIds);
-	getList();
-	proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    const operIds = row?.operId || ids.value;
+    await proxy?.$modal.confirm('鏄惁纭鍒犻櫎鏃ュ織缂栧彿涓�"' + operIds + '"鐨勬暟鎹」?');
+    await delOperlog(operIds);
+    getList();
+    proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
 }
 
 /** 娓呯┖鎸夐挳鎿嶄綔 */
 const handleClean = async () => {
-	await proxy?.$modal.confirm("鏄惁纭娓呯┖鎵�鏈夋搷浣滄棩蹇楁暟鎹」?");
-	await cleanOperlog();
-	getList();
-	proxy?.$modal.msgSuccess("娓呯┖鎴愬姛");
+    await proxy?.$modal.confirm("鏄惁纭娓呯┖鎵�鏈夋搷浣滄棩蹇楁暟鎹」?");
+    await cleanOperlog();
+    getList();
+    proxy?.$modal.msgSuccess("娓呯┖鎴愬姛");
 }
 
 /** 瀵煎嚭鎸夐挳鎿嶄綔 */
 const handleExport = () => {
-  proxy?.download("monitor/operlog/export", {
-    ...queryParams.value,
-  }, `config_${new Date().getTime()}.xlsx`);
+    proxy?.download("monitor/operlog/export", {
+        ...queryParams.value,
+    }, `config_${new Date().getTime()}.xlsx`);
 }
 onMounted(() => {
-  getList();
+    getList();
 })
 </script>
-<template>
-	<div class="p-2">
-		<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-			<div class="search" v-show="showSearch">
-				<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
-					<el-form-item label="绯荤粺妯″潡" prop="title">
-						<el-input v-model="queryParams.title" placeholder="璇疯緭鍏ョ郴缁熸ā鍧�" clearable style="width: 240px;" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鎿嶄綔浜哄憳" prop="operName">
-						<el-input v-model="queryParams.operName" placeholder="璇疯緭鍏ユ搷浣滀汉鍛�" clearable style="width: 240px;" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="绫诲瀷" prop="businessType">
-						<el-select v-model="queryParams.businessType" placeholder="鎿嶄綔绫诲瀷" clearable style="width: 240px">
-							<el-option v-for="dict in sys_oper_type" :key="dict.value" :label="dict.label" :value="dict.value" />
-						</el-select>
-					</el-form-item>
-					<el-form-item label="鐘舵��" prop="status">
-						<el-select v-model="queryParams.status" placeholder="鎿嶄綔鐘舵��" clearable style="width: 240px">
-							<el-option v-for="dict in sys_common_status" :key="dict.value" :label="dict.label" :value="dict.value" />
-						</el-select>
-					</el-form-item>
-					<el-form-item label="鎿嶄綔鏃堕棿" style="width: 308px">
-						<el-date-picker
-							v-model="dateRange"
-							value-format="YYYY-MM-DD HH:mm:ss"
-							type="daterange"
-							range-separator="-"
-							start-placeholder="寮�濮嬫棩鏈�"
-							end-placeholder="缁撴潫鏃ユ湡"
-							:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
-						></el-date-picker>
-					</el-form-item>
-					<el-form-item>
-						<el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
-						<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-					</el-form-item>
-				</el-form>
-			</div>
-		</transition>
-
-		<el-card shadow="never">
-			<template #header>
-				<el-row :gutter="10" class="mb8">
-					<el-col :span="1.5">
-						<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['monitor:operlog:remove']">
-							鍒犻櫎
-						</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="danger" plain icon="WarnTriangleFilled" @click="handleClean" v-hasPermi="['monitor:operlog:remove']">娓呯┖</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['monitor:operlog:export']">瀵煎嚭</el-button>
-					</el-col>
-					<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-				</el-row>
-			</template>
-
-			<el-table
-				ref="operLogTableRef"
-				v-loading="loading"
-				:data="operlogList"
-				@selection-change="handleSelectionChange"
-				:default-sort="defaultSort"
-				@sort-change="handleSortChange"
-			>
-				<el-table-column type="selection" width="50" align="center" />
-				<el-table-column label="鏃ュ織缂栧彿" align="center" prop="operId" />
-				<el-table-column label="绯荤粺妯″潡" align="center" prop="title" :show-overflow-tooltip="true" />
-				<el-table-column label="鎿嶄綔绫诲瀷" align="center" prop="businessType">
-					<template #default="scope">
-						<dict-tag :options="sys_oper_type" :value="scope.row.businessType" />
-					</template>
-				</el-table-column>
-				<el-table-column
-					label="鎿嶄綔浜哄憳"
-					align="center"
-					width="110"
-					prop="operName"
-					:show-overflow-tooltip="true"
-					sortable="custom"
-					:sort-orders="['descending', 'ascending']"
-				/>
-				<el-table-column label="涓绘満" align="center" prop="operIp" width="130" :show-overflow-tooltip="true" />
-				<el-table-column label="鎿嶄綔鐘舵��" align="center" prop="status">
-					<template #default="scope">
-						<dict-tag :options="sys_common_status" :value="scope.row.status" />
-					</template>
-				</el-table-column>
-				<el-table-column label="鎿嶄綔鏃ユ湡" align="center" prop="operTime" width="180" sortable="custom" :sort-orders="['descending', 'ascending']">
-					<template #default="scope">
-						<span>{{ parseTime(scope.row.operTime) }}</span>
-					</template>
-				</el-table-column>
-				<el-table-column
-					label="娑堣�楁椂闂�"
-					align="center"
-					prop="costTime"
-					width="110"
-					:show-overflow-tooltip="true"
-					sortable="custom"
-					:sort-orders="['descending', 'ascending']"
-				>
-					<template #default="scope">
-						<span>{{ scope.row.costTime }}姣</span>
-					</template>
-				</el-table-column>
-				<el-table-column label="鎿嶄綔" fixed="right" align="center" class-name="small-padding fixed-width">
-					<template #default="scope">
-						<el-tooltip content="璇︾粏" placement="top">
-							<el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['monitor:operlog:query']"> </el-button>
-						</el-tooltip>
-					</template>
-				</el-table-column>
-			</el-table>
-
-			<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
-		</el-card>
-		<!-- 鎿嶄綔鏃ュ織璇︾粏 -->
-		<el-dialog title="鎿嶄綔鏃ュ織璇︾粏" v-model="dialog.visible" width="700px" append-to-body>
-			<el-form :model="form" label-width="100px">
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="鎿嶄綔妯″潡锛�">{{ form.title }} / {{ typeFormat(form) }}</el-form-item>
-						<el-form-item label="鐧诲綍淇℃伅锛�">{{ form.operName }} / {{ form.operIp }} / {{ form.operLocation }}</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="璇锋眰鍦板潃锛�">{{ form.operUrl }}</el-form-item>
-						<el-form-item label="璇锋眰鏂瑰紡锛�">{{ form.requestMethod }}</el-form-item>
-					</el-col>
-					<el-col :span="24">
-						<el-form-item label="鎿嶄綔鏂规硶锛�">{{ form.method }}</el-form-item>
-					</el-col>
-					<el-col :span="24">
-						<el-form-item label="璇锋眰鍙傛暟锛�">{{form.operParam}}</el-form-item>
-					</el-col>
-					<el-col :span="24">
-						<el-form-item label="杩斿洖鍙傛暟锛�">{{ form.jsonResult }}</el-form-item>
-					</el-col>
-					<el-col :span="6">
-						<el-form-item label="鎿嶄綔鐘舵�侊細">
-							<div v-if="form.status === 0">姝e父</div>
-							<div v-else-if="form.status === 1">澶辫触</div>
-						</el-form-item>
-					</el-col>
-					<el-col :span="8">
-						<el-form-item label="娑堣�楁椂闂达細">{{ form.costTime }}姣</el-form-item>
-					</el-col>
-					<el-col :span="10">
-						<el-form-item label="鎿嶄綔鏃堕棿锛�">{{ parseTime(form.operTime) }}</el-form-item>
-					</el-col>
-					<el-col :span="24">
-						<el-form-item label="寮傚父淇℃伅锛�" v-if="form.status === 1">{{ form.errorMsg }}</el-form-item>
-					</el-col>
-				</el-row>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button @click="dialog.visible = false">鍏� 闂�</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</div>
-</template>
diff --git a/src/views/monitor/xxljob/index.vue b/src/views/monitor/xxljob/index.vue
index d9e9e43..9349081 100644
--- a/src/views/monitor/xxljob/index.vue
+++ b/src/views/monitor/xxljob/index.vue
@@ -1,7 +1,7 @@
 <template>
-	<div>
-		<i-frame v-model:src="url"></i-frame>
-	</div>
+  <div>
+    <i-frame v-model:src="url"></i-frame>
+  </div>
 </template>
 
 <script setup lang="ts">
diff --git a/src/views/redirect/index.vue b/src/views/redirect/index.vue
index 48333ba..15401f8 100644
--- a/src/views/redirect/index.vue
+++ b/src/views/redirect/index.vue
@@ -1,5 +1,5 @@
 <template>
-	<div></div>
+  <div></div>
 </template>
 
 <script setup>
diff --git a/src/views/register.vue b/src/views/register.vue
index c1f0a0c..b80ce5d 100644
--- a/src/views/register.vue
+++ b/src/views/register.vue
@@ -1,3 +1,60 @@
+<template>
+  <div class="register">
+    <el-form ref="registerRef" :model="registerForm" :rules="registerRules" class="register-form">
+      <h3 class="title">RuoYi-Vue-Plus澶氱鎴风鐞嗙郴缁�</h3>
+      <el-form-item prop="tenantId" v-if="tenantEnabled">
+        <el-select v-model="registerForm.tenantId" filterable placeholder="璇烽�夋嫨/杈撳叆鍏徃鍚嶇О" style="width: 100%">
+          <el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId"> </el-option>
+          <template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template>
+        </el-select>
+      </el-form-item>
+      <el-form-item prop="username">
+        <el-input v-model="registerForm.username" type="text" size="large" auto-complete="off" placeholder="璐﹀彿">
+          <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
+        </el-input>
+      </el-form-item>
+      <el-form-item prop="password">
+        <el-input v-model="registerForm.password" type="password" size="large" auto-complete="off" placeholder="瀵嗙爜" @keyup.enter="handleRegister">
+          <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
+        </el-input>
+      </el-form-item>
+      <el-form-item prop="confirmPassword">
+        <el-input
+          v-model="registerForm.confirmPassword"
+          type="password"
+          size="large"
+          auto-complete="off"
+          placeholder="纭瀵嗙爜"
+          @keyup.enter="handleRegister"
+        >
+          <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
+        </el-input>
+      </el-form-item>
+      <el-form-item prop="code" v-if="captchaEnabled">
+        <el-input size="large" v-model="registerForm.code" auto-complete="off" placeholder="楠岃瘉鐮�" style="width: 63%" @keyup.enter="handleRegister">
+          <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
+        </el-input>
+        <div class="register-code">
+          <img :src="codeUrl" @click="getCode" class="register-code-img" />
+        </div>
+      </el-form-item>
+      <el-form-item style="width:100%;">
+        <el-button :loading="loading" size="large" type="primary" style="width:100%;" @click.prevent="handleRegister">
+          <span v-if="!loading">娉� 鍐�</span>
+          <span v-else>娉� 鍐� 涓�...</span>
+        </el-button>
+        <div style="float: right;">
+          <router-link class="link-type" :to="'/login'">浣跨敤宸叉湁璐︽埛鐧诲綍</router-link>
+        </div>
+      </el-form-item>
+    </el-form>
+    <!--  搴曢儴  -->
+    <div class="el-register-footer">
+      <span>Copyright 漏 2018-2023 鐤媯鐨勭嫯瀛怢i All Rights Reserved.</span>
+    </div>
+  </div>
+</template>
+
 <script setup lang="ts">
 import { getCodeImg, register, getTenantList } from '@/api/login';
 import { RegisterForm, TenantVO } from '@/api/types';
@@ -7,13 +64,13 @@
 const router = useRouter();
 
 const registerForm = ref<RegisterForm>({
-  tenantId: "",
-  username: "",
-  password: "",
-  confirmPassword: "",
-  code: "",
-  uuid: "",
-  userType: "sys_user"
+    tenantId: "",
+    username: "",
+    password: "",
+    confirmPassword: "",
+    code: "",
+    uuid: "",
+    userType: "sys_user"
 });
 
 // 绉熸埛寮�鍏�
@@ -21,30 +78,30 @@
 
 
 const equalToPassword = (rule: any, value: string, callback: any) => {
-  if (registerForm.value.password !== value) {
-    callback(new Error("涓ゆ杈撳叆鐨勫瘑鐮佷笉涓�鑷�"));
-  } else {
-    callback();
-  }
+    if (registerForm.value.password !== value) {
+        callback(new Error("涓ゆ杈撳叆鐨勫瘑鐮佷笉涓�鑷�"));
+    } else {
+        callback();
+    }
 };
 
 const registerRules: FormRules = {
-  tenantId: [
-    { required: true, trigger: "blur", message: "璇疯緭鍏ユ偍鐨勭鎴风紪鍙�" }
-  ],
-  username: [
-    { required: true, trigger: "blur", message: "璇疯緭鍏ユ偍鐨勮处鍙�" },
-    { min: 2, max: 20, message: "鐢ㄦ埛璐﹀彿闀垮害蹇呴』浠嬩簬 2 鍜� 20 涔嬮棿", trigger: "blur" }
-  ],
-  password: [
-    { required: true, trigger: "blur", message: "璇疯緭鍏ユ偍鐨勫瘑鐮�" },
-    { min: 5, max: 20, message: "鐢ㄦ埛瀵嗙爜闀垮害蹇呴』浠嬩簬 5 鍜� 20 涔嬮棿", trigger: "blur" }
-  ],
-  confirmPassword: [
-    { required: true, trigger: "blur", message: "璇峰啀娆¤緭鍏ユ偍鐨勫瘑鐮�" },
-    { required: true, validator: equalToPassword, trigger: "blur" }
-  ],
-  code: [{ required: true, trigger: "change", message: "璇疯緭鍏ラ獙璇佺爜" }]
+    tenantId: [
+        { required: true, trigger: "blur", message: "璇疯緭鍏ユ偍鐨勭鎴风紪鍙�" }
+    ],
+    username: [
+        { required: true, trigger: "blur", message: "璇疯緭鍏ユ偍鐨勮处鍙�" },
+        { min: 2, max: 20, message: "鐢ㄦ埛璐﹀彿闀垮害蹇呴』浠嬩簬 2 鍜� 20 涔嬮棿", trigger: "blur" }
+    ],
+    password: [
+        { required: true, trigger: "blur", message: "璇疯緭鍏ユ偍鐨勫瘑鐮�" },
+        { min: 5, max: 20, message: "鐢ㄦ埛瀵嗙爜闀垮害蹇呴』浠嬩簬 5 鍜� 20 涔嬮棿", trigger: "blur" }
+    ],
+    confirmPassword: [
+        { required: true, trigger: "blur", message: "璇峰啀娆¤緭鍏ユ偍鐨勫瘑鐮�" },
+        { required: true, validator: equalToPassword, trigger: "blur" }
+    ],
+    code: [{ required: true, trigger: "change", message: "璇疯緭鍏ラ獙璇佺爜" }]
 };
 const codeUrl = ref("");
 const loading = ref(false);
@@ -54,109 +111,52 @@
 const tenantList = ref<TenantVO[]>([]);
 
 const handleRegister = () => {
-  registerRef.value.validate(async (valid: boolean) => {
-    if (valid) {
-      loading.value = true;
-      const [err] = await to(register(registerForm.value));
-      if (!err) {
-        const username = registerForm.value.username;
-        await ElMessageBox.alert("<font color='red'>鎭枩浣狅紝鎮ㄧ殑璐﹀彿 " + username + " 娉ㄥ唽鎴愬姛锛�</font>", "绯荤粺鎻愮ず", {
-          dangerouslyUseHTMLString: true,
-          type: "success",
-        });
-        await router.push("/login");
-      } else {
-        loading.value = false;
-        if (captchaEnabled) {
-          getCode();
+    registerRef.value.validate(async (valid: boolean) => {
+        if (valid) {
+            loading.value = true;
+            const [err] = await to(register(registerForm.value));
+            if (!err) {
+                const username = registerForm.value.username;
+                await ElMessageBox.alert("<font color='red'>鎭枩浣狅紝鎮ㄧ殑璐﹀彿 " + username + " 娉ㄥ唽鎴愬姛锛�</font>", "绯荤粺鎻愮ず", {
+                    dangerouslyUseHTMLString: true,
+                    type: "success",
+                });
+                await router.push("/login");
+            } else {
+                loading.value = false;
+                if (captchaEnabled) {
+                    getCode();
+                }
+            }
         }
-      }
-    }
-  });
+    });
 }
 
 const getCode = async () => {
-  const { data } = await getCodeImg();
-  captchaEnabled.value = data.captchaEnabled === undefined ? true : data.captchaEnabled;
+    const { data } = await getCodeImg();
+    captchaEnabled.value = data.captchaEnabled === undefined ? true : data.captchaEnabled;
     if (captchaEnabled.value) {
-      codeUrl.value = "data:image/gif;base64," + data.img;
-      registerForm.value.uuid = data.uuid;
+        codeUrl.value = "data:image/gif;base64," + data.img;
+        registerForm.value.uuid = data.uuid;
     }
 }
 
 const initTenantList = async () => {
-  const { data } = await getTenantList();
+    const { data } = await getTenantList();
     tenantEnabled.value = data.tenantEnabled === undefined ? true : data.tenantEnabled;
     if (tenantEnabled.value) {
-      tenantList.value = data.voList;
-      if (tenantList.value != null && tenantList.value.length !== 0) {
-          registerForm.value.tenantId = tenantList.value[0].tenantId;
-      }
+        tenantList.value = data.voList;
+        if (tenantList.value != null && tenantList.value.length !== 0) {
+            registerForm.value.tenantId = tenantList.value[0].tenantId;
+        }
     }
 }
 
 onMounted(() => {
-  getCode();
-  initTenantList();
+    getCode();
+    initTenantList();
 })
 </script>
-
-<template>
-	<div class="register">
-		<el-form ref="registerRef" :model="registerForm" :rules="registerRules" class="register-form">
-			<h3 class="title">RuoYi-Vue-Plus澶氱鎴风鐞嗙郴缁�</h3>
-			<el-form-item prop="tenantId" v-if="tenantEnabled">
-				<el-select v-model="registerForm.tenantId" filterable placeholder="璇烽�夋嫨/杈撳叆鍏徃鍚嶇О" style="width: 100%">
-					<el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId"> </el-option>
-					<template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template>
-				</el-select>
-			</el-form-item>
-			<el-form-item prop="username">
-				<el-input v-model="registerForm.username" type="text" size="large" auto-complete="off" placeholder="璐﹀彿">
-					<template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
-				</el-input>
-			</el-form-item>
-			<el-form-item prop="password">
-				<el-input v-model="registerForm.password" type="password" size="large" auto-complete="off" placeholder="瀵嗙爜" @keyup.enter="handleRegister">
-					<template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
-				</el-input>
-			</el-form-item>
-			<el-form-item prop="confirmPassword">
-				<el-input
-					v-model="registerForm.confirmPassword"
-					type="password"
-					size="large"
-					auto-complete="off"
-					placeholder="纭瀵嗙爜"
-					@keyup.enter="handleRegister"
-				>
-					<template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
-				</el-input>
-			</el-form-item>
-			<el-form-item prop="code" v-if="captchaEnabled">
-				<el-input size="large" v-model="registerForm.code" auto-complete="off" placeholder="楠岃瘉鐮�" style="width: 63%" @keyup.enter="handleRegister">
-					<template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
-				</el-input>
-				<div class="register-code">
-					<img :src="codeUrl" @click="getCode" class="register-code-img" />
-				</div>
-			</el-form-item>
-			<el-form-item style="width:100%;">
-				<el-button :loading="loading" size="large" type="primary" style="width:100%;" @click.prevent="handleRegister">
-					<span v-if="!loading">娉� 鍐�</span>
-					<span v-else>娉� 鍐� 涓�...</span>
-				</el-button>
-				<div style="float: right;">
-					<router-link class="link-type" :to="'/login'">浣跨敤宸叉湁璐︽埛鐧诲綍</router-link>
-				</div>
-			</el-form-item>
-		</el-form>
-		<!--  搴曢儴  -->
-		<div class="el-register-footer">
-			<span>Copyright 漏 2018-2023 鐤媯鐨勭嫯瀛怢i All Rights Reserved.</span>
-		</div>
-	</div>
-</template>
 
 <style lang="scss" scoped>
 .register {
diff --git a/src/views/system/config/index.vue b/src/views/system/config/index.vue
index 09a0493..f461ecd 100644
--- a/src/views/system/config/index.vue
+++ b/src/views/system/config/index.vue
@@ -51,10 +51,10 @@
 /** 鏌ヨ鍙傛暟鍒楄〃 */
 const getList = async () => {
   loading.value = true;
-	const res = await listConfig(proxy?.addDateRange(queryParams.value, dateRange.value));
-	configList.value = res.rows;
-	total.value = res.total;
-	loading.value = false;
+  const res = await listConfig(proxy?.addDateRange(queryParams.value, dateRange.value));
+  configList.value = res.rows;
+  total.value = res.total;
+  loading.value = false;
 }
 /** 鍙栨秷鎸夐挳 */
 const cancel = () => {
@@ -63,7 +63,7 @@
 }
 /** 琛ㄥ崟閲嶇疆 */
 const reset = () => {
-	form.value = {...initFormData};
+  form.value = {...initFormData};
   configFormRef.value.resetFields();
 }
 /** 鎼滅储鎸夐挳鎿嶄綔 */
@@ -93,33 +93,33 @@
 }
 /** 淇敼鎸夐挳鎿嶄綔 */
 const handleUpdate = (row?: ConfigVO) => {
-	dialog.visible = true;
-	dialog.title = "淇敼鍙傛暟";
-	const configId = row?.configId || ids.value[0];
+  dialog.visible = true;
+  dialog.title = "淇敼鍙傛暟";
+  const configId = row?.configId || ids.value[0];
   nextTick(async () => {
-		reset();
-		const res = await getConfig(configId);
-		form.value = res.data;
-	})
+    reset();
+    const res = await getConfig(configId);
+    form.value = res.data;
+  })
 }
 /** 鎻愪氦鎸夐挳 */
 const submitForm = () => {
   configFormRef.value.validate(async (valid: boolean) => {
-		if (valid) {
-			form.value.configId ? await updateConfig(form.value) : await addConfig(form.value);
-			proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛");
-			dialog.visible = false;
-			getList();
+    if (valid) {
+      form.value.configId ? await updateConfig(form.value) : await addConfig(form.value);
+      proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛");
+      dialog.visible = false;
+      getList();
     }
   });
 }
 /** 鍒犻櫎鎸夐挳鎿嶄綔 */
 const handleDelete = async (row?: ConfigVO) => {
   const configIds = row?.configId || ids.value;
-	await proxy?.$modal.confirm('鏄惁纭鍒犻櫎鍙傛暟缂栧彿涓�"' + configIds + '"鐨勬暟鎹」锛�');
-	await delConfig(configIds);
-	getList();
-	proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+  await proxy?.$modal.confirm('鏄惁纭鍒犻櫎鍙傛暟缂栧彿涓�"' + configIds + '"鐨勬暟鎹」锛�');
+  await delConfig(configIds);
+  getList();
+  proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
 }
 /** 瀵煎嚭鎸夐挳鎿嶄綔 */
 const handleExport = () => {
@@ -129,133 +129,133 @@
 }
 /** 鍒锋柊缂撳瓨鎸夐挳鎿嶄綔 */
 const handleRefreshCache = async () => {
-	await refreshCache();
-	proxy?.$modal.msgSuccess("鍒锋柊缂撳瓨鎴愬姛");
+  await refreshCache();
+  proxy?.$modal.msgSuccess("鍒锋柊缂撳瓨鎴愬姛");
 }
 
 onMounted(() => {
-	getList();
+  getList();
 })
 </script>
 
 <template>
-	<div class="p-2">
-		<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-			<div class="search" v-show="showSearch">
-				<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
-					<el-form-item label="鍙傛暟鍚嶇О" prop="configName">
-						<el-input v-model="queryParams.configName" placeholder="璇疯緭鍏ュ弬鏁板悕绉�" clearable style="width: 240px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鍙傛暟閿悕" prop="configKey">
-						<el-input v-model="queryParams.configKey" placeholder="璇疯緭鍏ュ弬鏁伴敭鍚�" clearable style="width: 240px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="绯荤粺鍐呯疆" prop="configType">
-						<el-select v-model="queryParams.configType" placeholder="绯荤粺鍐呯疆" clearable>
-							<el-option v-for="dict in sys_yes_no" :key="dict.value" :label="dict.label" :value="dict.value" />
-						</el-select>
-					</el-form-item>
-					<el-form-item label="鍒涘缓鏃堕棿" style="width: 308px;">
-						<el-date-picker
-							v-model="dateRange"
-							value-format="YYYY-MM-DD HH:mm:ss"
-							type="daterange"
-							range-separator="-"
-							start-placeholder="寮�濮嬫棩鏈�"
-							end-placeholder="缁撴潫鏃ユ湡"
-							:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
-						></el-date-picker>
-					</el-form-item>
-					<el-form-item>
-						<el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
-						<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-					</el-form-item>
-				</el-form>
-			</div>
-		</transition>
-		<el-card shadow="never">
-			<template #header>
-				<el-row :gutter="10" class="mb8">
-					<el-col :span="1.5">
-						<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:config:add']">鏂板</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:config:edit']">
-							淇敼
-						</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:config:remove']">
-							鍒犻櫎
-						</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:config:export']">瀵煎嚭</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="danger" plain icon="Refresh" @click="handleRefreshCache" v-hasPermi="['system:config:remove']">鍒锋柊缂撳瓨</el-button>
-					</el-col>
-					<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-				</el-row>
-			</template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+          <el-form-item label="鍙傛暟鍚嶇О" prop="configName">
+            <el-input v-model="queryParams.configName" placeholder="璇疯緭鍏ュ弬鏁板悕绉�" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鍙傛暟閿悕" prop="configKey">
+            <el-input v-model="queryParams.configKey" placeholder="璇疯緭鍏ュ弬鏁伴敭鍚�" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="绯荤粺鍐呯疆" prop="configType">
+            <el-select v-model="queryParams.configType" placeholder="绯荤粺鍐呯疆" clearable>
+              <el-option v-for="dict in sys_yes_no" :key="dict.value" :label="dict.label" :value="dict.value" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="鍒涘缓鏃堕棿" style="width: 308px;">
+            <el-date-picker
+              v-model="dateRange"
+              value-format="YYYY-MM-DD HH:mm:ss"
+              type="daterange"
+              range-separator="-"
+              start-placeholder="寮�濮嬫棩鏈�"
+              end-placeholder="缁撴潫鏃ユ湡"
+              :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
+            ></el-date-picker>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:config:add']">鏂板</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:config:edit']">
+              淇敼
+            </el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:config:remove']">
+              鍒犻櫎
+            </el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:config:export']">瀵煎嚭</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Refresh" @click="handleRefreshCache" v-hasPermi="['system:config:remove']">鍒锋柊缂撳瓨</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
 
-			<el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange">
-				<el-table-column type="selection" width="55" align="center" />
-				<el-table-column label="鍙傛暟涓婚敭" align="center" prop="configId" v-if="false" />
-				<el-table-column label="鍙傛暟鍚嶇О" align="center" prop="configName" :show-overflow-tooltip="true" />
-				<el-table-column label="鍙傛暟閿悕" align="center" prop="configKey" :show-overflow-tooltip="true" />
-				<el-table-column label="鍙傛暟閿��" align="center" prop="configValue" :show-overflow-tooltip="true" />
-				<el-table-column label="绯荤粺鍐呯疆" align="center" prop="configType">
-					<template #default="scope">
-						<dict-tag :options="sys_yes_no" :value="scope.row.configType" />
-					</template>
-				</el-table-column>
-				<el-table-column label="澶囨敞" align="center" prop="remark" :show-overflow-tooltip="true" />
-				<el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180">
-					<template #default="scope">
-						<span>{{ parseTime(scope.row.createTime) }}</span>
-					</template>
-				</el-table-column>
-				<el-table-column label="鎿嶄綔" align="center" width="150" class-name="small-padding fixed-width">
-					<template #default="scope">
-						<el-tooltip content="淇敼" placement="top">
-							<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:config:edit']"></el-button>
-						</el-tooltip>
-						<el-tooltip content="鍒犻櫎" placement="top">
-							<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:config:remove']"></el-button>
-						</el-tooltip>
-					</template>
-				</el-table-column>
-			</el-table>
-			<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
-		</el-card>
+      <el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="鍙傛暟涓婚敭" align="center" prop="configId" v-if="false" />
+        <el-table-column label="鍙傛暟鍚嶇О" align="center" prop="configName" :show-overflow-tooltip="true" />
+        <el-table-column label="鍙傛暟閿悕" align="center" prop="configKey" :show-overflow-tooltip="true" />
+        <el-table-column label="鍙傛暟閿��" align="center" prop="configValue" :show-overflow-tooltip="true" />
+        <el-table-column label="绯荤粺鍐呯疆" align="center" prop="configType">
+          <template #default="scope">
+            <dict-tag :options="sys_yes_no" :value="scope.row.configType" />
+          </template>
+        </el-table-column>
+        <el-table-column label="澶囨敞" align="center" prop="remark" :show-overflow-tooltip="true" />
+        <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.createTime) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" align="center" width="150" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-tooltip content="淇敼" placement="top">
+              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:config:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="鍒犻櫎" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:config:remove']"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+    </el-card>
 
-		<!-- 娣诲姞鎴栦慨鏀瑰弬鏁伴厤缃璇濇 -->
-		<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
-			<el-form ref="configFormRef" :model="form" :rules="rules" label-width="80px">
-				<el-form-item label="鍙傛暟鍚嶇О" prop="configName">
-					<el-input v-model="form.configName" placeholder="璇疯緭鍏ュ弬鏁板悕绉�" />
-				</el-form-item>
-				<el-form-item label="鍙傛暟閿悕" prop="configKey">
-					<el-input v-model="form.configKey" placeholder="璇疯緭鍏ュ弬鏁伴敭鍚�" />
-				</el-form-item>
-				<el-form-item label="鍙傛暟閿��" prop="configValue">
-					<el-input v-model="form.configValue" placeholder="璇疯緭鍏ュ弬鏁伴敭鍊�" />
-				</el-form-item>
-				<el-form-item label="绯荤粺鍐呯疆" prop="configType">
-					<el-radio-group v-model="form.configType">
-						<el-radio v-for="dict in sys_yes_no" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
-					</el-radio-group>
-				</el-form-item>
-				<el-form-item label="澶囨敞" prop="remark">
-					<el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" />
-				</el-form-item>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
-					<el-button @click="cancel">鍙� 娑�</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</div>
+    <!-- 娣诲姞鎴栦慨鏀瑰弬鏁伴厤缃璇濇 -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
+      <el-form ref="configFormRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="鍙傛暟鍚嶇О" prop="configName">
+          <el-input v-model="form.configName" placeholder="璇疯緭鍏ュ弬鏁板悕绉�" />
+        </el-form-item>
+        <el-form-item label="鍙傛暟閿悕" prop="configKey">
+          <el-input v-model="form.configKey" placeholder="璇疯緭鍏ュ弬鏁伴敭鍚�" />
+        </el-form-item>
+        <el-form-item label="鍙傛暟閿��" prop="configValue">
+          <el-input v-model="form.configValue" placeholder="璇疯緭鍏ュ弬鏁伴敭鍊�" />
+        </el-form-item>
+        <el-form-item label="绯荤粺鍐呯疆" prop="configType">
+          <el-radio-group v-model="form.configType">
+            <el-radio v-for="dict in sys_yes_no" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
 </template>
diff --git a/src/views/system/dept/index.vue b/src/views/system/dept/index.vue
index b560d5f..2f45839 100644
--- a/src/views/system/dept/index.vue
+++ b/src/views/system/dept/index.vue
@@ -1,12 +1,142 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="68px">
+          <el-form-item label="鑿滃崟鍚嶇О" prop="menuName">
+            <el-input v-model="queryParams.deptName" placeholder="璇疯緭鍏ラ儴闂ㄥ悕绉�" clearable @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鐘舵��" prop="status">
+            <el-select v-model="queryParams.status" placeholder="閮ㄩ棬鐘舵��" clearable>
+              <el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['system:dept:add']">鏂板 </el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">灞曞紑/鎶樺彔</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table
+        v-loading="loading"
+        :data="deptList"
+        row-key="deptId"
+        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
+        ref="deptTableRef"
+        :default-expand-all="isExpandAll"
+      >
+        <el-table-column prop="deptName" label="閮ㄩ棬鍚嶇О" width="260"></el-table-column>
+        <el-table-column prop="orderNum" align="center" label="鎺掑簭" width="200"></el-table-column>
+        <el-table-column prop="status" align="center" label="鐘舵��" width="100">
+          <template #default="scope">
+            <dict-tag :options="sys_normal_disable" :value="scope.row.status" />
+          </template>
+        </el-table-column>
+        <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="200">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.createTime) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column fixed="right" align="center" label="鎿嶄綔">
+          <template #default="scope">
+            <el-tooltip content="淇敼" placement="top">
+              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dept:edit']" />
+            </el-tooltip>
+            <el-tooltip content="鏂板" placement="top">
+              <el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['system:dept:add']" />
+            </el-tooltip>
+            <el-tooltip content="鍒犻櫎" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dept:remove']" />
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+
+    <el-dialog :title="dialog.title" v-model="dialog.visible" destroy-on-close append-to-bod width="600px">
+      <el-form ref="deptFormRef" :model="form" :rules="rules" label-width="80px">
+        <el-row>
+          <el-col :span="24" v-if="form.parentId !== 0">
+            <el-form-item label="涓婄骇閮ㄩ棬" prop="parentId">
+              <el-tree-select
+                v-model="form.parentId"
+                :data="deptOptions"
+                :props="{ value: 'deptId', label: 'deptName', children: 'children' }"
+                value-key="deptId"
+                placeholder="閫夋嫨涓婄骇閮ㄩ棬"
+                check-strictly
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="閮ㄩ棬鍚嶇О" prop="deptName">
+              <el-input v-model="form.deptName" placeholder="璇疯緭鍏ラ儴闂ㄥ悕绉�" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鏄剧ず鎺掑簭" prop="orderNum">
+              <el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="璐熻矗浜�" prop="leader">
+              <el-input v-model="form.leader" placeholder="璇疯緭鍏ヨ礋璐d汉" maxlength="20" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鑱旂郴鐢佃瘽" prop="phone">
+              <el-input v-model="form.phone" placeholder="璇疯緭鍏ヨ仈绯荤數璇�" maxlength="11" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="閭" prop="email">
+              <el-input v-model="form.email" placeholder="璇疯緭鍏ラ偖绠�" maxlength="50" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="閮ㄩ棬鐘舵��">
+              <el-radio-group v-model="form.status">
+                <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label
+                }}</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
 <script setup name="Dept" lang="ts">
 import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild } from "@/api/system/dept"
 import { ComponentInternalInstance } from 'vue';
 import { DeptForm, DeptQuery, DeptVO } from "@/api/system/dept/types";
 
 interface DeptOptionsType {
-  deptId: number | string;
-  deptName: string;
-  children: DeptOptionsType[];
+    deptId: number | string;
+    deptName: string;
+    children: DeptOptionsType[];
 
 }
 
@@ -21,8 +151,8 @@
 
 
 const dialog = reactive<DialogOption>({
-  visible: false,
-  title: ''
+    visible: false,
+    title: ''
 });
 
 const deptTableRef = ref(ElTable);
@@ -30,263 +160,133 @@
 const deptFormRef = ref(ElForm);
 
 const initFormData: DeptForm = {
-  deptId: undefined,
-  parentId: undefined,
-  deptName: undefined,
-  orderNum: 0,
-  leader: undefined,
-  phone: undefined,
-  email: undefined,
-  status: "0"
+    deptId: undefined,
+    parentId: undefined,
+    deptName: undefined,
+    orderNum: 0,
+    leader: undefined,
+    phone: undefined,
+    email: undefined,
+    status: "0"
 }
 const data = reactive<PageData<DeptForm, DeptQuery>>({
-  form: {...initFormData},
-  queryParams: {
-    pageNum: 1,
-    pageSize: 10,
-    deptName: undefined,
-    status: undefined
-  },
-  rules: {
-    parentId: [{ required: true, message: "涓婄骇閮ㄩ棬涓嶈兘涓虹┖", trigger: "blur" }],
-    deptName: [{ required: true, message: "閮ㄩ棬鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }],
-    orderNum: [{ required: true, message: "鏄剧ず鎺掑簭涓嶈兘涓虹┖", trigger: "blur" }],
-    email: [{ type: "email", message: "璇疯緭鍏ユ纭殑閭鍦板潃", trigger: ["blur", "change"] }],
-    phone: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "璇疯緭鍏ユ纭殑鎵嬫満鍙风爜", trigger: "blur" }]
-  },
+    form: {...initFormData},
+    queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        deptName: undefined,
+        status: undefined
+    },
+    rules: {
+        parentId: [{ required: true, message: "涓婄骇閮ㄩ棬涓嶈兘涓虹┖", trigger: "blur" }],
+        deptName: [{ required: true, message: "閮ㄩ棬鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }],
+        orderNum: [{ required: true, message: "鏄剧ず鎺掑簭涓嶈兘涓虹┖", trigger: "blur" }],
+        email: [{ type: "email", message: "璇疯緭鍏ユ纭殑閭鍦板潃", trigger: ["blur", "change"] }],
+        phone: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "璇疯緭鍏ユ纭殑鎵嬫満鍙风爜", trigger: "blur" }]
+    },
 })
 
 const { queryParams, form, rules } = toRefs<PageData<DeptForm, DeptQuery>>(data)
 
 /** 鏌ヨ鑿滃崟鍒楄〃 */
 const getList = async () => {
-	loading.value = true;
-  const res = await listDept(queryParams.value);
-	const data = proxy?.handleTree<DeptVO>(res.data, "deptId")
-	if (data) {
-		deptList.value = data
-	}
-	loading.value = false
+    loading.value = true;
+    const res = await listDept(queryParams.value);
+    const data = proxy?.handleTree<DeptVO>(res.data, "deptId")
+    if (data) {
+        deptList.value = data
+    }
+    loading.value = false
 }
 /** 鍙栨秷鎸夐挳 */
 const cancel = () => {
-  reset()
-  dialog.visible = false
+    reset()
+    dialog.visible = false
 }
 /** 琛ㄥ崟閲嶇疆 */
 const reset = () => {
-  form.value = {...initFormData};
-  deptFormRef.value.resetFields();
+    form.value = {...initFormData};
+    deptFormRef.value.resetFields();
 }
 
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-  getList();
+    getList();
 }
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 const resetQuery = () => {
-  queryFormRef.value.resetFields();
-  handleQuery()
+    queryFormRef.value.resetFields();
+    handleQuery()
 }
 /** 鏂板鎸夐挳鎿嶄綔 */
 const handleAdd = (row?: DeptVO) => {
-  listDept().then(res => {
-    const data = proxy?.handleTree<DeptOptionsType>(res.data, "deptId");
-    if (data) {
-      deptOptions.value = data
-      dialog.visible = true;
-      dialog.title = "娣诲姞閮ㄩ棬";
-      nextTick(() => {
-        reset();
-        if (row && row.deptId) {
-          form.value.parentId = row?.parentId;
+    listDept().then(res => {
+        const data = proxy?.handleTree<DeptOptionsType>(res.data, "deptId");
+        if (data) {
+            deptOptions.value = data
+            dialog.visible = true;
+            dialog.title = "娣诲姞閮ㄩ棬";
+            nextTick(() => {
+                reset();
+                if (row && row.deptId) {
+                    form.value.parentId = row?.parentId;
+                }
+            })
         }
-      })
-    }
-  })
+    })
 }
 /** 灞曞紑/鎶樺彔鎿嶄綔 */
 const handleToggleExpandAll = () => {
-  isExpandAll.value = !isExpandAll.value;
-  toggleExpandAll(deptList.value, isExpandAll.value)
+    isExpandAll.value = !isExpandAll.value;
+    toggleExpandAll(deptList.value, isExpandAll.value)
 }
 /** 灞曞紑/鎶樺彔鎵�鏈� */
 const toggleExpandAll = (data: DeptVO[], status: boolean) => {
-  data.forEach((item) => {
-    deptTableRef.value.toggleRowExpansion(item, status)
-    if(item.children && item.children.length > 0) toggleExpandAll(item.children, status)
-  })
+    data.forEach((item) => {
+        deptTableRef.value.toggleRowExpansion(item, status)
+        if(item.children && item.children.length > 0) toggleExpandAll(item.children, status)
+    })
 }
 
 /** 淇敼鎸夐挳鎿嶄綔 */
 const handleUpdate = async (row: DeptVO) => {
-	const res = await getDept(row.deptId);
-	dialog.visible = true;
-	dialog.title = "淇敼閮ㄩ棬";
-	nextTick(async () => {
-		reset();
-		form.value = res.data
-		const response = await listDeptExcludeChild(row.deptId);
-		const data = proxy?.handleTree<DeptOptionsType>(response.data, "deptId")
-		if (data) {
-			deptOptions.value = data;
-			if (data.length === 0) {
-				const noResultsOptions: DeptOptionsType = { deptId: res.data.parentId, deptName: res.data.parentName, children: [] };
-				deptOptions.value.push(noResultsOptions);
-			}
-		}
-	})
+    const res = await getDept(row.deptId);
+    dialog.visible = true;
+    dialog.title = "淇敼閮ㄩ棬";
+    nextTick(async () => {
+        reset();
+        form.value = res.data
+        const response = await listDeptExcludeChild(row.deptId);
+        const data = proxy?.handleTree<DeptOptionsType>(response.data, "deptId")
+        if (data) {
+            deptOptions.value = data;
+            if (data.length === 0) {
+                const noResultsOptions: DeptOptionsType = { deptId: res.data.parentId, deptName: res.data.parentName, children: [] };
+                deptOptions.value.push(noResultsOptions);
+            }
+        }
+    })
 }
 /** 鎻愪氦鎸夐挳 */
 const submitForm = () => {
-  deptFormRef.value.validate(async (valid: boolean) => {
-		if (valid) {
-			form.value.deptId ? await updateDept(form.value) : await addDept(form.value);
-			proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛");
-			dialog.visible = false;
-			getList();
-    }
-  })
+    deptFormRef.value.validate(async (valid: boolean) => {
+        if (valid) {
+            form.value.deptId ? await updateDept(form.value) : await addDept(form.value);
+            proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛");
+            dialog.visible = false;
+            getList();
+        }
+    })
 }
 /** 鍒犻櫎鎸夐挳鎿嶄綔 */
 const handleDelete = async (row: DeptVO) => {
-	await proxy?.$modal.confirm('鏄惁纭鍒犻櫎鍚嶇О涓�"' + row.deptName + '"鐨勬暟鎹」?');
-	await delDept(row.deptId);
-	getList();
-	proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    await proxy?.$modal.confirm('鏄惁纭鍒犻櫎鍚嶇О涓�"' + row.deptName + '"鐨勬暟鎹」?');
+    await delDept(row.deptId);
+    getList();
+    proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
 }
 
 onMounted(() => {
-  getList();
+    getList();
 });
 </script>
-
-<template>
-	<div class="p-2">
-		<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-			<div class="search" v-show="showSearch">
-				<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="68px">
-					<el-form-item label="鑿滃崟鍚嶇О" prop="menuName">
-						<el-input v-model="queryParams.deptName" placeholder="璇疯緭鍏ラ儴闂ㄥ悕绉�" clearable @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鐘舵��" prop="status">
-						<el-select v-model="queryParams.status" placeholder="閮ㄩ棬鐘舵��" clearable>
-							<el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
-						</el-select>
-					</el-form-item>
-					<el-form-item>
-						<el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
-						<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-					</el-form-item>
-				</el-form>
-			</div>
-		</transition>
-
-		<el-card shadow="never">
-			<template #header>
-				<el-row :gutter="10">
-					<el-col :span="1.5">
-						<el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['system:dept:add']">鏂板 </el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">灞曞紑/鎶樺彔</el-button>
-					</el-col>
-					<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-				</el-row>
-			</template>
-
-			<el-table
-				v-loading="loading"
-				:data="deptList"
-				row-key="deptId"
-				:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
-				ref="deptTableRef"
-				:default-expand-all="isExpandAll"
-			>
-				<el-table-column prop="deptName" label="閮ㄩ棬鍚嶇О" width="260"></el-table-column>
-				<el-table-column prop="orderNum" align="center" label="鎺掑簭" width="200"></el-table-column>
-				<el-table-column prop="status" align="center" label="鐘舵��" width="100">
-					<template #default="scope">
-						<dict-tag :options="sys_normal_disable" :value="scope.row.status" />
-					</template>
-				</el-table-column>
-				<el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="200">
-					<template #default="scope">
-						<span>{{ parseTime(scope.row.createTime) }}</span>
-					</template>
-				</el-table-column>
-				<el-table-column fixed="right" align="center" label="鎿嶄綔">
-					<template #default="scope">
-						<el-tooltip content="淇敼" placement="top">
-							<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dept:edit']" />
-						</el-tooltip>
-						<el-tooltip content="鏂板" placement="top">
-							<el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['system:dept:add']" />
-						</el-tooltip>
-						<el-tooltip content="鍒犻櫎" placement="top">
-							<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dept:remove']" />
-						</el-tooltip>
-					</template>
-				</el-table-column>
-			</el-table>
-		</el-card>
-
-		<el-dialog :title="dialog.title" v-model="dialog.visible" destroy-on-close append-to-bod width="600px">
-			<el-form ref="deptFormRef" :model="form" :rules="rules" label-width="80px">
-				<el-row>
-					<el-col :span="24" v-if="form.parentId !== 0">
-						<el-form-item label="涓婄骇閮ㄩ棬" prop="parentId">
-							<el-tree-select
-								v-model="form.parentId"
-								:data="deptOptions"
-								:props="{ value: 'deptId', label: 'deptName', children: 'children' }"
-								value-key="deptId"
-								placeholder="閫夋嫨涓婄骇閮ㄩ棬"
-								check-strictly
-							/>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="閮ㄩ棬鍚嶇О" prop="deptName">
-							<el-input v-model="form.deptName" placeholder="璇疯緭鍏ラ儴闂ㄥ悕绉�" />
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="鏄剧ず鎺掑簭" prop="orderNum">
-							<el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="璐熻矗浜�" prop="leader">
-							<el-input v-model="form.leader" placeholder="璇疯緭鍏ヨ礋璐d汉" maxlength="20" />
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="鑱旂郴鐢佃瘽" prop="phone">
-							<el-input v-model="form.phone" placeholder="璇疯緭鍏ヨ仈绯荤數璇�" maxlength="11" />
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="閭" prop="email">
-							<el-input v-model="form.email" placeholder="璇疯緭鍏ラ偖绠�" maxlength="50" />
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="閮ㄩ棬鐘舵��">
-							<el-radio-group v-model="form.status">
-								<el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label
-								}}</el-radio>
-							</el-radio-group>
-						</el-form-item>
-					</el-col>
-				</el-row>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
-					<el-button @click="cancel">鍙� 娑�</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</div>
-</template>
diff --git a/src/views/system/dict/data.vue b/src/views/system/dict/data.vue
index f5c2dbe..2b26493 100644
--- a/src/views/system/dict/data.vue
+++ b/src/views/system/dict/data.vue
@@ -1,3 +1,136 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+          <el-form-item label="瀛楀吀鍚嶇О" prop="dictType">
+            <el-select v-model="queryParams.dictType" style="width: 200px">
+              <el-option v-for="item in typeOptions" :key="item.dictId" :label="item.dictName" :value="item.dictType" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="瀛楀吀鏍囩" prop="dictLabel">
+            <el-input v-model="queryParams.dictLabel" placeholder="璇疯緭鍏ュ瓧鍏告爣绛�" clearable style="width: 200px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鐘舵��" prop="status">
+            <el-select v-model="queryParams.status" placeholder="鏁版嵁鐘舵��" clearable style="width: 200px">
+              <el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:dict:add']">鏂板</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:dict:edit']">淇敼</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:dict:remove']">
+              鍒犻櫎
+            </el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:dict:export']">瀵煎嚭</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Close" @click="handleClose">鍏抽棴</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="瀛楀吀缂栫爜" align="center" prop="dictCode" v-if="false" />
+        <el-table-column label="瀛楀吀鏍囩" align="center" prop="dictLabel">
+          <template #default="scope">
+            <span v-if="scope.row.listClass === '' || scope.row.listClass === 'default'">{{ scope.row.dictLabel }}</span>
+            <el-tag v-else :type="scope.row.listClass === 'primary' ? '' : scope.row.listClass">{{ scope.row.dictLabel
+            }}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="瀛楀吀閿��" align="center" prop="dictValue" />
+        <el-table-column label="瀛楀吀鎺掑簭" align="center" prop="dictSort" />
+        <el-table-column label="鐘舵��" align="center" prop="status">
+          <template #default="scope">
+            <dict-tag :options="sys_normal_disable" :value="scope.row.status" />
+          </template>
+        </el-table-column>
+        <el-table-column label="澶囨敞" align="center" prop="remark" :show-overflow-tooltip="true" />
+        <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.createTime) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" align="center" width="160" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-tooltip content="淇敼" placement="top">
+              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dict:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="鍒犻櫎" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dict:remove']"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+    </el-card>
+    <!-- 娣诲姞鎴栦慨鏀瑰弬鏁伴厤缃璇濇 -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
+      <el-form ref="dataFormRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="瀛楀吀绫诲瀷">
+          <el-input v-model="form.dictType" :disabled="true" />
+        </el-form-item>
+        <el-form-item label="鏁版嵁鏍囩" prop="dictLabel">
+          <el-input v-model="form.dictLabel" placeholder="璇疯緭鍏ユ暟鎹爣绛�" />
+        </el-form-item>
+        <el-form-item label="鏁版嵁閿��" prop="dictValue">
+          <el-input v-model="form.dictValue" placeholder="璇疯緭鍏ユ暟鎹敭鍊�" />
+        </el-form-item>
+        <el-form-item label="鏍峰紡灞炴��" prop="cssClass">
+          <el-input v-model="form.cssClass" placeholder="璇疯緭鍏ユ牱寮忓睘鎬�" />
+        </el-form-item>
+        <el-form-item label="鏄剧ず鎺掑簭" prop="dictSort">
+          <el-input-number v-model="form.dictSort" controls-position="right" :min="0" />
+        </el-form-item>
+        <el-form-item label="鍥炴樉鏍峰紡" prop="listClass">
+          <el-select v-model="form.listClass">
+            <el-option
+              v-for="item in listClassOptions"
+              :key="item.value"
+              :label="item.label + '(' + item.value + ')'"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鐘舵��" prop="status">
+          <el-radio-group v-model="form.status">
+            <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�"></el-input>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
 <script setup name="Data" lang="ts">
 import useDictStore from '@/store/modules/dict'
 import { optionselect as getDictOptionselect, getType } from "@/api/system/dict/type";
@@ -26,287 +159,154 @@
 
 
 const dialog = reactive<DialogOption>({
-	visible: false,
-	title: ''
+    visible: false,
+    title: ''
 });
 
 // 鏁版嵁鏍囩鍥炴樉鏍峰紡
 const listClassOptions = ref<Array<{ value: string, label: string }>>([
-	{ value: "default", label: "榛樿" },
-	{ value: "primary", label: "涓昏" },
-	{ value: "success", label: "鎴愬姛" },
-	{ value: "info", label: "淇℃伅" },
-	{ value: "warning", label: "璀﹀憡" },
-	{ value: "danger", label: "鍗遍櫓" }
+    { value: "default", label: "榛樿" },
+    { value: "primary", label: "涓昏" },
+    { value: "success", label: "鎴愬姛" },
+    { value: "info", label: "淇℃伅" },
+    { value: "warning", label: "璀﹀憡" },
+    { value: "danger", label: "鍗遍櫓" }
 ]);
 
 const initFormData: DictDataForm = {
-	dictCode: undefined,
-	dictLabel: '',
-	dictValue: '',
-	cssClass: '',
-	listClass: "default",
-	dictSort: 0,
-	status: "0",
-	remark: ''
+    dictCode: undefined,
+    dictLabel: '',
+    dictValue: '',
+    cssClass: '',
+    listClass: "default",
+    dictSort: 0,
+    status: "0",
+    remark: ''
 }
 const data = reactive<PageData<DictDataForm, DictDataQuery>>({
-	form: { ...initFormData },
-	queryParams: {
-		pageNum: 1,
-		pageSize: 10,
-		dictName: '',
-		dictType: '',
-		status: '',
-		dictLabel: ''
-	},
-	rules: {
-		dictLabel: [{ required: true, message: "鏁版嵁鏍囩涓嶈兘涓虹┖", trigger: "blur" }],
-		dictValue: [{ required: true, message: "鏁版嵁閿�间笉鑳戒负绌�", trigger: "blur" }],
-		dictSort: [{ required: true, message: "鏁版嵁椤哄簭涓嶈兘涓虹┖", trigger: "blur" }]
-	}
+    form: { ...initFormData },
+    queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        dictName: '',
+        dictType: '',
+        status: '',
+        dictLabel: ''
+    },
+    rules: {
+        dictLabel: [{ required: true, message: "鏁版嵁鏍囩涓嶈兘涓虹┖", trigger: "blur" }],
+        dictValue: [{ required: true, message: "鏁版嵁閿�间笉鑳戒负绌�", trigger: "blur" }],
+        dictSort: [{ required: true, message: "鏁版嵁椤哄簭涓嶈兘涓虹┖", trigger: "blur" }]
+    }
 });
 
 const { queryParams, form, rules } = toRefs(data);
 
 /** 鏌ヨ瀛楀吀绫诲瀷璇︾粏 */
 const getTypes = async (dictId: string | number) => {
-	const { data } = await getType(dictId);
-	queryParams.value.dictType = data.dictType;
-	defaultDictType.value = data.dictType;
-	getList();
+    const { data } = await getType(dictId);
+    queryParams.value.dictType = data.dictType;
+    defaultDictType.value = data.dictType;
+    getList();
 }
 
 /** 鏌ヨ瀛楀吀绫诲瀷鍒楄〃 */
 const getTypeList = async () => {
-	const res = await getDictOptionselect()
-	typeOptions.value = res.data;
+    const res = await getDictOptionselect()
+    typeOptions.value = res.data;
 }
 /** 鏌ヨ瀛楀吀鏁版嵁鍒楄〃 */
 const getList = async () => {
-	loading.value = true;
-	const res = await listData(queryParams.value);
-	dataList.value = res.rows;
-	total.value = res.total;
-	loading.value = false;
+    loading.value = true;
+    const res = await listData(queryParams.value);
+    dataList.value = res.rows;
+    total.value = res.total;
+    loading.value = false;
 }
 /** 鍙栨秷鎸夐挳 */
 const cancel = () => {
-	dialog.visible = false;
-	reset();
+    dialog.visible = false;
+    reset();
 }
 /** 琛ㄥ崟閲嶇疆 */
 const reset = () => {
-	form.value = { ...initFormData };
-	dataFormRef.value.resetFields();
+    form.value = { ...initFormData };
+    dataFormRef.value.resetFields();
 }
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-	queryParams.value.pageNum = 1;
-	getList();
+    queryParams.value.pageNum = 1;
+    getList();
 }
 /** 杩斿洖鎸夐挳鎿嶄綔 */
 const handleClose = () => {
-	const obj = { path: "/system/dict" };
-	proxy?.$tab.closeOpenPage(obj);
+    const obj = { path: "/system/dict" };
+    proxy?.$tab.closeOpenPage(obj);
 }
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 const resetQuery = () => {
-	queryFormRef.value.resetFields();
-	queryParams.value.dictType = defaultDictType.value;
-	handleQuery();
+    queryFormRef.value.resetFields();
+    queryParams.value.dictType = defaultDictType.value;
+    handleQuery();
 }
 /** 鏂板鎸夐挳鎿嶄綔 */
 const handleAdd = () => {
-	dialog.visible = true;
-	dialog.title = "娣诲姞瀛楀吀鏁版嵁";
-	nextTick(() => {
-		reset();
-		form.value.dictType = queryParams.value.dictType;
-	})
+    dialog.visible = true;
+    dialog.title = "娣诲姞瀛楀吀鏁版嵁";
+    nextTick(() => {
+        reset();
+        form.value.dictType = queryParams.value.dictType;
+    })
 }
 /** 澶氶�夋閫変腑鏁版嵁 */
 const handleSelectionChange = (selection: DictDataVO[]) => {
-	ids.value = selection.map(item => item.dictCode);
-	single.value = selection.length != 1;
-	multiple.value = !selection.length;
+    ids.value = selection.map(item => item.dictCode);
+    single.value = selection.length != 1;
+    multiple.value = !selection.length;
 }
 /** 淇敼鎸夐挳鎿嶄綔 */
 const handleUpdate = (row?: DictDataVO) => {
-	const dictCode = row?.dictCode || ids.value[0];
-	dialog.visible = true;
-	dialog.title = "淇敼瀛楀吀鏁版嵁";
-	nextTick(async () => {
-		const res =  await getData(dictCode);
-		reset();
-		form.value = res.data;
-	})
+    const dictCode = row?.dictCode || ids.value[0];
+    dialog.visible = true;
+    dialog.title = "淇敼瀛楀吀鏁版嵁";
+    nextTick(async () => {
+        const res =  await getData(dictCode);
+        reset();
+        form.value = res.data;
+    })
 }
 /** 鎻愪氦鎸夐挳 */
 const submitForm = () => {
-	dataFormRef.value.validate(async (valid: boolean) => {
-		if (valid) {
-			form.value.dictCode ? await updateData(form.value) : await addData(form.value);
-			useDictStore().removeDict(queryParams.value.dictType);
-			proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛");
-			dialog.visible = false;
-			getList();
+    dataFormRef.value.validate(async (valid: boolean) => {
+        if (valid) {
+            form.value.dictCode ? await updateData(form.value) : await addData(form.value);
+            useDictStore().removeDict(queryParams.value.dictType);
+            proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛");
+            dialog.visible = false;
+            getList();
 
-		}
-	});
+        }
+    });
 }
 /** 鍒犻櫎鎸夐挳鎿嶄綔 */
 const handleDelete = async (row?: DictDataVO) => {
-	const dictCodes = row?.dictCode || ids.value;
-	await proxy?.$modal.confirm('鏄惁纭鍒犻櫎瀛楀吀缂栫爜涓�"' + dictCodes + '"鐨勬暟鎹」锛�');
-	await delData(dictCodes);
-	getList();
-	proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-	useDictStore().removeDict(queryParams.value.dictType);
+    const dictCodes = row?.dictCode || ids.value;
+    await proxy?.$modal.confirm('鏄惁纭鍒犻櫎瀛楀吀缂栫爜涓�"' + dictCodes + '"鐨勬暟鎹」锛�');
+    await delData(dictCodes);
+    getList();
+    proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    useDictStore().removeDict(queryParams.value.dictType);
 
 }
 /** 瀵煎嚭鎸夐挳鎿嶄綔 */
 const handleExport = () => {
-	proxy?.download("system/dict/data/export", {
-		...queryParams.value
-	}, `dict_data_${new Date().getTime()}.xlsx`);
+    proxy?.download("system/dict/data/export", {
+        ...queryParams.value
+    }, `dict_data_${new Date().getTime()}.xlsx`);
 }
 
 onMounted(() => {
-	getTypes(route.params && route.params.dictId as string);
-	getTypeList();
+    getTypes(route.params && route.params.dictId as string);
+    getTypeList();
 })
 </script>
-
-<template>
-	<div class="p-2">
-		<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-			<div class="search" v-show="showSearch">
-				<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
-					<el-form-item label="瀛楀吀鍚嶇О" prop="dictType">
-						<el-select v-model="queryParams.dictType" style="width: 200px">
-							<el-option v-for="item in typeOptions" :key="item.dictId" :label="item.dictName" :value="item.dictType" />
-						</el-select>
-					</el-form-item>
-					<el-form-item label="瀛楀吀鏍囩" prop="dictLabel">
-						<el-input v-model="queryParams.dictLabel" placeholder="璇疯緭鍏ュ瓧鍏告爣绛�" clearable style="width: 200px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鐘舵��" prop="status">
-						<el-select v-model="queryParams.status" placeholder="鏁版嵁鐘舵��" clearable style="width: 200px">
-							<el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
-						</el-select>
-					</el-form-item>
-					<el-form-item>
-						<el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
-						<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-					</el-form-item>
-				</el-form>
-			</div>
-		</transition>
-		<el-card shadow="never">
-			<template #header>
-				<el-row :gutter="10" class="mb8">
-					<el-col :span="1.5">
-						<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:dict:add']">鏂板</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:dict:edit']">淇敼</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:dict:remove']">
-							鍒犻櫎
-						</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:dict:export']">瀵煎嚭</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="warning" plain icon="Close" @click="handleClose">鍏抽棴</el-button>
-					</el-col>
-					<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-				</el-row>
-			</template>
-
-			<el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
-				<el-table-column type="selection" width="55" align="center" />
-				<el-table-column label="瀛楀吀缂栫爜" align="center" prop="dictCode" v-if="false" />
-				<el-table-column label="瀛楀吀鏍囩" align="center" prop="dictLabel">
-					<template #default="scope">
-						<span v-if="scope.row.listClass === '' || scope.row.listClass === 'default'">{{ scope.row.dictLabel }}</span>
-						<el-tag v-else :type="scope.row.listClass === 'primary' ? '' : scope.row.listClass">{{ scope.row.dictLabel
-						}}</el-tag>
-					</template>
-				</el-table-column>
-				<el-table-column label="瀛楀吀閿��" align="center" prop="dictValue" />
-				<el-table-column label="瀛楀吀鎺掑簭" align="center" prop="dictSort" />
-				<el-table-column label="鐘舵��" align="center" prop="status">
-					<template #default="scope">
-						<dict-tag :options="sys_normal_disable" :value="scope.row.status" />
-					</template>
-				</el-table-column>
-				<el-table-column label="澶囨敞" align="center" prop="remark" :show-overflow-tooltip="true" />
-				<el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180">
-					<template #default="scope">
-						<span>{{ parseTime(scope.row.createTime) }}</span>
-					</template>
-				</el-table-column>
-				<el-table-column label="鎿嶄綔" align="center" width="160" class-name="small-padding fixed-width">
-					<template #default="scope">
-						<el-tooltip content="淇敼" placement="top">
-							<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dict:edit']"></el-button>
-						</el-tooltip>
-						<el-tooltip content="鍒犻櫎" placement="top">
-							<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dict:remove']"></el-button>
-						</el-tooltip>
-					</template>
-				</el-table-column>
-			</el-table>
-
-			<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
-		</el-card>
-		<!-- 娣诲姞鎴栦慨鏀瑰弬鏁伴厤缃璇濇 -->
-		<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
-			<el-form ref="dataFormRef" :model="form" :rules="rules" label-width="80px">
-				<el-form-item label="瀛楀吀绫诲瀷">
-					<el-input v-model="form.dictType" :disabled="true" />
-				</el-form-item>
-				<el-form-item label="鏁版嵁鏍囩" prop="dictLabel">
-					<el-input v-model="form.dictLabel" placeholder="璇疯緭鍏ユ暟鎹爣绛�" />
-				</el-form-item>
-				<el-form-item label="鏁版嵁閿��" prop="dictValue">
-					<el-input v-model="form.dictValue" placeholder="璇疯緭鍏ユ暟鎹敭鍊�" />
-				</el-form-item>
-				<el-form-item label="鏍峰紡灞炴��" prop="cssClass">
-					<el-input v-model="form.cssClass" placeholder="璇疯緭鍏ユ牱寮忓睘鎬�" />
-				</el-form-item>
-				<el-form-item label="鏄剧ず鎺掑簭" prop="dictSort">
-					<el-input-number v-model="form.dictSort" controls-position="right" :min="0" />
-				</el-form-item>
-				<el-form-item label="鍥炴樉鏍峰紡" prop="listClass">
-					<el-select v-model="form.listClass">
-						<el-option
-							v-for="item in listClassOptions"
-							:key="item.value"
-							:label="item.label + '(' + item.value + ')'"
-							:value="item.value"
-						></el-option>
-					</el-select>
-				</el-form-item>
-				<el-form-item label="鐘舵��" prop="status">
-					<el-radio-group v-model="form.status">
-						<el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
-					</el-radio-group>
-				</el-form-item>
-				<el-form-item label="澶囨敞" prop="remark">
-					<el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�"></el-input>
-				</el-form-item>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
-					<el-button @click="cancel">鍙� 娑�</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</div>
-</template>
diff --git a/src/views/system/dict/index.vue b/src/views/system/dict/index.vue
index 9407f51..7872c76 100644
--- a/src/views/system/dict/index.vue
+++ b/src/views/system/dict/index.vue
@@ -1,3 +1,125 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+          <el-form-item label="瀛楀吀鍚嶇О" prop="dictName">
+            <el-input v-model="queryParams.dictName" placeholder="璇疯緭鍏ュ瓧鍏稿悕绉�" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="瀛楀吀绫诲瀷" prop="dictType">
+            <el-input v-model="queryParams.dictType" placeholder="璇疯緭鍏ュ瓧鍏哥被鍨�" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鐘舵��" prop="status">
+            <el-select v-model="queryParams.status" placeholder="瀛楀吀鐘舵��" clearable style="width: 240px">
+              <el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="鍒涘缓鏃堕棿" style="width: 308px">
+            <el-date-picker
+              v-model="dateRange"
+              value-format="YYYY-MM-DD HH:mm:ss"
+              type="daterange"
+              range-separator="-"
+              start-placeholder="寮�濮嬫棩鏈�"
+              end-placeholder="缁撴潫鏃ユ湡"
+              :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
+            ></el-date-picker>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:dict:add']">鏂板</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:dict:edit']">淇敼</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:dict:remove']">
+              鍒犻櫎
+            </el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:dict:export']">瀵煎嚭</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Refresh" @click="handleRefreshCache" v-hasPermi="['system:dict:remove']">鍒锋柊缂撳瓨</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table v-loading="loading" :data="typeList" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="瀛楀吀缂栧彿" align="center" prop="dictId" v-if="false" />
+        <el-table-column label="瀛楀吀鍚嶇О" align="center" prop="dictName" :show-overflow-tooltip="true" />
+        <el-table-column label="瀛楀吀绫诲瀷" align="center" :show-overflow-tooltip="true">
+          <template #default="scope">
+            <router-link :to="'/system/dict-data/index/' + scope.row.dictId" class="link-type">
+              <span>{{ scope.row.dictType }}</span>
+            </router-link>
+          </template>
+        </el-table-column>
+        <el-table-column label="鐘舵��" align="center" prop="status">
+          <template #default="scope">
+            <dict-tag :options="sys_normal_disable" :value="scope.row.status" />
+          </template>
+        </el-table-column>
+        <el-table-column label="澶囨敞" align="center" prop="remark" :show-overflow-tooltip="true" />
+        <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.createTime) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" align="center" width="160" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-tooltip content="淇敼" placement="top">
+              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dict:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="鍒犻櫎" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dict:remove']"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+    </el-card>
+    <!-- 娣诲姞鎴栦慨鏀瑰弬鏁伴厤缃璇濇 -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
+      <el-form ref="dictFormRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="瀛楀吀鍚嶇О" prop="dictName">
+          <el-input v-model="form.dictName" placeholder="璇疯緭鍏ュ瓧鍏稿悕绉�" />
+        </el-form-item>
+        <el-form-item label="瀛楀吀绫诲瀷" prop="dictType">
+          <el-input v-model="form.dictType" placeholder="璇疯緭鍏ュ瓧鍏哥被鍨�" />
+        </el-form-item>
+        <el-form-item label="鐘舵��" prop="status">
+          <el-radio-group v-model="form.status">
+            <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�"></el-input>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
 <script setup name="Dict" lang="ts">
 import useDictStore from '@/store/modules/dict'
 import { listType, getType, delType, addType, updateType, refreshCache } from "@/api/system/dict/type";
@@ -22,245 +144,123 @@
 
 
 const dialog = reactive<DialogOption>({
-  visible: false,
-  title: ''
+    visible: false,
+    title: ''
 });
 
 const initFormData: DictTypeForm = {
-  dictId: undefined,
-  dictName: '',
-  dictType: '',
-  status: "0",
-  remark: ''
-}
-const data = reactive<PageData<DictTypeForm, DictTypeQuery>>({
-  form: {...initFormData},
-  queryParams: {
-    pageNum: 1,
-    pageSize: 10,
+    dictId: undefined,
     dictName: '',
     dictType: '',
-    status: ''
-  },
-  rules: {
-    dictName: [{ required: true, message: "瀛楀吀鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }],
-    dictType: [{ required: true, message: "瀛楀吀绫诲瀷涓嶈兘涓虹┖", trigger: "blur" }]
-  },
+    status: "0",
+    remark: ''
+}
+const data = reactive<PageData<DictTypeForm, DictTypeQuery>>({
+    form: {...initFormData},
+    queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        dictName: '',
+        dictType: '',
+        status: ''
+    },
+    rules: {
+        dictName: [{ required: true, message: "瀛楀吀鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }],
+        dictType: [{ required: true, message: "瀛楀吀绫诲瀷涓嶈兘涓虹┖", trigger: "blur" }]
+    },
 });
 
 const { queryParams, form, rules } = toRefs(data);
 
 /** 鏌ヨ瀛楀吀绫诲瀷鍒楄〃 */
 const getList = () => {
-  loading.value = true;
-  listType(proxy?.addDateRange(queryParams.value, dateRange.value)).then(res => {
-    typeList.value = res.rows;
-    total.value = res.total;
-    loading.value = false;
-  });
+    loading.value = true;
+    listType(proxy?.addDateRange(queryParams.value, dateRange.value)).then(res => {
+        typeList.value = res.rows;
+        total.value = res.total;
+        loading.value = false;
+    });
 }
 /** 鍙栨秷鎸夐挳 */
 const cancel = () => {
-  reset();
-  dialog.visible = false;
+    reset();
+    dialog.visible = false;
 }
 /** 琛ㄥ崟閲嶇疆 */
 const reset = () => {
-	form.value = {...initFormData};
-	dictFormRef.value.resetFields();
+    form.value = {...initFormData};
+    dictFormRef.value.resetFields();
 }
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-  queryParams.value.pageNum = 1;
-  getList();
+    queryParams.value.pageNum = 1;
+    getList();
 }
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 const resetQuery = () => {
-  dateRange.value = ['', ''];
-  queryFormRef.value.resetFields();
-  handleQuery();
+    dateRange.value = ['', ''];
+    queryFormRef.value.resetFields();
+    handleQuery();
 }
 /** 鏂板鎸夐挳鎿嶄綔 */
 const handleAdd = () => {
-  dialog.visible = true;
-  dialog.title = "娣诲姞瀛楀吀绫诲瀷";
-	nextTick(() => {
-		reset();
-	})
+    dialog.visible = true;
+    dialog.title = "娣诲姞瀛楀吀绫诲瀷";
+    nextTick(() => {
+        reset();
+    })
 }
 /** 澶氶�夋閫変腑鏁版嵁 */
 const handleSelectionChange = (selection: DictTypeVO[]) =>  {
-  ids.value = selection.map(item => item.dictId);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
+    ids.value = selection.map(item => item.dictId);
+    single.value = selection.length != 1;
+    multiple.value = !selection.length;
 }
 /** 淇敼鎸夐挳鎿嶄綔 */
 const handleUpdate = (row?: DictTypeVO) => {
-	dialog.visible = true;
-	dialog.title = "淇敼瀛楀吀绫诲瀷";
-	const dictId = row?.dictId || ids.value[0];
-	nextTick(async () => {
-		reset();
-		const res = await getType(dictId);
-    form.value = res.data;
-	})
+    dialog.visible = true;
+    dialog.title = "淇敼瀛楀吀绫诲瀷";
+    const dictId = row?.dictId || ids.value[0];
+    nextTick(async () => {
+        reset();
+        const res = await getType(dictId);
+        form.value = res.data;
+    })
 
 }
 /** 鎻愪氦鎸夐挳 */
 const submitForm = () => {
-  dictFormRef.value.validate(async (valid: boolean) => {
-		if (valid) {
-			form.value.dictId ? await updateType(form.value) : await addType(form.value);
-			proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛");
-			dialog.visible = false;
-			getList();
-    }
-  });
+    dictFormRef.value.validate(async (valid: boolean) => {
+        if (valid) {
+            form.value.dictId ? await updateType(form.value) : await addType(form.value);
+            proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛");
+            dialog.visible = false;
+            getList();
+        }
+    });
 }
 /** 鍒犻櫎鎸夐挳鎿嶄綔 */
 const handleDelete = async (row?: DictTypeVO) => {
-  const dictIds = row?.dictId || ids.value;
-	await proxy?.$modal.confirm('鏄惁纭鍒犻櫎瀛楀吀缂栧彿涓�"' + dictIds + '"鐨勬暟鎹」锛�');
-	await delType(dictIds);
-	getList();
-	proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    const dictIds = row?.dictId || ids.value;
+    await proxy?.$modal.confirm('鏄惁纭鍒犻櫎瀛楀吀缂栧彿涓�"' + dictIds + '"鐨勬暟鎹」锛�');
+    await delType(dictIds);
+    getList();
+    proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
 }
 /** 瀵煎嚭鎸夐挳鎿嶄綔 */
 const handleExport = () => {
-  proxy?.download("system/dict/type/export", {
-    ...queryParams.value
-  }, `dict_${new Date().getTime()}.xlsx`);
+    proxy?.download("system/dict/type/export", {
+        ...queryParams.value
+    }, `dict_${new Date().getTime()}.xlsx`);
 }
 /** 鍒锋柊缂撳瓨鎸夐挳鎿嶄綔 */
 const handleRefreshCache = async () => {
-	await refreshCache();
-	proxy?.$modal.msgSuccess("鍒锋柊鎴愬姛");
-	useDictStore().cleanDict();
+    await refreshCache();
+    proxy?.$modal.msgSuccess("鍒锋柊鎴愬姛");
+    useDictStore().cleanDict();
 }
 
 onMounted(()=>{
-  getList();
+    getList();
 })
 </script>
-
-<template>
-	<div class="p-2">
-		<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-			<div class="search" v-show="showSearch">
-				<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
-					<el-form-item label="瀛楀吀鍚嶇О" prop="dictName">
-						<el-input v-model="queryParams.dictName" placeholder="璇疯緭鍏ュ瓧鍏稿悕绉�" clearable style="width: 240px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="瀛楀吀绫诲瀷" prop="dictType">
-						<el-input v-model="queryParams.dictType" placeholder="璇疯緭鍏ュ瓧鍏哥被鍨�" clearable style="width: 240px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鐘舵��" prop="status">
-						<el-select v-model="queryParams.status" placeholder="瀛楀吀鐘舵��" clearable style="width: 240px">
-							<el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
-						</el-select>
-					</el-form-item>
-					<el-form-item label="鍒涘缓鏃堕棿" style="width: 308px">
-						<el-date-picker
-							v-model="dateRange"
-							value-format="YYYY-MM-DD HH:mm:ss"
-							type="daterange"
-							range-separator="-"
-							start-placeholder="寮�濮嬫棩鏈�"
-							end-placeholder="缁撴潫鏃ユ湡"
-							:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
-						></el-date-picker>
-					</el-form-item>
-					<el-form-item>
-						<el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
-						<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-					</el-form-item>
-				</el-form>
-			</div>
-		</transition>
-		<el-card shadow="never">
-			<template #header>
-				<el-row :gutter="10" class="mb8">
-					<el-col :span="1.5">
-						<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:dict:add']">鏂板</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:dict:edit']">淇敼</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:dict:remove']">
-							鍒犻櫎
-						</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:dict:export']">瀵煎嚭</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="danger" plain icon="Refresh" @click="handleRefreshCache" v-hasPermi="['system:dict:remove']">鍒锋柊缂撳瓨</el-button>
-					</el-col>
-					<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-				</el-row>
-			</template>
-
-			<el-table v-loading="loading" :data="typeList" @selection-change="handleSelectionChange">
-				<el-table-column type="selection" width="55" align="center" />
-				<el-table-column label="瀛楀吀缂栧彿" align="center" prop="dictId" v-if="false" />
-				<el-table-column label="瀛楀吀鍚嶇О" align="center" prop="dictName" :show-overflow-tooltip="true" />
-				<el-table-column label="瀛楀吀绫诲瀷" align="center" :show-overflow-tooltip="true">
-					<template #default="scope">
-						<router-link :to="'/system/dict-data/index/' + scope.row.dictId" class="link-type">
-							<span>{{ scope.row.dictType }}</span>
-						</router-link>
-					</template>
-				</el-table-column>
-				<el-table-column label="鐘舵��" align="center" prop="status">
-					<template #default="scope">
-						<dict-tag :options="sys_normal_disable" :value="scope.row.status" />
-					</template>
-				</el-table-column>
-				<el-table-column label="澶囨敞" align="center" prop="remark" :show-overflow-tooltip="true" />
-				<el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180">
-					<template #default="scope">
-						<span>{{ parseTime(scope.row.createTime) }}</span>
-					</template>
-				</el-table-column>
-				<el-table-column label="鎿嶄綔" align="center" width="160" class-name="small-padding fixed-width">
-					<template #default="scope">
-						<el-tooltip content="淇敼" placement="top">
-							<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dict:edit']"></el-button>
-						</el-tooltip>
-						<el-tooltip content="鍒犻櫎" placement="top">
-							<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dict:remove']"></el-button>
-						</el-tooltip>
-					</template>
-				</el-table-column>
-			</el-table>
-
-			<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
-		</el-card>
-		<!-- 娣诲姞鎴栦慨鏀瑰弬鏁伴厤缃璇濇 -->
-		<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
-			<el-form ref="dictFormRef" :model="form" :rules="rules" label-width="80px">
-				<el-form-item label="瀛楀吀鍚嶇О" prop="dictName">
-					<el-input v-model="form.dictName" placeholder="璇疯緭鍏ュ瓧鍏稿悕绉�" />
-				</el-form-item>
-				<el-form-item label="瀛楀吀绫诲瀷" prop="dictType">
-					<el-input v-model="form.dictType" placeholder="璇疯緭鍏ュ瓧鍏哥被鍨�" />
-				</el-form-item>
-				<el-form-item label="鐘舵��" prop="status">
-					<el-radio-group v-model="form.status">
-						<el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
-					</el-radio-group>
-				</el-form-item>
-				<el-form-item label="澶囨敞" prop="remark">
-					<el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�"></el-input>
-				</el-form-item>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
-					<el-button @click="cancel">鍙� 娑�</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</div>
-</template>
diff --git a/src/views/system/menu/index.vue b/src/views/system/menu/index.vue
index 3cf9257..f06b0b3 100644
--- a/src/views/system/menu/index.vue
+++ b/src/views/system/menu/index.vue
@@ -1,3 +1,264 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="68px">
+          <el-form-item label="鑿滃崟鍚嶇О" prop="menuName">
+            <el-input v-model="queryParams.menuName" placeholder="璇疯緭鍏ヨ彍鍗曞悕绉�" clearable @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鐘舵��" prop="status">
+            <el-select v-model="queryParams.status" placeholder="鑿滃崟鐘舵��" clearable>
+              <el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['system:menu:add']">鏂板 </el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">灞曞紑/鎶樺彔</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table
+        v-loading="loading"
+        :data="menuList"
+        row-key="menuId"
+        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
+        border
+        ref="menuTableRef"
+        :default-expand-all="isExpandAll"
+      >
+        <el-table-column prop="menuName" label="鑿滃崟鍚嶇О" :show-overflow-tooltip="true" width="160"></el-table-column>
+        <el-table-column prop="icon" label="鍥炬爣" align="center" width="100">
+          <template #default="scope">
+            <svg-icon :icon-class="scope.row.icon" />
+          </template>
+        </el-table-column>
+        <el-table-column prop="orderNum" label="鎺掑簭" width="60"></el-table-column>
+        <el-table-column prop="perms" label="鏉冮檺鏍囪瘑" :show-overflow-tooltip="true"></el-table-column>
+        <el-table-column prop="component" label="缁勪欢璺緞" :show-overflow-tooltip="true"></el-table-column>
+        <el-table-column prop="status" label="鐘舵��" width="80">
+          <template #default="scope">
+            <dict-tag :options="sys_normal_disable" :value="scope.row.status" />
+          </template>
+        </el-table-column>
+        <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime">
+          <template #default="scope">
+            <span>{{ scope.row.createTime }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column fixed="right" label="鎿嶄綔" width="180">
+          <template #default="scope">
+            <el-tooltip content="淇敼" placement="top">
+              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:menu:edit']" />
+            </el-tooltip>
+            <el-tooltip content="鏂板" placement="top">
+              <el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['system:menu:add']" />
+            </el-tooltip>
+            <el-tooltip content="鍒犻櫎" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:menu:remove']" />
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+
+    <el-dialog :title="dialog.title" v-model="dialog.visible" destroy-on-close append-to-bod width="750px">
+      <el-form ref="menuFormRef" :model="form" :rules="rules" label-width="100px">
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="涓婄骇鑿滃崟">
+              <el-tree-select
+                v-model="form.parentId"
+                :data="menuOptions"
+                :props="{ value: 'menuId', label: 'menuName', children: 'children' }"
+                value-key="menuId"
+                placeholder="閫夋嫨涓婄骇鑿滃崟"
+                check-strictly
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="鑿滃崟绫诲瀷" prop="menuType">
+              <el-radio-group v-model="form.menuType">
+                <el-radio label="M">鐩綍</el-radio>
+                <el-radio label="C">鑿滃崟</el-radio>
+                <el-radio label="F">鎸夐挳</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24" v-if="form.menuType !== 'F'">
+            <el-form-item label="鑿滃崟鍥炬爣" prop="icon">
+              <!-- 鍥炬爣閫夋嫨鍣� -->
+              <icon-select v-model="form.icon" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鑿滃崟鍚嶇О" prop="menuName">
+              <el-input v-model="form.menuName" placeholder="璇疯緭鍏ヨ彍鍗曞悕绉�" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鏄剧ず鎺掑簭" prop="orderNum">
+              <el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12" v-if="form.menuType !== 'F'">
+            <el-form-item>
+              <template #label>
+                <span>
+                  <el-tooltip content="閫夋嫨鏄閾惧垯璺敱鍦板潃闇�瑕佷互`http(s)://`寮�澶�" placement="top">
+                    <el-icon>
+                      <question-filled />
+                    </el-icon> </el-tooltip
+                  >鏄惁澶栭摼
+                </span>
+              </template>
+              <el-radio-group v-model="form.isFrame">
+                <el-radio label="0">鏄�</el-radio>
+                <el-radio label="1">鍚�</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12" v-if="form.menuType !== 'F'">
+            <el-form-item prop="path">
+              <template #label>
+                <span>
+                  <el-tooltip content="璁块棶鐨勮矾鐢卞湴鍧�锛屽锛歚user`锛屽澶栫綉鍦板潃闇�鍐呴摼璁块棶鍒欎互`http(s)://`寮�澶�" placement="top">
+                    <el-icon>
+                      <question-filled />
+                    </el-icon>
+                  </el-tooltip>
+                  璺敱鍦板潃
+                </span>
+              </template>
+              <el-input v-model="form.path" placeholder="璇疯緭鍏ヨ矾鐢卞湴鍧�" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12" v-if="form.menuType === 'C'">
+            <el-form-item prop="component">
+              <template #label>
+                <span>
+                  <el-tooltip content="璁块棶鐨勭粍浠惰矾寰勶紝濡傦細`system/user/index`锛岄粯璁ゅ湪`views`鐩綍涓�" placement="top">
+                    <el-icon>
+                      <question-filled />
+                    </el-icon>
+                  </el-tooltip>
+                  缁勪欢璺緞
+                </span>
+              </template>
+              <el-input v-model="form.component" placeholder="璇疯緭鍏ョ粍浠惰矾寰�" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12" v-if="form.menuType !== 'M'">
+            <el-form-item>
+              <el-input v-model="form.perms" placeholder="璇疯緭鍏ユ潈闄愭爣璇�" maxlength="100" />
+              <template #label>
+                <span>
+                  <el-tooltip content="鎺у埗鍣ㄤ腑瀹氫箟鐨勬潈闄愬瓧绗︼紝濡傦細@PreAuthorize(`@ss.hasPermi('system:user:list')`)" placement="top">
+                    <el-icon>
+                      <question-filled />
+                    </el-icon>
+                  </el-tooltip>
+                  鏉冮檺瀛楃
+                </span>
+              </template>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12" v-if="form.menuType === 'C'">
+            <el-form-item>
+              <el-input v-model="form.query" placeholder="璇疯緭鍏ヨ矾鐢卞弬鏁�" maxlength="255" />
+              <template #label>
+                <span>
+                  <el-tooltip content='璁块棶璺敱鐨勯粯璁や紶閫掑弬鏁帮紝濡傦細`{"id": 1, "name": "ry"}`' placement="top">
+                    <el-icon>
+                      <question-filled />
+                    </el-icon>
+                  </el-tooltip>
+                  璺敱鍙傛暟
+                </span>
+              </template>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12" v-if="form.menuType === 'C'">
+            <el-form-item>
+              <template #label>
+                <span>
+                  <el-tooltip content="閫夋嫨鏄垯浼氳`keep-alive`缂撳瓨锛岄渶瑕佸尮閰嶇粍浠剁殑`name`鍜屽湴鍧�淇濇寔涓�鑷�" placement="top">
+                    <el-icon>
+                      <question-filled />
+                    </el-icon>
+                  </el-tooltip>
+                  鏄惁缂撳瓨
+                </span>
+              </template>
+              <el-radio-group v-model="form.isCache">
+                <el-radio label="0">缂撳瓨</el-radio>
+                <el-radio label="1">涓嶇紦瀛�</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12" v-if="form.menuType !== 'F'">
+            <el-form-item>
+              <template #label>
+                <span>
+                  <el-tooltip content="閫夋嫨闅愯棌鍒欒矾鐢卞皢涓嶄細鍑虹幇鍦ㄤ晶杈规爮锛屼絾浠嶇劧鍙互璁块棶" placement="top">
+                    <el-icon>
+                      <question-filled />
+                    </el-icon>
+                  </el-tooltip>
+                  鏄剧ず鐘舵��
+                </span>
+              </template>
+              <el-radio-group v-model="form.visible">
+                <el-radio v-for="dict in sys_show_hide" :key="dict.value" :label="dict.value">{{ dict.label }} </el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12" v-if="form.menuType !== 'F'">
+            <el-form-item>
+              <template #label>
+                <span>
+                  <el-tooltip content="閫夋嫨鍋滅敤鍒欒矾鐢卞皢涓嶄細鍑虹幇鍦ㄤ晶杈规爮锛屼篃涓嶈兘琚闂�" placement="top">
+                    <el-icon>
+                      <question-filled />
+                    </el-icon>
+                  </el-tooltip>
+                  鑿滃崟鐘舵��
+                </span>
+              </template>
+              <el-radio-group v-model="form.status">
+                <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">
+                  {{ dict.label }}
+                </el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
 <script setup name="Menu" lang="ts">
 import { addMenu, delMenu, getMenu, listMenu, updateMenu } from '@/api/system/menu';
 import { MenuForm, MenuQuery, MenuVO } from '@/api/system/menu/types';
@@ -6,9 +267,9 @@
 import { ElTable, ElForm } from 'element-plus';
 
 interface MenuOptionsType {
-	menuId: number;
-	menuName: string;
-	children: MenuOptionsType[] | undefined;
+    menuId: number;
+    menuName: string;
+    children: MenuOptionsType[] | undefined;
 }
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance
@@ -21,36 +282,36 @@
 const isExpandAll = ref(false)
 
 const dialog = reactive<DialogOption>({
-	visible: false,
-	title: ''
+    visible: false,
+    title: ''
 });
 
 const queryFormRef = ref(ElForm);
 const menuFormRef = ref(ElForm);
 const initFormData = {
-	path: '',
-	menuId: undefined,
-	parentId: 0,
-	menuName: '',
-	icon: '',
-	menuType: MenuTypeEnum.M,
-	orderNum: 1,
-	isFrame: "1",
-	isCache: "0",
-	visible: "0",
-	status: "0"
+    path: '',
+    menuId: undefined,
+    parentId: 0,
+    menuName: '',
+    icon: '',
+    menuType: MenuTypeEnum.M,
+    orderNum: 1,
+    isFrame: "1",
+    isCache: "0",
+    visible: "0",
+    status: "0"
 }
 const data = reactive<PageData<MenuForm, MenuQuery>>({
-	form: { ...initFormData },
-	queryParams: {
-		menuName: undefined,
-		status: undefined
-	},
-	rules: {
-		menuName: [{ required: true, message: "鑿滃崟鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }],
-		orderNum: [{ required: true, message: "鑿滃崟椤哄簭涓嶈兘涓虹┖", trigger: "blur" }],
-		path: [{ required: true, message: "璺敱鍦板潃涓嶈兘涓虹┖", trigger: "blur" }]
-	},
+    form: { ...initFormData },
+    queryParams: {
+        menuName: undefined,
+        status: undefined
+    },
+    rules: {
+        menuName: [{ required: true, message: "鑿滃崟鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }],
+        orderNum: [{ required: true, message: "鑿滃崟椤哄簭涓嶈兘涓虹┖", trigger: "blur" }],
+        path: [{ required: true, message: "璺敱鍦板潃涓嶈兘涓虹┖", trigger: "blur" }]
+    },
 })
 
 const menuTableRef = ref(ElTable);
@@ -58,360 +319,99 @@
 const { queryParams, form, rules } = toRefs<PageData<MenuForm, MenuQuery>>(data)
 /** 鏌ヨ鑿滃崟鍒楄〃 */
 const getList = async () => {
-	loading.value = true
-	const res = await listMenu(queryParams.value);
-	const data = proxy?.handleTree<MenuVO>(res.data, "menuId")
-	if (data) {
-		menuList.value = data
-	}
-	loading.value = false
+    loading.value = true
+    const res = await listMenu(queryParams.value);
+    const data = proxy?.handleTree<MenuVO>(res.data, "menuId")
+    if (data) {
+        menuList.value = data
+    }
+    loading.value = false
 }
 /** 鏌ヨ鑿滃崟涓嬫媺鏍戠粨鏋� */
 const getTreeselect = async () => {
-	menuOptions.value = []
-	const response = await listMenu();
-	const menu: MenuOptionsType = { menuId: 0, menuName: "涓荤被鐩�", children: [] }
-	menu.children = proxy?.handleTree<MenuOptionsType>(response.data, "menuId")
-	menuOptions.value.push(menu)
+    menuOptions.value = []
+    const response = await listMenu();
+    const menu: MenuOptionsType = { menuId: 0, menuName: "涓荤被鐩�", children: [] }
+    menu.children = proxy?.handleTree<MenuOptionsType>(response.data, "menuId")
+    menuOptions.value.push(menu)
 }
 /** 鍙栨秷鎸夐挳 */
 const cancel = () => {
-	reset()
-	dialog.visible = false
+    reset()
+    dialog.visible = false
 }
 /** 琛ㄥ崟閲嶇疆 */
 const reset = () => {
-	form.value = { ...initFormData };
-	menuFormRef.value.resetFields();
+    form.value = { ...initFormData };
+    menuFormRef.value.resetFields();
 }
 
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-	getList();
+    getList();
 }
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 const resetQuery = () => {
-	queryFormRef.value.resetFields();
-	handleQuery();
+    queryFormRef.value.resetFields();
+    handleQuery();
 }
 /** 鏂板鎸夐挳鎿嶄綔 */
 const handleAdd = (row?: MenuVO) => {
-	dialog.visible = true;
-	dialog.title = "娣诲姞鑿滃崟";
-	getTreeselect();
-	nextTick(() => {
-		reset();
-		row && row.menuId ? form.value.parentId = row.menuId : form.value.parentId = 0;
-	})
+    dialog.visible = true;
+    dialog.title = "娣诲姞鑿滃崟";
+    getTreeselect();
+    nextTick(() => {
+        reset();
+        row && row.menuId ? form.value.parentId = row.menuId : form.value.parentId = 0;
+    })
 
 }
 /** 灞曞紑/鎶樺彔鎿嶄綔 */
 const handleToggleExpandAll = () => {
-	isExpandAll.value = !isExpandAll.value;
-	toggleExpandAll(menuList.value, isExpandAll.value)
+    isExpandAll.value = !isExpandAll.value;
+    toggleExpandAll(menuList.value, isExpandAll.value)
 }
 /** 灞曞紑/鎶樺彔鎵�鏈� */
 const toggleExpandAll = (data: MenuVO[], status: boolean) => {
-	data.forEach((item: MenuVO) => {
-		menuTableRef.value.toggleRowExpansion(item, status)
-		if (item.children && item.children.length > 0) toggleExpandAll(item.children, status)
-	})
+    data.forEach((item: MenuVO) => {
+        menuTableRef.value.toggleRowExpansion(item, status)
+        if (item.children && item.children.length > 0) toggleExpandAll(item.children, status)
+    })
 }
 /** 淇敼鎸夐挳鎿嶄綔 */
 const handleUpdate = async (row: MenuVO) => {
-	await getTreeselect();
-	dialog.visible = true;
-	dialog.title = "淇敼鑿滃崟";
-	await nextTick(async () => {
-		if (row.menuId) {
-			const { data } = await getMenu(row.menuId);
-			reset();
-			form.value = data;
-		}
-	})
+    await getTreeselect();
+    dialog.visible = true;
+    dialog.title = "淇敼鑿滃崟";
+    await nextTick(async () => {
+        if (row.menuId) {
+            const { data } = await getMenu(row.menuId);
+            reset();
+            form.value = data;
+        }
+    })
 
 }
 /** 鎻愪氦鎸夐挳 */
 const submitForm = () => {
-	menuFormRef.value.validate(async (valid: boolean) => {
-		if (valid) {
-			form.value.menuId ? await updateMenu(form.value) : await addMenu(form.value);
-			proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛");
-			dialog.visible = false;
-			getList();
-		}
-	})
+    menuFormRef.value.validate(async (valid: boolean) => {
+        if (valid) {
+            form.value.menuId ? await updateMenu(form.value) : await addMenu(form.value);
+            proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛");
+            dialog.visible = false;
+            getList();
+        }
+    })
 }
 /** 鍒犻櫎鎸夐挳鎿嶄綔 */
 const handleDelete = async (row: MenuVO) => {
-	await proxy?.$modal.confirm('鏄惁纭鍒犻櫎鍚嶇О涓�"' + row.menuName + '"鐨勬暟鎹」?');
-	await delMenu(row.menuId);
-	getList();
-	proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    await proxy?.$modal.confirm('鏄惁纭鍒犻櫎鍚嶇О涓�"' + row.menuName + '"鐨勬暟鎹」?');
+    await delMenu(row.menuId);
+    getList();
+    proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
 }
 
 onMounted(() => {
-	getList();
+    getList();
 });
 </script>
-
-<template>
-	<div class="p-2">
-		<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-			<div class="search" v-show="showSearch">
-				<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="68px">
-					<el-form-item label="鑿滃崟鍚嶇О" prop="menuName">
-						<el-input v-model="queryParams.menuName" placeholder="璇疯緭鍏ヨ彍鍗曞悕绉�" clearable @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鐘舵��" prop="status">
-						<el-select v-model="queryParams.status" placeholder="鑿滃崟鐘舵��" clearable>
-							<el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
-						</el-select>
-					</el-form-item>
-					<el-form-item>
-						<el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
-						<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-					</el-form-item>
-				</el-form>
-			</div>
-		</transition>
-
-		<el-card shadow="never">
-			<template #header>
-				<el-row :gutter="10">
-					<el-col :span="1.5">
-						<el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['system:menu:add']">鏂板 </el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">灞曞紑/鎶樺彔</el-button>
-					</el-col>
-					<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-				</el-row>
-			</template>
-
-			<el-table
-				v-loading="loading"
-				:data="menuList"
-				row-key="menuId"
-				:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
-				border
-				ref="menuTableRef"
-				:default-expand-all="isExpandAll"
-			>
-				<el-table-column prop="menuName" label="鑿滃崟鍚嶇О" :show-overflow-tooltip="true" width="160"></el-table-column>
-				<el-table-column prop="icon" label="鍥炬爣" align="center" width="100">
-					<template #default="scope">
-						<svg-icon :icon-class="scope.row.icon" />
-					</template>
-				</el-table-column>
-				<el-table-column prop="orderNum" label="鎺掑簭" width="60"></el-table-column>
-				<el-table-column prop="perms" label="鏉冮檺鏍囪瘑" :show-overflow-tooltip="true"></el-table-column>
-				<el-table-column prop="component" label="缁勪欢璺緞" :show-overflow-tooltip="true"></el-table-column>
-				<el-table-column prop="status" label="鐘舵��" width="80">
-					<template #default="scope">
-						<dict-tag :options="sys_normal_disable" :value="scope.row.status" />
-					</template>
-				</el-table-column>
-				<el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime">
-					<template #default="scope">
-						<span>{{ scope.row.createTime }}</span>
-					</template>
-				</el-table-column>
-				<el-table-column fixed="right" label="鎿嶄綔" width="180">
-					<template #default="scope">
-						<el-tooltip content="淇敼" placement="top">
-							<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:menu:edit']" />
-						</el-tooltip>
-						<el-tooltip content="鏂板" placement="top">
-							<el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['system:menu:add']" />
-						</el-tooltip>
-						<el-tooltip content="鍒犻櫎" placement="top">
-							<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:menu:remove']" />
-						</el-tooltip>
-					</template>
-				</el-table-column>
-			</el-table>
-		</el-card>
-
-		<el-dialog :title="dialog.title" v-model="dialog.visible" destroy-on-close append-to-bod width="750px">
-			<el-form ref="menuFormRef" :model="form" :rules="rules" label-width="100px">
-				<el-row>
-					<el-col :span="24">
-						<el-form-item label="涓婄骇鑿滃崟">
-							<el-tree-select
-								v-model="form.parentId"
-								:data="menuOptions"
-								:props="{ value: 'menuId', label: 'menuName', children: 'children' }"
-								value-key="menuId"
-								placeholder="閫夋嫨涓婄骇鑿滃崟"
-								check-strictly
-							/>
-						</el-form-item>
-					</el-col>
-					<el-col :span="24">
-						<el-form-item label="鑿滃崟绫诲瀷" prop="menuType">
-							<el-radio-group v-model="form.menuType">
-								<el-radio label="M">鐩綍</el-radio>
-								<el-radio label="C">鑿滃崟</el-radio>
-								<el-radio label="F">鎸夐挳</el-radio>
-							</el-radio-group>
-						</el-form-item>
-					</el-col>
-					<el-col :span="24" v-if="form.menuType !== 'F'">
-						<el-form-item label="鑿滃崟鍥炬爣" prop="icon">
-							<!-- 鍥炬爣閫夋嫨鍣� -->
-							<icon-select v-model="form.icon" />
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="鑿滃崟鍚嶇О" prop="menuName">
-							<el-input v-model="form.menuName" placeholder="璇疯緭鍏ヨ彍鍗曞悕绉�" />
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="鏄剧ず鎺掑簭" prop="orderNum">
-							<el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.menuType !== 'F'">
-						<el-form-item>
-							<template #label>
-								<span>
-									<el-tooltip content="閫夋嫨鏄閾惧垯璺敱鍦板潃闇�瑕佷互`http(s)://`寮�澶�" placement="top">
-										<el-icon>
-											<question-filled />
-										</el-icon> </el-tooltip
-									>鏄惁澶栭摼
-								</span>
-							</template>
-							<el-radio-group v-model="form.isFrame">
-								<el-radio label="0">鏄�</el-radio>
-								<el-radio label="1">鍚�</el-radio>
-							</el-radio-group>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.menuType !== 'F'">
-						<el-form-item prop="path">
-							<template #label>
-								<span>
-									<el-tooltip content="璁块棶鐨勮矾鐢卞湴鍧�锛屽锛歚user`锛屽澶栫綉鍦板潃闇�鍐呴摼璁块棶鍒欎互`http(s)://`寮�澶�" placement="top">
-										<el-icon>
-											<question-filled />
-										</el-icon>
-									</el-tooltip>
-									璺敱鍦板潃
-								</span>
-							</template>
-							<el-input v-model="form.path" placeholder="璇疯緭鍏ヨ矾鐢卞湴鍧�" />
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.menuType === 'C'">
-						<el-form-item prop="component">
-							<template #label>
-								<span>
-									<el-tooltip content="璁块棶鐨勭粍浠惰矾寰勶紝濡傦細`system/user/index`锛岄粯璁ゅ湪`views`鐩綍涓�" placement="top">
-										<el-icon>
-											<question-filled />
-										</el-icon>
-									</el-tooltip>
-									缁勪欢璺緞
-								</span>
-							</template>
-							<el-input v-model="form.component" placeholder="璇疯緭鍏ョ粍浠惰矾寰�" />
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.menuType !== 'M'">
-						<el-form-item>
-							<el-input v-model="form.perms" placeholder="璇疯緭鍏ユ潈闄愭爣璇�" maxlength="100" />
-							<template #label>
-								<span>
-									<el-tooltip content="鎺у埗鍣ㄤ腑瀹氫箟鐨勬潈闄愬瓧绗︼紝濡傦細@PreAuthorize(`@ss.hasPermi('system:user:list')`)" placement="top">
-										<el-icon>
-											<question-filled />
-										</el-icon>
-									</el-tooltip>
-									鏉冮檺瀛楃
-								</span>
-							</template>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.menuType === 'C'">
-						<el-form-item>
-							<el-input v-model="form.query" placeholder="璇疯緭鍏ヨ矾鐢卞弬鏁�" maxlength="255" />
-							<template #label>
-								<span>
-									<el-tooltip content='璁块棶璺敱鐨勯粯璁や紶閫掑弬鏁帮紝濡傦細`{"id": 1, "name": "ry"}`' placement="top">
-										<el-icon>
-											<question-filled />
-										</el-icon>
-									</el-tooltip>
-									璺敱鍙傛暟
-								</span>
-							</template>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.menuType === 'C'">
-						<el-form-item>
-							<template #label>
-								<span>
-									<el-tooltip content="閫夋嫨鏄垯浼氳`keep-alive`缂撳瓨锛岄渶瑕佸尮閰嶇粍浠剁殑`name`鍜屽湴鍧�淇濇寔涓�鑷�" placement="top">
-										<el-icon>
-											<question-filled />
-										</el-icon>
-									</el-tooltip>
-									鏄惁缂撳瓨
-								</span>
-							</template>
-							<el-radio-group v-model="form.isCache">
-								<el-radio label="0">缂撳瓨</el-radio>
-								<el-radio label="1">涓嶇紦瀛�</el-radio>
-							</el-radio-group>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.menuType !== 'F'">
-						<el-form-item>
-							<template #label>
-								<span>
-									<el-tooltip content="閫夋嫨闅愯棌鍒欒矾鐢卞皢涓嶄細鍑虹幇鍦ㄤ晶杈规爮锛屼絾浠嶇劧鍙互璁块棶" placement="top">
-										<el-icon>
-											<question-filled />
-										</el-icon>
-									</el-tooltip>
-									鏄剧ず鐘舵��
-								</span>
-							</template>
-							<el-radio-group v-model="form.visible">
-								<el-radio v-for="dict in sys_show_hide" :key="dict.value" :label="dict.value">{{ dict.label }} </el-radio>
-							</el-radio-group>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12" v-if="form.menuType !== 'F'">
-						<el-form-item>
-							<template #label>
-								<span>
-									<el-tooltip content="閫夋嫨鍋滅敤鍒欒矾鐢卞皢涓嶄細鍑虹幇鍦ㄤ晶杈规爮锛屼篃涓嶈兘琚闂�" placement="top">
-										<el-icon>
-											<question-filled />
-										</el-icon>
-									</el-tooltip>
-									鑿滃崟鐘舵��
-								</span>
-							</template>
-							<el-radio-group v-model="form.status">
-								<el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">
-									{{ dict.label }}
-								</el-radio>
-							</el-radio-group>
-						</el-form-item>
-					</el-col>
-				</el-row>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
-					<el-button @click="cancel">鍙� 娑�</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</div>
-</template>
diff --git a/src/views/system/notice/index.vue b/src/views/system/notice/index.vue
index ab68a1a..b041bb2 100644
--- a/src/views/system/notice/index.vue
+++ b/src/views/system/notice/index.vue
@@ -1,3 +1,122 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+          <el-form-item label="鍏憡鏍囬" prop="noticeTitle">
+            <el-input v-model="queryParams.noticeTitle" placeholder="璇疯緭鍏ュ叕鍛婃爣棰�" clearable style="width: 200px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鎿嶄綔浜哄憳" prop="createByName">
+            <el-input v-model="queryParams.createByName" placeholder="璇疯緭鍏ユ搷浣滀汉鍛�" clearable style="width: 200px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="绫诲瀷" prop="noticeType">
+            <el-select v-model="queryParams.noticeType" placeholder="鍏憡绫诲瀷" clearable style="width: 200px">
+              <el-option v-for="dict in sys_notice_type" :key="dict.value" :label="dict.label" :value="dict.value" />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:notice:add']">鏂板</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:notice:edit']"
+              >淇敼</el-button
+            >
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:notice:remove']">
+              鍒犻櫎
+            </el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table v-loading="loading" :data="noticeList" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="搴忓彿" align="center" prop="noticeId" width="100" v-if="false" />
+        <el-table-column label="鍏憡鏍囬" align="center" prop="noticeTitle" :show-overflow-tooltip="true" />
+        <el-table-column label="鍏憡绫诲瀷" align="center" prop="noticeType" width="100">
+          <template #default="scope">
+            <dict-tag :options="sys_notice_type" :value="scope.row.noticeType" />
+          </template>
+        </el-table-column>
+        <el-table-column label="鐘舵��" align="center" prop="status" width="100">
+          <template #default="scope">
+            <dict-tag :options="sys_notice_status" :value="scope.row.status" />
+          </template>
+        </el-table-column>
+        <el-table-column label="鍒涘缓鑰�" align="center" prop="createByName" width="100" />
+        <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="100">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-tooltip content="淇敼" placement="top">
+              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:notice:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="鍒犻櫎" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:notice:remove']"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+    </el-card>
+    <!-- 娣诲姞鎴栦慨鏀瑰叕鍛婂璇濇 -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="780px" append-to-body>
+      <el-form ref="noticeFormRef" :model="form" :rules="rules" label-width="80px">
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="鍏憡鏍囬" prop="noticeTitle">
+              <el-input v-model="form.noticeTitle" placeholder="璇疯緭鍏ュ叕鍛婃爣棰�" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍏憡绫诲瀷" prop="noticeType">
+              <el-select v-model="form.noticeType" placeholder="璇烽�夋嫨">
+                <el-option v-for="dict in sys_notice_type" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="鐘舵��">
+              <el-radio-group v-model="form.status">
+                <el-radio v-for="dict in sys_notice_status" :key="dict.value" :label="dict.value">{{ dict.label
+                }}</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="鍐呭">
+              <editor v-model="form.noticeContent" :min-height="192" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
 <script setup name="Notice" lang="ts">
 import { listNotice, getNotice, delNotice, addNotice, updateNotice } from "@/api/system/notice";
 import { ComponentInternalInstance } from "vue";
@@ -20,229 +139,111 @@
 
 
 const dialog = reactive<DialogOption>({
-	visible: false,
-	title: ''
+    visible: false,
+    title: ''
 });
 
 const initFormData: NoticeForm = {
-	noticeId: undefined,
-	noticeTitle: '',
-	noticeType: '',
-	noticeContent: '',
-	status: "0",
-	remark: '',
-	createByName: ''
+    noticeId: undefined,
+    noticeTitle: '',
+    noticeType: '',
+    noticeContent: '',
+    status: "0",
+    remark: '',
+    createByName: ''
 }
 const data = reactive<PageData<NoticeForm, NoticeQuery>>({
-	form: { ...initFormData },
-	queryParams: {
-		pageNum: 1,
-		pageSize: 10,
-		noticeTitle: '',
-		createByName: '',
-		status: '',
-		noticeType: ''
-	},
-	rules: {
-		noticeTitle: [{ required: true, message: "鍏憡鏍囬涓嶈兘涓虹┖", trigger: "blur" }],
-		noticeType: [{ required: true, message: "鍏憡绫诲瀷涓嶈兘涓虹┖", trigger: "change" }]
-	},
+    form: { ...initFormData },
+    queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        noticeTitle: '',
+        createByName: '',
+        status: '',
+        noticeType: ''
+    },
+    rules: {
+        noticeTitle: [{ required: true, message: "鍏憡鏍囬涓嶈兘涓虹┖", trigger: "blur" }],
+        noticeType: [{ required: true, message: "鍏憡绫诲瀷涓嶈兘涓虹┖", trigger: "change" }]
+    },
 });
 
 const { queryParams, form, rules } = toRefs(data);
 
 /** 鏌ヨ鍏憡鍒楄〃 */
 const getList = async () => {
-	loading.value = true;
-	const res = await listNotice(queryParams.value);
-	noticeList.value = res.rows;
-	total.value = res.total;
-	loading.value = false;
+    loading.value = true;
+    const res = await listNotice(queryParams.value);
+    noticeList.value = res.rows;
+    total.value = res.total;
+    loading.value = false;
 }
 /** 鍙栨秷鎸夐挳 */
 const cancel = () => {
-	reset();
-	dialog.visible = false;
+    reset();
+    dialog.visible = false;
 }
 /** 琛ㄥ崟閲嶇疆 */
 const reset = () => {
-	form.value = { ...initFormData };
-	noticeFormRef.value.resetFields();
+    form.value = { ...initFormData };
+    noticeFormRef.value.resetFields();
 }
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-	queryParams.value.pageNum = 1;
-	getList();
+    queryParams.value.pageNum = 1;
+    getList();
 }
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 const resetQuery = () => {
-	queryFormRef.value.resetFields();
-	handleQuery();
+    queryFormRef.value.resetFields();
+    handleQuery();
 }
 /** 澶氶�夋閫変腑鏁版嵁 */
 const handleSelectionChange = (selection: NoticeVO[]) => {
-	ids.value = selection.map(item => item.noticeId);
-	single.value = selection.length != 1;
-	multiple.value = !selection.length;
+    ids.value = selection.map(item => item.noticeId);
+    single.value = selection.length != 1;
+    multiple.value = !selection.length;
 }
 /** 鏂板鎸夐挳鎿嶄綔 */
 const handleAdd = () => {
-	dialog.visible = true;
-	dialog.title = "娣诲姞鍏憡";
-	nextTick(() => {
-		reset();
-	})
+    dialog.visible = true;
+    dialog.title = "娣诲姞鍏憡";
+    nextTick(() => {
+        reset();
+    })
 }
 /**淇敼鎸夐挳鎿嶄綔 */
 const handleUpdate = (row?: NoticeVO) => {
-	dialog.visible = true;
-	dialog.title = "淇敼鍏憡";
-	nextTick(async () => {
-		const noticeId = row?.noticeId || ids.value[0];
-		reset();
-		const { data } = await getNotice(noticeId);
-		form.value = data;
-	})
+    dialog.visible = true;
+    dialog.title = "淇敼鍏憡";
+    nextTick(async () => {
+        const noticeId = row?.noticeId || ids.value[0];
+        reset();
+        const { data } = await getNotice(noticeId);
+        form.value = data;
+    })
 }
 /** 鎻愪氦鎸夐挳 */
 const submitForm = () => {
-	noticeFormRef.value.validate(async (valid: boolean) => {
-		if (valid) {
-			form.value.noticeId ? await updateNotice(form.value) : await addNotice(form.value);
-			proxy?.$modal.msgSuccess("淇敼鎴愬姛");
-			dialog.visible = false;
-			getList();
-		}
-	});
+    noticeFormRef.value.validate(async (valid: boolean) => {
+        if (valid) {
+            form.value.noticeId ? await updateNotice(form.value) : await addNotice(form.value);
+            proxy?.$modal.msgSuccess("淇敼鎴愬姛");
+            dialog.visible = false;
+            getList();
+        }
+    });
 }
 /** 鍒犻櫎鎸夐挳鎿嶄綔 */
 const handleDelete = async (row?: NoticeVO) => {
-	const noticeIds = row?.noticeId || ids.value
-	await proxy?.$modal.confirm('鏄惁纭鍒犻櫎鍏憡缂栧彿涓�"' + noticeIds + '"鐨勬暟鎹」锛�');
-	await delNotice(noticeIds);
-	getList();
-	proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    const noticeIds = row?.noticeId || ids.value
+    await proxy?.$modal.confirm('鏄惁纭鍒犻櫎鍏憡缂栧彿涓�"' + noticeIds + '"鐨勬暟鎹」锛�');
+    await delNotice(noticeIds);
+    getList();
+    proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
 }
 
 onMounted(() => {
-	getList();
+    getList();
 })
-</script>
-<template>
-	<div class="p-2">
-		<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-			<div class="search" v-show="showSearch">
-				<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
-					<el-form-item label="鍏憡鏍囬" prop="noticeTitle">
-						<el-input v-model="queryParams.noticeTitle" placeholder="璇疯緭鍏ュ叕鍛婃爣棰�" clearable style="width: 200px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鎿嶄綔浜哄憳" prop="createByName">
-						<el-input v-model="queryParams.createByName" placeholder="璇疯緭鍏ユ搷浣滀汉鍛�" clearable style="width: 200px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="绫诲瀷" prop="noticeType">
-						<el-select v-model="queryParams.noticeType" placeholder="鍏憡绫诲瀷" clearable style="width: 200px">
-							<el-option v-for="dict in sys_notice_type" :key="dict.value" :label="dict.label" :value="dict.value" />
-						</el-select>
-					</el-form-item>
-					<el-form-item>
-						<el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
-						<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-					</el-form-item>
-				</el-form>
-			</div>
-		</transition>
-
-		<el-card shadow="never">
-			<template #header>
-				<el-row :gutter="10" class="mb8">
-					<el-col :span="1.5">
-						<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:notice:add']">鏂板</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:notice:edit']"
-							>淇敼</el-button
-						>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:notice:remove']">
-							鍒犻櫎
-						</el-button>
-					</el-col>
-					<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-				</el-row>
-			</template>
-
-			<el-table v-loading="loading" :data="noticeList" @selection-change="handleSelectionChange">
-				<el-table-column type="selection" width="55" align="center" />
-				<el-table-column label="搴忓彿" align="center" prop="noticeId" width="100" v-if="false" />
-				<el-table-column label="鍏憡鏍囬" align="center" prop="noticeTitle" :show-overflow-tooltip="true" />
-				<el-table-column label="鍏憡绫诲瀷" align="center" prop="noticeType" width="100">
-					<template #default="scope">
-						<dict-tag :options="sys_notice_type" :value="scope.row.noticeType" />
-					</template>
-				</el-table-column>
-				<el-table-column label="鐘舵��" align="center" prop="status" width="100">
-					<template #default="scope">
-						<dict-tag :options="sys_notice_status" :value="scope.row.status" />
-					</template>
-				</el-table-column>
-				<el-table-column label="鍒涘缓鑰�" align="center" prop="createByName" width="100" />
-				<el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="100">
-					<template #default="scope">
-						<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
-					</template>
-				</el-table-column>
-				<el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
-					<template #default="scope">
-						<el-tooltip content="淇敼" placement="top">
-							<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:notice:edit']"></el-button>
-						</el-tooltip>
-						<el-tooltip content="鍒犻櫎" placement="top">
-							<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:notice:remove']"></el-button>
-						</el-tooltip>
-					</template>
-				</el-table-column>
-			</el-table>
-
-			<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
-		</el-card>
-		<!-- 娣诲姞鎴栦慨鏀瑰叕鍛婂璇濇 -->
-		<el-dialog :title="dialog.title" v-model="dialog.visible" width="780px" append-to-body>
-			<el-form ref="noticeFormRef" :model="form" :rules="rules" label-width="80px">
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="鍏憡鏍囬" prop="noticeTitle">
-							<el-input v-model="form.noticeTitle" placeholder="璇疯緭鍏ュ叕鍛婃爣棰�" />
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="鍏憡绫诲瀷" prop="noticeType">
-							<el-select v-model="form.noticeType" placeholder="璇烽�夋嫨">
-								<el-option v-for="dict in sys_notice_type" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
-							</el-select>
-						</el-form-item>
-					</el-col>
-					<el-col :span="24">
-						<el-form-item label="鐘舵��">
-							<el-radio-group v-model="form.status">
-								<el-radio v-for="dict in sys_notice_status" :key="dict.value" :label="dict.value">{{ dict.label
-								}}</el-radio>
-							</el-radio-group>
-						</el-form-item>
-					</el-col>
-					<el-col :span="24">
-						<el-form-item label="鍐呭">
-							<editor v-model="form.noticeContent" :min-height="192" />
-						</el-form-item>
-					</el-col>
-				</el-row>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
-					<el-button @click="cancel">鍙� 娑�</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</div>
-</template>
+</script>
\ No newline at end of file
diff --git a/src/views/system/oss/config.vue b/src/views/system/oss/config.vue
index 7b31987..2d74633 100644
--- a/src/views/system/oss/config.vue
+++ b/src/views/system/oss/config.vue
@@ -1,11 +1,142 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+          <el-form-item label="閰嶇疆key" prop="configKey">
+            <el-input v-model="queryParams.configKey" placeholder="閰嶇疆key" clearable style="width: 200px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="妗跺悕绉�" prop="bucketName">
+            <el-input v-model="queryParams.bucketName" placeholder="璇疯緭鍏ユ《鍚嶇О" clearable style="width: 200px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鏄惁榛樿" prop="status">
+            <el-select v-model="queryParams.status" placeholder="璇烽�夋嫨鐘舵��" clearable style="width: 200px">
+              <el-option key="0" label="鏄�" value="0" />
+              <el-option key="1" label="鍚�" value="1" />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="search" @click="handleQuery">鎼滅储</el-button>
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:oss:add']">鏂板</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:oss:edit']">淇敼</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:oss:remove']">
+              鍒犻櫎
+            </el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table v-loading="loading" :data="ossConfigList" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="涓诲缓" align="center" prop="ossConfigId" v-if="columns[0].visible" />
+        <el-table-column label="閰嶇疆key" align="center" prop="configKey" v-if="columns[1].visible" />
+        <el-table-column label="璁块棶绔欑偣" align="center" prop="endpoint" v-if="columns[2].visible" width="200" />
+        <el-table-column label="鑷畾涔夊煙鍚�" align="center" prop="domain" v-if="columns[3].visible" width="200" />
+        <el-table-column label="妗跺悕绉�" align="center" prop="bucketName" v-if="columns[4].visible" />
+        <el-table-column label="鍓嶇紑" align="center" prop="prefix" v-if="columns[5].visible" />
+        <el-table-column label="鍩�" align="center" prop="region" v-if="columns[6].visible" />
+        <el-table-column label="妗舵潈闄愮被鍨�" align="center" prop="accessPolicy" v-if="columns[7].visible">
+          <template #default="scope">
+            <el-tag type="warning" v-if="scope.row.accessPolicy === '0'">private</el-tag>
+            <el-tag type="success" v-if="scope.row.accessPolicy === '1'">public</el-tag>
+            <el-tag type="info" v-if="scope.row.accessPolicy === '2'">custom</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="鏄惁榛樿" align="center" prop="status" v-if="columns[8].visible">
+          <template #default="scope">
+            <el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" align="center" width="150" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-tooltip content="淇敼" placement="top">
+              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:oss:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="鍒犻櫎" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:oss:remove']"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+    </el-card>
+    <!-- 娣诲姞鎴栦慨鏀瑰璞″瓨鍌ㄩ厤缃璇濇 -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="800px" append-to-body>
+      <el-form ref="ossConfigFormRef" :model="form" :rules="rules" label-width="120px">
+        <el-form-item label="閰嶇疆key" prop="configKey">
+          <el-input v-model="form.configKey" placeholder="璇疯緭鍏ラ厤缃甼ey" />
+        </el-form-item>
+        <el-form-item label="璁块棶绔欑偣" prop="endpoint">
+          <el-input v-model="form.endpoint" placeholder="璇疯緭鍏ヨ闂珯鐐�" />
+        </el-form-item>
+        <el-form-item label="鑷畾涔夊煙鍚�" prop="domain">
+          <el-input v-model="form.domain" placeholder="璇疯緭鍏ヨ嚜瀹氫箟鍩熷悕" />
+        </el-form-item>
+        <el-form-item label="accessKey" prop="accessKey">
+          <el-input v-model="form.accessKey" placeholder="璇疯緭鍏ccessKey" />
+        </el-form-item>
+        <el-form-item label="secretKey" prop="secretKey">
+          <el-input v-model="form.secretKey" placeholder="璇疯緭鍏ョ閽�" show-password />
+        </el-form-item>
+        <el-form-item label="妗跺悕绉�" prop="bucketName">
+          <el-input v-model="form.bucketName" placeholder="璇疯緭鍏ユ《鍚嶇О" />
+        </el-form-item>
+        <el-form-item label="鍓嶇紑" prop="prefix">
+          <el-input v-model="form.prefix" placeholder="璇疯緭鍏ュ墠缂�" />
+        </el-form-item>
+        <el-form-item label="鏄惁HTTPS">
+          <el-radio-group v-model="form.isHttps">
+            <el-radio v-for="dict in sys_yes_no" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="妗舵潈闄愮被鍨�">
+          <el-radio-group v-model="form.accessPolicy">
+            <el-radio label="0">private</el-radio>
+            <el-radio label="1">public</el-radio>
+            <el-radio label="2">custom</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="鍩�" prop="region">
+          <el-input v-model="form.region" placeholder="璇疯緭鍏ュ煙" />
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
 <script setup name="OssConfig" lang="ts">
 import {
-  listOssConfig,
-  getOssConfig,
-  delOssConfig,
-  addOssConfig,
-  updateOssConfig,
-  changeOssConfigStatus
+    listOssConfig,
+    getOssConfig,
+    delOssConfig,
+    addOssConfig,
+    updateOssConfig,
+    changeOssConfigStatus
 } from "@/api/system/ossConfig";
 import { ComponentInternalInstance } from "vue";
 import { OssConfigForm, OssConfigQuery, OssConfigVO } from "@/api/system/ossConfig/types";
@@ -28,319 +159,189 @@
 const ossConfigFormRef = ref(ElForm);
 
 const dialog = reactive<DialogOption>({
-  visible: false,
-  title: ''
+    visible: false,
+    title: ''
 });
 
 // 鍒楁樉闅愪俊鎭�
 const columns = ref<FieldOption[]>([
-  { key: 0, label: `涓诲缓`, visible: true },
-  { key: 1, label: `閰嶇疆key`, visible: false },
-  { key: 2, label: `璁块棶绔欑偣`, visible: true },
-  { key: 3, label: `鑷畾涔夊煙鍚峘, visible: true },
-  { key: 4, label: `妗跺悕绉癭, visible: true },
-  { key: 5, label: `鍓嶇紑`, visible: true },
-  { key: 6, label: `鍩焋, visible: true },
-  { key: 7, label: `妗舵潈闄愮被鍨媊, visible: true },
-  { key: 8, label: `鐘舵�乣, visible: true }
+    { key: 0, label: `涓诲缓`, visible: true },
+    { key: 1, label: `閰嶇疆key`, visible: false },
+    { key: 2, label: `璁块棶绔欑偣`, visible: true },
+    { key: 3, label: `鑷畾涔夊煙鍚峘, visible: true },
+    { key: 4, label: `妗跺悕绉癭, visible: true },
+    { key: 5, label: `鍓嶇紑`, visible: true },
+    { key: 6, label: `鍩焋, visible: true },
+    { key: 7, label: `妗舵潈闄愮被鍨媊, visible: true },
+    { key: 8, label: `鐘舵�乣, visible: true }
 ]);
 
 
 const initFormData: OssConfigForm = {
-  ossConfigId: undefined,
-  configKey: '',
-  accessKey: '',
-  secretKey: '',
-  bucketName: '',
-  prefix: '',
-  endpoint: '',
-  domain: '',
-  isHttps: "N",
-  accessPolicy: "1",
-  region: '',
-  status: "1",
-  remark: '',
+    ossConfigId: undefined,
+    configKey: '',
+    accessKey: '',
+    secretKey: '',
+    bucketName: '',
+    prefix: '',
+    endpoint: '',
+    domain: '',
+    isHttps: "N",
+    accessPolicy: "1",
+    region: '',
+    status: "1",
+    remark: '',
 }
 const data = reactive<PageData<OssConfigForm, OssConfigQuery>>({
-  form: { ...initFormData },
-  // 鏌ヨ鍙傛暟
-  queryParams: {
-    pageNum: 1,
-    pageSize: 10,
-    configKey: '',
-    bucketName: '',
-    status: '',
-  },
-  rules: {
-    configKey: [{ required: true, message: "configKey涓嶈兘涓虹┖", trigger: "blur" },],
-    accessKey: [
-      { required: true, message: "accessKey涓嶈兘涓虹┖", trigger: "blur" },
-      {
-        min: 2,
-        max: 200,
-        message: "accessKey闀垮害蹇呴』浠嬩簬 2 鍜� 100 涔嬮棿",
-        trigger: "blur",
-      },
-    ],
-    secretKey: [
-      { required: true, message: "secretKey涓嶈兘涓虹┖", trigger: "blur" },
-      {
-        min: 2,
-        max: 100,
-        message: "secretKey闀垮害蹇呴』浠嬩簬 2 鍜� 100 涔嬮棿",
-        trigger: "blur",
-      },
-    ],
-    bucketName: [
-      { required: true, message: "bucketName涓嶈兘涓虹┖", trigger: "blur" },
-      {
-        min: 2,
-        max: 100,
-        message: "bucketName闀垮害蹇呴』浠嬩簬 2 鍜� 100 涔嬮棿",
-        trigger: "blur",
-      },
-    ],
-    endpoint: [
-      { required: true, message: "endpoint涓嶈兘涓虹┖", trigger: "blur" },
-      {
-        min: 2,
-        max: 100,
-        message: "endpoint鍚嶇О闀垮害蹇呴』浠嬩簬 2 鍜� 100 涔嬮棿",
-        trigger: "blur",
-      },
-    ],
-    accessPolicy: [{ required: true, message: "accessPolicy涓嶈兘涓虹┖", trigger: "blur" }]
-  }
+    form: { ...initFormData },
+    // 鏌ヨ鍙傛暟
+    queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        configKey: '',
+        bucketName: '',
+        status: '',
+    },
+    rules: {
+        configKey: [{ required: true, message: "configKey涓嶈兘涓虹┖", trigger: "blur" },],
+        accessKey: [
+            { required: true, message: "accessKey涓嶈兘涓虹┖", trigger: "blur" },
+            {
+                min: 2,
+                max: 200,
+                message: "accessKey闀垮害蹇呴』浠嬩簬 2 鍜� 100 涔嬮棿",
+                trigger: "blur",
+            },
+        ],
+        secretKey: [
+            { required: true, message: "secretKey涓嶈兘涓虹┖", trigger: "blur" },
+            {
+                min: 2,
+                max: 100,
+                message: "secretKey闀垮害蹇呴』浠嬩簬 2 鍜� 100 涔嬮棿",
+                trigger: "blur",
+            },
+        ],
+        bucketName: [
+            { required: true, message: "bucketName涓嶈兘涓虹┖", trigger: "blur" },
+            {
+                min: 2,
+                max: 100,
+                message: "bucketName闀垮害蹇呴』浠嬩簬 2 鍜� 100 涔嬮棿",
+                trigger: "blur",
+            },
+        ],
+        endpoint: [
+            { required: true, message: "endpoint涓嶈兘涓虹┖", trigger: "blur" },
+            {
+                min: 2,
+                max: 100,
+                message: "endpoint鍚嶇О闀垮害蹇呴』浠嬩簬 2 鍜� 100 涔嬮棿",
+                trigger: "blur",
+            },
+        ],
+        accessPolicy: [{ required: true, message: "accessPolicy涓嶈兘涓虹┖", trigger: "blur" }]
+    }
 });
 
 const { queryParams, form, rules } = toRefs(data);
 
 /** 鏌ヨ瀵硅薄瀛樺偍閰嶇疆鍒楄〃 */
 const getList = async () => {
-  loading.value = true;
-  const res = await listOssConfig(queryParams.value);
-  ossConfigList.value = res.rows;
-  total.value = res.total;
-  loading.value = false;
+    loading.value = true;
+    const res = await listOssConfig(queryParams.value);
+    ossConfigList.value = res.rows;
+    total.value = res.total;
+    loading.value = false;
 }
 /** 鍙栨秷鎸夐挳 */
 const cancel = () => {
-  dialog.visible = false;
-  reset();
+    dialog.visible = false;
+    reset();
 }
 /** 琛ㄥ崟閲嶇疆 */
 const reset = () => {
-  form.value = { ...initFormData };
-  ossConfigFormRef.value.resetFields();
+    form.value = { ...initFormData };
+    ossConfigFormRef.value.resetFields();
 }
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-  queryParams.value.pageNum = 1;
-  getList();
+    queryParams.value.pageNum = 1;
+    getList();
 }
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 const resetQuery = () => {
-  queryFormRef.value.resetFields();
-  handleQuery();
+    queryFormRef.value.resetFields();
+    handleQuery();
 }
 /** 閫夋嫨鏉℃暟  */
 const handleSelectionChange = (selection: OssConfigVO[]) => {
-  ids.value = selection.map(item => item.ossConfigId);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
+    ids.value = selection.map(item => item.ossConfigId);
+    single.value = selection.length != 1;
+    multiple.value = !selection.length;
 }
 /** 鏂板鎸夐挳鎿嶄綔 */
 const handleAdd = () => {
-  dialog.visible = true;
-  dialog.title = "娣诲姞瀵硅薄瀛樺偍閰嶇疆";
-  nextTick(() => {
-    reset();
-  })
+    dialog.visible = true;
+    dialog.title = "娣诲姞瀵硅薄瀛樺偍閰嶇疆";
+    nextTick(() => {
+        reset();
+    })
 }
 /** 淇敼鎸夐挳鎿嶄綔 */
 const handleUpdate = (row?: OssConfigVO) => {
-  loading.value = true;
-  dialog.visible = true;
-  dialog.title = "淇敼瀵硅薄瀛樺偍閰嶇疆";
-  const ossConfigId = row?.ossConfigId || ids.value[0];
-  nextTick(async () => {
-    reset();
-    const res = await getOssConfig(ossConfigId);
-    loading.value = false;
-    form.value = res.data;
-  })
+    loading.value = true;
+    dialog.visible = true;
+    dialog.title = "淇敼瀵硅薄瀛樺偍閰嶇疆";
+    const ossConfigId = row?.ossConfigId || ids.value[0];
+    nextTick(async () => {
+        reset();
+        const res = await getOssConfig(ossConfigId);
+        loading.value = false;
+        form.value = res.data;
+    })
 }
 /** 鎻愪氦鎸夐挳 */
 const submitForm = () => {
-  ossConfigFormRef.value.validate(async (valid: boolean) => {
-    if (valid) {
-      buttonLoading.value = true;
-      if (form.value.ossConfigId) {
-        await updateOssConfig(form.value).finally(() => buttonLoading.value = false);
-      } else {
-        await addOssConfig(form.value).finally(() => buttonLoading.value = false);
-      }
-      proxy?.$modal.msgSuccess("鏂板鎴愬姛");
-      dialog.visible = false;
-      getList();
-    }
-  });
+    ossConfigFormRef.value.validate(async (valid: boolean) => {
+        if (valid) {
+            buttonLoading.value = true;
+            if (form.value.ossConfigId) {
+                await updateOssConfig(form.value).finally(() => buttonLoading.value = false);
+            } else {
+                await addOssConfig(form.value).finally(() => buttonLoading.value = false);
+            }
+            proxy?.$modal.msgSuccess("鏂板鎴愬姛");
+            dialog.visible = false;
+            getList();
+        }
+    });
 }
 /** 鐘舵�佷慨鏀�  */
 const  handleStatusChange = async (row: OssConfigVO) => {
-  let text = row.status === "0" ? "鍚敤" : "鍋滅敤";
-  try {
-    await proxy?.$modal.confirm('纭瑕�"' + text + '""' + row.configKey + '"閰嶇疆鍚�?');
-    await changeOssConfigStatus(row.ossConfigId, row.status, row.configKey);
-    getList()
-    proxy?.$modal.msgSuccess(text + "鎴愬姛");
-  } catch { return } finally {
-    row.status = row.status === "0" ? "1" : "0";
-  }
+    let text = row.status === "0" ? "鍚敤" : "鍋滅敤";
+    try {
+        await proxy?.$modal.confirm('纭瑕�"' + text + '""' + row.configKey + '"閰嶇疆鍚�?');
+        await changeOssConfigStatus(row.ossConfigId, row.status, row.configKey);
+        getList()
+        proxy?.$modal.msgSuccess(text + "鎴愬姛");
+    } catch { return } finally {
+        row.status = row.status === "0" ? "1" : "0";
+    }
 
 }
 /** 鍒犻櫎鎸夐挳鎿嶄綔 */
 const handleDelete = async (row?: OssConfigVO) => {
-  const ossConfigIds = row?.ossConfigId || ids.value;
-  await proxy?.$modal.confirm('鏄惁纭鍒犻櫎OSS閰嶇疆缂栧彿涓�"' + ossConfigIds + '"鐨勬暟鎹」?');
-  loading.value = true;
-  await delOssConfig(ossConfigIds).finally(() => loading.value = false);
-  getList();
-  proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    const ossConfigIds = row?.ossConfigId || ids.value;
+    await proxy?.$modal.confirm('鏄惁纭鍒犻櫎OSS閰嶇疆缂栧彿涓�"' + ossConfigIds + '"鐨勬暟鎹」?');
+    loading.value = true;
+    await delOssConfig(ossConfigIds).finally(() => loading.value = false);
+    getList();
+    proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
 
 }
 
 onMounted(() => {
-  getList();
+    getList();
 })
-</script>
-<template>
-	<div class="p-2">
-		<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-			<div class="search" v-show="showSearch">
-				<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
-					<el-form-item label="閰嶇疆key" prop="configKey">
-						<el-input v-model="queryParams.configKey" placeholder="閰嶇疆key" clearable style="width: 200px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="妗跺悕绉�" prop="bucketName">
-						<el-input v-model="queryParams.bucketName" placeholder="璇疯緭鍏ユ《鍚嶇О" clearable style="width: 200px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鏄惁榛樿" prop="status">
-						<el-select v-model="queryParams.status" placeholder="璇烽�夋嫨鐘舵��" clearable style="width: 200px">
-							<el-option key="0" label="鏄�" value="0" />
-							<el-option key="1" label="鍚�" value="1" />
-						</el-select>
-					</el-form-item>
-					<el-form-item>
-						<el-button type="primary" icon="search" @click="handleQuery">鎼滅储</el-button>
-						<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-					</el-form-item>
-				</el-form>
-			</div>
-		</transition>
-
-		<el-card shadow="never">
-			<template #header>
-				<el-row :gutter="10" class="mb8">
-					<el-col :span="1.5">
-						<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:oss:add']">鏂板</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:oss:edit']">淇敼</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:oss:remove']">
-							鍒犻櫎
-						</el-button>
-					</el-col>
-					<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-				</el-row>
-			</template>
-
-			<el-table v-loading="loading" :data="ossConfigList" @selection-change="handleSelectionChange">
-				<el-table-column type="selection" width="55" align="center" />
-				<el-table-column label="涓诲缓" align="center" prop="ossConfigId" v-if="columns[0].visible" />
-				<el-table-column label="閰嶇疆key" align="center" prop="configKey" v-if="columns[1].visible" />
-				<el-table-column label="璁块棶绔欑偣" align="center" prop="endpoint" v-if="columns[2].visible" width="200" />
-				<el-table-column label="鑷畾涔夊煙鍚�" align="center" prop="domain" v-if="columns[3].visible" width="200" />
-				<el-table-column label="妗跺悕绉�" align="center" prop="bucketName" v-if="columns[4].visible" />
-				<el-table-column label="鍓嶇紑" align="center" prop="prefix" v-if="columns[5].visible" />
-				<el-table-column label="鍩�" align="center" prop="region" v-if="columns[6].visible" />
-				<el-table-column label="妗舵潈闄愮被鍨�" align="center" prop="accessPolicy" v-if="columns[7].visible">
-					<template #default="scope">
-						<el-tag type="warning" v-if="scope.row.accessPolicy === '0'">private</el-tag>
-						<el-tag type="success" v-if="scope.row.accessPolicy === '1'">public</el-tag>
-						<el-tag type="info" v-if="scope.row.accessPolicy === '2'">custom</el-tag>
-					</template>
-				</el-table-column>
-				<el-table-column label="鏄惁榛樿" align="center" prop="status" v-if="columns[8].visible">
-					<template #default="scope">
-						<el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
-					</template>
-				</el-table-column>
-				<el-table-column label="鎿嶄綔" align="center" width="150" class-name="small-padding fixed-width">
-					<template #default="scope">
-						<el-tooltip content="淇敼" placement="top">
-							<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:oss:edit']"></el-button>
-						</el-tooltip>
-						<el-tooltip content="鍒犻櫎" placement="top">
-							<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:oss:remove']"></el-button>
-						</el-tooltip>
-					</template>
-				</el-table-column>
-			</el-table>
-
-			<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
-		</el-card>
-		<!-- 娣诲姞鎴栦慨鏀瑰璞″瓨鍌ㄩ厤缃璇濇 -->
-		<el-dialog :title="dialog.title" v-model="dialog.visible" width="800px" append-to-body>
-			<el-form ref="ossConfigFormRef" :model="form" :rules="rules" label-width="120px">
-				<el-form-item label="閰嶇疆key" prop="configKey">
-					<el-input v-model="form.configKey" placeholder="璇疯緭鍏ラ厤缃甼ey" />
-				</el-form-item>
-				<el-form-item label="璁块棶绔欑偣" prop="endpoint">
-					<el-input v-model="form.endpoint" placeholder="璇疯緭鍏ヨ闂珯鐐�" />
-				</el-form-item>
-				<el-form-item label="鑷畾涔夊煙鍚�" prop="domain">
-					<el-input v-model="form.domain" placeholder="璇疯緭鍏ヨ嚜瀹氫箟鍩熷悕" />
-				</el-form-item>
-				<el-form-item label="accessKey" prop="accessKey">
-					<el-input v-model="form.accessKey" placeholder="璇疯緭鍏ccessKey" />
-				</el-form-item>
-				<el-form-item label="secretKey" prop="secretKey">
-					<el-input v-model="form.secretKey" placeholder="璇疯緭鍏ョ閽�" show-password />
-				</el-form-item>
-				<el-form-item label="妗跺悕绉�" prop="bucketName">
-					<el-input v-model="form.bucketName" placeholder="璇疯緭鍏ユ《鍚嶇О" />
-				</el-form-item>
-				<el-form-item label="鍓嶇紑" prop="prefix">
-					<el-input v-model="form.prefix" placeholder="璇疯緭鍏ュ墠缂�" />
-				</el-form-item>
-				<el-form-item label="鏄惁HTTPS">
-					<el-radio-group v-model="form.isHttps">
-						<el-radio v-for="dict in sys_yes_no" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
-					</el-radio-group>
-				</el-form-item>
-				<el-form-item label="妗舵潈闄愮被鍨�">
-					<el-radio-group v-model="form.accessPolicy">
-						<el-radio label="0">private</el-radio>
-						<el-radio label="1">public</el-radio>
-						<el-radio label="2">custom</el-radio>
-					</el-radio-group>
-				</el-form-item>
-				<el-form-item label="鍩�" prop="region">
-					<el-input v-model="form.region" placeholder="璇疯緭鍏ュ煙" />
-				</el-form-item>
-				<el-form-item label="澶囨敞" prop="remark">
-					<el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" />
-				</el-form-item>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
-					<el-button @click="cancel">鍙� 娑�</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</div>
-</template>
+</script>
\ No newline at end of file
diff --git a/src/views/system/oss/index.vue b/src/views/system/oss/index.vue
index 2ffe927..8bd94ee 100644
--- a/src/views/system/oss/index.vue
+++ b/src/views/system/oss/index.vue
@@ -1,3 +1,135 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+          <el-form-item label="鏂囦欢鍚�" prop="fileName">
+            <el-input v-model="queryParams.fileName" placeholder="璇疯緭鍏ユ枃浠跺悕" clearable style="width: 200px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鍘熷悕" prop="originalName">
+            <el-input v-model="queryParams.originalName" placeholder="璇疯緭鍏ュ師鍚�" clearable style="width: 200px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鏂囦欢鍚庣紑" prop="fileSuffix">
+            <el-input v-model="queryParams.fileSuffix" placeholder="璇疯緭鍏ユ枃浠跺悗缂�" clearable style="width: 200px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鍒涘缓鏃堕棿">
+            <el-date-picker
+              v-model="daterangeCreateTime"
+              value-format="YYYY-MM-DD HH:mm:ss"
+              type="daterange"
+              range-separator="-"
+              start-placeholder="寮�濮嬫棩鏈�"
+              end-placeholder="缁撴潫鏃ユ湡"
+              :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
+            ></el-date-picker>
+          </el-form-item>
+          <el-form-item label="鏈嶅姟鍟�" prop="service">
+            <el-input v-model="queryParams.service" placeholder="璇疯緭鍏ユ湇鍔″晢" clearable style="width: 200px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="search" @click="handleQuery">鎼滅储</el-button>
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Upload" @click="handleFile" v-hasPermi="['system:oss:upload']">涓婁紶鏂囦欢</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Upload" @click="handleImage" v-hasPermi="['system:oss:upload']">涓婁紶鍥剧墖</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:oss:remove']">
+              鍒犻櫎
+            </el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button
+              :type="previewListResource ? 'danger' : 'warning'"
+              plain
+              @click="handlePreviewListResource(!previewListResource)"
+              v-hasPermi="['system:oss:edit']"
+              >棰勮寮�鍏� :
+              {{
+                previewListResource ? "绂佺敤" : "鍚敤" }}</el-button
+            >
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="info" plain icon="Operation" @click="handleOssConfig" v-hasPermi="['system:oss:list']">閰嶇疆绠$悊</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table
+        v-loading="loading"
+        :data="ossList"
+        @selection-change="handleSelectionChange"
+        :header-cell-class-name="handleHeaderClass"
+        @header-click="handleHeaderCLick"
+        v-if="showTable"
+      >
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="瀵硅薄瀛樺偍涓婚敭" align="center" prop="ossId" v-if="false" />
+        <el-table-column label="鏂囦欢鍚�" align="center" prop="fileName" />
+        <el-table-column label="鍘熷悕" align="center" prop="originalName" />
+        <el-table-column label="鏂囦欢鍚庣紑" align="center" prop="fileSuffix" />
+        <el-table-column label="鏂囦欢灞曠ず" align="center" prop="url">
+          <template #default="scope">
+            <ImagePreview
+              v-if="previewListResource && checkFileSuffix(scope.row.fileSuffix)"
+              :width="100"
+              :height="100"
+              :src="scope.row.url"
+              :preview-src-list="[scope.row.url]"
+            />
+            <span v-text="scope.row.url" v-if="!checkFileSuffix(scope.row.fileSuffix) || !previewListResource" />
+          </template>
+        </el-table-column>
+        <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180" sortable="custom">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="涓婁紶浜�" align="center" prop="createByName" />
+        <el-table-column label="鏈嶅姟鍟�" align="center" prop="service" sortable="custom" />
+        <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-tooltip content="涓嬭浇" placement="top">
+              <el-button link type="primary" icon="Download" @click="handleDownload(scope.row)" v-hasPermi="['system:oss:download']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="鍒犻櫎" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:oss:remove']"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+    </el-card>
+    <!-- 娣诲姞鎴栦慨鏀筄SS瀵硅薄瀛樺偍瀵硅瘽妗� -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
+      <el-form ref="ossFormRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="鏂囦欢鍚�">
+          <fileUpload v-model="form.file" v-if="type === 0" />
+          <imageUpload v-model="form.file" v-if="type === 1" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
 <script setup name="Oss" lang="ts">
 import { listOss, delOss } from "@/api/system/oss";
 import ImagePreview from "@/components/ImagePreview/index.vue";
@@ -22,8 +154,8 @@
 const daterangeCreateTime = ref<[DateModelType, DateModelType]>(['', '']);
 
 const dialog = reactive<DialogOption>({
-	visible: false,
-	title: ''
+    visible: false,
+    title: ''
 });
 
 // 榛樿鎺掑簭
@@ -33,310 +165,178 @@
 const queryFormRef = ref(ElForm);
 
 const initFormData = {
-	file: undefined,
+    file: undefined,
 }
 const data = reactive<PageData<OssForm, OssQuery>>({
-	form: { ...initFormData },
-	// 鏌ヨ鍙傛暟
-	queryParams: {
-		pageNum: 1,
-		pageSize: 10,
-		fileName: '',
-		originalName: '',
-		fileSuffix: '',
-		createTime: '',
-		service: '',
-		orderByColumn: defaultSort.value.prop,
-		isAsc: defaultSort.value.order
-	},
-	rules: {
-		file: [
-			{ required: true, message: "鏂囦欢涓嶈兘涓虹┖", trigger: "blur" }
-		]
-	}
+    form: { ...initFormData },
+    // 鏌ヨ鍙傛暟
+    queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        fileName: '',
+        originalName: '',
+        fileSuffix: '',
+        createTime: '',
+        service: '',
+        orderByColumn: defaultSort.value.prop,
+        isAsc: defaultSort.value.order
+    },
+    rules: {
+        file: [
+            { required: true, message: "鏂囦欢涓嶈兘涓虹┖", trigger: "blur" }
+        ]
+    }
 });
 
 const { queryParams, form, rules } = toRefs(data);
 
 /** 鏌ヨOSS瀵硅薄瀛樺偍鍒楄〃 */
 const getList = async () => {
-	loading.value = true;
-	const res = await proxy?.getConfigKey("sys.oss.previewListResource");
-	previewListResource.value = res?.msg === undefined ? true : res.msg === 'true';
-	const response = await listOss(proxy?.addDateRange(queryParams.value, daterangeCreateTime.value, "CreateTime"));
-	ossList.value = response.rows;
-	total.value = response.total;
-	loading.value = false;
-	showTable.value = true;
+    loading.value = true;
+    const res = await proxy?.getConfigKey("sys.oss.previewListResource");
+    previewListResource.value = res?.msg === undefined ? true : res.msg === 'true';
+    const response = await listOss(proxy?.addDateRange(queryParams.value, daterangeCreateTime.value, "CreateTime"));
+    ossList.value = response.rows;
+    total.value = response.total;
+    loading.value = false;
+    showTable.value = true;
 }
 function checkFileSuffix(fileSuffix: string[]) {
-	let arr = ["png", "jpg", "jpeg"];
-	return arr.some(type => {
-		return fileSuffix.indexOf(type) > -1;
-	});
+    let arr = ["png", "jpg", "jpeg"];
+    return arr.some(type => {
+        return fileSuffix.indexOf(type) > -1;
+    });
 }
 /** 鍙栨秷鎸夐挳 */
 function cancel() {
-	dialog.visible = false;
-	reset();
+    dialog.visible = false;
+    reset();
 }
 /** 琛ㄥ崟閲嶇疆 */
 function reset() {
-	form.value = { ...initFormData };
-	ossFormRef.value.resetFields();
+    form.value = { ...initFormData };
+    ossFormRef.value.resetFields();
 }
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 function handleQuery() {
-	queryParams.value.pageNum = 1;
-	getList();
+    queryParams.value.pageNum = 1;
+    getList();
 }
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 function resetQuery() {
-	showTable.value = false;
-	daterangeCreateTime.value = ['', ''];
-	queryFormRef.value.resetFields();
-	queryParams.value.orderByColumn = defaultSort.value.prop;
-	queryParams.value.isAsc = defaultSort.value.order;
-	handleQuery();
+    showTable.value = false;
+    daterangeCreateTime.value = ['', ''];
+    queryFormRef.value.resetFields();
+    queryParams.value.orderByColumn = defaultSort.value.prop;
+    queryParams.value.isAsc = defaultSort.value.order;
+    handleQuery();
 }
 /** 閫夋嫨鏉℃暟  */
 function handleSelectionChange(selection: OssVO[]) {
-	ids.value = selection.map(item => item.ossId);
-	single.value = selection.length != 1;
-	multiple.value = !selection.length;
+    ids.value = selection.map(item => item.ossId);
+    single.value = selection.length != 1;
+    multiple.value = !selection.length;
 }
 /** 璁剧疆鍒楃殑鎺掑簭涓烘垜浠嚜瀹氫箟鐨勬帓搴� */
 const handleHeaderClass = ({ column }: any): any => {
-	column.order = column.multiOrder
+    column.order = column.multiOrder
 }
 /** 鐐瑰嚮琛ㄥご杩涜鎺掑簭 */
 const handleHeaderCLick = (column: any) => {
-	if (column.sortable !== 'custom') {
-		return
-	}
-	switch (column.multiOrder) {
-		case 'descending':
-			column.multiOrder = 'ascending';
-			break;
-		case 'ascending':
-			column.multiOrder = '';
-			break;
-		default:
-			column.multiOrder = 'descending';
-			break;
-	}
-	handleOrderChange(column.property, column.multiOrder)
+    if (column.sortable !== 'custom') {
+        return
+    }
+    switch (column.multiOrder) {
+        case 'descending':
+            column.multiOrder = 'ascending';
+            break;
+        case 'ascending':
+            column.multiOrder = '';
+            break;
+        default:
+            column.multiOrder = 'descending';
+            break;
+    }
+    handleOrderChange(column.property, column.multiOrder)
 }
 const handleOrderChange = (prop: string, order: string) => {
-	let orderByArr = queryParams.value.orderByColumn ? queryParams.value.orderByColumn.split(",") : [];
-	let isAscArr = queryParams.value.isAsc ? queryParams.value.isAsc.split(",") : [];
-	let propIndex = orderByArr.indexOf(prop)
-	if (propIndex !== -1) {
-		if (order) {
-			//鎺掑簭閲屽凡瀛樺湪 鍙慨鏀规帓搴�
-			isAscArr[propIndex] = order;
-		} else {
-			//濡傛灉order涓簄ull 鍒欏垹闄ゆ帓搴忓瓧娈靛拰灞炴��
-			isAscArr.splice(propIndex, 1);//鍒犻櫎鎺掑簭
-			orderByArr.splice(propIndex, 1);//鍒犻櫎灞炴��
-		}
-	} else {
-		//鎺掑簭閲屼笉瀛樺湪鍒欐柊澧炴帓搴�
-		orderByArr.push(prop);
-		isAscArr.push(order);
-	}
-	//鍚堝苟鎺掑簭
-	queryParams.value.orderByColumn = orderByArr.join(",");
-	queryParams.value.isAsc = isAscArr.join(",");
-	getList();
+    let orderByArr = queryParams.value.orderByColumn ? queryParams.value.orderByColumn.split(",") : [];
+    let isAscArr = queryParams.value.isAsc ? queryParams.value.isAsc.split(",") : [];
+    let propIndex = orderByArr.indexOf(prop)
+    if (propIndex !== -1) {
+        if (order) {
+            //鎺掑簭閲屽凡瀛樺湪 鍙慨鏀规帓搴�
+            isAscArr[propIndex] = order;
+        } else {
+            //濡傛灉order涓簄ull 鍒欏垹闄ゆ帓搴忓瓧娈靛拰灞炴��
+            isAscArr.splice(propIndex, 1);//鍒犻櫎鎺掑簭
+            orderByArr.splice(propIndex, 1);//鍒犻櫎灞炴��
+        }
+    } else {
+        //鎺掑簭閲屼笉瀛樺湪鍒欐柊澧炴帓搴�
+        orderByArr.push(prop);
+        isAscArr.push(order);
+    }
+    //鍚堝苟鎺掑簭
+    queryParams.value.orderByColumn = orderByArr.join(",");
+    queryParams.value.isAsc = isAscArr.join(",");
+    getList();
 }
 /** 浠诲姟鏃ュ織鍒楄〃鏌ヨ */
 const handleOssConfig = () => {
-	router.push('/system/oss-config/index')
+    router.push('/system/oss-config/index')
 }
 /** 鏂囦欢鎸夐挳鎿嶄綔 */
 const handleFile = () => {
-	dialog.visible = true;
-	dialog.title = "涓婁紶鏂囦欢";
-	nextTick(() => {
-		reset();
-		type.value = 0;
-	})
+    dialog.visible = true;
+    dialog.title = "涓婁紶鏂囦欢";
+    nextTick(() => {
+        reset();
+        type.value = 0;
+    })
 }
 /** 鍥剧墖鎸夐挳鎿嶄綔 */
 const handleImage = () => {
-	dialog.visible = true;
-	dialog.title = "涓婁紶鍥剧墖";
-	nextTick(() => {
-		reset();
-		type.value = 1;
-	})
+    dialog.visible = true;
+    dialog.title = "涓婁紶鍥剧墖";
+    nextTick(() => {
+        reset();
+        type.value = 1;
+    })
 }
 /** 鎻愪氦鎸夐挳 */
 const submitForm = () => {
-	dialog.visible = false;
-	getList();
+    dialog.visible = false;
+    getList();
 }
 /** 涓嬭浇鎸夐挳鎿嶄綔 */
 const handleDownload = (row: OssVO) => {
-	proxy?.$download.oss(row.ossId)
+    proxy?.$download.oss(row.ossId)
 }
 /** 鐢ㄦ埛鐘舵�佷慨鏀�  */
 const handlePreviewListResource = async (preview: boolean) => {
-	let text = preview ? "鍚敤" : "鍋滅敤";
-	try {
-		await proxy?.$modal.confirm('纭瑕�"' + text + '""棰勮鍒楄〃鍥剧墖"閰嶇疆鍚�?');
-		await proxy?.updateConfigByKey("sys.oss.previewListResource", preview);
-		getList()
-		proxy?.$modal.msgSuccess(text + "鎴愬姛");
-	} catch {
-		previewListResource.value = previewListResource.value !== true;
-	}
+    let text = preview ? "鍚敤" : "鍋滅敤";
+    try {
+        await proxy?.$modal.confirm('纭瑕�"' + text + '""棰勮鍒楄〃鍥剧墖"閰嶇疆鍚�?');
+        await proxy?.updateConfigByKey("sys.oss.previewListResource", preview);
+        getList()
+        proxy?.$modal.msgSuccess(text + "鎴愬姛");
+    } catch {
+        previewListResource.value = previewListResource.value !== true;
+    }
 
 
 }
 /** 鍒犻櫎鎸夐挳鎿嶄綔 */
 const handleDelete = async (row?: OssVO) => {
-	const ossIds = row?.ossId || ids.value;
-	await proxy?.$modal.confirm('鏄惁纭鍒犻櫎OSS瀵硅薄瀛樺偍缂栧彿涓�"' + ossIds + '"鐨勬暟鎹」?');
-	loading.value = true;
-	await delOss(ossIds).finally(() => loading.value = false);
-	getList();
-	proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    const ossIds = row?.ossId || ids.value;
+    await proxy?.$modal.confirm('鏄惁纭鍒犻櫎OSS瀵硅薄瀛樺偍缂栧彿涓�"' + ossIds + '"鐨勬暟鎹」?');
+    loading.value = true;
+    await delOss(ossIds).finally(() => loading.value = false);
+    getList();
+    proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
 }
 onMounted(() => {
-	getList();
+    getList();
 })
 </script>
-
-<template>
-	<div class="p-2">
-		<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-			<div class="search" v-show="showSearch">
-				<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
-					<el-form-item label="鏂囦欢鍚�" prop="fileName">
-						<el-input v-model="queryParams.fileName" placeholder="璇疯緭鍏ユ枃浠跺悕" clearable style="width: 200px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鍘熷悕" prop="originalName">
-						<el-input v-model="queryParams.originalName" placeholder="璇疯緭鍏ュ師鍚�" clearable style="width: 200px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鏂囦欢鍚庣紑" prop="fileSuffix">
-						<el-input v-model="queryParams.fileSuffix" placeholder="璇疯緭鍏ユ枃浠跺悗缂�" clearable style="width: 200px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鍒涘缓鏃堕棿">
-						<el-date-picker
-							v-model="daterangeCreateTime"
-							value-format="YYYY-MM-DD HH:mm:ss"
-							type="daterange"
-							range-separator="-"
-							start-placeholder="寮�濮嬫棩鏈�"
-							end-placeholder="缁撴潫鏃ユ湡"
-							:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
-						></el-date-picker>
-					</el-form-item>
-					<el-form-item label="鏈嶅姟鍟�" prop="service">
-						<el-input v-model="queryParams.service" placeholder="璇疯緭鍏ユ湇鍔″晢" clearable style="width: 200px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item>
-						<el-button type="primary" icon="search" @click="handleQuery">鎼滅储</el-button>
-						<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-					</el-form-item>
-				</el-form>
-			</div>
-		</transition>
-
-		<el-card shadow="never">
-			<template #header>
-				<el-row :gutter="10" class="mb8">
-					<el-col :span="1.5">
-						<el-button type="primary" plain icon="Upload" @click="handleFile" v-hasPermi="['system:oss:upload']">涓婁紶鏂囦欢</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="primary" plain icon="Upload" @click="handleImage" v-hasPermi="['system:oss:upload']">涓婁紶鍥剧墖</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:oss:remove']">
-							鍒犻櫎
-						</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button
-							:type="previewListResource ? 'danger' : 'warning'"
-							plain
-							@click="handlePreviewListResource(!previewListResource)"
-							v-hasPermi="['system:oss:edit']"
-							>棰勮寮�鍏� :
-							{{
-								previewListResource ? "绂佺敤" : "鍚敤" }}</el-button
-						>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="info" plain icon="Operation" @click="handleOssConfig" v-hasPermi="['system:oss:list']">閰嶇疆绠$悊</el-button>
-					</el-col>
-					<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-				</el-row>
-			</template>
-
-			<el-table
-				v-loading="loading"
-				:data="ossList"
-				@selection-change="handleSelectionChange"
-				:header-cell-class-name="handleHeaderClass"
-				@header-click="handleHeaderCLick"
-				v-if="showTable"
-			>
-				<el-table-column type="selection" width="55" align="center" />
-				<el-table-column label="瀵硅薄瀛樺偍涓婚敭" align="center" prop="ossId" v-if="false" />
-				<el-table-column label="鏂囦欢鍚�" align="center" prop="fileName" />
-				<el-table-column label="鍘熷悕" align="center" prop="originalName" />
-				<el-table-column label="鏂囦欢鍚庣紑" align="center" prop="fileSuffix" />
-				<el-table-column label="鏂囦欢灞曠ず" align="center" prop="url">
-					<template #default="scope">
-						<ImagePreview
-							v-if="previewListResource && checkFileSuffix(scope.row.fileSuffix)"
-							:width="100"
-							:height="100"
-							:src="scope.row.url"
-							:preview-src-list="[scope.row.url]"
-						/>
-						<span v-text="scope.row.url" v-if="!checkFileSuffix(scope.row.fileSuffix) || !previewListResource" />
-					</template>
-				</el-table-column>
-				<el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180" sortable="custom">
-					<template #default="scope">
-						<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
-					</template>
-				</el-table-column>
-				<el-table-column label="涓婁紶浜�" align="center" prop="createByName" />
-				<el-table-column label="鏈嶅姟鍟�" align="center" prop="service" sortable="custom" />
-				<el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
-					<template #default="scope">
-						<el-tooltip content="涓嬭浇" placement="top">
-							<el-button link type="primary" icon="Download" @click="handleDownload(scope.row)" v-hasPermi="['system:oss:download']"></el-button>
-						</el-tooltip>
-						<el-tooltip content="鍒犻櫎" placement="top">
-							<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:oss:remove']"></el-button>
-						</el-tooltip>
-					</template>
-				</el-table-column>
-			</el-table>
-
-			<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
-		</el-card>
-		<!-- 娣诲姞鎴栦慨鏀筄SS瀵硅薄瀛樺偍瀵硅瘽妗� -->
-		<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
-			<el-form ref="ossFormRef" :model="form" :rules="rules" label-width="80px">
-				<el-form-item label="鏂囦欢鍚�">
-					<fileUpload v-model="form.file" v-if="type === 0" />
-					<imageUpload v-model="form.file" v-if="type === 1" />
-				</el-form-item>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
-					<el-button @click="cancel">鍙� 娑�</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</div>
-</template>
diff --git a/src/views/system/post/index.vue b/src/views/system/post/index.vue
index 666764b..2dc0ca0 100644
--- a/src/views/system/post/index.vue
+++ b/src/views/system/post/index.vue
@@ -1,3 +1,109 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="70">
+          <el-form-item label="宀椾綅缂栫爜" prop="postCode">
+            <el-input v-model="queryParams.postCode" placeholder="璇疯緭鍏ュ矖浣嶇紪鐮�" clearable style="width: 200px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="宀椾綅鍚嶇О" prop="postName">
+            <el-input v-model="queryParams.postName" placeholder="璇疯緭鍏ュ矖浣嶅悕绉�" clearable style="width: 200px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鐘舵��" prop="status">
+            <el-select v-model="queryParams.status" placeholder="宀椾綅鐘舵��" clearable style="width: 200px">
+              <el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:post:add']">鏂板</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:post:edit']">淇敼</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:post:remove']">
+              鍒犻櫎
+            </el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:post:export']">瀵煎嚭</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="宀椾綅缂栧彿" align="center" prop="postId" v-if="false" />
+        <el-table-column label="宀椾綅缂栫爜" align="center" prop="postCode" />
+        <el-table-column label="宀椾綅鍚嶇О" align="center" prop="postName" />
+        <el-table-column label="宀椾綅鎺掑簭" align="center" prop="postSort" />
+        <el-table-column label="鐘舵��" align="center" prop="status">
+          <template #default="scope">
+            <dict-tag :options="sys_normal_disable" :value="scope.row.status" />
+          </template>
+        </el-table-column>
+        <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.createTime) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" width="180" align="center" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-tooltip content="淇敼" placement="top">
+              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:post:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="鍒犻櫎" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:post:remove']"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+    </el-card>
+
+    <!-- 娣诲姞鎴栦慨鏀瑰矖浣嶅璇濇 -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
+      <el-form ref="postFormRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="宀椾綅鍚嶇О" prop="postName">
+          <el-input v-model="form.postName" placeholder="璇疯緭鍏ュ矖浣嶅悕绉�" />
+        </el-form-item>
+        <el-form-item label="宀椾綅缂栫爜" prop="postCode">
+          <el-input v-model="form.postCode" placeholder="璇疯緭鍏ョ紪鐮佸悕绉�" />
+        </el-form-item>
+        <el-form-item label="宀椾綅椤哄簭" prop="postSort">
+          <el-input-number v-model="form.postSort" controls-position="right" :min="0" />
+        </el-form-item>
+        <el-form-item label="宀椾綅鐘舵��" prop="status">
+          <el-radio-group v-model="form.status">
+            <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
 <script setup name="Post" lang="ts">
 import { listPost, addPost, delPost, getPost, updatePost } from "@/api/system/post";
 import { PostForm, PostQuery, PostVO } from "@/api/system/post/types";
@@ -18,223 +124,117 @@
 const queryFormRef = ref(ElForm);
 
 const dialog = reactive<DialogOption>({
-	visible: false,
-	title: ''
+    visible: false,
+    title: ''
 });
 
 const initFormData: PostForm = {
-	postId: undefined,
-	postCode: '',
-	postName: '',
-	postSort: 0,
-	status: "0",
-	remark: ''
+    postId: undefined,
+    postCode: '',
+    postName: '',
+    postSort: 0,
+    status: "0",
+    remark: ''
 }
 
 const data = reactive<PageData<PostForm, PostQuery>>({
-	form: {...initFormData},
-	queryParams: {
-		pageNum: 1,
-		pageSize: 10,
-		postCode: '',
-		postName: '',
-		status: ''
-	},
-	rules: {
-		postName: [{ required: true, message: "宀椾綅鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }],
-		postCode: [{ required: true, message: "宀椾綅缂栫爜涓嶈兘涓虹┖", trigger: "blur" }],
-		postSort: [{ required: true, message: "宀椾綅椤哄簭涓嶈兘涓虹┖", trigger: "blur" }],
-	}
+    form: {...initFormData},
+    queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        postCode: '',
+        postName: '',
+        status: ''
+    },
+    rules: {
+        postName: [{ required: true, message: "宀椾綅鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }],
+        postCode: [{ required: true, message: "宀椾綅缂栫爜涓嶈兘涓虹┖", trigger: "blur" }],
+        postSort: [{ required: true, message: "宀椾綅椤哄簭涓嶈兘涓虹┖", trigger: "blur" }],
+    }
 });
 
 const { queryParams, form, rules } = toRefs<PageData<PostForm, PostQuery>>(data);
 
 /** 鏌ヨ宀椾綅鍒楄〃 */
 const getList = async () => {
-	loading.value = true;
-	const res = await listPost(queryParams.value);
-	postList.value = res.rows;
-	total.value = res.total;
-	loading.value = false;
+    loading.value = true;
+    const res = await listPost(queryParams.value);
+    postList.value = res.rows;
+    total.value = res.total;
+    loading.value = false;
 }
 /** 鍙栨秷鎸夐挳 */
 const cancel = () => {
-	reset();
-	dialog.visible = false;
+    reset();
+    dialog.visible = false;
 }
 /** 琛ㄥ崟閲嶇疆 */
 const reset = () => {
-	form.value = {...initFormData};
-	postFormRef.value.resetFields();
+    form.value = {...initFormData};
+    postFormRef.value.resetFields();
 }
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-	queryParams.value.pageNum = 1;
-	getList();
+    queryParams.value.pageNum = 1;
+    getList();
 }
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 const resetQuery = () => {
-	queryFormRef.value.resetFields();
-	handleQuery();
+    queryFormRef.value.resetFields();
+    handleQuery();
 }
 /** 澶氶�夋閫変腑鏁版嵁 */
 const handleSelectionChange = (selection: PostVO[]) => {
-	ids.value = selection.map(item => item.postId);
-	single.value = selection.length != 1;
-	multiple.value = !selection.length;
+    ids.value = selection.map(item => item.postId);
+    single.value = selection.length != 1;
+    multiple.value = !selection.length;
 }
 /** 鏂板鎸夐挳鎿嶄綔 */
 const handleAdd = () => {
-	dialog.visible = true;
-	dialog.title = "娣诲姞宀椾綅";
-	nextTick(() => {
-		reset();
-	})
+    dialog.visible = true;
+    dialog.title = "娣诲姞宀椾綅";
+    nextTick(() => {
+        reset();
+    })
 }
 /** 淇敼鎸夐挳鎿嶄綔 */
 const handleUpdate = (row?: PostVO) => {
-	dialog.visible = true;
-	dialog.title = "淇敼宀椾綅";
-	nextTick(async () => {
-		reset();
-		const postId = row?.postId || ids.value[0];
-		const res = await getPost(postId);
-		form.value = res.data;
-	})
+    dialog.visible = true;
+    dialog.title = "淇敼宀椾綅";
+    nextTick(async () => {
+        reset();
+        const postId = row?.postId || ids.value[0];
+        const res = await getPost(postId);
+        form.value = res.data;
+    })
 }
 /** 鎻愪氦鎸夐挳 */
 const submitForm = () => {
-	postFormRef.value.validate(async (valid: boolean) => {
-		if (valid) {
-			form.value.postId ? await updatePost(form.value) : await addPost(form.value);
-			proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛");
-			dialog.visible = false;
-			getList();
-		}
-	});
+    postFormRef.value.validate(async (valid: boolean) => {
+        if (valid) {
+            form.value.postId ? await updatePost(form.value) : await addPost(form.value);
+            proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛");
+            dialog.visible = false;
+            getList();
+        }
+    });
 }
 /** 鍒犻櫎鎸夐挳鎿嶄綔 */
 const handleDelete = async (row?: PostVO) => {
-	const postIds = row?.postId || ids.value;
-	await proxy?.$modal.confirm('鏄惁纭鍒犻櫎宀椾綅缂栧彿涓�"' + postIds + '"鐨勬暟鎹」锛�');
-	await delPost(postIds);
-	getList();
-	proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    const postIds = row?.postId || ids.value;
+    await proxy?.$modal.confirm('鏄惁纭鍒犻櫎宀椾綅缂栧彿涓�"' + postIds + '"鐨勬暟鎹」锛�');
+    await delPost(postIds);
+    getList();
+    proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
 }
 /** 瀵煎嚭鎸夐挳鎿嶄綔 */
 const handleExport = () => {
-	proxy?.download("system/post/export", {
-		...queryParams.value
-	}, `post_${new Date().getTime()}.xlsx`);
+    proxy?.download("system/post/export", {
+        ...queryParams.value
+    }, `post_${new Date().getTime()}.xlsx`);
 }
 
 onMounted(() => {
-	getList();
+    getList();
 });
 </script>
-
-<template>
-	<div class="p-2">
-		<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-			<div class="search" v-show="showSearch">
-				<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="70">
-					<el-form-item label="宀椾綅缂栫爜" prop="postCode">
-						<el-input v-model="queryParams.postCode" placeholder="璇疯緭鍏ュ矖浣嶇紪鐮�" clearable style="width: 200px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="宀椾綅鍚嶇О" prop="postName">
-						<el-input v-model="queryParams.postName" placeholder="璇疯緭鍏ュ矖浣嶅悕绉�" clearable style="width: 200px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鐘舵��" prop="status">
-						<el-select v-model="queryParams.status" placeholder="宀椾綅鐘舵��" clearable style="width: 200px">
-							<el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
-						</el-select>
-					</el-form-item>
-					<el-form-item>
-						<el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
-						<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-					</el-form-item>
-				</el-form>
-			</div>
-		</transition>
-		<el-card shadow="never">
-			<template #header>
-				<el-row :gutter="10" class="mb8">
-					<el-col :span="1.5">
-						<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:post:add']">鏂板</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:post:edit']">淇敼</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:post:remove']">
-							鍒犻櫎
-						</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:post:export']">瀵煎嚭</el-button>
-					</el-col>
-					<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-				</el-row>
-			</template>
-
-			<el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange">
-				<el-table-column type="selection" width="55" align="center" />
-				<el-table-column label="宀椾綅缂栧彿" align="center" prop="postId" v-if="false" />
-				<el-table-column label="宀椾綅缂栫爜" align="center" prop="postCode" />
-				<el-table-column label="宀椾綅鍚嶇О" align="center" prop="postName" />
-				<el-table-column label="宀椾綅鎺掑簭" align="center" prop="postSort" />
-				<el-table-column label="鐘舵��" align="center" prop="status">
-					<template #default="scope">
-						<dict-tag :options="sys_normal_disable" :value="scope.row.status" />
-					</template>
-				</el-table-column>
-				<el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180">
-					<template #default="scope">
-						<span>{{ parseTime(scope.row.createTime) }}</span>
-					</template>
-				</el-table-column>
-				<el-table-column label="鎿嶄綔" width="180" align="center" class-name="small-padding fixed-width">
-					<template #default="scope">
-						<el-tooltip content="淇敼" placement="top">
-							<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:post:edit']"></el-button>
-						</el-tooltip>
-						<el-tooltip content="鍒犻櫎" placement="top">
-							<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:post:remove']"></el-button>
-						</el-tooltip>
-					</template>
-				</el-table-column>
-			</el-table>
-
-			<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
-		</el-card>
-
-		<!-- 娣诲姞鎴栦慨鏀瑰矖浣嶅璇濇 -->
-		<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
-			<el-form ref="postFormRef" :model="form" :rules="rules" label-width="80px">
-				<el-form-item label="宀椾綅鍚嶇О" prop="postName">
-					<el-input v-model="form.postName" placeholder="璇疯緭鍏ュ矖浣嶅悕绉�" />
-				</el-form-item>
-				<el-form-item label="宀椾綅缂栫爜" prop="postCode">
-					<el-input v-model="form.postCode" placeholder="璇疯緭鍏ョ紪鐮佸悕绉�" />
-				</el-form-item>
-				<el-form-item label="宀椾綅椤哄簭" prop="postSort">
-					<el-input-number v-model="form.postSort" controls-position="right" :min="0" />
-				</el-form-item>
-				<el-form-item label="宀椾綅鐘舵��" prop="status">
-					<el-radio-group v-model="form.status">
-						<el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
-					</el-radio-group>
-				</el-form-item>
-				<el-form-item label="澶囨敞" prop="remark">
-					<el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" />
-				</el-form-item>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
-					<el-button @click="cancel">鍙� 娑�</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</div>
-</template>
diff --git a/src/views/system/role/authUser.vue b/src/views/system/role/authUser.vue
index a9e2225..4b2bec8 100644
--- a/src/views/system/role/authUser.vue
+++ b/src/views/system/role/authUser.vue
@@ -1,3 +1,75 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form :model="queryParams" ref="queryFormRef" :inline="true">
+          <el-form-item label="鐢ㄦ埛鍚嶇О" prop="userName">
+            <el-input v-model="queryParams.userName" placeholder="璇疯緭鍏ョ敤鎴峰悕绉�" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鎵嬫満鍙风爜" prop="phonenumber">
+            <el-input v-model="queryParams.phonenumber" placeholder="璇疯緭鍏ユ墜鏈哄彿鐮�" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Plus" @click="openSelectUser" v-hasPermi="['system:role:add']">娣诲姞鐢ㄦ埛</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="CircleClose" :disabled="multiple" @click="cancelAuthUserAll" v-hasPermi="['system:role:remove']">
+              鎵归噺鍙栨秷鎺堟潈
+            </el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Close" @click="handleClose">鍏抽棴</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList" :search="true"></right-toolbar>
+        </el-row>
+      </template>
+      <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="鐢ㄦ埛鍚嶇О" prop="userName" :show-overflow-tooltip="true" />
+        <el-table-column label="鐢ㄦ埛鏄电О" prop="nickName" :show-overflow-tooltip="true" />
+        <el-table-column label="閭" prop="email" :show-overflow-tooltip="true" />
+        <el-table-column label="鎵嬫満" prop="phonenumber" :show-overflow-tooltip="true" />
+        <el-table-column label="鐘舵��" align="center" prop="status">
+          <template #default="scope">
+            <dict-tag :options="sys_normal_disable" :value="scope.row.status" />
+          </template>
+        </el-table-column>
+        <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180">
+          <template #default="scope">
+            <span>{{ scope.row.createTime }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-tooltip content="鍙栨秷鎺堟潈" placement="top">
+              <el-button link type="primary" icon="CircleClose" @click="cancelAuthUser(scope.row)" v-hasPermi="['system:role:remove']"> </el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination
+        v-show="total > 0"
+        :total="total"
+        v-model:page="queryParams.pageNum"
+        v-model:limit="queryParams.pageSize"
+        @pagination="handleQuery"
+      />
+      <select-user ref="selectRef" :roleId="queryParams.roleId" @ok="handleQuery" />
+    </el-card>
+  </div>
+</template>
+
 <script setup name="AuthUser" lang="ts">
 import { allocatedUserList, authUserCancel, authUserCancelAll } from "@/api/system/role";
 import { UserQuery } from "@/api/system/user/types";
@@ -22,137 +94,65 @@
 const selectRef = ref(SelectUser);
 
 const queryParams = reactive<UserQuery>({
-  pageNum: 1,
-  pageSize: 10,
-  roleId: route.params.roleId as string,
-  userName: undefined,
-  phonenumber: undefined,
+    pageNum: 1,
+    pageSize: 10,
+    roleId: route.params.roleId as string,
+    userName: undefined,
+    phonenumber: undefined,
 });
 
 /** 鏌ヨ鎺堟潈鐢ㄦ埛鍒楄〃 */
 const getList = async () => {
-  loading.value = true;
-	const res = await allocatedUserList(queryParams);
-	userList.value = res.rows;
-	total.value = res.total;
-	loading.value = false;
+    loading.value = true;
+    const res = await allocatedUserList(queryParams);
+    userList.value = res.rows;
+    total.value = res.total;
+    loading.value = false;
 }
 // 杩斿洖鎸夐挳
 const handleClose = () => {
-  const obj = { path: "/system/role" };
-  proxy?.$tab.closeOpenPage(obj);
+    const obj = { path: "/system/role" };
+    proxy?.$tab.closeOpenPage(obj);
 }
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery=() => {
-  queryParams.pageNum = 1;
-  getList();
+    queryParams.pageNum = 1;
+    getList();
 }
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 const resetQuery=() =>{
-  queryFormRef.value.resetFields();
-  handleQuery();
+    queryFormRef.value.resetFields();
+    handleQuery();
 }
 // 澶氶�夋閫変腑鏁版嵁
 const handleSelectionChange = (selection: UserVO[]) =>{
-  userIds.value = selection.map(item => item.userId);
-  multiple.value = !selection.length;
+    userIds.value = selection.map(item => item.userId);
+    multiple.value = !selection.length;
 }
 /** 鎵撳紑鎺堟潈鐢ㄦ埛琛ㄥ脊绐� */
 const openSelectUser = () => {
-  selectRef.value.show();
+    selectRef.value.show();
 }
 /** 鍙栨秷鎺堟潈鎸夐挳鎿嶄綔 */
 const cancelAuthUser = async (row: UserVO) => {
-	await proxy?.$modal.confirm('纭瑕佸彇娑堣鐢ㄦ埛"' + row.userName + '"瑙掕壊鍚楋紵');
-	await authUserCancel({ userId: row.userId, roleId: queryParams.roleId });
-	getList();
-	proxy?.$modal.msgSuccess("鍙栨秷鎺堟潈鎴愬姛");
+    await proxy?.$modal.confirm('纭瑕佸彇娑堣鐢ㄦ埛"' + row.userName + '"瑙掕壊鍚楋紵');
+    await authUserCancel({ userId: row.userId, roleId: queryParams.roleId });
+    getList();
+    proxy?.$modal.msgSuccess("鍙栨秷鎺堟潈鎴愬姛");
 }
 /** 鎵归噺鍙栨秷鎺堟潈鎸夐挳鎿嶄綔 */
 const cancelAuthUserAll = async () => {
-  const roleId = queryParams.roleId;
-  const uIds = userIds.value.join(",");
-	await proxy?.$modal.confirm("鏄惁鍙栨秷閫変腑鐢ㄦ埛鎺堟潈鏁版嵁椤�?");
-	await authUserCancelAll({ roleId: roleId, userIds: uIds });
-	getList();
-	proxy?.$modal.msgSuccess("鍙栨秷鎺堟潈鎴愬姛");
+    const roleId = queryParams.roleId;
+    const uIds = userIds.value.join(",");
+    await proxy?.$modal.confirm("鏄惁鍙栨秷閫変腑鐢ㄦ埛鎺堟潈鏁版嵁椤�?");
+    await authUserCancelAll({ roleId: roleId, userIds: uIds });
+    getList();
+    proxy?.$modal.msgSuccess("鍙栨秷鎺堟潈鎴愬姛");
 }
 
 onMounted(() => {
-  getList();
+    getList();
 });
 </script>
-
-<template>
-	<div class="p-2">
-		<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-			<div class="search" v-show="showSearch">
-				<el-form :model="queryParams" ref="queryFormRef" :inline="true">
-					<el-form-item label="鐢ㄦ埛鍚嶇О" prop="userName">
-						<el-input v-model="queryParams.userName" placeholder="璇疯緭鍏ョ敤鎴峰悕绉�" clearable style="width: 240px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鎵嬫満鍙风爜" prop="phonenumber">
-						<el-input v-model="queryParams.phonenumber" placeholder="璇疯緭鍏ユ墜鏈哄彿鐮�" clearable style="width: 240px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item>
-						<el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
-						<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-					</el-form-item>
-				</el-form>
-			</div>
-		</transition>
-		<el-card shadow="never">
-			<template #header>
-				<el-row :gutter="10">
-					<el-col :span="1.5">
-						<el-button type="primary" plain icon="Plus" @click="openSelectUser" v-hasPermi="['system:role:add']">娣诲姞鐢ㄦ埛</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="danger" plain icon="CircleClose" :disabled="multiple" @click="cancelAuthUserAll" v-hasPermi="['system:role:remove']">
-							鎵归噺鍙栨秷鎺堟潈
-						</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="warning" plain icon="Close" @click="handleClose">鍏抽棴</el-button>
-					</el-col>
-					<right-toolbar v-model:showSearch="showSearch" @queryTable="getList" :search="true"></right-toolbar>
-				</el-row>
-			</template>
-			<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
-				<el-table-column type="selection" width="55" align="center" />
-				<el-table-column label="鐢ㄦ埛鍚嶇О" prop="userName" :show-overflow-tooltip="true" />
-				<el-table-column label="鐢ㄦ埛鏄电О" prop="nickName" :show-overflow-tooltip="true" />
-				<el-table-column label="閭" prop="email" :show-overflow-tooltip="true" />
-				<el-table-column label="鎵嬫満" prop="phonenumber" :show-overflow-tooltip="true" />
-				<el-table-column label="鐘舵��" align="center" prop="status">
-					<template #default="scope">
-						<dict-tag :options="sys_normal_disable" :value="scope.row.status" />
-					</template>
-				</el-table-column>
-				<el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180">
-					<template #default="scope">
-						<span>{{ scope.row.createTime }}</span>
-					</template>
-				</el-table-column>
-				<el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
-					<template #default="scope">
-						<el-tooltip content="鍙栨秷鎺堟潈" placement="top">
-							<el-button link type="primary" icon="CircleClose" @click="cancelAuthUser(scope.row)" v-hasPermi="['system:role:remove']"> </el-button>
-						</el-tooltip>
-					</template>
-				</el-table-column>
-			</el-table>
-
-			<pagination
-				v-show="total > 0"
-				:total="total"
-				v-model:page="queryParams.pageNum"
-				v-model:limit="queryParams.pageSize"
-				@pagination="handleQuery"
-			/>
-			<select-user ref="selectRef" :roleId="queryParams.roleId" @ok="handleQuery" />
-		</el-card>
-	</div>
-</template>
 
 <style lang="scss" scoped></style>
diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue
index 34a91d3..04fc3df 100644
--- a/src/views/system/role/index.vue
+++ b/src/views/system/role/index.vue
@@ -1,3 +1,196 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="68px">
+          <el-form-item label="瑙掕壊鍚嶇О" prop="roleName">
+            <el-input v-model="queryParams.roleName" placeholder="璇疯緭鍏ヨ鑹插悕绉�" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鏉冮檺瀛楃" prop="roleKey">
+            <el-input v-model="queryParams.roleKey" placeholder="璇疯緭鍏ユ潈闄愬瓧绗�" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鐘舵��" prop="status">
+            <el-select v-model="queryParams.status" placeholder="瑙掕壊鐘舵��" clearable style="width: 240px">
+              <el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="鍒涘缓鏃堕棿" style="width: 308px">
+            <el-date-picker
+              v-model="dateRange"
+              value-format="YYYY-MM-DD"
+              type="daterange"
+              range-separator="-"
+              start-placeholder="寮�濮嬫棩鏈�"
+              end-placeholder="缁撴潫鏃ユ湡"
+              :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
+            ></el-date-picker>
+          </el-form-item>
+
+          <el-form-item>
+            <el-button type="primary" @click="handleQuery" icon="Search">鎼滅储</el-button>
+            <el-button @click="resetQuery" icon="Refresh">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10">
+          <el-col :span="1.5">
+            <el-button type="primary" plain @click="handleAdd()" icon="Plus" v-hasPermi="['system:role:add']">鏂板</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="success" plain @click="handleUpdate()" :disabled="single" icon="Edit" v-hasPermi="['system:role:edit']">淇敼</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain :disabled="ids.length === 0" @click="handleDelete()" v-hasPermi="['system:role:delete']">鍒犻櫎</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:role:export']">瀵煎嚭</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table ref="roleTableRef" v-loading="loading" :data="roleList" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="瑙掕壊缂栧彿" prop="roleId" width="120" v-if="false" />
+        <el-table-column label="瑙掕壊鍚嶇О" prop="roleName" :show-overflow-tooltip="true" width="150" />
+        <el-table-column label="鏉冮檺瀛楃" prop="roleKey" :show-overflow-tooltip="true" width="200" />
+        <el-table-column label="鏄剧ず椤哄簭" prop="roleSort" width="100" />
+        <el-table-column label="鐘舵��" align="center" width="100">
+          <template #default="scope">
+            <el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
+          </template>
+        </el-table-column>
+        <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.createTime) }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column fixed="right" label="鎿嶄綔" width="180">
+          <template #default="scope">
+            <el-tooltip content="淇敼" placement="top" v-if="scope.row.roleId !== 1">
+              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:role:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="鍒犻櫎" placement="top" v-if="scope.row.roleId !== 1">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:role:remove']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="鏁版嵁鏉冮檺" placement="top" v-if="scope.row.roleId !== 1">
+              <el-button link type="primary" icon="CircleCheck" @click="handleDataScope(scope.row)" v-hasPermi="['system:role:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="鍒嗛厤鐢ㄦ埛" placement="top" v-if="scope.row.roleId !== 1">
+              <el-button link type="primary" icon="User" @click="handleAuthUser(scope.row)" v-hasPermi="['system:role:edit']"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination
+        v-if="total > 0"
+        v-model:total="total"
+        v-model:page="queryParams.pageNum"
+        v-model:limit="queryParams.pageSize"
+        @pagination="handleQuery"
+      />
+    </el-card>
+
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
+      <el-form ref="roleFormRef" :model="form" :rules="rules" label-width="100px">
+        <el-form-item label="瑙掕壊鍚嶇О" prop="roleName">
+          <el-input v-model="form.roleName" placeholder="璇疯緭鍏ヨ鑹插悕绉�" />
+        </el-form-item>
+        <el-form-item prop="roleKey">
+          <template #label>
+            <span>
+              <el-tooltip content="鎺у埗鍣ㄤ腑瀹氫箟鐨勬潈闄愬瓧绗︼紝濡傦細@PreAuthorize(`@ss.hasRole('admin')`)" placement="top">
+                <el-icon><question-filled /></el-icon>
+              </el-tooltip>
+              鏉冮檺瀛楃
+            </span>
+          </template>
+          <el-input v-model="form.roleKey" placeholder="璇疯緭鍏ユ潈闄愬瓧绗�" />
+        </el-form-item>
+        <el-form-item label="瑙掕壊椤哄簭" prop="roleSort">
+          <el-input-number v-model="form.roleSort" controls-position="right" :min="0" />
+        </el-form-item>
+        <el-form-item label="鐘舵��">
+          <el-radio-group v-model="form.status">
+            <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">{{
+                dict.label
+            }}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="鑿滃崟鏉冮檺">
+          <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">灞曞紑/鎶樺彔</el-checkbox>
+          <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">鍏ㄩ��/鍏ㄤ笉閫�</el-checkbox>
+          <el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">鐖跺瓙鑱斿姩</el-checkbox>
+          <el-tree
+            class="tree-border"
+            :data="menuOptions"
+            show-checkbox
+            ref="menuRef"
+            node-key="id"
+            :check-strictly="!form.menuCheckStrictly"
+            empty-text="鍔犺浇涓紝璇风◢鍊�"
+            :props="{ label: 'label', children: 'children' }"
+          ></el-tree>
+        </el-form-item>
+        <el-form-item label="澶囨敞">
+          <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�"></el-input>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <!-- 鍒嗛厤瑙掕壊鏁版嵁鏉冮檺瀵硅瘽妗� -->
+    <el-dialog :title="dialog.title" v-model="openDataScope" width="500px" append-to-body>
+      <el-form :model="form" label-width="80px" ref="dataScopeRef">
+        <el-form-item label="瑙掕壊鍚嶇О">
+          <el-input v-model="form.roleName" :disabled="true" />
+        </el-form-item>
+        <el-form-item label="鏉冮檺瀛楃">
+          <el-input v-model="form.roleKey" :disabled="true" />
+        </el-form-item>
+        <el-form-item label="鏉冮檺鑼冨洿">
+          <el-select v-model="form.dataScope" @change="dataScopeSelectChange">
+            <el-option v-for="item in dataScopeOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鏁版嵁鏉冮檺" v-show="form.dataScope === 2">
+          <el-checkbox v-model="deptExpand" @change="handleCheckedTreeExpand($event, 'dept')">灞曞紑/鎶樺彔</el-checkbox>
+          <el-checkbox v-model="deptNodeAll" @change="handleCheckedTreeNodeAll($event, 'dept')">鍏ㄩ��/鍏ㄤ笉閫�</el-checkbox>
+          <el-checkbox v-model="form.deptCheckStrictly" @change="handleCheckedTreeConnect($event, 'dept')">鐖跺瓙鑱斿姩</el-checkbox>
+          <el-tree
+            class="tree-border"
+            :data="deptOptions"
+            show-checkbox
+            default-expand-all
+            ref="deptRef"
+            node-key="id"
+            :check-strictly="!form.deptCheckStrictly"
+            empty-text="鍔犺浇涓紝璇风◢鍊�"
+            :props="{ label: 'label', children: 'children' }"
+          ></el-tree>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitDataScope">纭� 瀹�</el-button>
+          <el-button @click="cancelDataScope">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
 <script setup name="Role" lang="ts">
 import { addRole, changeRoleStatus, dataScope, delRole, getRole, listRole, updateRole, deptTreeSelect } from "@/api/system/role";
 import { roleMenuTreeselect, treeselect as menuTreeselect } from '@/api/system/menu/index';
@@ -28,11 +221,11 @@
 
 /** 鏁版嵁鑼冨洿閫夐」*/
 const dataScopeOptions = ref([
-  { value: "1", label: "鍏ㄩ儴鏁版嵁鏉冮檺" },
-  { value: "2", label: "鑷畾鏁版嵁鏉冮檺" },
-  { value: "3", label: "鏈儴闂ㄦ暟鎹潈闄�" },
-  { value: "4", label: "鏈儴闂ㄥ強浠ヤ笅鏁版嵁鏉冮檺" },
-  { value: "5", label: "浠呮湰浜烘暟鎹潈闄�" }
+    { value: "1", label: "鍏ㄩ儴鏁版嵁鏉冮檺" },
+    { value: "2", label: "鑷畾鏁版嵁鏉冮檺" },
+    { value: "3", label: "鏈儴闂ㄦ暟鎹潈闄�" },
+    { value: "4", label: "鏈儴闂ㄥ強浠ヤ笅鏁版嵁鏉冮檺" },
+    { value: "5", label: "浠呮湰浜烘暟鎹潈闄�" }
 ])
 
 const queryFormRef = ref(ElForm);
@@ -42,40 +235,40 @@
 const deptRef = ref(ElTree);
 
 const initForm: RoleForm = {
-  roleId: undefined,
-  roleSort: 1,
-  status: '0',
-  roleName: '',
-  roleKey: '',
-  menuCheckStrictly: true,
-  deptCheckStrictly: true,
-  remark: '',
-  dataScope: 1,
-  menuIds: [],
-  deptIds: [],
+    roleId: undefined,
+    roleSort: 1,
+    status: '0',
+    roleName: '',
+    roleKey: '',
+    menuCheckStrictly: true,
+    deptCheckStrictly: true,
+    remark: '',
+    dataScope: 1,
+    menuIds: [],
+    deptIds: [],
 }
 
 const data = reactive<PageData<RoleForm, RoleQuery>>({
-  form: {...initForm},
-  queryParams: {
-    pageNum: 1,
-    pageSize: 10,
-    roleName: '',
-    roleKey: '',
-    status: '',
-  },
-  rules: {
-    roleName: [{ required: true, message: "瑙掕壊鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }],
-    roleKey: [{ required: true, message: "鏉冮檺瀛楃涓嶈兘涓虹┖", trigger: "blur" }],
-    roleSort: [{ required: true, message: "瑙掕壊椤哄簭涓嶈兘涓虹┖", trigger: "blur" }]
-  }
+    form: {...initForm},
+    queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        roleName: '',
+        roleKey: '',
+        status: '',
+    },
+    rules: {
+        roleName: [{ required: true, message: "瑙掕壊鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }],
+        roleKey: [{ required: true, message: "鏉冮檺瀛楃涓嶈兘涓虹┖", trigger: "blur" }],
+        roleSort: [{ required: true, message: "瑙掕壊椤哄簭涓嶈兘涓虹┖", trigger: "blur" }]
+    }
 })
 const { form, queryParams, rules } = toRefs(data)
 
 
 const dialog = reactive<DialogOption>({
-  visible: false,
-  title: ''
+    visible: false,
+    title: ''
 });
 
 
@@ -83,426 +276,233 @@
  * 鏌ヨ瑙掕壊鍒楄〃
  */
 const getList = () => {
-  loading.value = true
-  listRole(proxy?.addDateRange(queryParams.value, dateRange.value)).then(res => {
-    roleList.value = res.rows
-    total.value = res.total
-    loading.value = false
-  })
+    loading.value = true
+    listRole(proxy?.addDateRange(queryParams.value, dateRange.value)).then(res => {
+        roleList.value = res.rows
+        total.value = res.total
+        loading.value = false
+    })
 }
 
 /**
  * 鎼滅储鎸夐挳鎿嶄綔
  */
 const handleQuery = () => {
-  queryParams.value.pageNum = 1;
-  getList();
+    queryParams.value.pageNum = 1;
+    getList();
 }
 
 /** 閲嶇疆 */
 const resetQuery = () => {
-  dateRange.value = ['', '']
-  queryFormRef.value.resetFields();
-  handleQuery();
+    dateRange.value = ['', '']
+    queryFormRef.value.resetFields();
+    handleQuery();
 }
 /**鍒犻櫎鎸夐挳鎿嶄綔 */
 const handleDelete = async (row?: RoleVO) => {
-  const roleids = row?.roleId || ids.value;
-  await proxy?.$modal.confirm('鏄惁纭鍒犻櫎瑙掕壊缂栧彿涓�' + roleids + '鏁版嵁椤圭洰');
-  await delRole(roleids);
-  getList();
-  proxy?.$modal.msgSuccess('鍒犻櫎鎴愬姛');
+    const roleids = row?.roleId || ids.value;
+    await proxy?.$modal.confirm('鏄惁纭鍒犻櫎瑙掕壊缂栧彿涓�' + roleids + '鏁版嵁椤圭洰');
+    await delRole(roleids);
+    getList();
+    proxy?.$modal.msgSuccess('鍒犻櫎鎴愬姛');
 }
 
 /** 瀵煎嚭鎸夐挳鎿嶄綔 */
 const handleExport = () => {
-  proxy?.download("system/role/export", {
-    ...queryParams.value,
-  }, `role_${new Date().getTime()}.xlsx`)
+    proxy?.download("system/role/export", {
+        ...queryParams.value,
+    }, `role_${new Date().getTime()}.xlsx`)
 }
 /** 澶氶�夋閫変腑鏁版嵁 */
 const handleSelectionChange = (selection: RoleVO[]) => {
-  ids.value = selection.map((item: RoleVO) => item.roleId);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
+    ids.value = selection.map((item: RoleVO) => item.roleId);
+    single.value = selection.length != 1;
+    multiple.value = !selection.length;
 }
 
 /** 瑙掕壊鐘舵�佷慨鏀� */
 const handleStatusChange = async (row: RoleVO) => {
-  let text = row.status === "0" ? "鍚敤" : "鍋滅敤";
-  try {
-    await proxy?.$modal.confirm('纭瑕�"' + text + '""' + row.roleName + '"瑙掕壊鍚�?');
-    await changeRoleStatus(row.roleId, row.status);
-  proxy?.$modal.msgSuccess(text + "鎴愬姛");
-  } catch {
-    row.status = row.status === "0" ? "1" : "0";
-  }
+    let text = row.status === "0" ? "鍚敤" : "鍋滅敤";
+    try {
+        await proxy?.$modal.confirm('纭瑕�"' + text + '""' + row.roleName + '"瑙掕壊鍚�?');
+        await changeRoleStatus(row.roleId, row.status);
+        proxy?.$modal.msgSuccess(text + "鎴愬姛");
+    } catch {
+        row.status = row.status === "0" ? "1" : "0";
+    }
 }
 
 /** 鍒嗛厤鐢ㄦ埛 */
 const handleAuthUser = (row: RoleVO) => {
-  router.push("/system/role-auth/user/" + row.roleId);
+    router.push("/system/role-auth/user/" + row.roleId);
 }
 
 /** 鏌ヨ鑿滃崟鏍戠粨鏋� */
 const getMenuTreeselect = async () => {
-  const res = await menuTreeselect();
-  menuOptions.value = res.data;
+    const res = await menuTreeselect();
+    menuOptions.value = res.data;
 }
 /** 鎵�鏈夐儴闂ㄨ妭鐐规暟鎹� */
 const getDeptAllCheckedKeys = () => {
-  // 鐩墠琚�変腑鐨勯儴闂ㄨ妭鐐�
-  let checkedKeys = deptRef.value.getCheckedKeys();
-  // 鍗婇�変腑鐨勯儴闂ㄨ妭鐐�
-  let halfCheckedKeys = deptRef.value.getHalfCheckedKeys();
-  checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
-  return checkedKeys
+    // 鐩墠琚�変腑鐨勯儴闂ㄨ妭鐐�
+    let checkedKeys = deptRef.value.getCheckedKeys();
+    // 鍗婇�変腑鐨勯儴闂ㄨ妭鐐�
+    let halfCheckedKeys = deptRef.value.getHalfCheckedKeys();
+    checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
+    return checkedKeys
 }
 /** 閲嶇疆鏂板鐨勮〃鍗曚互鍙婂叾浠栨暟鎹�  */
 const reset = () => {
-  menuRef.value.setCheckedKeys([]);
-  menuExpand.value = false
-  menuNodeAll.value = false
-  deptExpand.value = true
-  deptNodeAll.value = false
-  form.value = initForm
-  roleFormRef.value.resetFields();
+    menuRef.value.setCheckedKeys([]);
+    menuExpand.value = false
+    menuNodeAll.value = false
+    deptExpand.value = true
+    deptNodeAll.value = false
+    form.value = initForm
+    roleFormRef.value.resetFields();
 
 }
 
 /** 娣诲姞瑙掕壊 */
 const handleAdd = () => {
-  dialog.visible = true;
-  dialog.title = "娣诲姞瑙掕壊";
-  nextTick(() => {
-    reset();
-    getMenuTreeselect();
-  })
+    dialog.visible = true;
+    dialog.title = "娣诲姞瑙掕壊";
+    nextTick(() => {
+        reset();
+        getMenuTreeselect();
+    })
 }
 /** 淇敼瑙掕壊 */
 const handleUpdate = async (row?: RoleVO) => {
-  const roleId = row?.roleId || ids.value[0]
-  const roleMenu = getRoleMenuTreeselect(roleId)
-  const { data } = await getRole(roleId);
-  dialog.visible = true;
-  dialog.title = "淇敼瑙掕壊";
-  nextTick(() => {
-    reset();
-    Object.assign(form.value, data);
-    form.value.roleSort = Number(form.value.roleSort);
-    nextTick(async () => {
-      const res = await roleMenu;
-      let checkedKeys = res.checkedKeys;
-      checkedKeys.forEach((v) => {
-        nextTick(() => {
-          menuRef.value.setChecked(v, true, false);
+    const roleId = row?.roleId || ids.value[0]
+    const roleMenu = getRoleMenuTreeselect(roleId)
+    const { data } = await getRole(roleId);
+    dialog.visible = true;
+    dialog.title = "淇敼瑙掕壊";
+    nextTick(() => {
+        reset();
+        Object.assign(form.value, data);
+        form.value.roleSort = Number(form.value.roleSort);
+        nextTick(async () => {
+            const res = await roleMenu;
+            let checkedKeys = res.checkedKeys;
+            checkedKeys.forEach((v) => {
+                nextTick(() => {
+                    menuRef.value.setChecked(v, true, false);
+                })
+            })
         })
-      })
     })
-  })
 }
 /** 鏍规嵁瑙掕壊ID鏌ヨ鑿滃崟鏍戠粨鏋� */
 const getRoleMenuTreeselect = (roleId: string | number) => {
-  return roleMenuTreeselect(roleId).then((res): RoleMenuTree => {
-    menuOptions.value = res.data.menus;
-    return res.data;
-  })
+    return roleMenuTreeselect(roleId).then((res): RoleMenuTree => {
+        menuOptions.value = res.data.menus;
+        return res.data;
+    })
 }
 /** 鏍规嵁瑙掕壊ID鏌ヨ閮ㄩ棬鏍戠粨鏋� */
 const getRoleDeptTreeSelect = async (roleId: string | number) => {
-  const res = await deptTreeSelect(roleId);
-  deptOptions.value = res.data.depts;
-  return res.data;
+    const res = await deptTreeSelect(roleId);
+    deptOptions.value = res.data.depts;
+    return res.data;
 }
 /** 鏍戞潈闄愶紙灞曞紑/鎶樺彔锛�*/
 const handleCheckedTreeExpand = (value: any, type: string) => {
-  if (type == "menu") {
-    let treeList = menuOptions.value;
-    for (let i = 0; i < treeList.length; i++) {
-      menuRef.value.store.nodesMap[treeList[i].id].expanded = value;
+    if (type == "menu") {
+        let treeList = menuOptions.value;
+        for (let i = 0; i < treeList.length; i++) {
+            menuRef.value.store.nodesMap[treeList[i].id].expanded = value;
+        }
+    } else if (type == "dept") {
+        let treeList = deptOptions.value;
+        for (let i = 0; i < treeList.length; i++) {
+            deptRef.value.store.nodesMap[treeList[i].id].expanded = value;
+        }
     }
-  } else if (type == "dept") {
-    let treeList = deptOptions.value;
-    for (let i = 0; i < treeList.length; i++) {
-      deptRef.value.store.nodesMap[treeList[i].id].expanded = value;
-    }
-  }
 }
 /** 鏍戞潈闄愶紙鍏ㄩ��/鍏ㄤ笉閫夛級 */
 const handleCheckedTreeNodeAll = (value: any, type: string) => {
-  if (type == "menu") {
-    menuRef.value.setCheckedNodes(value ? menuOptions.value : []);
-  } else if (type == "dept") {
-    deptRef.value.setCheckedNodes(value ? deptOptions.value : []);
-  }
+    if (type == "menu") {
+        menuRef.value.setCheckedNodes(value ? menuOptions.value : []);
+    } else if (type == "dept") {
+        deptRef.value.setCheckedNodes(value ? deptOptions.value : []);
+    }
 }
 /** 鏍戞潈闄愶紙鐖跺瓙鑱斿姩锛� */
 const handleCheckedTreeConnect = (value: any, type: string) => {
-  if (type == "menu") {
-    form.value.menuCheckStrictly = value;
-  } else if (type == "dept") {
-    form.value.deptCheckStrictly = value;
-  }
+    if (type == "menu") {
+        form.value.menuCheckStrictly = value;
+    } else if (type == "dept") {
+        form.value.deptCheckStrictly = value;
+    }
 }
 /** 鎵�鏈夎彍鍗曡妭鐐规暟鎹� */
 const getMenuAllCheckedKeys = () => {
-  // 鐩墠琚�変腑鐨勮彍鍗曡妭鐐�
-  let checkedKeys = menuRef.value.getCheckedKeys();
-  // 鍗婇�変腑鐨勮彍鍗曡妭鐐�
-  let halfCheckedKeys = menuRef.value.getHalfCheckedKeys();
-  checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
-  return checkedKeys;
+    // 鐩墠琚�変腑鐨勮彍鍗曡妭鐐�
+    let checkedKeys = menuRef.value.getCheckedKeys();
+    // 鍗婇�変腑鐨勮彍鍗曡妭鐐�
+    let halfCheckedKeys = menuRef.value.getHalfCheckedKeys();
+    checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
+    return checkedKeys;
 }
 /** 鎻愪氦鎸夐挳 */
 const submitForm = () => {
-  roleFormRef.value.validate(async (valid: boolean) => {
-    if (valid) {
-      form.value.menuIds = getMenuAllCheckedKeys()
-      form.value.roleId ? await updateRole(form.value) : await addRole(form.value);
-      proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛")
-      dialog.visible = false
-      getList()
-    }
-  })
+    roleFormRef.value.validate(async (valid: boolean) => {
+        if (valid) {
+            form.value.menuIds = getMenuAllCheckedKeys()
+            form.value.roleId ? await updateRole(form.value) : await addRole(form.value);
+            proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛")
+            dialog.visible = false
+            getList()
+        }
+    })
 }
 /** 鍙栨秷鎸夐挳 */
 const cancel = () => {
-  reset()
-  dialog.visible = false;
+    reset()
+    dialog.visible = false;
 }
 /** 閫夋嫨瑙掕壊鏉冮檺鑼冨洿瑙﹀彂 */
 const dataScopeSelectChange = (value: string) => {
-  if (value !== "2") {
-    deptRef.value.setCheckedKeys([])
-  }
+    if (value !== "2") {
+        deptRef.value.setCheckedKeys([])
+    }
 }
 /** 鍒嗛厤鏁版嵁鏉冮檺鎿嶄綔 */
 const handleDataScope = async (row: RoleVO) => {
-  const roleDeptTreeselect = getRoleDeptTreeSelect(row.roleId);
-  const response = await getRole(row.roleId);
-  Object.assign(form.value, response.data);
-  openDataScope.value = true;
-  dialog.title = "鍒嗛厤鏁版嵁鏉冮檺";
-  nextTick(async () => {
-    const res = await roleDeptTreeselect;
-    nextTick(() => {
-      if (deptRef.value) {
-        deptRef.value.setCheckedKeys(res.checkedKeys);
-      }
+    const roleDeptTreeselect = getRoleDeptTreeSelect(row.roleId);
+    const response = await getRole(row.roleId);
+    Object.assign(form.value, response.data);
+    openDataScope.value = true;
+    dialog.title = "鍒嗛厤鏁版嵁鏉冮檺";
+    nextTick(async () => {
+        const res = await roleDeptTreeselect;
+        nextTick(() => {
+            if (deptRef.value) {
+                deptRef.value.setCheckedKeys(res.checkedKeys);
+            }
+        })
     })
-  })
 }
 /** 鎻愪氦鎸夐挳锛堟暟鎹潈闄愶級 */
 const submitDataScope = async () => {
-  if (form.value.roleId) {
-    form.value.deptIds = getDeptAllCheckedKeys();
-    await dataScope(form.value);
-    proxy?.$modal.msgSuccess("淇敼鎴愬姛");
-    openDataScope.value = false;
-    getList();
-  }
+    if (form.value.roleId) {
+        form.value.deptIds = getDeptAllCheckedKeys();
+        await dataScope(form.value);
+        proxy?.$modal.msgSuccess("淇敼鎴愬姛");
+        openDataScope.value = false;
+        getList();
+    }
 }
 /** 鍙栨秷鎸夐挳锛堟暟鎹潈闄愶級*/
 const cancelDataScope = () => {
-  dataScopeRef.value.resetFields();
-  form.value = {...initForm};
-  openDataScope.value = false;
+    dataScopeRef.value.resetFields();
+    form.value = {...initForm};
+    openDataScope.value = false;
 }
 
 onMounted(() => {
-  getList();
+    getList();
 });
 </script>
-
-<template>
-	<div class="p-2">
-		<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-			<div class="search" v-show="showSearch">
-				<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="68px">
-					<el-form-item label="瑙掕壊鍚嶇О" prop="roleName">
-						<el-input v-model="queryParams.roleName" placeholder="璇疯緭鍏ヨ鑹插悕绉�" clearable style="width: 240px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鏉冮檺瀛楃" prop="roleKey">
-						<el-input v-model="queryParams.roleKey" placeholder="璇疯緭鍏ユ潈闄愬瓧绗�" clearable style="width: 240px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鐘舵��" prop="status">
-						<el-select v-model="queryParams.status" placeholder="瑙掕壊鐘舵��" clearable style="width: 240px">
-							<el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
-						</el-select>
-					</el-form-item>
-					<el-form-item label="鍒涘缓鏃堕棿" style="width: 308px">
-						<el-date-picker
-							v-model="dateRange"
-							value-format="YYYY-MM-DD"
-							type="daterange"
-							range-separator="-"
-							start-placeholder="寮�濮嬫棩鏈�"
-							end-placeholder="缁撴潫鏃ユ湡"
-							:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
-						></el-date-picker>
-					</el-form-item>
-
-					<el-form-item>
-						<el-button type="primary" @click="handleQuery" icon="Search">鎼滅储</el-button>
-						<el-button @click="resetQuery" icon="Refresh">閲嶇疆</el-button>
-					</el-form-item>
-				</el-form>
-			</div>
-		</transition>
-
-		<el-card shadow="never">
-			<template #header>
-				<el-row :gutter="10">
-					<el-col :span="1.5">
-						<el-button type="primary" plain @click="handleAdd()" icon="Plus" v-hasPermi="['system:role:add']">鏂板</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="success" plain @click="handleUpdate()" :disabled="single" icon="Edit" v-hasPermi="['system:role:edit']">淇敼</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="danger" plain :disabled="ids.length === 0" @click="handleDelete()" v-hasPermi="['system:role:delete']">鍒犻櫎</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:role:export']">瀵煎嚭</el-button>
-					</el-col>
-					<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-				</el-row>
-			</template>
-
-			<el-table ref="roleTableRef" v-loading="loading" :data="roleList" @selection-change="handleSelectionChange">
-				<el-table-column type="selection" width="55" align="center" />
-				<el-table-column label="瑙掕壊缂栧彿" prop="roleId" width="120" v-if="false" />
-				<el-table-column label="瑙掕壊鍚嶇О" prop="roleName" :show-overflow-tooltip="true" width="150" />
-				<el-table-column label="鏉冮檺瀛楃" prop="roleKey" :show-overflow-tooltip="true" width="200" />
-				<el-table-column label="鏄剧ず椤哄簭" prop="roleSort" width="100" />
-				<el-table-column label="鐘舵��" align="center" width="100">
-					<template #default="scope">
-						<el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
-					</template>
-				</el-table-column>
-				<el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime">
-					<template #default="scope">
-						<span>{{ parseTime(scope.row.createTime) }}</span>
-					</template>
-				</el-table-column>
-
-				<el-table-column fixed="right" label="鎿嶄綔" width="180">
-					<template #default="scope">
-						<el-tooltip content="淇敼" placement="top" v-if="scope.row.roleId !== 1">
-							<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:role:edit']"></el-button>
-						</el-tooltip>
-						<el-tooltip content="鍒犻櫎" placement="top" v-if="scope.row.roleId !== 1">
-							<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:role:remove']"></el-button>
-						</el-tooltip>
-						<el-tooltip content="鏁版嵁鏉冮檺" placement="top" v-if="scope.row.roleId !== 1">
-							<el-button link type="primary" icon="CircleCheck" @click="handleDataScope(scope.row)" v-hasPermi="['system:role:edit']"></el-button>
-						</el-tooltip>
-						<el-tooltip content="鍒嗛厤鐢ㄦ埛" placement="top" v-if="scope.row.roleId !== 1">
-							<el-button link type="primary" icon="User" @click="handleAuthUser(scope.row)" v-hasPermi="['system:role:edit']"></el-button>
-						</el-tooltip>
-					</template>
-				</el-table-column>
-			</el-table>
-
-			<pagination
-				v-if="total > 0"
-				v-model:total="total"
-				v-model:page="queryParams.pageNum"
-				v-model:limit="queryParams.pageSize"
-				@pagination="handleQuery"
-			/>
-		</el-card>
-
-		<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
-			<el-form ref="roleFormRef" :model="form" :rules="rules" label-width="100px">
-				<el-form-item label="瑙掕壊鍚嶇О" prop="roleName">
-					<el-input v-model="form.roleName" placeholder="璇疯緭鍏ヨ鑹插悕绉�" />
-				</el-form-item>
-				<el-form-item prop="roleKey">
-					<template #label>
-						<span>
-							<el-tooltip content="鎺у埗鍣ㄤ腑瀹氫箟鐨勬潈闄愬瓧绗︼紝濡傦細@PreAuthorize(`@ss.hasRole('admin')`)" placement="top">
-								<el-icon><question-filled /></el-icon>
-							</el-tooltip>
-							鏉冮檺瀛楃
-						</span>
-					</template>
-					<el-input v-model="form.roleKey" placeholder="璇疯緭鍏ユ潈闄愬瓧绗�" />
-				</el-form-item>
-				<el-form-item label="瑙掕壊椤哄簭" prop="roleSort">
-					<el-input-number v-model="form.roleSort" controls-position="right" :min="0" />
-				</el-form-item>
-				<el-form-item label="鐘舵��">
-					<el-radio-group v-model="form.status">
-						<el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">{{
-                dict.label
-						}}</el-radio>
-					</el-radio-group>
-				</el-form-item>
-				<el-form-item label="鑿滃崟鏉冮檺">
-					<el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">灞曞紑/鎶樺彔</el-checkbox>
-					<el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">鍏ㄩ��/鍏ㄤ笉閫�</el-checkbox>
-					<el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">鐖跺瓙鑱斿姩</el-checkbox>
-					<el-tree
-						class="tree-border"
-						:data="menuOptions"
-						show-checkbox
-						ref="menuRef"
-						node-key="id"
-						:check-strictly="!form.menuCheckStrictly"
-						empty-text="鍔犺浇涓紝璇风◢鍊�"
-						:props="{ label: 'label', children: 'children' }"
-					></el-tree>
-				</el-form-item>
-				<el-form-item label="澶囨敞">
-					<el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�"></el-input>
-				</el-form-item>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
-					<el-button @click="cancel">鍙� 娑�</el-button>
-				</div>
-			</template>
-		</el-dialog>
-
-		<!-- 鍒嗛厤瑙掕壊鏁版嵁鏉冮檺瀵硅瘽妗� -->
-		<el-dialog :title="dialog.title" v-model="openDataScope" width="500px" append-to-body>
-			<el-form :model="form" label-width="80px" ref="dataScopeRef">
-				<el-form-item label="瑙掕壊鍚嶇О">
-					<el-input v-model="form.roleName" :disabled="true" />
-				</el-form-item>
-				<el-form-item label="鏉冮檺瀛楃">
-					<el-input v-model="form.roleKey" :disabled="true" />
-				</el-form-item>
-				<el-form-item label="鏉冮檺鑼冨洿">
-					<el-select v-model="form.dataScope" @change="dataScopeSelectChange">
-						<el-option v-for="item in dataScopeOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
-					</el-select>
-				</el-form-item>
-				<el-form-item label="鏁版嵁鏉冮檺" v-show="form.dataScope === 2">
-					<el-checkbox v-model="deptExpand" @change="handleCheckedTreeExpand($event, 'dept')">灞曞紑/鎶樺彔</el-checkbox>
-					<el-checkbox v-model="deptNodeAll" @change="handleCheckedTreeNodeAll($event, 'dept')">鍏ㄩ��/鍏ㄤ笉閫�</el-checkbox>
-					<el-checkbox v-model="form.deptCheckStrictly" @change="handleCheckedTreeConnect($event, 'dept')">鐖跺瓙鑱斿姩</el-checkbox>
-					<el-tree
-						class="tree-border"
-						:data="deptOptions"
-						show-checkbox
-						default-expand-all
-						ref="deptRef"
-						node-key="id"
-						:check-strictly="!form.deptCheckStrictly"
-						empty-text="鍔犺浇涓紝璇风◢鍊�"
-						:props="{ label: 'label', children: 'children' }"
-					></el-tree>
-				</el-form-item>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button type="primary" @click="submitDataScope">纭� 瀹�</el-button>
-					<el-button @click="cancelDataScope">鍙� 娑�</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</div>
-</template>
diff --git a/src/views/system/role/selectUser.vue b/src/views/system/role/selectUser.vue
index ccae9e1..38c6a44 100644
--- a/src/views/system/role/selectUser.vue
+++ b/src/views/system/role/selectUser.vue
@@ -1,3 +1,48 @@
+<template>
+  <el-row>
+    <el-dialog title="閫夋嫨鐢ㄦ埛" v-model="visible" width="800px" top="5vh" append-to-body>
+      <el-form :model="queryParams" ref="queryFormRef" :inline="true">
+        <el-form-item label="鐢ㄦ埛鍚嶇О" prop="userName">
+          <el-input v-model="queryParams.userName" placeholder="璇疯緭鍏ョ敤鎴峰悕绉�" clearable @keyup.enter="handleQuery" />
+        </el-form-item>
+        <el-form-item label="鎵嬫満鍙风爜" prop="phonenumber">
+          <el-input v-model="queryParams.phonenumber" placeholder="璇疯緭鍏ユ墜鏈哄彿鐮�" clearable @keyup.enter="handleQuery" />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+          <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+        </el-form-item>
+      </el-form>
+      <el-row>
+        <el-table @row-click="clickRow" ref="tableRef" :data="userList" @selection-change="handleSelectionChange" height="260px">
+          <el-table-column type="selection" width="55"></el-table-column>
+          <el-table-column label="鐢ㄦ埛鍚嶇О" prop="userName" :show-overflow-tooltip="true" />
+          <el-table-column label="鐢ㄦ埛鏄电О" prop="nickName" :show-overflow-tooltip="true" />
+          <el-table-column label="閭" prop="email" :show-overflow-tooltip="true" />
+          <el-table-column label="鎵嬫満" prop="phonenumber" :show-overflow-tooltip="true" />
+          <el-table-column label="鐘舵��" align="center" prop="status">
+            <template #default="scope">
+              <dict-tag :options="sys_normal_disable" :value="scope.row.status" />
+            </template>
+          </el-table-column>
+          <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180">
+            <template #default="scope">
+              <span>{{ parseTime(scope.row.createTime) }}</span>
+            </template>
+          </el-table-column>
+        </el-table>
+        <pagination v-if="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+      </el-row>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="handleSelectUser">纭� 瀹�</el-button>
+          <el-button @click="visible = false">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </el-row>
+</template>
+
 <script setup name="SelectUser" lang="ts">
 import { authUserSelectAll, unallocatedUserList } from "@/api/system/role";
 import { UserVO } from '@/api/system/user/types';
@@ -7,9 +52,9 @@
 
 
 const props = defineProps({
-  roleId: {
-    type: [Number, String]
-  }
+    roleId: {
+        type: [Number, String]
+    }
 })
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
@@ -21,113 +66,68 @@
 const userIds = ref<Array<string | number>>([]);
 
 const queryParams = reactive<UserQuery>({
-  pageNum: 1,
-  pageSize: 10,
-  roleId: undefined,
-  userName: undefined,
-  phonenumber: undefined
+    pageNum: 1,
+    pageSize: 10,
+    roleId: undefined,
+    userName: undefined,
+    phonenumber: undefined
 })
 
 const tableRef = ref(ElTable);
 const queryFormRef = ref(ElForm);
 
 const show = () => {
-  queryParams.roleId = props.roleId;
-  getList();
-  visible.value = true;
+    queryParams.roleId = props.roleId;
+    getList();
+    visible.value = true;
 }
 
 /**
  * 閫夋嫨琛�
  */
 const clickRow = (row: any) => {
-  tableRef.value.toggleRowSelection(row);
+    tableRef.value.toggleRowSelection(row);
 }
 /** 澶氶�夋閫変腑鏁版嵁 */
 const handleSelectionChange = (selection: UserVO[]) => {
-  userIds.value = selection.map((item: UserVO) => item.userId);
+    userIds.value = selection.map((item: UserVO) => item.userId);
 }
 
 /** 鏌ヨ鏁版嵁 */
 const getList = async () => {
-	const res = await unallocatedUserList(queryParams);
-	userList.value = res.rows;
-	total.value = res.total;
+    const res = await unallocatedUserList(queryParams);
+    userList.value = res.rows;
+    total.value = res.total;
 }
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-  queryParams.pageNum = 1;
-  getList();
+    queryParams.pageNum = 1;
+    getList();
 }
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 const resetQuery = () => {
-  queryFormRef.value.resetFields();
-  getList();
+    queryFormRef.value.resetFields();
+    getList();
 }
 
 const emit = defineEmits(["ok"]);
 /**閫夋嫨鎺堟潈鐢ㄦ埛鎿嶄綔 */
 const handleSelectUser = async () => {
-  const roleId = queryParams.roleId;
-  const ids = userIds.value.join(',');
-  if (ids == "") {
-    proxy?.$modal.msgError('璇烽�夋嫨瑕佸垎閰嶇殑鐢ㄦ埛');
-    return;
-  }
-	await authUserSelectAll({ roleId, userIds: ids });
-	proxy?.$modal.msgSuccess('鍒嗛厤鎴愬姛');
-	emit('ok');
-	visible.value = false;
+    const roleId = queryParams.roleId;
+    const ids = userIds.value.join(',');
+    if (ids == "") {
+        proxy?.$modal.msgError('璇烽�夋嫨瑕佸垎閰嶇殑鐢ㄦ埛');
+        return;
+    }
+    await authUserSelectAll({ roleId, userIds: ids });
+    proxy?.$modal.msgSuccess('鍒嗛厤鎴愬姛');
+    emit('ok');
+    visible.value = false;
 }
 // 鏆撮湶
 defineExpose({
-  show,
+    show,
 });
 </script>
-
-<template>
-	<el-row>
-		<el-dialog title="閫夋嫨鐢ㄦ埛" v-model="visible" width="800px" top="5vh" append-to-body>
-			<el-form :model="queryParams" ref="queryFormRef" :inline="true">
-				<el-form-item label="鐢ㄦ埛鍚嶇О" prop="userName">
-					<el-input v-model="queryParams.userName" placeholder="璇疯緭鍏ョ敤鎴峰悕绉�" clearable @keyup.enter="handleQuery" />
-				</el-form-item>
-				<el-form-item label="鎵嬫満鍙风爜" prop="phonenumber">
-					<el-input v-model="queryParams.phonenumber" placeholder="璇疯緭鍏ユ墜鏈哄彿鐮�" clearable @keyup.enter="handleQuery" />
-				</el-form-item>
-				<el-form-item>
-					<el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
-					<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-				</el-form-item>
-			</el-form>
-			<el-row>
-				<el-table @row-click="clickRow" ref="tableRef" :data="userList" @selection-change="handleSelectionChange" height="260px">
-					<el-table-column type="selection" width="55"></el-table-column>
-					<el-table-column label="鐢ㄦ埛鍚嶇О" prop="userName" :show-overflow-tooltip="true" />
-					<el-table-column label="鐢ㄦ埛鏄电О" prop="nickName" :show-overflow-tooltip="true" />
-					<el-table-column label="閭" prop="email" :show-overflow-tooltip="true" />
-					<el-table-column label="鎵嬫満" prop="phonenumber" :show-overflow-tooltip="true" />
-					<el-table-column label="鐘舵��" align="center" prop="status">
-						<template #default="scope">
-							<dict-tag :options="sys_normal_disable" :value="scope.row.status" />
-						</template>
-					</el-table-column>
-					<el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180">
-						<template #default="scope">
-							<span>{{ parseTime(scope.row.createTime) }}</span>
-						</template>
-					</el-table-column>
-				</el-table>
-				<pagination v-if="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
-			</el-row>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button type="primary" @click="handleSelectUser">纭� 瀹�</el-button>
-					<el-button @click="visible = false">鍙� 娑�</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</el-row>
-</template>
 
 <style scoped></style>
diff --git a/src/views/system/tenant/index.vue b/src/views/system/tenant/index.vue
index 8feddb8..99d2cb1 100644
--- a/src/views/system/tenant/index.vue
+++ b/src/views/system/tenant/index.vue
@@ -1,3 +1,143 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+          <el-form-item label="绉熸埛缂栧彿" prop="tenantId">
+            <el-input v-model="queryParams.tenantId" placeholder="璇疯緭鍏ョ鎴风紪鍙�" clearable @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鑱旂郴浜�" prop="contactUserName">
+            <el-input v-model="queryParams.contactUserName" placeholder="璇疯緭鍏ヨ仈绯讳汉" clearable @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鑱旂郴鐢佃瘽" prop="contactPhone">
+            <el-input v-model="queryParams.contactPhone" placeholder="璇疯緭鍏ヨ仈绯荤數璇�" clearable @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="浼佷笟鍚嶇О" prop="companyName">
+            <el-input v-model="queryParams.companyName" placeholder="璇疯緭鍏ヤ紒涓氬悕绉�" clearable @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:tenant:add']">鏂板</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:tenant:edit']"
+              >淇敼</el-button
+            >
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:tenant:remove']">
+              鍒犻櫎
+            </el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:tenant:export']">瀵煎嚭</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table v-loading="loading" :data="tenantList" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="id" align="center" prop="id" v-if="false" />
+        <el-table-column label="绉熸埛缂栧彿" align="center" prop="tenantId" />
+        <el-table-column label="鑱旂郴浜�" align="center" prop="contactUserName" />
+        <el-table-column label="鑱旂郴鐢佃瘽" align="center" prop="contactPhone" />
+        <el-table-column label="浼佷笟鍚嶇О" align="center" prop="companyName" />
+        <el-table-column label="绀句細淇$敤浠g爜" align="center" prop="licenseNumber" />
+        <el-table-column label="杩囨湡鏃堕棿" align="center" prop="expireTime" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.expireTime, '{y}-{m}-{d}') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="绉熸埛鐘舵��" align="center" prop="status">
+          <template #default="scope">
+            <el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-tooltip content="淇敼" placement="top">
+              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:tenant:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="鍚屾濂楅" placement="top">
+              <el-button link type="primary" icon="Refresh" @click="handleSyncTenantPackage(scope.row)" v-hasPermi="['system:tenant:edit']">
+              </el-button>
+            </el-tooltip>
+            <el-tooltip content="鍒犻櫎" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:tenant:remove']"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination v-show="total>0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+    </el-card>
+    <!-- 娣诲姞鎴栦慨鏀圭鎴峰璇濇 -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
+      <el-form ref="tenantFormRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="浼佷笟鍚嶇О" prop="companyName">
+          <el-input v-model="form.companyName" placeholder="璇疯緭鍏ヤ紒涓氬悕绉�" />
+        </el-form-item>
+        <el-form-item label="鑱旂郴浜�" prop="contactUserName">
+          <el-input v-model="form.contactUserName" placeholder="璇疯緭鍏ヨ仈绯讳汉" />
+        </el-form-item>
+        <el-form-item label="鑱旂郴鐢佃瘽" prop="contactPhone">
+          <el-input v-model="form.contactPhone" placeholder="璇疯緭鍏ヨ仈绯荤數璇�" />
+        </el-form-item>
+        <el-form-item v-if="!form.id" label="鐢ㄦ埛鍚�" prop="username">
+          <el-input v-model="form.username" placeholder="璇疯緭鍏ョ郴缁熺敤鎴峰悕" maxlength="30" />
+        </el-form-item>
+        <el-form-item v-if="!form.id" label="鐢ㄦ埛瀵嗙爜" prop="password">
+          <el-input type="password" v-model="form.password" placeholder="璇疯緭鍏ョ郴缁熺敤鎴峰瘑鐮�" maxlength="20" />
+        </el-form-item>
+        <el-form-item label="绉熸埛濂楅" prop="packageId">
+          <el-select v-model="form.packageId" :disabled="!!form.tenantId" placeholder="璇烽�夋嫨绉熸埛濂楅" clearable style="width: 100%">
+            <el-option v-for="item in packageList" :key="item.packageId" :label="item.packageName" :value="item.packageId" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="杩囨湡鏃堕棿" prop="expireTime">
+          <el-date-picker clearable v-model="form.expireTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="璇烽�夋嫨杩囨湡鏃堕棿">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="鐢ㄦ埛鏁伴噺" prop="accountCount">
+          <el-input v-model="form.accountCount" placeholder="璇疯緭鍏ョ敤鎴锋暟閲�" />
+        </el-form-item>
+        <el-form-item label="缁戝畾鍩熷悕" prop="domain">
+          <el-input v-model="form.domain" placeholder="璇疯緭鍏ョ粦瀹氬煙鍚�" />
+        </el-form-item>
+        <el-form-item label="浼佷笟鍦板潃" prop="address">
+          <el-input v-model="form.address" placeholder="璇疯緭鍏ヤ紒涓氬湴鍧�" />
+        </el-form-item>
+        <el-form-item label="浼佷笟浠g爜" prop="licenseNumber">
+          <el-input v-model="form.licenseNumber" placeholder="璇疯緭鍏ョ粺涓�绀句細淇$敤浠g爜" />
+        </el-form-item>
+        <el-form-item label="浼佷笟绠�浠�" prop="intro">
+          <el-input type="textarea" v-model="form.intro" placeholder="璇疯緭鍏ヤ紒涓氱畝浠�" />
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="form.remark" placeholder="璇疯緭鍏ュ娉�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
 <script setup name="Tenant" lang="ts">
 import { listTenant, getTenant, delTenant, addTenant, updateTenant, changeTenantStatus, syncTenantPackage} from '@/api/system/tenant';
 import { listTenantPackage } from '@/api/system/tenantPackage';
@@ -23,332 +163,192 @@
 const tenantFormRef = ref(ElForm);
 
 const dialog = reactive<DialogOption>({
-  visible: false,
-  title: ''
+    visible: false,
+    title: ''
 });
 
 const initFormData: TenantForm = {
-  id: undefined,
-  tenantId: undefined,
-  contactUserName: '',
-  contactPhone: '',
-  username: '',
-  password: '',
-  companyName: '',
-  licenseNumber: '',
-  domain: '',
-  address: '',
-  intro: '',
-  remark: '',
-  packageId: '',
-  expireTime: '',
-  accountCount: 0,
-  status: '0',
-}
-const data = reactive<PageData<TenantForm, TenantQuery>>({
-  form: {...initFormData},
-  queryParams: {
-    pageNum: 1,
-    pageSize: 10,
-    tenantId: '',
+    id: undefined,
+    tenantId: undefined,
     contactUserName: '',
     contactPhone: '',
-    companyName: ''
-  },
-  rules: {
-    id: [{ required: true, message: "id涓嶈兘涓虹┖", trigger: "blur" }],
-    tenantId: [{ required: true, message: "绉熸埛缂栧彿涓嶈兘涓虹┖", trigger: "blur" }],
-    contactUserName: [{ required: true, message: "鑱旂郴浜轰笉鑳戒负绌�", trigger: "blur" }],
-    contactPhone: [{ required: true, message: "鑱旂郴鐢佃瘽涓嶈兘涓虹┖", trigger: "blur" }],
-    companyName: [{ required: true, message: "浼佷笟鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }],
-    username: [
-      { required: true, message: "鐢ㄦ埛鍚嶄笉鑳戒负绌�", trigger: "blur" },
-      { min: 2, max: 20, message: '鐢ㄦ埛鍚嶇О闀垮害蹇呴』浠嬩簬 2 鍜� 20 涔嬮棿', trigger: 'blur' }
-    ],
-    password: [
-      { required: true, message: "瀵嗙爜涓嶈兘涓虹┖", trigger: "blur" },
-      { min: 5, max: 20, message: '鐢ㄦ埛瀵嗙爜闀垮害蹇呴』浠嬩簬 5 鍜� 20 涔嬮棿', trigger: 'blur' }
-    ]
-  }
+    username: '',
+    password: '',
+    companyName: '',
+    licenseNumber: '',
+    domain: '',
+    address: '',
+    intro: '',
+    remark: '',
+    packageId: '',
+    expireTime: '',
+    accountCount: 0,
+    status: '0',
+}
+const data = reactive<PageData<TenantForm, TenantQuery>>({
+    form: {...initFormData},
+    queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        tenantId: '',
+        contactUserName: '',
+        contactPhone: '',
+        companyName: ''
+    },
+    rules: {
+        id: [{ required: true, message: "id涓嶈兘涓虹┖", trigger: "blur" }],
+        tenantId: [{ required: true, message: "绉熸埛缂栧彿涓嶈兘涓虹┖", trigger: "blur" }],
+        contactUserName: [{ required: true, message: "鑱旂郴浜轰笉鑳戒负绌�", trigger: "blur" }],
+        contactPhone: [{ required: true, message: "鑱旂郴鐢佃瘽涓嶈兘涓虹┖", trigger: "blur" }],
+        companyName: [{ required: true, message: "浼佷笟鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }],
+        username: [
+            { required: true, message: "鐢ㄦ埛鍚嶄笉鑳戒负绌�", trigger: "blur" },
+            { min: 2, max: 20, message: '鐢ㄦ埛鍚嶇О闀垮害蹇呴』浠嬩簬 2 鍜� 20 涔嬮棿', trigger: 'blur' }
+        ],
+        password: [
+            { required: true, message: "瀵嗙爜涓嶈兘涓虹┖", trigger: "blur" },
+            { min: 5, max: 20, message: '鐢ㄦ埛瀵嗙爜闀垮害蹇呴』浠嬩簬 5 鍜� 20 涔嬮棿', trigger: 'blur' }
+        ]
+    }
 });
 
 const { queryParams, form, rules } = toRefs(data);
 
 /** 鏌ヨ鎵�鏈夌鎴峰椁� */
 const getTenantPackage = async () => {
-  const res = await listTenantPackage()
-  packageList.value = res.rows;
+    const res = await listTenantPackage()
+    packageList.value = res.rows;
 }
 
 /** 鏌ヨ绉熸埛鍒楄〃 */
 const getList = async () => {
-  loading.value = true;
-  const res = await listTenant(queryParams.value);
-  tenantList.value = res.rows;
-  total.value = res.total;
-  loading.value = false;
+    loading.value = true;
+    const res = await listTenant(queryParams.value);
+    tenantList.value = res.rows;
+    total.value = res.total;
+    loading.value = false;
 }
 
 // 绉熸埛濂楅鐘舵�佷慨鏀�
 const handleStatusChange = async (row: TenantVO) => {
-  let text = row.status === "0" ? "鍚敤" : "鍋滅敤";
-  try {
-    await proxy?.$modal.confirm('纭瑕�"' + text + '""' + row.companyName + '"绉熸埛鍚楋紵');
-    await changeTenantStatus(row.id, row.tenantId, row.status);
-    proxy?.$modal.msgSuccess(text + "鎴愬姛");
-  } catch {
-    row.status = row.status === "0" ? "1" : "0";
-  }
+    let text = row.status === "0" ? "鍚敤" : "鍋滅敤";
+    try {
+        await proxy?.$modal.confirm('纭瑕�"' + text + '""' + row.companyName + '"绉熸埛鍚楋紵');
+        await changeTenantStatus(row.id, row.tenantId, row.status);
+        proxy?.$modal.msgSuccess(text + "鎴愬姛");
+    } catch {
+        row.status = row.status === "0" ? "1" : "0";
+    }
 
 
 }
 
 // 鍙栨秷鎸夐挳
 const cancel = () => {
-  reset();
-  dialog.visible = false;
+    reset();
+    dialog.visible = false;
 }
 
 // 琛ㄥ崟閲嶇疆
 const reset = () => {
-  form.value = {...initFormData};
-  tenantFormRef.value.resetFields();
+    form.value = {...initFormData};
+    tenantFormRef.value.resetFields();
 }
 
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-  queryParams.value.pageNum = 1;
-  getList();
+    queryParams.value.pageNum = 1;
+    getList();
 }
 
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 const resetQuery = () => {
-  queryFormRef.value.resetFields();
-  handleQuery();
+    queryFormRef.value.resetFields();
+    handleQuery();
 }
 
 // 澶氶�夋閫変腑鏁版嵁
 const handleSelectionChange = (selection: TenantVO[]) => {
-  ids.value = selection.map(item => item.id);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
+    ids.value = selection.map(item => item.id);
+    single.value = selection.length != 1;
+    multiple.value = !selection.length;
 }
 
 /** 鏂板鎸夐挳鎿嶄綔 */
 const handleAdd = () => {
-  dialog.visible = true;
-  dialog.title = "娣诲姞绉熸埛";
-  nextTick(() => {
-    reset();
-    getTenantPackage();
-  })
+    dialog.visible = true;
+    dialog.title = "娣诲姞绉熸埛";
+    nextTick(() => {
+        reset();
+        getTenantPackage();
+    })
 }
 
 /** 淇敼鎸夐挳鎿嶄綔 */
 const handleUpdate = (row?: TenantVO) => {
-  loading.value = true;
-  dialog.visible = true;
-  dialog.title = "淇敼绉熸埛";
-  nextTick(async () => {
-    reset();
-    getTenantPackage();
-    const _id = row?.id || ids.value[0];
-    const res = await getTenant(_id);
-    loading.value = false;
-    Object.assign(form.value, res.data)
-  })
+    loading.value = true;
+    dialog.visible = true;
+    dialog.title = "淇敼绉熸埛";
+    nextTick(async () => {
+        reset();
+        getTenantPackage();
+        const _id = row?.id || ids.value[0];
+        const res = await getTenant(_id);
+        loading.value = false;
+        Object.assign(form.value, res.data)
+    })
 }
 
 /** 鎻愪氦鎸夐挳 */
 const submitForm = () => {
-  tenantFormRef.value.validate(async (valid: boolean) => {
-    if (valid) {
-      buttonLoading.value = true;
-      if (form.value.id) {
-        await updateTenant(form.value).finally(() => buttonLoading.value = false);
-      } else {
-        await addTenant(form.value).finally(() => buttonLoading.value = false);
-      }
-      proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛");
-      dialog.visible = false;
-      getList();
-    }
-  });
+    tenantFormRef.value.validate(async (valid: boolean) => {
+        if (valid) {
+            buttonLoading.value = true;
+            if (form.value.id) {
+                await updateTenant(form.value).finally(() => buttonLoading.value = false);
+            } else {
+                await addTenant(form.value).finally(() => buttonLoading.value = false);
+            }
+            proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛");
+            dialog.visible = false;
+            getList();
+        }
+    });
 }
 
 /** 鍒犻櫎鎸夐挳鎿嶄綔 */
 const handleDelete = async (row?: TenantVO) => {
-  const _ids = row?.id || ids.value;
-  await proxy?.$modal.confirm('鏄惁纭鍒犻櫎绉熸埛缂栧彿涓�"' + _ids + '"鐨勬暟鎹」锛�')
-  loading.value = true;
-  await delTenant(_ids).finally(() => loading.value = false);
-  getList();
-  proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    const _ids = row?.id || ids.value;
+    await proxy?.$modal.confirm('鏄惁纭鍒犻櫎绉熸埛缂栧彿涓�"' + _ids + '"鐨勬暟鎹」锛�')
+    loading.value = true;
+    await delTenant(_ids).finally(() => loading.value = false);
+    getList();
+    proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
 
 
 }
 
 /** 鍚屾绉熸埛濂楅鎸夐挳鎿嶄綔 */
 const handleSyncTenantPackage = async (row: TenantVO) => {
-  try {
-    await proxy?.$modal.confirm('鏄惁纭鍚屾绉熸埛濂楅绉熸埛缂栧彿涓�"' + row.tenantId + '"鐨勬暟鎹」锛�');
-    loading.value = true;
-    await syncTenantPackage(row.tenantId, row.packageId);
-    getList();
-    proxy?.$modal.msgSuccess("鍚屾鎴愬姛");
-  } catch {return} finally {
-    loading.value = false;
-  }
+    try {
+        await proxy?.$modal.confirm('鏄惁纭鍚屾绉熸埛濂楅绉熸埛缂栧彿涓�"' + row.tenantId + '"鐨勬暟鎹」锛�');
+        loading.value = true;
+        await syncTenantPackage(row.tenantId, row.packageId);
+        getList();
+        proxy?.$modal.msgSuccess("鍚屾鎴愬姛");
+    } catch {return} finally {
+        loading.value = false;
+    }
 }
 
 /** 瀵煎嚭鎸夐挳鎿嶄綔 */
 const handleExport = () => {
-  proxy?.download('system/tenant/export', {
-    ...queryParams.value
-  }, `tenant_${new Date().getTime()}.xlsx`)
+    proxy?.download('system/tenant/export', {
+        ...queryParams.value
+    }, `tenant_${new Date().getTime()}.xlsx`)
 }
 
 onMounted(() => {
-  getList();
+    getList();
 })
 </script>
-
-<template>
-	<div class="p-2">
-		<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-			<div class="search" v-show="showSearch">
-				<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
-					<el-form-item label="绉熸埛缂栧彿" prop="tenantId">
-						<el-input v-model="queryParams.tenantId" placeholder="璇疯緭鍏ョ鎴风紪鍙�" clearable @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鑱旂郴浜�" prop="contactUserName">
-						<el-input v-model="queryParams.contactUserName" placeholder="璇疯緭鍏ヨ仈绯讳汉" clearable @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鑱旂郴鐢佃瘽" prop="contactPhone">
-						<el-input v-model="queryParams.contactPhone" placeholder="璇疯緭鍏ヨ仈绯荤數璇�" clearable @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="浼佷笟鍚嶇О" prop="companyName">
-						<el-input v-model="queryParams.companyName" placeholder="璇疯緭鍏ヤ紒涓氬悕绉�" clearable @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item>
-						<el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
-						<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-					</el-form-item>
-				</el-form>
-			</div>
-		</transition>
-
-		<el-card shadow="never">
-			<template #header>
-				<el-row :gutter="10" class="mb8">
-					<el-col :span="1.5">
-						<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:tenant:add']">鏂板</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:tenant:edit']"
-							>淇敼</el-button
-						>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:tenant:remove']">
-							鍒犻櫎
-						</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:tenant:export']">瀵煎嚭</el-button>
-					</el-col>
-					<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-				</el-row>
-			</template>
-
-			<el-table v-loading="loading" :data="tenantList" @selection-change="handleSelectionChange">
-				<el-table-column type="selection" width="55" align="center" />
-				<el-table-column label="id" align="center" prop="id" v-if="false" />
-				<el-table-column label="绉熸埛缂栧彿" align="center" prop="tenantId" />
-				<el-table-column label="鑱旂郴浜�" align="center" prop="contactUserName" />
-				<el-table-column label="鑱旂郴鐢佃瘽" align="center" prop="contactPhone" />
-				<el-table-column label="浼佷笟鍚嶇О" align="center" prop="companyName" />
-				<el-table-column label="绀句細淇$敤浠g爜" align="center" prop="licenseNumber" />
-				<el-table-column label="杩囨湡鏃堕棿" align="center" prop="expireTime" width="180">
-					<template #default="scope">
-						<span>{{ parseTime(scope.row.expireTime, '{y}-{m}-{d}') }}</span>
-					</template>
-				</el-table-column>
-				<el-table-column label="绉熸埛鐘舵��" align="center" prop="status">
-					<template #default="scope">
-						<el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
-					</template>
-				</el-table-column>
-				<el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
-					<template #default="scope">
-						<el-tooltip content="淇敼" placement="top">
-							<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:tenant:edit']"></el-button>
-						</el-tooltip>
-						<el-tooltip content="鍚屾濂楅" placement="top">
-							<el-button link type="primary" icon="Refresh" @click="handleSyncTenantPackage(scope.row)" v-hasPermi="['system:tenant:edit']">
-							</el-button>
-						</el-tooltip>
-						<el-tooltip content="鍒犻櫎" placement="top">
-							<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:tenant:remove']"></el-button>
-						</el-tooltip>
-					</template>
-				</el-table-column>
-			</el-table>
-
-			<pagination v-show="total>0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
-		</el-card>
-		<!-- 娣诲姞鎴栦慨鏀圭鎴峰璇濇 -->
-		<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
-			<el-form ref="tenantFormRef" :model="form" :rules="rules" label-width="80px">
-				<el-form-item label="浼佷笟鍚嶇О" prop="companyName">
-					<el-input v-model="form.companyName" placeholder="璇疯緭鍏ヤ紒涓氬悕绉�" />
-				</el-form-item>
-				<el-form-item label="鑱旂郴浜�" prop="contactUserName">
-					<el-input v-model="form.contactUserName" placeholder="璇疯緭鍏ヨ仈绯讳汉" />
-				</el-form-item>
-				<el-form-item label="鑱旂郴鐢佃瘽" prop="contactPhone">
-					<el-input v-model="form.contactPhone" placeholder="璇疯緭鍏ヨ仈绯荤數璇�" />
-				</el-form-item>
-				<el-form-item v-if="!form.id" label="鐢ㄦ埛鍚�" prop="username">
-					<el-input v-model="form.username" placeholder="璇疯緭鍏ョ郴缁熺敤鎴峰悕" maxlength="30" />
-				</el-form-item>
-				<el-form-item v-if="!form.id" label="鐢ㄦ埛瀵嗙爜" prop="password">
-					<el-input type="password" v-model="form.password" placeholder="璇疯緭鍏ョ郴缁熺敤鎴峰瘑鐮�" maxlength="20" />
-				</el-form-item>
-				<el-form-item label="绉熸埛濂楅" prop="packageId">
-					<el-select v-model="form.packageId" :disabled="!!form.tenantId" placeholder="璇烽�夋嫨绉熸埛濂楅" clearable style="width: 100%">
-						<el-option v-for="item in packageList" :key="item.packageId" :label="item.packageName" :value="item.packageId" />
-					</el-select>
-				</el-form-item>
-				<el-form-item label="杩囨湡鏃堕棿" prop="expireTime">
-					<el-date-picker clearable v-model="form.expireTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="璇烽�夋嫨杩囨湡鏃堕棿">
-					</el-date-picker>
-				</el-form-item>
-				<el-form-item label="鐢ㄦ埛鏁伴噺" prop="accountCount">
-					<el-input v-model="form.accountCount" placeholder="璇疯緭鍏ョ敤鎴锋暟閲�" />
-				</el-form-item>
-				<el-form-item label="缁戝畾鍩熷悕" prop="domain">
-					<el-input v-model="form.domain" placeholder="璇疯緭鍏ョ粦瀹氬煙鍚�" />
-				</el-form-item>
-				<el-form-item label="浼佷笟鍦板潃" prop="address">
-					<el-input v-model="form.address" placeholder="璇疯緭鍏ヤ紒涓氬湴鍧�" />
-				</el-form-item>
-				<el-form-item label="浼佷笟浠g爜" prop="licenseNumber">
-					<el-input v-model="form.licenseNumber" placeholder="璇疯緭鍏ョ粺涓�绀句細淇$敤浠g爜" />
-				</el-form-item>
-				<el-form-item label="浼佷笟绠�浠�" prop="intro">
-					<el-input type="textarea" v-model="form.intro" placeholder="璇疯緭鍏ヤ紒涓氱畝浠�" />
-				</el-form-item>
-				<el-form-item label="澶囨敞" prop="remark">
-					<el-input v-model="form.remark" placeholder="璇疯緭鍏ュ娉�" />
-				</el-form-item>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
-					<el-button @click="cancel">鍙� 娑�</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</div>
-</template>
diff --git a/src/views/system/tenantPackage/index.vue b/src/views/system/tenantPackage/index.vue
index 6a3a494..790d003 100644
--- a/src/views/system/tenantPackage/index.vue
+++ b/src/views/system/tenantPackage/index.vue
@@ -1,3 +1,102 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+          <el-form-item label="濂楅鍚嶇О" prop="packageName">
+            <el-input v-model="queryParams.packageName" placeholder="璇疯緭鍏ュ椁愬悕绉�" clearable @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:tenantPackage:add']">鏂板</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:tenantPackage:edit']"
+              >淇敼</el-button
+            >
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:tenantPackage:remove']"
+              >鍒犻櫎</el-button
+            >
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:tenantPackage:export']">瀵煎嚭</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table v-loading="loading" :data="tenantPackageList" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="绉熸埛濂楅id" align="center" prop="packageId" v-if="false" />
+        <el-table-column label="濂楅鍚嶇О" align="center" prop="packageName" />
+        <el-table-column label="澶囨敞" align="center" prop="remark" />
+        <el-table-column label="鐘舵��" align="center" prop="status">
+          <template #default="scope">
+            <el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @click="handleStatusChange(scope.row)"></el-switch>
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-tooltip content="淇敼" placement="top">
+              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:tenantPackage:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="鍒犻櫎" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:tenantPackage:remove']"> </el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination v-show="total>0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+    </el-card>
+
+    <!-- 娣诲姞鎴栦慨鏀圭鎴峰椁愬璇濇 -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
+      <el-form ref="tenantPackageFormRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="濂楅鍚嶇О" prop="packageName">
+          <el-input v-model="form.packageName" placeholder="璇疯緭鍏ュ椁愬悕绉�" />
+        </el-form-item>
+        <el-form-item label="鍏宠仈鑿滃崟">
+          <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">灞曞紑/鎶樺彔</el-checkbox>
+          <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">鍏ㄩ��/鍏ㄤ笉閫�</el-checkbox>
+          <el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">鐖跺瓙鑱斿姩</el-checkbox>
+          <el-tree
+            class="tree-border"
+            :data="menuOptions"
+            show-checkbox
+            ref="menuTreeRef"
+            node-key="id"
+            :check-strictly="!form.menuCheckStrictly"
+            empty-text="鍔犺浇涓紝璇风◢鍊�"
+            :props="{ label: 'label', children: 'children' }"
+          ></el-tree>
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="form.remark" placeholder="璇疯緭鍏ュ娉�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
 <script setup name="TenantPackage" lang="ts">
 import { listTenantPackage, getTenantPackage, delTenantPackage, addTenantPackage, updateTenantPackage, changePackageStatus } from "@/api/system/tenantPackage";
 import { treeselect as menuTreeselect, tenantPackageMenuTreeselect } from "@/api/system/menu";
@@ -26,308 +125,209 @@
 const tenantPackageFormRef = ref(ElForm);
 
 const dialog = reactive<DialogOption>({
-  visible: false,
-  title: ''
+    visible: false,
+    title: ''
 });
 
 
 const initFormData: TenantPkgForm = {
-  packageId: undefined,
-  packageName: '',
-  menuIds: '',
-  remark: '',
-  menuCheckStrictly: true,
-  status: ''
+    packageId: undefined,
+    packageName: '',
+    menuIds: '',
+    remark: '',
+    menuCheckStrictly: true,
+    status: ''
 };
 const data = reactive<PageData<TenantPkgForm, TenantPkgQuery>>({
-  form: {...initFormData},
-  queryParams: {
-    pageNum: 1,
-    pageSize: 10,
-    packageName: '',
-    status: '',
-  },
-  rules: {
-    packageId: [{ required: true, message: "绉熸埛濂楅id涓嶈兘涓虹┖", trigger: "blur" }],
-    packageName: [{ required: true, message: "濂楅鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }]
-  }
+    form: {...initFormData},
+    queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        packageName: '',
+        status: '',
+    },
+    rules: {
+        packageId: [{ required: true, message: "绉熸埛濂楅id涓嶈兘涓虹┖", trigger: "blur" }],
+        packageName: [{ required: true, message: "濂楅鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }]
+    }
 });
 
 const { queryParams, form, rules } = toRefs(data);
 
 /** 鏌ヨ鑿滃崟鏍戠粨鏋� */
 const getMenuTreeselect = async() => {
-  const { data } = await menuTreeselect();
-  menuOptions.value = data;
+    const { data } = await menuTreeselect();
+    menuOptions.value = data;
 }
 
 // 鎵�鏈夎彍鍗曡妭鐐规暟鎹�
 const getMenuAllCheckedKeys = () => {
-  // 鐩墠琚�変腑鐨勮彍鍗曡妭鐐�
-  let checkedKeys = menuTreeRef.value.getCheckedKeys();
-  // 鍗婇�変腑鐨勮彍鍗曡妭鐐�
-  let halfCheckedKeys = menuTreeRef.value.getHalfCheckedKeys();
-  checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
-  return checkedKeys;
+    // 鐩墠琚�変腑鐨勮彍鍗曡妭鐐�
+    let checkedKeys = menuTreeRef.value.getCheckedKeys();
+    // 鍗婇�変腑鐨勮彍鍗曡妭鐐�
+    let halfCheckedKeys = menuTreeRef.value.getHalfCheckedKeys();
+    checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
+    return checkedKeys;
 }
 
 /** 鏍规嵁绉熸埛濂楅ID鏌ヨ鑿滃崟鏍戠粨鏋� */
 const getPackageMenuTreeselect = async(packageId: string | number) => {
-  const res = await tenantPackageMenuTreeselect(packageId);
-  menuOptions.value = res.data.menus;
-  return Promise.resolve(res);
+    const res = await tenantPackageMenuTreeselect(packageId);
+    menuOptions.value = res.data.menus;
+    return Promise.resolve(res);
 }
 
 /** 鏌ヨ绉熸埛濂楅鍒楄〃 */
 const getList = async () => {
-  loading.value = true;
-  const res = await listTenantPackage(queryParams.value);
-  tenantPackageList.value = res.rows;
-  total.value = res.total;
-  loading.value = false;
+    loading.value = true;
+    const res = await listTenantPackage(queryParams.value);
+    tenantPackageList.value = res.rows;
+    total.value = res.total;
+    loading.value = false;
 }
 
 // 绉熸埛濂楅鐘舵�佷慨鏀�
 const handleStatusChange = async (row: TenantPkgVO) => {
-  let text = row.status === "0" ? "鍚敤" : "鍋滅敤";
-  const [err] = await to(proxy?.$modal.confirm('纭瑕�"' + text + '""' + row.packageName + '"濂楅鍚楋紵') as Promise<any>)
-  if (err) {
-    row.status = row.status === "0" ? "1" : "0";
-  } else {
-    await changePackageStatus(row.packageId, row.status);
-    proxy?.$modal.msgSuccess(text + "鎴愬姛");
-  }
+    let text = row.status === "0" ? "鍚敤" : "鍋滅敤";
+    const [err] = await to(proxy?.$modal.confirm('纭瑕�"' + text + '""' + row.packageName + '"濂楅鍚楋紵') as Promise<any>)
+    if (err) {
+        row.status = row.status === "0" ? "1" : "0";
+    } else {
+        await changePackageStatus(row.packageId, row.status);
+        proxy?.$modal.msgSuccess(text + "鎴愬姛");
+    }
 }
 
 // 鍙栨秷鎸夐挳
 const cancel = () => {
-  reset();
-  dialog.visible = false;
+    reset();
+    dialog.visible = false;
 }
 
 // 琛ㄥ崟閲嶇疆
 const reset = () => {
-  menuTreeRef.value.setCheckedKeys([]);
-  menuExpand.value = false;
-  menuNodeAll.value = false;
-  form.value = {...initFormData};
-  tenantPackageFormRef.value.resetFields();
+    menuTreeRef.value.setCheckedKeys([]);
+    menuExpand.value = false;
+    menuNodeAll.value = false;
+    form.value = {...initFormData};
+    tenantPackageFormRef.value.resetFields();
 }
 
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-  queryParams.value.pageNum = 1;
-  getList();
+    queryParams.value.pageNum = 1;
+    getList();
 }
 
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 const resetQuery = () => {
-  queryFormRef.value.resetFields();
-  handleQuery();
+    queryFormRef.value.resetFields();
+    handleQuery();
 }
 
 // 澶氶�夋閫変腑鏁版嵁
 const handleSelectionChange = (selection: TenantPkgVO[]) => {
-  ids.value = selection.map(item => item.packageId);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
+    ids.value = selection.map(item => item.packageId);
+    single.value = selection.length != 1;
+    multiple.value = !selection.length;
 }
 
 // 鏍戞潈闄愶紙灞曞紑/鎶樺彔锛�
 const handleCheckedTreeExpand = (value: CheckboxValueType, type: string) => {
-  if (type == 'menu') {
-    let treeList = menuOptions.value;
-    for (let i = 0; i < treeList.length; i++) {
-      menuTreeRef.value.store.nodesMap[treeList[i].id].expanded = value;
+    if (type == 'menu') {
+        let treeList = menuOptions.value;
+        for (let i = 0; i < treeList.length; i++) {
+            menuTreeRef.value.store.nodesMap[treeList[i].id].expanded = value;
+        }
     }
-  }
 }
 
 // 鏍戞潈闄愶紙鍏ㄩ��/鍏ㄤ笉閫夛級
 const handleCheckedTreeNodeAll = (value: CheckboxValueType, type: string) => {
-  if (type == 'menu') {
-    menuTreeRef.value.setCheckedNodes(value ? menuOptions.value: []);
-  }
+    if (type == 'menu') {
+        menuTreeRef.value.setCheckedNodes(value ? menuOptions.value: []);
+    }
 }
 
 // 鏍戞潈闄愶紙鐖跺瓙鑱斿姩锛�
 const handleCheckedTreeConnect = (value: CheckboxValueType, type: string) => {
-  if (type == 'menu') {
-    form.value.menuCheckStrictly = value as boolean;
-  }
+    if (type == 'menu') {
+        form.value.menuCheckStrictly = value as boolean;
+    }
 }
 
 /** 鏂板鎸夐挳鎿嶄綔 */
 const handleAdd = () => {
-  dialog.visible = true;
-  dialog.title = "娣诲姞绉熸埛濂楅";
-  nextTick(() => {
-    reset();
-    getMenuTreeselect();
-  })
+    dialog.visible = true;
+    dialog.title = "娣诲姞绉熸埛濂楅";
+    nextTick(() => {
+        reset();
+        getMenuTreeselect();
+    })
 }
 
 /** 淇敼鎸夐挳鎿嶄綔 */
 const handleUpdate = (row?: TenantPkgVO) => {
-  loading.value = true
-  dialog.visible = true;
-  dialog.title = "淇敼绉熸埛濂楅";
-  nextTick(async () => {
-    reset();
-    const _packageId = row?.packageId || ids.value[0];
-    const packageMenu = getPackageMenuTreeselect(_packageId);
-    const response = await getTenantPackage(_packageId);
-    loading.value = false;
-    form.value = response.data;
+    loading.value = true
+    dialog.visible = true;
+    dialog.title = "淇敼绉熸埛濂楅";
     nextTick(async () => {
-      const res = await packageMenu;
-      let checkedKeys = res.data.checkedKeys
-        checkedKeys.forEach((v) => {
-          nextTick(() => {
-            menuTreeRef.value.setChecked(v, true ,false);
-          })
-        })
-    });
-  })
+        reset();
+        const _packageId = row?.packageId || ids.value[0];
+        const packageMenu = getPackageMenuTreeselect(_packageId);
+        const response = await getTenantPackage(_packageId);
+        loading.value = false;
+        form.value = response.data;
+        nextTick(async () => {
+            const res = await packageMenu;
+            let checkedKeys = res.data.checkedKeys
+            checkedKeys.forEach((v) => {
+                nextTick(() => {
+                    menuTreeRef.value.setChecked(v, true ,false);
+                })
+            })
+        });
+    })
 }
 
 /** 鎻愪氦鎸夐挳 */
 const submitForm = () => {
-  tenantPackageFormRef.value.validate(async (valid: boolean) => {
-    if (valid) {
-      buttonLoading.value = true;
-      form.value.menuIds = getMenuAllCheckedKeys();
-      if (form.value.packageId != null) {
-        await updateTenantPackage(form.value).finally(() => buttonLoading.value = false);
-      } else {
-        await addTenantPackage(form.value).finally(() => buttonLoading.value = false);
-      }
-      proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛");
-      dialog.visible = false;
-      getList();
-    }
-  });
+    tenantPackageFormRef.value.validate(async (valid: boolean) => {
+        if (valid) {
+            buttonLoading.value = true;
+            form.value.menuIds = getMenuAllCheckedKeys();
+            if (form.value.packageId != null) {
+                await updateTenantPackage(form.value).finally(() => buttonLoading.value = false);
+            } else {
+                await addTenantPackage(form.value).finally(() => buttonLoading.value = false);
+            }
+            proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛");
+            dialog.visible = false;
+            getList();
+        }
+    });
 }
 
 /** 鍒犻櫎鎸夐挳鎿嶄綔 */
 const handleDelete = async (row?: TenantPkgVO) => {
-  const _packageIds = row?.packageId || ids.value;
-  await proxy?.$modal.confirm('鏄惁纭鍒犻櫎绉熸埛濂楅缂栧彿涓�"' + _packageIds + '"鐨勬暟鎹」锛�').finally(() => {
-  loading.value = false;
-  });
-  await delTenantPackage(_packageIds);
-  loading.value = true;
-  getList();
-  proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    const _packageIds = row?.packageId || ids.value;
+    await proxy?.$modal.confirm('鏄惁纭鍒犻櫎绉熸埛濂楅缂栧彿涓�"' + _packageIds + '"鐨勬暟鎹」锛�').finally(() => {
+        loading.value = false;
+    });
+    await delTenantPackage(_packageIds);
+    loading.value = true;
+    getList();
+    proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
 }
 
 /** 瀵煎嚭鎸夐挳鎿嶄綔 */
 const handleExport = () => {
-  proxy?.download('system/tenantPackage/export', {
-    ...queryParams.value
-  }, `tenantPackage_${new Date().getTime()}.xlsx`)
+    proxy?.download('system/tenantPackage/export', {
+        ...queryParams.value
+    }, `tenantPackage_${new Date().getTime()}.xlsx`)
 }
 
 onMounted(() => {
-  getList();
+    getList();
 })
 </script>
-
-<template>
-	<div class="p-2">
-		<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-			<div class="search" v-show="showSearch">
-				<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
-					<el-form-item label="濂楅鍚嶇О" prop="packageName">
-						<el-input v-model="queryParams.packageName" placeholder="璇疯緭鍏ュ椁愬悕绉�" clearable @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item>
-						<el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
-						<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-					</el-form-item>
-				</el-form>
-			</div>
-		</transition>
-
-		<el-card shadow="never">
-			<template #header>
-				<el-row :gutter="10" class="mb8">
-					<el-col :span="1.5">
-						<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:tenantPackage:add']">鏂板</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:tenantPackage:edit']"
-							>淇敼</el-button
-						>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:tenantPackage:remove']"
-							>鍒犻櫎</el-button
-						>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:tenantPackage:export']">瀵煎嚭</el-button>
-					</el-col>
-					<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-				</el-row>
-			</template>
-
-			<el-table v-loading="loading" :data="tenantPackageList" @selection-change="handleSelectionChange">
-				<el-table-column type="selection" width="55" align="center" />
-				<el-table-column label="绉熸埛濂楅id" align="center" prop="packageId" v-if="false" />
-				<el-table-column label="濂楅鍚嶇О" align="center" prop="packageName" />
-				<el-table-column label="澶囨敞" align="center" prop="remark" />
-				<el-table-column label="鐘舵��" align="center" prop="status">
-					<template #default="scope">
-						<el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @click="handleStatusChange(scope.row)"></el-switch>
-					</template>
-				</el-table-column>
-				<el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
-					<template #default="scope">
-						<el-tooltip content="淇敼" placement="top">
-							<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:tenantPackage:edit']"></el-button>
-						</el-tooltip>
-						<el-tooltip content="鍒犻櫎" placement="top">
-							<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:tenantPackage:remove']"> </el-button>
-						</el-tooltip>
-					</template>
-				</el-table-column>
-			</el-table>
-
-			<pagination v-show="total>0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
-		</el-card>
-
-		<!-- 娣诲姞鎴栦慨鏀圭鎴峰椁愬璇濇 -->
-		<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
-			<el-form ref="tenantPackageFormRef" :model="form" :rules="rules" label-width="80px">
-				<el-form-item label="濂楅鍚嶇О" prop="packageName">
-					<el-input v-model="form.packageName" placeholder="璇疯緭鍏ュ椁愬悕绉�" />
-				</el-form-item>
-				<el-form-item label="鍏宠仈鑿滃崟">
-					<el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">灞曞紑/鎶樺彔</el-checkbox>
-					<el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">鍏ㄩ��/鍏ㄤ笉閫�</el-checkbox>
-					<el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">鐖跺瓙鑱斿姩</el-checkbox>
-					<el-tree
-						class="tree-border"
-						:data="menuOptions"
-						show-checkbox
-						ref="menuTreeRef"
-						node-key="id"
-						:check-strictly="!form.menuCheckStrictly"
-						empty-text="鍔犺浇涓紝璇风◢鍊�"
-						:props="{ label: 'label', children: 'children' }"
-					></el-tree>
-				</el-form-item>
-				<el-form-item label="澶囨敞" prop="remark">
-					<el-input v-model="form.remark" placeholder="璇疯緭鍏ュ娉�" />
-				</el-form-item>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
-					<el-button @click="cancel">鍙� 娑�</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</div>
-</template>
diff --git a/src/views/system/user/authRole.vue b/src/views/system/user/authRole.vue
index 0616f67..0e8eba2 100644
--- a/src/views/system/user/authRole.vue
+++ b/src/views/system/user/authRole.vue
@@ -1,3 +1,59 @@
+<template>
+  <div class="p-2">
+    <div class="panel">
+      <h4 class="panel-title">鍩烘湰淇℃伅</h4>
+      <el-form :model="form" label-width="80px" :inline="true">
+        <el-row :gutter="10">
+          <el-col :span="2.5">
+            <el-form-item label="鐢ㄦ埛鏄电О" prop="nickName">
+              <el-input v-model="form.nickName" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="2.5">
+            <el-form-item label="鐧诲綍璐﹀彿" prop="userName">
+              <el-input v-model="form.userName" disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </div>
+    <div class="panel">
+      <h4 class="panel-title">瑙掕壊淇℃伅</h4>
+      <div>
+        <el-table
+          v-loading="loading"
+          :row-key="getRowKey"
+          @row-click="clickRow"
+          ref="tableRef"
+          @selection-change="handleSelectionChange"
+          :data="roles.slice((pageNum - 1) * pageSize, pageNum * pageSize)"
+        >
+          <el-table-column label="搴忓彿" width="55" type="index" align="center">
+            <template #default="scope">
+              <span>{{ (pageNum - 1) * pageSize + scope.$index + 1 }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column type="selection" :reserve-selection="true" width="55"></el-table-column>
+          <el-table-column label="瑙掕壊缂栧彿" align="center" prop="roleId" />
+          <el-table-column label="瑙掕壊鍚嶇О" align="center" prop="roleName" />
+          <el-table-column label="鏉冮檺瀛楃" align="center" prop="roleKey" />
+          <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180">
+            <template #default="scope">
+              <span>{{ parseTime(scope.row.createTime) }}</span>
+            </template>
+          </el-table-column>
+        </el-table>
+        <pagination v-show="total > 0" :total="total" v-model:page="pageNum" v-model:limit="pageSize" />
+        <div style="text-align: center;margin-left:-120px;margin-top:30px;">
+          <el-button type="primary" @click="submitForm()">鎻愪氦</el-button>
+          <el-button @click="close()">杩斿洖</el-button>
+        </div>
+        <div></div>
+      </div>
+    </div>
+  </div>
+</template>
+
 <script setup name="AuthRole" lang="ts">
 import { RoleVO } from '@/api/system/role/types';
 import { getAuthRole, updateAuthRole } from '@/api/system/user';
@@ -14,114 +70,58 @@
 const roleIds = ref<Array<string | number>>([]);
 const roles = ref<RoleVO[]>([]);
 const form = ref<Partial<UserForm>>({
-  nickName: undefined,
-  userName: '',
-  userId: undefined
+    nickName: undefined,
+    userName: '',
+    userId: undefined
 });
 
 const tableRef = ref(ElTable)
 
 /** 鍗曞嚮閫変腑琛屾暟鎹� */
 const clickRow = (row: RoleVO) => {
-  tableRef.value.toggleRowSelection(row);
+    tableRef.value.toggleRowSelection(row);
 };
 /** 澶氶�夋閫変腑鏁版嵁 */
 const handleSelectionChange = (selection: RoleVO[]) => {
-  roleIds.value = selection.map(item => item.roleId);
+    roleIds.value = selection.map(item => item.roleId);
 };
 /** 淇濆瓨閫変腑鐨勬暟鎹紪鍙� */
 const getRowKey = (row: RoleVO): string => {
-  return String(row.roleId);
+    return String(row.roleId);
 };
 /** 鍏抽棴鎸夐挳 */
 const close = () => {
-  const obj = { path: "/system/user" };
-  proxy?.$tab.closeOpenPage(obj);
+    const obj = { path: "/system/user" };
+    proxy?.$tab.closeOpenPage(obj);
 };
 /** 鎻愪氦鎸夐挳 */
 const submitForm = async () => {
-  const userId = form.value.userId;
-  const rIds = roleIds.value.join(",");
-  await updateAuthRole({ userId: userId as string, roleIds: rIds })
-	proxy?.$modal.msgSuccess("鎺堟潈鎴愬姛");
-	close();
+    const userId = form.value.userId;
+    const rIds = roleIds.value.join(",");
+    await updateAuthRole({ userId: userId as string, roleIds: rIds })
+    proxy?.$modal.msgSuccess("鎺堟潈鎴愬姛");
+    close();
 };
 
 const getList = async() => {
-  const userId = route.params && route.params.userId;
-  if (userId) {
-    loading.value = true;
-		const res = await getAuthRole(userId as string);
-		Object.assign(form.value, res.data.user)
-		Object.assign(roles.value, res.data.roles)
-		total.value = roles.value.length;
-		await nextTick(() => {
-			roles.value.forEach(row => {
-				if (row?.flag) {
-					tableRef.value.toggleRowSelection(row);
-				}
-			});
-		});
-		loading.value = false;
-  }
+    const userId = route.params && route.params.userId;
+    if (userId) {
+        loading.value = true;
+        const res = await getAuthRole(userId as string);
+        Object.assign(form.value, res.data.user)
+        Object.assign(roles.value, res.data.roles)
+        total.value = roles.value.length;
+        await nextTick(() => {
+            roles.value.forEach(row => {
+                if (row?.flag) {
+                    tableRef.value.toggleRowSelection(row);
+                }
+            });
+        });
+        loading.value = false;
+    }
 }
 onMounted(() => {
-  getList();
+    getList();
 })
 </script>
-
-<template>
-	<div class="p-2">
-		<div class="panel">
-			<h4 class="panel-title">鍩烘湰淇℃伅</h4>
-			<el-form :model="form" label-width="80px" :inline="true">
-				<el-row :gutter="10">
-					<el-col :span="2.5">
-						<el-form-item label="鐢ㄦ埛鏄电О" prop="nickName">
-							<el-input v-model="form.nickName" disabled />
-						</el-form-item>
-					</el-col>
-					<el-col :span="2.5">
-						<el-form-item label="鐧诲綍璐﹀彿" prop="userName">
-							<el-input v-model="form.userName" disabled />
-						</el-form-item>
-					</el-col>
-				</el-row>
-			</el-form>
-		</div>
-		<div class="panel">
-			<h4 class="panel-title">瑙掕壊淇℃伅</h4>
-			<div>
-				<el-table
-					v-loading="loading"
-					:row-key="getRowKey"
-					@row-click="clickRow"
-					ref="tableRef"
-					@selection-change="handleSelectionChange"
-					:data="roles.slice((pageNum - 1) * pageSize, pageNum * pageSize)"
-				>
-					<el-table-column label="搴忓彿" width="55" type="index" align="center">
-						<template #default="scope">
-							<span>{{ (pageNum - 1) * pageSize + scope.$index + 1 }}</span>
-						</template>
-					</el-table-column>
-					<el-table-column type="selection" :reserve-selection="true" width="55"></el-table-column>
-					<el-table-column label="瑙掕壊缂栧彿" align="center" prop="roleId" />
-					<el-table-column label="瑙掕壊鍚嶇О" align="center" prop="roleName" />
-					<el-table-column label="鏉冮檺瀛楃" align="center" prop="roleKey" />
-					<el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180">
-						<template #default="scope">
-							<span>{{ parseTime(scope.row.createTime) }}</span>
-						</template>
-					</el-table-column>
-				</el-table>
-				<pagination v-show="total > 0" :total="total" v-model:page="pageNum" v-model:limit="pageSize" />
-				<div style="text-align: center;margin-left:-120px;margin-top:30px;">
-					<el-button type="primary" @click="submitForm()">鎻愪氦</el-button>
-					<el-button @click="close()">杩斿洖</el-button>
-				</div>
-				<div></div>
-			</div>
-		</div>
-	</div>
-</template>
diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue
index 41be116..c911bd9 100644
--- a/src/views/system/user/index.vue
+++ b/src/views/system/user/index.vue
@@ -1,13 +1,300 @@
+<template>
+  <div class="p-2">
+    <el-row :gutter="20">
+      <!-- 閮ㄩ棬鏍� -->
+      <el-col :lg="4" :xs="24" style="">
+        <el-card shadow="never">
+          <el-input v-model="deptName" placeholder="璇疯緭鍏ラ儴闂ㄥ悕绉�" prefix-icon="Search" clearable />
+          <el-tree
+            class="mt-2"
+            ref="deptTreeRef"
+            :data="deptOptions"
+            :props="{ label: 'label', children: 'children' }"
+            :expand-on-click-node="false"
+            :filter-node-method="filterNode"
+            highlight-current
+            default-expand-all
+            @node-click="handleNodeClick"
+          ></el-tree>
+        </el-card>
+      </el-col>
+      <el-col :lg="20" :xs="24">
+        <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+          <div class="search" v-show="showSearch">
+            <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="68px">
+              <el-form-item label="鐢ㄦ埛鍚嶇О" prop="userName">
+                <el-input v-model="queryParams.userName" placeholder="璇疯緭鍏ョ敤鎴峰悕绉�" clearable style="width: 240px" @keyup.enter="handleQuery" />
+              </el-form-item>
+              <el-form-item label="鎵嬫満鍙风爜" prop="phonenumber">
+                <el-input v-model="queryParams.phonenumber" placeholder="璇疯緭鍏ユ墜鏈哄彿鐮�" clearable style="width: 240px" @keyup.enter="handleQuery" />
+              </el-form-item>
+
+              <el-form-item label="鐘舵��" prop="status">
+                <el-select v-model="queryParams.status" placeholder="鐢ㄦ埛鐘舵��" clearable style="width: 240px">
+                  <el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
+                </el-select>
+              </el-form-item>
+              <el-form-item label="鍒涘缓鏃堕棿" style="width: 308px;">
+                <el-date-picker
+                  v-model="dateRange"
+                  value-format="YYYY-MM-DD"
+                  type="daterange"
+                  range-separator="-"
+                  start-placeholder="寮�濮嬫棩鏈�"
+                  end-placeholder="缁撴潫鏃ユ湡"
+                ></el-date-picker>
+              </el-form-item>
+              <el-form-item>
+                <el-button type="primary" @click="handleQuery" icon="Search">鎼滅储</el-button>
+                <el-button @click="resetQuery" icon="Refresh">閲嶇疆</el-button>
+              </el-form-item>
+            </el-form>
+          </div>
+        </transition>
+
+        <el-card shadow="never">
+          <template #header>
+            <el-row :gutter="10">
+              <el-col :span="1.5">
+                <el-button type="primary" plain @click="handleAdd()" v-has-permi="['sys:user:add']" icon="Plus">鏂板</el-button>
+              </el-col>
+              <el-col :span="1.5">
+                <el-button type="success" plain @click="handleUpdate()" :disabled="single" v-has-permi="['sys:user:add']" icon="Edit">淇敼</el-button>
+              </el-col>
+              <el-col :span="1.5">
+                <el-button type="danger" plain @click="handleDelete()" :disabled="multiple" v-has-permi="['sys:user:delete']" icon="Delete">
+                  鍒犻櫎
+                </el-button>
+              </el-col>
+              <el-col :span="1.5">
+                <el-dropdown class="mt-[1px]">
+                  <el-button plain type="info">
+                    鏇村
+                    <el-icon class="el-icon--right"><arrow-down /></el-icon
+                  ></el-button>
+                  <template #dropdown>
+                    <el-dropdown-menu>
+                      <el-dropdown-item @click="importTemplate" icon="Download">涓嬭浇妯℃澘</el-dropdown-item>
+                      <el-dropdown-item @click="handleImport" icon="Top"> 瀵煎叆鏁版嵁</el-dropdown-item>
+                      <el-dropdown-item @click="handleExport" icon="Download"> 瀵煎嚭鏁版嵁</el-dropdown-item>
+                    </el-dropdown-menu>
+                  </template>
+                </el-dropdown>
+              </el-col>
+              <right-toolbar v-model:showSearch="showSearch" @queryTable="getList" :columns="columns" :search="true"></right-toolbar>
+            </el-row>
+          </template>
+
+          <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
+            <el-table-column type="selection" width="50" align="center" />
+            <el-table-column label="鐢ㄦ埛缂栧彿" align="center" key="userId" prop="userId" v-if="columns[0].visible" />
+            <el-table-column label="鐢ㄦ埛鍚嶇О" align="center" key="userName" prop="userName" v-if="columns[1].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="鐢ㄦ埛鏄电О" align="center" key="nickName" prop="nickName" v-if="columns[2].visible" :show-overflow-tooltip="true" />
+            <el-table-column
+              label="閮ㄩ棬"
+              align="center"
+              key="deptName"
+              prop="dept.deptName"
+              v-if="columns[3].visible"
+              :show-overflow-tooltip="true"
+            />
+            <el-table-column label="鎵嬫満鍙风爜" align="center" key="phonenumber" prop="phonenumber" v-if="columns[4].visible" width="120" />
+            <el-table-column label="鐘舵��" align="center" key="status" v-if="columns[5].visible">
+              <template #default="scope">
+                <el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
+              </template>
+            </el-table-column>
+
+            <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" v-if="columns[6].visible" width="160">
+              <template #default="scope">
+                <span>{{ scope.row.createTime }}</span>
+              </template>
+            </el-table-column>
+
+            <el-table-column label="鎿嶄綔" fixed="right" width="180" class-name="small-padding fixed-width">
+              <template #default="scope">
+                <el-tooltip content="淇敼" placement="top" v-if="scope.row.userId !== 1">
+                  <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:user:edit']"></el-button>
+                </el-tooltip>
+                <el-tooltip content="鍒犻櫎" placement="top" v-if="scope.row.userId !== 1">
+                  <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:user:remove']"></el-button>
+                </el-tooltip>
+
+                <el-tooltip content="閲嶇疆瀵嗙爜" placement="top" v-if="scope.row.userId !== 1">
+                  <el-button link type="primary" icon="Key" @click="handleResetPwd(scope.row)" v-hasPermi="['system:user:resetPwd']"></el-button>
+                </el-tooltip>
+
+                <el-tooltip content="鍒嗛厤瑙掕壊" placement="top" v-if="scope.row.userId !== 1">
+                  <el-button link type="primary" icon="CircleCheck" @click="handleAuthRole(scope.row)" v-hasPermi="['system:user:edit']"></el-button>
+                </el-tooltip>
+              </template>
+            </el-table-column>
+          </el-table>
+
+          <pagination
+            v-show="total > 0"
+            :total="total"
+            v-model:page="queryParams.pageNum"
+            v-model:limit="queryParams.pageSize"
+            @pagination="handleQuery"
+          />
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 娣诲姞鎴栦慨鏀圭敤鎴烽厤缃璇濇 -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="600px" append-to-body @close="closeDialog">
+      <el-form :model="form" :rules="rules" ref="userFormRef" label-width="80px">
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="鐢ㄦ埛鏄电О" prop="nickName">
+              <el-input v-model="form.nickName" placeholder="璇疯緭鍏ョ敤鎴锋樀绉�" maxlength="30" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="褰掑睘閮ㄩ棬" prop="deptId">
+              <el-tree-select
+                v-model="form.deptId"
+                :data="deptOptions"
+                :props="{ value: 'id', label: 'label', children: 'children' }"
+                value-key="id"
+                placeholder="璇烽�夋嫨褰掑睘閮ㄩ棬"
+                check-strictly
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="鎵嬫満鍙风爜" prop="phonenumber">
+              <el-input v-model="form.phonenumber" placeholder="璇疯緭鍏ユ墜鏈哄彿鐮�" maxlength="11" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="閭" prop="email">
+              <el-input v-model="form.email" placeholder="璇疯緭鍏ラ偖绠�" maxlength="50" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item v-if="form.userId == undefined" label="鐢ㄦ埛鍚嶇О" prop="userName">
+              <el-input v-model="form.userName" placeholder="璇疯緭鍏ョ敤鎴峰悕绉�" maxlength="30" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item v-if="form.userId == undefined" label="鐢ㄦ埛瀵嗙爜" prop="password">
+              <el-input v-model="form.password" placeholder="璇疯緭鍏ョ敤鎴峰瘑鐮�" type="password" maxlength="20" show-password />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="鐢ㄦ埛鎬у埆">
+              <el-select v-model="form.sex" placeholder="璇烽�夋嫨">
+                <el-option v-for="dict in sys_user_sex" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鐘舵��">
+              <el-radio-group v-model="form.status">
+                <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">{{
+                    dict.label }}</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="宀椾綅">
+              <el-select v-model="form.postIds" multiple placeholder="璇烽�夋嫨">
+                <el-option
+                  v-for="item in postOptions"
+                  :key="item.postId"
+                  :label="item.postName"
+                  :value="item.postId"
+                  :disabled="item.status == '1'"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="瑙掕壊">
+              <el-select v-model="form.roleIds" multiple placeholder="璇烽�夋嫨">
+                <el-option
+                  v-for="item in roleOptions"
+                  :key="item.roleId"
+                  :label="item.roleName"
+                  :value="item.roleId"
+                  :disabled="item.status == '1'"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="澶囨敞">
+              <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel()">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <!-- 鐢ㄦ埛瀵煎叆瀵硅瘽妗� -->
+    <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
+      <el-upload
+        ref="uploadRef"
+        :limit="1"
+        accept=".xlsx, .xls"
+        :headers="upload.headers"
+        :action="upload.url + '?updateSupport=' + upload.updateSupport"
+        :disabled="upload.isUploading"
+        :on-progress="handleFileUploadProgress"
+        :on-success="handleFileSuccess"
+        :auto-upload="false"
+        drag
+      >
+        <el-icon class="el-icon--upload">
+          <i-ep-upload-filled />
+        </el-icon>
+        <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+        <template #tip>
+          <div class="text-center el-upload__tip">
+            <div class="el-upload__tip"><el-checkbox v-model="upload.updateSupport" />鏄惁鏇存柊宸茬粡瀛樺湪鐨勭敤鎴锋暟鎹�</div>
+            <span>浠呭厑璁稿鍏ls銆亁lsx鏍煎紡鏂囦欢銆�</span>
+            <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">涓嬭浇妯℃澘</el-link>
+          </div>
+        </template>
+      </el-upload>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
+          <el-button @click="upload.open = false">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
 <script setup name="User" lang="ts">
 import {
-  changeUserStatus,
-  listUser,
-  resetUserPwd,
-  delUser,
-  getUser,
-  updateUser,
-  addUser,
-  deptTreeSelect
+    changeUserStatus,
+    listUser,
+    resetUserPwd,
+    delUser,
+    getUser,
+    updateUser,
+    addUser,
+    deptTreeSelect
 } from "@/api/system/user"
 import { UserForm, UserQuery, UserVO } from '@/api/system/user/types';
 import { ComponentInternalInstance } from "vue";
@@ -38,28 +325,28 @@
 const roleOptions = ref<RoleVO[]>([]);
 /*** 鐢ㄦ埛瀵煎叆鍙傛暟 */
 const upload = reactive<ImportOption>({
-  // 鏄惁鏄剧ず寮瑰嚭灞傦紙鐢ㄦ埛瀵煎叆锛�
-  open: false,
-  // 寮瑰嚭灞傛爣棰橈紙鐢ㄦ埛瀵煎叆锛�
-  title: "",
-  // 鏄惁绂佺敤涓婁紶
-  isUploading: false,
-  // 鏄惁鏇存柊宸茬粡瀛樺湪鐨勭敤鎴锋暟鎹�
-  updateSupport: 0,
-  // 璁剧疆涓婁紶鐨勮姹傚ご閮�
-  headers: { Authorization: "Bearer " + getToken() },
-  // 涓婁紶鐨勫湴鍧�
-  url: import.meta.env.VITE_APP_BASE_API + "/system/user/importData"
+    // 鏄惁鏄剧ず寮瑰嚭灞傦紙鐢ㄦ埛瀵煎叆锛�
+    open: false,
+    // 寮瑰嚭灞傛爣棰橈紙鐢ㄦ埛瀵煎叆锛�
+    title: "",
+    // 鏄惁绂佺敤涓婁紶
+    isUploading: false,
+    // 鏄惁鏇存柊宸茬粡瀛樺湪鐨勭敤鎴锋暟鎹�
+    updateSupport: 0,
+    // 璁剧疆涓婁紶鐨勮姹傚ご閮�
+    headers: { Authorization: "Bearer " + getToken() },
+    // 涓婁紶鐨勫湴鍧�
+    url: import.meta.env.VITE_APP_BASE_API + "/system/user/importData"
 })
 // 鍒楁樉闅愪俊鎭�
 const columns = ref<FieldOption[]>([
-  { key: 0, label: `鐢ㄦ埛缂栧彿`, visible: false },
-  { key: 1, label: `鐢ㄦ埛鍚嶇О`, visible: true },
-  { key: 2, label: `鐢ㄦ埛鏄电О`, visible: true },
-  { key: 3, label: `閮ㄩ棬`, visible: true },
-  { key: 4, label: `鎵嬫満鍙风爜`, visible: true },
-  { key: 5, label: `鐘舵�乣, visible: true },
-  { key: 6, label: `鍒涘缓鏃堕棿`, visible: true }
+    { key: 0, label: `鐢ㄦ埛缂栧彿`, visible: false },
+    { key: 1, label: `鐢ㄦ埛鍚嶇О`, visible: true },
+    { key: 2, label: `鐢ㄦ埛鏄电О`, visible: true },
+    { key: 3, label: `閮ㄩ棬`, visible: true },
+    { key: 4, label: `鎵嬫満鍙风爜`, visible: true },
+    { key: 5, label: `鐘舵�乣, visible: true },
+    { key: 6, label: `鍒涘缓鏃堕棿`, visible: true }
 ])
 
 
@@ -69,242 +356,242 @@
 const uploadRef = ref(ElUpload);
 
 const dialog = reactive<DialogOption>({
-  visible: false,
-  title: ''
+    visible: false,
+    title: ''
 });
 
 const initFormData: UserForm = {
-  userId: undefined,
-  deptId: undefined,
-  userName: '',
-  nickName: undefined,
-  password: '',
-  phonenumber: undefined,
-  email: undefined,
-  sex: undefined,
-  status: "0",
-  remark: '',
-  postIds: [],
-  roleIds: []
+    userId: undefined,
+    deptId: undefined,
+    userName: '',
+    nickName: undefined,
+    password: '',
+    phonenumber: undefined,
+    email: undefined,
+    sex: undefined,
+    status: "0",
+    remark: '',
+    postIds: [],
+    roleIds: []
 }
 const data = reactive<PageData<UserForm, UserQuery>>({
-  form: { ...initFormData },
-  queryParams: {
-    pageNum: 1,
-    pageSize: 10,
-    userName: '',
-    phonenumber: '',
-    status: '',
-    deptId: ''
-  },
-  rules: {
-    userName: [{ required: true, message: "鐢ㄦ埛鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }, { min: 2, max: 20, message: "鐢ㄦ埛鍚嶇О闀垮害蹇呴』浠嬩簬 2 鍜� 20 涔嬮棿", trigger: "blur" }],
-    nickName: [{ required: true, message: "鐢ㄦ埛鏄电О涓嶈兘涓虹┖", trigger: "blur" }],
-    password: [{ required: true, message: "鐢ㄦ埛瀵嗙爜涓嶈兘涓虹┖", trigger: "blur" }, { min: 5, max: 20, message: "鐢ㄦ埛瀵嗙爜闀垮害蹇呴』浠嬩簬 5 鍜� 20 涔嬮棿", trigger: "blur" }],
-    email: [{ type: "email", message: "璇疯緭鍏ユ纭殑閭鍦板潃", trigger: ["blur", "change"] }],
-    phonenumber: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "璇疯緭鍏ユ纭殑鎵嬫満鍙风爜", trigger: "blur" }]
-  }
+    form: { ...initFormData },
+    queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        userName: '',
+        phonenumber: '',
+        status: '',
+        deptId: ''
+    },
+    rules: {
+        userName: [{ required: true, message: "鐢ㄦ埛鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }, { min: 2, max: 20, message: "鐢ㄦ埛鍚嶇О闀垮害蹇呴』浠嬩簬 2 鍜� 20 涔嬮棿", trigger: "blur" }],
+        nickName: [{ required: true, message: "鐢ㄦ埛鏄电О涓嶈兘涓虹┖", trigger: "blur" }],
+        password: [{ required: true, message: "鐢ㄦ埛瀵嗙爜涓嶈兘涓虹┖", trigger: "blur" }, { min: 5, max: 20, message: "鐢ㄦ埛瀵嗙爜闀垮害蹇呴』浠嬩簬 5 鍜� 20 涔嬮棿", trigger: "blur" }],
+        email: [{ type: "email", message: "璇疯緭鍏ユ纭殑閭鍦板潃", trigger: ["blur", "change"] }],
+        phonenumber: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "璇疯緭鍏ユ纭殑鎵嬫満鍙风爜", trigger: "blur" }]
+    }
 })
 
 const { queryParams, form, rules } = toRefs<PageData<UserForm, UserQuery>>(data)
 
 /** 閫氳繃鏉′欢杩囨护鑺傜偣  */
 const filterNode = (value: string, data: any) => {
-  if (!value) return true
-  return data.label.indexOf(value) !== -1
+    if (!value) return true
+    return data.label.indexOf(value) !== -1
 }
 /** 鏍规嵁鍚嶇О绛涢�夐儴闂ㄦ爲 */
 watchEffect(
     () => {deptTreeRef.value.filter(deptName.value);},
     {
-      flush: 'post' // watchEffect浼氬湪DOM鎸傝浇鎴栬�呮洿鏂颁箣鍓嶅氨浼氳Е鍙戯紝姝ゅ睘鎬ф帶鍒跺湪DOM鍏冪礌鏇存柊鍚庤繍琛�
+        flush: 'post' // watchEffect浼氬湪DOM鎸傝浇鎴栬�呮洿鏂颁箣鍓嶅氨浼氳Е鍙戯紝姝ゅ睘鎬ф帶鍒跺湪DOM鍏冪礌鏇存柊鍚庤繍琛�
     }
 );
 
 /** 鏌ヨ閮ㄩ棬涓嬫媺鏍戠粨鏋� */
 const getTreeSelect = async () => {
-  const res = await deptTreeSelect();
-	deptOptions.value = res.data;
+    const res = await deptTreeSelect();
+    deptOptions.value = res.data;
 };
 
 /** 鏌ヨ鐢ㄦ埛鍒楄〃 */
 const getList = async () => {
-  loading.value = true;
-  const res = await listUser(proxy?.addDateRange(queryParams.value, dateRange.value));
-	loading.value = false;
-	userList.value = res.rows;
-	total.value = res.total;
+    loading.value = true;
+    const res = await listUser(proxy?.addDateRange(queryParams.value, dateRange.value));
+    loading.value = false;
+    userList.value = res.rows;
+    total.value = res.total;
 }
 
 /** 鑺傜偣鍗曞嚮浜嬩欢 */
 const handleNodeClick = (data: DeptVO) => {
-  queryParams.value.deptId = data.id;
-  handleQuery()
+    queryParams.value.deptId = data.id;
+    handleQuery()
 }
 
 
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-  queryParams.value.pageNum = 1
-  getList()
+    queryParams.value.pageNum = 1
+    getList()
 }
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 const resetQuery = () => {
-  dateRange.value = ['','']
-  queryFormRef.value.resetFields();
-  queryParams.value.pageNum = 1;
-  handleQuery();
+    dateRange.value = ['','']
+    queryFormRef.value.resetFields();
+    queryParams.value.pageNum = 1;
+    handleQuery();
 }
 
 /** 鍒犻櫎鎸夐挳鎿嶄綔 */
 const handleDelete = async (row?: UserVO) => {
-  const userIds = row?.userId || ids.value;
-  const [err] = await to(proxy?.$modal.confirm('鏄惁纭鍒犻櫎鐢ㄦ埛缂栧彿涓�"' + userIds + '"鐨勬暟鎹」锛�') as any);
-	if (!err) {
-		await delUser(userIds);
-		await getList();
-		proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-	}
+    const userIds = row?.userId || ids.value;
+    const [err] = await to(proxy?.$modal.confirm('鏄惁纭鍒犻櫎鐢ㄦ埛缂栧彿涓�"' + userIds + '"鐨勬暟鎹」锛�') as any);
+    if (!err) {
+        await delUser(userIds);
+        await getList();
+        proxy?.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    }
 }
 
 /** 鐢ㄦ埛鐘舵�佷慨鏀�  */
 const handleStatusChange = async (row: UserVO) => {
-	let text = row.status === "0" ? "鍚敤" : "鍋滅敤"
-	const [err] = await to(proxy?.$modal.confirm('纭瑕�"' + text + '""' + row.userName + '"鐢ㄦ埛鍚�?') as any)
-	if(err) {
-		row.status = row.status === "0" ? "1" : "0";
-	} else {
-		await changeUserStatus(row.userId, row.status);
-		proxy?.$modal.msgSuccess(text + "鎴愬姛");
-	}
+    let text = row.status === "0" ? "鍚敤" : "鍋滅敤"
+    const [err] = await to(proxy?.$modal.confirm('纭瑕�"' + text + '""' + row.userName + '"鐢ㄦ埛鍚�?') as any)
+    if(err) {
+        row.status = row.status === "0" ? "1" : "0";
+    } else {
+        await changeUserStatus(row.userId, row.status);
+        proxy?.$modal.msgSuccess(text + "鎴愬姛");
+    }
 
 }
 /** 璺宠浆瑙掕壊鍒嗛厤 */
 const handleAuthRole = (row: UserVO) => {
-  const userId = row.userId;
-  router.push("/system/user-auth/role/" + userId);
+    const userId = row.userId;
+    router.push("/system/user-auth/role/" + userId);
 }
 
 /** 閲嶇疆瀵嗙爜鎸夐挳鎿嶄綔 */
 const handleResetPwd = async (row: UserVO) => {
-  const [err, res] = await to(ElMessageBox.prompt('璇疯緭鍏�"' + row.userName + '"鐨勬柊瀵嗙爜', "鎻愮ず", {
-    confirmButtonText: "纭畾",
-    cancelButtonText: "鍙栨秷",
-    closeOnClickModal: false,
-    inputPattern: /^.{5,20}$/,
-    inputErrorMessage: "鐢ㄦ埛瀵嗙爜闀垮害蹇呴』浠嬩簬 5 鍜� 20 涔嬮棿",
-	}))
-	if (!err) {
-		await resetUserPwd(row.userId, res.value);
-		proxy?.$modal.msgSuccess("淇敼鎴愬姛锛屾柊瀵嗙爜鏄細" + res.value);
-	}
+    const [err, res] = await to(ElMessageBox.prompt('璇疯緭鍏�"' + row.userName + '"鐨勬柊瀵嗙爜', "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        closeOnClickModal: false,
+        inputPattern: /^.{5,20}$/,
+        inputErrorMessage: "鐢ㄦ埛瀵嗙爜闀垮害蹇呴』浠嬩簬 5 鍜� 20 涔嬮棿",
+    }))
+    if (!err) {
+        await resetUserPwd(row.userId, res.value);
+        proxy?.$modal.msgSuccess("淇敼鎴愬姛锛屾柊瀵嗙爜鏄細" + res.value);
+    }
 }
 
 /** 閫夋嫨鏉℃暟  */
 const handleSelectionChange = (selection: UserVO[]) => {
-  ids.value = selection.map((item) => item.userId);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
+    ids.value = selection.map((item) => item.userId);
+    single.value = selection.length != 1;
+    multiple.value = !selection.length;
 }
 
 /** 瀵煎叆鎸夐挳鎿嶄綔 */
 const handleImport = () => {
-  upload.title = "鐢ㄦ埛瀵煎叆";
-  upload.open = true;
+    upload.title = "鐢ㄦ埛瀵煎叆";
+    upload.open = true;
 }
 /** 瀵煎嚭鎸夐挳鎿嶄綔 */
 const handleExport = () => {
-  proxy?.download("system/user/export", {
-    ...queryParams.value,
-  }, `user_${new Date().getTime()}.xlsx`);
+    proxy?.download("system/user/export", {
+        ...queryParams.value,
+    }, `user_${new Date().getTime()}.xlsx`);
 };
 /** 涓嬭浇妯℃澘鎿嶄綔 */
 const importTemplate = () => {
-  proxy?.download("system/user/importTemplate", {
-  }, `user_template_${new Date().getTime()}.xlsx`);
+    proxy?.download("system/user/importTemplate", {
+    }, `user_template_${new Date().getTime()}.xlsx`);
 }
 
 /**鏂囦欢涓婁紶涓鐞� */
 const handleFileUploadProgress = () => {
-  upload.isUploading = true;
+    upload.isUploading = true;
 }
 /** 鏂囦欢涓婁紶鎴愬姛澶勭悊 */
 const handleFileSuccess = (response: any, file: UploadFile, fileList: UploadFiles) => {
-  upload.open = false;
-  upload.isUploading = false;
-  uploadRef.value.handleRemove(file);
-  ElMessageBox.alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "瀵煎叆缁撴灉", { dangerouslyUseHTMLString: true });
-  getList();
+    upload.open = false;
+    upload.isUploading = false;
+    uploadRef.value.handleRemove(file);
+    ElMessageBox.alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "瀵煎叆缁撴灉", { dangerouslyUseHTMLString: true });
+    getList();
 }
 
 /** 鎻愪氦涓婁紶鏂囦欢 */
 function submitFileForm() {
-  uploadRef.value.submit();
+    uploadRef.value.submit();
 }
 
 /** 鍒濆鍖栭儴闂ㄦ暟鎹� */
 const initTreeData = async () => {
-  // 鍒ゆ柇閮ㄩ棬鐨勬暟鎹槸鍚﹀瓨鍦紝瀛樺湪涓嶈幏鍙栵紝涓嶅瓨鍦ㄥ垯鑾峰彇
-  if (deptOptions.value === undefined) {
-    const { data } = await treeselect();
-		deptOptions.value = data;
-  }
+    // 鍒ゆ柇閮ㄩ棬鐨勬暟鎹槸鍚﹀瓨鍦紝瀛樺湪涓嶈幏鍙栵紝涓嶅瓨鍦ㄥ垯鑾峰彇
+    if (deptOptions.value === undefined) {
+        const { data } = await treeselect();
+        deptOptions.value = data;
+    }
 }
 
 
 /** 閲嶇疆鎿嶄綔琛ㄥ崟 */
 const reset = () => {
-  form.value = { ...initFormData };
-  userFormRef.value.resetFields();
+    form.value = { ...initFormData };
+    userFormRef.value.resetFields();
 }
 /** 鍙栨秷鎸夐挳 */
 const cancel = () => {
-  reset();
-  dialog.visible = false;
+    reset();
+    dialog.visible = false;
 }
 
 /** 鏂板鎸夐挳鎿嶄綔 */
 const handleAdd = () => {
-	dialog.visible = true;
-	dialog.title = "鏂板鐢ㄦ埛";
-	nextTick(async () => {
-		reset();
-		await initTreeData();
-		const { data } = await getUser();
-		postOptions.value = data.posts;
-		roleOptions.value = data.roles;
-		form.value.password = initPassword.value;
-	})
+    dialog.visible = true;
+    dialog.title = "鏂板鐢ㄦ埛";
+    nextTick(async () => {
+        reset();
+        await initTreeData();
+        const { data } = await getUser();
+        postOptions.value = data.posts;
+        roleOptions.value = data.roles;
+        form.value.password = initPassword.value;
+    })
 }
 /** 淇敼鎸夐挳鎿嶄綔 */
 const handleUpdate = (row?: UserForm) => {
-	dialog.visible = true;
-	dialog.title = "淇敼鐢ㄦ埛";
-	nextTick(async () => {
-		reset();
-		await initTreeData();
-		const userId = row?.userId || ids.value[0]
-		const { data } = await getUser(userId)
-		Object.assign(form.value, data.user);
-		postOptions.value = data.posts;
-		roleOptions.value = data.roles;
-		form.value.postIds = data.postIds;
-		form.value.roleIds = data.roleIds;
-		form.value.password = "";
-	})
+    dialog.visible = true;
+    dialog.title = "淇敼鐢ㄦ埛";
+    nextTick(async () => {
+        reset();
+        await initTreeData();
+        const userId = row?.userId || ids.value[0]
+        const { data } = await getUser(userId)
+        Object.assign(form.value, data.user);
+        postOptions.value = data.posts;
+        roleOptions.value = data.roles;
+        form.value.postIds = data.postIds;
+        form.value.roleIds = data.roleIds;
+        form.value.password = "";
+    })
 
 }
 
 /** 鎻愪氦鎸夐挳 */
 const submitForm = () => {
-  userFormRef.value.validate(async (valid: boolean) => {
-    if (valid) {
-			form.value.userId ? await updateUser(form.value) : await addUser(form.value);
-			proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛");
-			dialog.visible = false;
-			await getList();
-    }
-  })
+    userFormRef.value.validate(async (valid: boolean) => {
+        if (valid) {
+            form.value.userId ? await updateUser(form.value) : await addUser(form.value);
+            proxy?.$modal.msgSuccess("鎿嶄綔鎴愬姛");
+            dialog.visible = false;
+            await getList();
+        }
+    })
 }
 
 
@@ -312,311 +599,24 @@
  * 鍏抽棴鐢ㄦ埛寮圭獥
  */
 const closeDialog = () => {
-  dialog.visible = false;
-  resetForm();
+    dialog.visible = false;
+    resetForm();
 }
 
 /**
  * 閲嶇疆琛ㄥ崟
  */
 const resetForm = () => {
-  userFormRef.value.resetFields();
-  userFormRef.value.clearValidate();
+    userFormRef.value.resetFields();
+    userFormRef.value.clearValidate();
 
-  form.value.id = undefined;
-  form.value.status = '1';
+    form.value.id = undefined;
+    form.value.status = '1';
 }
 onMounted(() => {
-  getTreeSelect() // 鍒濆鍖栭儴闂ㄦ暟鎹�
-  getList() // 鍒濆鍖栧垪琛ㄦ暟鎹�
+    getTreeSelect() // 鍒濆鍖栭儴闂ㄦ暟鎹�
+    getList() // 鍒濆鍖栧垪琛ㄦ暟鎹�
 });
 </script>
-
-<template>
-	<div class="p-2">
-		<el-row :gutter="20">
-			<!-- 閮ㄩ棬鏍� -->
-			<el-col :lg="4" :xs="24" style="">
-				<el-card shadow="never">
-					<el-input v-model="deptName" placeholder="璇疯緭鍏ラ儴闂ㄥ悕绉�" prefix-icon="Search" clearable />
-					<el-tree
-						class="mt-2"
-						ref="deptTreeRef"
-						:data="deptOptions"
-						:props="{ label: 'label', children: 'children' }"
-						:expand-on-click-node="false"
-						:filter-node-method="filterNode"
-						highlight-current
-						default-expand-all
-						@node-click="handleNodeClick"
-					></el-tree>
-				</el-card>
-			</el-col>
-			<el-col :lg="20" :xs="24">
-				<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-					<div class="search" v-show="showSearch">
-						<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="68px">
-							<el-form-item label="鐢ㄦ埛鍚嶇О" prop="userName">
-								<el-input v-model="queryParams.userName" placeholder="璇疯緭鍏ョ敤鎴峰悕绉�" clearable style="width: 240px" @keyup.enter="handleQuery" />
-							</el-form-item>
-							<el-form-item label="鎵嬫満鍙风爜" prop="phonenumber">
-								<el-input v-model="queryParams.phonenumber" placeholder="璇疯緭鍏ユ墜鏈哄彿鐮�" clearable style="width: 240px" @keyup.enter="handleQuery" />
-							</el-form-item>
-
-							<el-form-item label="鐘舵��" prop="status">
-								<el-select v-model="queryParams.status" placeholder="鐢ㄦ埛鐘舵��" clearable style="width: 240px">
-									<el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
-								</el-select>
-							</el-form-item>
-							<el-form-item label="鍒涘缓鏃堕棿" style="width: 308px;">
-								<el-date-picker
-									v-model="dateRange"
-									value-format="YYYY-MM-DD"
-									type="daterange"
-									range-separator="-"
-									start-placeholder="寮�濮嬫棩鏈�"
-									end-placeholder="缁撴潫鏃ユ湡"
-								></el-date-picker>
-							</el-form-item>
-							<el-form-item>
-								<el-button type="primary" @click="handleQuery" icon="Search">鎼滅储</el-button>
-								<el-button @click="resetQuery" icon="Refresh">閲嶇疆</el-button>
-							</el-form-item>
-						</el-form>
-					</div>
-				</transition>
-
-				<el-card shadow="never">
-					<template #header>
-						<el-row :gutter="10">
-							<el-col :span="1.5">
-								<el-button type="primary" plain @click="handleAdd()" v-has-permi="['sys:user:add']" icon="Plus">鏂板</el-button>
-							</el-col>
-							<el-col :span="1.5">
-								<el-button type="success" plain @click="handleUpdate()" :disabled="single" v-has-permi="['sys:user:add']" icon="Edit">淇敼</el-button>
-							</el-col>
-							<el-col :span="1.5">
-								<el-button type="danger" plain @click="handleDelete()" :disabled="multiple" v-has-permi="['sys:user:delete']" icon="Delete">
-									鍒犻櫎
-								</el-button>
-							</el-col>
-							<el-col :span="1.5">
-								<el-dropdown class="mt-[1px]">
-									<el-button plain type="info">
-										鏇村
-										<el-icon class="el-icon--right"><arrow-down /></el-icon
-									></el-button>
-									<template #dropdown>
-										<el-dropdown-menu>
-											<el-dropdown-item @click="importTemplate" icon="Download">涓嬭浇妯℃澘</el-dropdown-item>
-											<el-dropdown-item @click="handleImport" icon="Top"> 瀵煎叆鏁版嵁</el-dropdown-item>
-											<el-dropdown-item @click="handleExport" icon="Download"> 瀵煎嚭鏁版嵁</el-dropdown-item>
-										</el-dropdown-menu>
-									</template>
-								</el-dropdown>
-							</el-col>
-							<right-toolbar v-model:showSearch="showSearch" @queryTable="getList" :columns="columns" :search="true"></right-toolbar>
-						</el-row>
-					</template>
-
-					<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
-						<el-table-column type="selection" width="50" align="center" />
-						<el-table-column label="鐢ㄦ埛缂栧彿" align="center" key="userId" prop="userId" v-if="columns[0].visible" />
-						<el-table-column label="鐢ㄦ埛鍚嶇О" align="center" key="userName" prop="userName" v-if="columns[1].visible" :show-overflow-tooltip="true" />
-						<el-table-column label="鐢ㄦ埛鏄电О" align="center" key="nickName" prop="nickName" v-if="columns[2].visible" :show-overflow-tooltip="true" />
-						<el-table-column
-							label="閮ㄩ棬"
-							align="center"
-							key="deptName"
-							prop="dept.deptName"
-							v-if="columns[3].visible"
-							:show-overflow-tooltip="true"
-						/>
-						<el-table-column label="鎵嬫満鍙风爜" align="center" key="phonenumber" prop="phonenumber" v-if="columns[4].visible" width="120" />
-						<el-table-column label="鐘舵��" align="center" key="status" v-if="columns[5].visible">
-							<template #default="scope">
-								<el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
-							</template>
-						</el-table-column>
-
-						<el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" v-if="columns[6].visible" width="160">
-							<template #default="scope">
-								<span>{{ scope.row.createTime }}</span>
-							</template>
-						</el-table-column>
-
-						<el-table-column label="鎿嶄綔" fixed="right" width="180" class-name="small-padding fixed-width">
-							<template #default="scope">
-								<el-tooltip content="淇敼" placement="top" v-if="scope.row.userId !== 1">
-									<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:user:edit']"></el-button>
-								</el-tooltip>
-								<el-tooltip content="鍒犻櫎" placement="top" v-if="scope.row.userId !== 1">
-									<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:user:remove']"></el-button>
-								</el-tooltip>
-
-								<el-tooltip content="閲嶇疆瀵嗙爜" placement="top" v-if="scope.row.userId !== 1">
-									<el-button link type="primary" icon="Key" @click="handleResetPwd(scope.row)" v-hasPermi="['system:user:resetPwd']"></el-button>
-								</el-tooltip>
-
-								<el-tooltip content="鍒嗛厤瑙掕壊" placement="top" v-if="scope.row.userId !== 1">
-									<el-button link type="primary" icon="CircleCheck" @click="handleAuthRole(scope.row)" v-hasPermi="['system:user:edit']"></el-button>
-								</el-tooltip>
-							</template>
-						</el-table-column>
-					</el-table>
-
-					<pagination
-						v-show="total > 0"
-						:total="total"
-						v-model:page="queryParams.pageNum"
-						v-model:limit="queryParams.pageSize"
-						@pagination="handleQuery"
-					/>
-				</el-card>
-			</el-col>
-		</el-row>
-
-		<!-- 娣诲姞鎴栦慨鏀圭敤鎴烽厤缃璇濇 -->
-		<el-dialog :title="dialog.title" v-model="dialog.visible" width="600px" append-to-body @close="closeDialog">
-			<el-form :model="form" :rules="rules" ref="userFormRef" label-width="80px">
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="鐢ㄦ埛鏄电О" prop="nickName">
-							<el-input v-model="form.nickName" placeholder="璇疯緭鍏ョ敤鎴锋樀绉�" maxlength="30" />
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="褰掑睘閮ㄩ棬" prop="deptId">
-							<el-tree-select
-								v-model="form.deptId"
-								:data="deptOptions"
-								:props="{ value: 'id', label: 'label', children: 'children' }"
-								value-key="id"
-								placeholder="璇烽�夋嫨褰掑睘閮ㄩ棬"
-								check-strictly
-							/>
-						</el-form-item>
-					</el-col>
-				</el-row>
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="鎵嬫満鍙风爜" prop="phonenumber">
-							<el-input v-model="form.phonenumber" placeholder="璇疯緭鍏ユ墜鏈哄彿鐮�" maxlength="11" />
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="閭" prop="email">
-							<el-input v-model="form.email" placeholder="璇疯緭鍏ラ偖绠�" maxlength="50" />
-						</el-form-item>
-					</el-col>
-				</el-row>
-				<el-row>
-					<el-col :span="12">
-						<el-form-item v-if="form.userId == undefined" label="鐢ㄦ埛鍚嶇О" prop="userName">
-							<el-input v-model="form.userName" placeholder="璇疯緭鍏ョ敤鎴峰悕绉�" maxlength="30" />
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item v-if="form.userId == undefined" label="鐢ㄦ埛瀵嗙爜" prop="password">
-							<el-input v-model="form.password" placeholder="璇疯緭鍏ョ敤鎴峰瘑鐮�" type="password" maxlength="20" show-password />
-						</el-form-item>
-					</el-col>
-				</el-row>
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="鐢ㄦ埛鎬у埆">
-							<el-select v-model="form.sex" placeholder="璇烽�夋嫨">
-								<el-option v-for="dict in sys_user_sex" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
-							</el-select>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="鐘舵��">
-							<el-radio-group v-model="form.status">
-								<el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">{{
-                    dict.label }}</el-radio>
-							</el-radio-group>
-						</el-form-item>
-					</el-col>
-				</el-row>
-				<el-row>
-					<el-col :span="12">
-						<el-form-item label="宀椾綅">
-							<el-select v-model="form.postIds" multiple placeholder="璇烽�夋嫨">
-								<el-option
-									v-for="item in postOptions"
-									:key="item.postId"
-									:label="item.postName"
-									:value="item.postId"
-									:disabled="item.status == '1'"
-								></el-option>
-							</el-select>
-						</el-form-item>
-					</el-col>
-					<el-col :span="12">
-						<el-form-item label="瑙掕壊">
-							<el-select v-model="form.roleIds" multiple placeholder="璇烽�夋嫨">
-								<el-option
-									v-for="item in roleOptions"
-									:key="item.roleId"
-									:label="item.roleName"
-									:value="item.roleId"
-									:disabled="item.status == '1'"
-								></el-option>
-							</el-select>
-						</el-form-item>
-					</el-col>
-				</el-row>
-				<el-row>
-					<el-col :span="24">
-						<el-form-item label="澶囨敞">
-							<el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�"></el-input>
-						</el-form-item>
-					</el-col>
-				</el-row>
-			</el-form>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
-					<el-button @click="cancel()">鍙� 娑�</el-button>
-				</div>
-			</template>
-		</el-dialog>
-
-		<!-- 鐢ㄦ埛瀵煎叆瀵硅瘽妗� -->
-		<el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
-			<el-upload
-				ref="uploadRef"
-				:limit="1"
-				accept=".xlsx, .xls"
-				:headers="upload.headers"
-				:action="upload.url + '?updateSupport=' + upload.updateSupport"
-				:disabled="upload.isUploading"
-				:on-progress="handleFileUploadProgress"
-				:on-success="handleFileSuccess"
-				:auto-upload="false"
-				drag
-			>
-				<el-icon class="el-icon--upload">
-					<i-ep-upload-filled />
-				</el-icon>
-				<div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
-				<template #tip>
-					<div class="text-center el-upload__tip">
-						<div class="el-upload__tip"><el-checkbox v-model="upload.updateSupport" />鏄惁鏇存柊宸茬粡瀛樺湪鐨勭敤鎴锋暟鎹�</div>
-						<span>浠呭厑璁稿鍏ls銆亁lsx鏍煎紡鏂囦欢銆�</span>
-						<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">涓嬭浇妯℃澘</el-link>
-					</div>
-				</template>
-			</el-upload>
-			<template #footer>
-				<div class="dialog-footer">
-					<el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
-					<el-button @click="upload.open = false">鍙� 娑�</el-button>
-				</div>
-			</template>
-		</el-dialog>
-	</div>
-</template>
 
 <style lang="scss" scoped></style>
diff --git a/src/views/system/user/profile/index.vue b/src/views/system/user/profile/index.vue
index 40a5156..73496b3 100644
--- a/src/views/system/user/profile/index.vue
+++ b/src/views/system/user/profile/index.vue
@@ -14,78 +14,78 @@
 const userForm = ref({});
 
 const getUser = async () => {
-	const res = await getUserProfile();
-	state.value.user = res.data.user;
-	userForm.value = { ...res.data.user }
-	state.value.roleGroup = res.data.roleGroup;
-	state.value.postGroup = res.data.postGroup;
+  const res = await getUserProfile();
+  state.value.user = res.data.user;
+  userForm.value = { ...res.data.user }
+  state.value.roleGroup = res.data.roleGroup;
+  state.value.postGroup = res.data.postGroup;
 };
 
 onMounted(() => {
-	getUser();
+  getUser();
 })
 </script>
 
 <template>
-	<div class="p-2">
-		<el-row :gutter="20">
-			<el-col :span="6" :xs="24">
-				<el-card class="box-card">
-					<template v-slot:header>
-						<div class="clearfix">
-							<span>涓汉淇℃伅</span>
-						</div>
-					</template>
-					<div>
-						<div class="text-center">
-							<userAvatar :user="state.user" />
-						</div>
-						<ul class="list-group list-group-striped">
-							<li class="list-group-item">
-								<svg-icon icon-class="user" />鐢ㄦ埛鍚嶇О
-								<div class="pull-right">{{ state.user.userName }}</div>
-							</li>
-							<li class="list-group-item">
-								<svg-icon icon-class="phone" />鎵嬫満鍙风爜
-								<div class="pull-right">{{ state.user.phonenumber }}</div>
-							</li>
-							<li class="list-group-item">
-								<svg-icon icon-class="email" />鐢ㄦ埛閭
-								<div class="pull-right">{{ state.user.email }}</div>
-							</li>
-							<li class="list-group-item">
-								<svg-icon icon-class="tree" />鎵�灞為儴闂�
-								<div class="pull-right" v-if="state.user.dept">{{ state.user.dept.deptName }} / {{ state.postGroup }}</div>
-							</li>
-							<li class="list-group-item">
-								<svg-icon icon-class="peoples" />鎵�灞炶鑹�
-								<div class="pull-right">{{ state.roleGroup }}</div>
-							</li>
-							<li class="list-group-item">
-								<svg-icon icon-class="date" />鍒涘缓鏃ユ湡
-								<div class="pull-right">{{ state.user.createTime }}</div>
-							</li>
-						</ul>
-					</div>
-				</el-card>
-			</el-col>
-			<el-col :span="18" :xs="24">
-				<el-card>
-					<template v-slot:header>
-						<div class="clearfix">
-							<span>鍩烘湰璧勬枡</span>
-						</div>
-					</template>
-					<el-tabs v-model="activeTab">
-						<el-tab-pane label="鍩烘湰璧勬枡" name="userinfo">
-							<userInfo :user="userForm" />
-						</el-tab-pane>
-						<el-tab-pane label="淇敼瀵嗙爜" name="resetPwd">
-							<resetPwd />
-						</el-tab-pane>
-					</el-tabs>
-				</el-card>
-			</el-col>
-		</el-row>
-	</div>
+  <div class="p-2">
+    <el-row :gutter="20">
+      <el-col :span="6" :xs="24">
+        <el-card class="box-card">
+          <template v-slot:header>
+            <div class="clearfix">
+              <span>涓汉淇℃伅</span>
+            </div>
+          </template>
+          <div>
+            <div class="text-center">
+              <userAvatar :user="state.user" />
+            </div>
+            <ul class="list-group list-group-striped">
+              <li class="list-group-item">
+                <svg-icon icon-class="user" />鐢ㄦ埛鍚嶇О
+                <div class="pull-right">{{ state.user.userName }}</div>
+              </li>
+              <li class="list-group-item">
+                <svg-icon icon-class="phone" />鎵嬫満鍙风爜
+                <div class="pull-right">{{ state.user.phonenumber }}</div>
+              </li>
+              <li class="list-group-item">
+                <svg-icon icon-class="email" />鐢ㄦ埛閭
+                <div class="pull-right">{{ state.user.email }}</div>
+              </li>
+              <li class="list-group-item">
+                <svg-icon icon-class="tree" />鎵�灞為儴闂�
+                <div class="pull-right" v-if="state.user.dept">{{ state.user.dept.deptName }} / {{ state.postGroup }}</div>
+              </li>
+              <li class="list-group-item">
+                <svg-icon icon-class="peoples" />鎵�灞炶鑹�
+                <div class="pull-right">{{ state.roleGroup }}</div>
+              </li>
+              <li class="list-group-item">
+                <svg-icon icon-class="date" />鍒涘缓鏃ユ湡
+                <div class="pull-right">{{ state.user.createTime }}</div>
+              </li>
+            </ul>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="18" :xs="24">
+        <el-card>
+          <template v-slot:header>
+            <div class="clearfix">
+              <span>鍩烘湰璧勬枡</span>
+            </div>
+          </template>
+          <el-tabs v-model="activeTab">
+            <el-tab-pane label="鍩烘湰璧勬枡" name="userinfo">
+              <userInfo :user="userForm" />
+            </el-tab-pane>
+            <el-tab-pane label="淇敼瀵嗙爜" name="resetPwd">
+              <resetPwd />
+            </el-tab-pane>
+          </el-tabs>
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
 </template>
diff --git a/src/views/system/user/profile/resetPwd.vue b/src/views/system/user/profile/resetPwd.vue
index 0207342..2f6551b 100644
--- a/src/views/system/user/profile/resetPwd.vue
+++ b/src/views/system/user/profile/resetPwd.vue
@@ -44,19 +44,19 @@
 </script>
 
 <template>
-	<el-form ref="pwdRef" :model="user" :rules="rules" label-width="80px">
-		<el-form-item label="鏃у瘑鐮�" prop="oldPassword">
-			<el-input v-model="user.oldPassword" placeholder="璇疯緭鍏ユ棫瀵嗙爜" type="password" show-password />
-		</el-form-item>
-		<el-form-item label="鏂板瘑鐮�" prop="newPassword">
-			<el-input v-model="user.newPassword" placeholder="璇疯緭鍏ユ柊瀵嗙爜" type="password" show-password />
-		</el-form-item>
-		<el-form-item label="纭瀵嗙爜" prop="confirmPassword">
-			<el-input v-model="user.confirmPassword" placeholder="璇风‘璁ゆ柊瀵嗙爜" type="password" show-password />
-		</el-form-item>
-		<el-form-item>
-			<el-button type="primary" @click="submit">淇濆瓨</el-button>
-			<el-button type="danger" @click="close">鍏抽棴</el-button>
-		</el-form-item>
-	</el-form>
+  <el-form ref="pwdRef" :model="user" :rules="rules" label-width="80px">
+    <el-form-item label="鏃у瘑鐮�" prop="oldPassword">
+      <el-input v-model="user.oldPassword" placeholder="璇疯緭鍏ユ棫瀵嗙爜" type="password" show-password />
+    </el-form-item>
+    <el-form-item label="鏂板瘑鐮�" prop="newPassword">
+      <el-input v-model="user.newPassword" placeholder="璇疯緭鍏ユ柊瀵嗙爜" type="password" show-password />
+    </el-form-item>
+    <el-form-item label="纭瀵嗙爜" prop="confirmPassword">
+      <el-input v-model="user.confirmPassword" placeholder="璇风‘璁ゆ柊瀵嗙爜" type="password" show-password />
+    </el-form-item>
+    <el-form-item>
+      <el-button type="primary" @click="submit">淇濆瓨</el-button>
+      <el-button type="danger" @click="close">鍏抽棴</el-button>
+    </el-form-item>
+  </el-form>
 </template>
diff --git a/src/views/system/user/profile/userAvatar.vue b/src/views/system/user/profile/userAvatar.vue
index 6094301..eaf8db3 100644
--- a/src/views/system/user/profile/userAvatar.vue
+++ b/src/views/system/user/profile/userAvatar.vue
@@ -100,58 +100,58 @@
 </script>
 
 <template>
-	<div class="user-info-head" @click="editCropper()">
-		<img :src="options.img as string" title="鐐瑰嚮涓婁紶澶村儚" class="img-circle img-lg" />
-		<el-dialog :title="title" v-model="open" width="800px" append-to-body @opened="modalOpened" @close="closeDialog">
-			<el-row>
-				<el-col :xs="24" :md="12" :style="{ height: '350px' }">
-					<vue-cropper
-						ref="cropper"
-						:img="options.img"
-						:info="true"
-						:autoCrop="options.autoCrop"
-						:autoCropWidth="options.autoCropWidth"
-						:autoCropHeight="options.autoCropHeight"
-						:fixedBox="options.fixedBox"
-						:outputType="options.outputType"
-						@realTime="realTime"
-						v-if="visible"
-					/>
-				</el-col>
-				<el-col :xs="24" :md="12" :style="{ height: '350px' }">
-					<div class="avatar-upload-preview">
-						<img :src="options.previews.url" :style="options.previews.img" />
-					</div>
-				</el-col>
-			</el-row>
-			<br />
-			<el-row>
-				<el-col :lg="2" :md="2">
-					<el-upload action="#" :http-request="requestUpload" :show-file-list="false" :before-upload="beforeUpload">
-						<el-button>
-							閫夋嫨
-							<el-icon class="el-icon--right"><Upload /></el-icon>
-						</el-button>
-					</el-upload>
-				</el-col>
-				<el-col :lg="{ span: 1, offset: 2 }" :md="2">
-					<el-button icon="Plus" @click="changeScale(1)"></el-button>
-				</el-col>
-				<el-col :lg="{ span: 1, offset: 1 }" :md="2">
-					<el-button icon="Minus" @click="changeScale(-1)"></el-button>
-				</el-col>
-				<el-col :lg="{ span: 1, offset: 1 }" :md="2">
-					<el-button icon="RefreshLeft" @click="rotateLeft()"></el-button>
-				</el-col>
-				<el-col :lg="{ span: 1, offset: 1 }" :md="2">
-					<el-button icon="RefreshRight" @click="rotateRight()"></el-button>
-				</el-col>
-				<el-col :lg="{ span: 2, offset: 6 }" :md="2">
-					<el-button type="primary" @click="uploadImg()">鎻� 浜�</el-button>
-				</el-col>
-			</el-row>
-		</el-dialog>
-	</div>
+  <div class="user-info-head" @click="editCropper()">
+    <img :src="options.img as string" title="鐐瑰嚮涓婁紶澶村儚" class="img-circle img-lg" />
+    <el-dialog :title="title" v-model="open" width="800px" append-to-body @opened="modalOpened" @close="closeDialog">
+      <el-row>
+        <el-col :xs="24" :md="12" :style="{ height: '350px' }">
+          <vue-cropper
+            ref="cropper"
+            :img="options.img"
+            :info="true"
+            :autoCrop="options.autoCrop"
+            :autoCropWidth="options.autoCropWidth"
+            :autoCropHeight="options.autoCropHeight"
+            :fixedBox="options.fixedBox"
+            :outputType="options.outputType"
+            @realTime="realTime"
+            v-if="visible"
+          />
+        </el-col>
+        <el-col :xs="24" :md="12" :style="{ height: '350px' }">
+          <div class="avatar-upload-preview">
+            <img :src="options.previews.url" :style="options.previews.img" />
+          </div>
+        </el-col>
+      </el-row>
+      <br />
+      <el-row>
+        <el-col :lg="2" :md="2">
+          <el-upload action="#" :http-request="requestUpload" :show-file-list="false" :before-upload="beforeUpload">
+            <el-button>
+              閫夋嫨
+              <el-icon class="el-icon--right"><Upload /></el-icon>
+            </el-button>
+          </el-upload>
+        </el-col>
+        <el-col :lg="{ span: 1, offset: 2 }" :md="2">
+          <el-button icon="Plus" @click="changeScale(1)"></el-button>
+        </el-col>
+        <el-col :lg="{ span: 1, offset: 1 }" :md="2">
+          <el-button icon="Minus" @click="changeScale(-1)"></el-button>
+        </el-col>
+        <el-col :lg="{ span: 1, offset: 1 }" :md="2">
+          <el-button icon="RefreshLeft" @click="rotateLeft()"></el-button>
+        </el-col>
+        <el-col :lg="{ span: 1, offset: 1 }" :md="2">
+          <el-button icon="RefreshRight" @click="rotateRight()"></el-button>
+        </el-col>
+        <el-col :lg="{ span: 2, offset: 6 }" :md="2">
+          <el-button type="primary" @click="uploadImg()">鎻� 浜�</el-button>
+        </el-col>
+      </el-row>
+    </el-dialog>
+  </div>
 </template>
 
 <style lang="scss" scoped>
diff --git a/src/views/system/user/profile/userInfo.vue b/src/views/system/user/profile/userInfo.vue
index 13cc29b..9cf7c0f 100644
--- a/src/views/system/user/profile/userInfo.vue
+++ b/src/views/system/user/profile/userInfo.vue
@@ -39,25 +39,25 @@
 </script>
 
 <template>
-	<el-form ref="userRef" :model="userForm" :rules="rules" label-width="80px">
-		<el-form-item label="鐢ㄦ埛鏄电О" prop="nickName">
-			<el-input v-model="userForm.nickName" maxlength="30" />
-		</el-form-item>
-		<el-form-item label="鎵嬫満鍙风爜" prop="phonenumber">
-			<el-input v-model="userForm.phonenumber" maxlength="11" />
-		</el-form-item>
-		<el-form-item label="閭" prop="email">
-			<el-input v-model="userForm.email" maxlength="50" />
-		</el-form-item>
-		<el-form-item label="鎬у埆">
-			<el-radio-group v-model="userForm.sex">
-				<el-radio label="0">鐢�</el-radio>
-				<el-radio label="1">濂�</el-radio>
-			</el-radio-group>
-		</el-form-item>
-		<el-form-item>
-			<el-button type="primary" @click="submit">淇濆瓨</el-button>
-			<el-button type="danger" @click="close">鍏抽棴</el-button>
-		</el-form-item>
-	</el-form>
+  <el-form ref="userRef" :model="userForm" :rules="rules" label-width="80px">
+    <el-form-item label="鐢ㄦ埛鏄电О" prop="nickName">
+      <el-input v-model="userForm.nickName" maxlength="30" />
+    </el-form-item>
+    <el-form-item label="鎵嬫満鍙风爜" prop="phonenumber">
+      <el-input v-model="userForm.phonenumber" maxlength="11" />
+    </el-form-item>
+    <el-form-item label="閭" prop="email">
+      <el-input v-model="userForm.email" maxlength="50" />
+    </el-form-item>
+    <el-form-item label="鎬у埆">
+      <el-radio-group v-model="userForm.sex">
+        <el-radio label="0">鐢�</el-radio>
+        <el-radio label="1">濂�</el-radio>
+      </el-radio-group>
+    </el-form-item>
+    <el-form-item>
+      <el-button type="primary" @click="submit">淇濆瓨</el-button>
+      <el-button type="danger" @click="close">鍏抽棴</el-button>
+    </el-form-item>
+  </el-form>
 </template>
diff --git a/src/views/tool/build/index.vue b/src/views/tool/build/index.vue
index 4d2b809..45f5457 100644
--- a/src/views/tool/build/index.vue
+++ b/src/views/tool/build/index.vue
@@ -1,3 +1,3 @@
 <template>
-	<div>琛ㄥ崟鏋勫缓 <svg-icon icon-class="build" /></div>
+  <div>琛ㄥ崟鏋勫缓 <svg-icon icon-class="build" /></div>
 </template>
diff --git a/src/views/tool/gen/basicInfoForm.vue b/src/views/tool/gen/basicInfoForm.vue
index 9e06929..0f77a7c 100644
--- a/src/views/tool/gen/basicInfoForm.vue
+++ b/src/views/tool/gen/basicInfoForm.vue
@@ -5,8 +5,8 @@
   info: {
     type: Object as PropType<any>,
     default: () => {
-			return {};
-		}
+      return {};
+    }
   }
 });
 
@@ -22,33 +22,33 @@
 </script>
 
 <template>
-	<el-form ref="basicInfoForm" :model="infoForm" :rules="rules" label-width="150px">
-		<el-row>
-			<el-col :span="12">
-				<el-form-item label="琛ㄥ悕绉�" prop="tableName">
-					<el-input placeholder="璇疯緭鍏ヤ粨搴撳悕绉�" v-model="infoForm.tableName" />
-				</el-form-item>
-			</el-col>
-			<el-col :span="12">
-				<el-form-item label="琛ㄦ弿杩�" prop="tableComment">
-					<el-input placeholder="璇疯緭鍏�" v-model="infoForm.tableComment" />
-				</el-form-item>
-			</el-col>
-			<el-col :span="12">
-				<el-form-item label="瀹炰綋绫诲悕绉�" prop="className">
-					<el-input placeholder="璇疯緭鍏�" v-model="infoForm.className" />
-				</el-form-item>
-			</el-col>
-			<el-col :span="12">
-				<el-form-item label="浣滆��" prop="functionAuthor">
-					<el-input placeholder="璇疯緭鍏�" v-model="infoForm.functionAuthor" />
-				</el-form-item>
-			</el-col>
-			<el-col :span="24">
-				<el-form-item label="澶囨敞" prop="remark">
-					<el-input type="textarea" :rows="3" v-model="infoForm.remark"></el-input>
-				</el-form-item>
-			</el-col>
-		</el-row>
-	</el-form>
+  <el-form ref="basicInfoForm" :model="infoForm" :rules="rules" label-width="150px">
+    <el-row>
+      <el-col :span="12">
+        <el-form-item label="琛ㄥ悕绉�" prop="tableName">
+          <el-input placeholder="璇疯緭鍏ヤ粨搴撳悕绉�" v-model="infoForm.tableName" />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="琛ㄦ弿杩�" prop="tableComment">
+          <el-input placeholder="璇疯緭鍏�" v-model="infoForm.tableComment" />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="瀹炰綋绫诲悕绉�" prop="className">
+          <el-input placeholder="璇疯緭鍏�" v-model="infoForm.className" />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="浣滆��" prop="functionAuthor">
+          <el-input placeholder="璇疯緭鍏�" v-model="infoForm.functionAuthor" />
+        </el-form-item>
+      </el-col>
+      <el-col :span="24">
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input type="textarea" :rows="3" v-model="infoForm.remark"></el-input>
+        </el-form-item>
+      </el-col>
+    </el-row>
+  </el-form>
 </template>
diff --git a/src/views/tool/gen/editTable.vue b/src/views/tool/gen/editTable.vue
index be1b392..0d7e490 100644
--- a/src/views/tool/gen/editTable.vue
+++ b/src/views/tool/gen/editTable.vue
@@ -1,3 +1,117 @@
+<template>
+  <el-card>
+    <el-tabs v-model="activeName">
+      <el-tab-pane label="鍩烘湰淇℃伅" name="basic">
+        <basic-info-form ref="basicInfo" :info="info" />
+      </el-tab-pane>
+      <el-tab-pane label="瀛楁淇℃伅" name="columnInfo">
+        <el-table ref="dragTable" :data="columns" row-key="columnId" :max-height="tableHeight">
+          <el-table-column label="搴忓彿" type="index" min-width="5%" />
+          <el-table-column label="瀛楁鍒楀悕" prop="columnName" min-width="10%" :show-overflow-tooltip="true" />
+          <el-table-column label="瀛楁鎻忚堪" min-width="10%">
+            <template #default="scope">
+              <el-input v-model="scope.row.columnComment"></el-input>
+            </template>
+          </el-table-column>
+          <el-table-column label="鐗╃悊绫诲瀷" prop="columnType" min-width="10%" :show-overflow-tooltip="true" />
+          <el-table-column label="Java绫诲瀷" min-width="11%">
+            <template #default="scope">
+              <el-select v-model="scope.row.javaType">
+                <el-option label="Long" value="Long" />
+                <el-option label="String" value="String" />
+                <el-option label="Integer" value="Integer" />
+                <el-option label="Double" value="Double" />
+                <el-option label="BigDecimal" value="BigDecimal" />
+                <el-option label="Date" value="Date" />
+                <el-option label="Boolean" value="Boolean" />
+              </el-select>
+            </template>
+          </el-table-column>
+          <el-table-column label="java灞炴��" min-width="10%">
+            <template #default="scope">
+              <el-input v-model="scope.row.javaField"></el-input>
+            </template>
+          </el-table-column>
+
+          <el-table-column label="鎻掑叆" min-width="5%">
+            <template #default="scope">
+              <el-checkbox true-label="1" false-label="0" v-model="scope.row.isInsert"></el-checkbox>
+            </template>
+          </el-table-column>
+          <el-table-column label="缂栬緫" min-width="5%">
+            <template #default="scope">
+              <el-checkbox true-label="1" false-label="0" v-model="scope.row.isEdit"></el-checkbox>
+            </template>
+          </el-table-column>
+          <el-table-column label="鍒楄〃" min-width="5%">
+            <template #default="scope">
+              <el-checkbox true-label="1" false-label="0" v-model="scope.row.isList"></el-checkbox>
+            </template>
+          </el-table-column>
+          <el-table-column label="鏌ヨ" min-width="5%">
+            <template #default="scope">
+              <el-checkbox true-label="1" false-label="0" v-model="scope.row.isQuery"></el-checkbox>
+            </template>
+          </el-table-column>
+          <el-table-column label="鏌ヨ鏂瑰紡" min-width="10%">
+            <template #default="scope">
+              <el-select v-model="scope.row.queryType">
+                <el-option label="=" value="EQ" />
+                <el-option label="!=" value="NE" />
+                <el-option label=">" value="GT" />
+                <el-option label=">=" value="GE" />
+                <el-option label="<" value="LT" />
+                <el-option label="<=" value="LE" />
+                <el-option label="LIKE" value="LIKE" />
+                <el-option label="BETWEEN" value="BETWEEN" />
+              </el-select>
+            </template>
+          </el-table-column>
+          <el-table-column label="蹇呭~" min-width="5%">
+            <template #default="scope">
+              <el-checkbox true-label="1" false-label="0" v-model="scope.row.isRequired"></el-checkbox>
+            </template>
+          </el-table-column>
+          <el-table-column label="鏄剧ず绫诲瀷" min-width="12%">
+            <template #default="scope">
+              <el-select v-model="scope.row.htmlType">
+                <el-option label="鏂囨湰妗�" value="input" />
+                <el-option label="鏂囨湰鍩�" value="textarea" />
+                <el-option label="涓嬫媺妗�" value="select" />
+                <el-option label="鍗曢�夋" value="radio" />
+                <el-option label="澶嶉�夋" value="checkbox" />
+                <el-option label="鏃ユ湡鎺т欢" value="datetime" />
+                <el-option label="鍥剧墖涓婁紶" value="imageUpload" />
+                <el-option label="鏂囦欢涓婁紶" value="fileUpload" />
+                <el-option label="瀵屾枃鏈帶浠�" value="editor" />
+              </el-select>
+            </template>
+          </el-table-column>
+          <el-table-column label="瀛楀吀绫诲瀷" min-width="12%">
+            <template #default="scope">
+              <el-select v-model="scope.row.dictType" clearable filterable placeholder="璇烽�夋嫨">
+                <el-option v-for="dict in dictOptions" :key="dict.dictType" :label="dict.dictName" :value="dict.dictType">
+                  <span style="float: left">{{ dict.dictName }}</span>
+                  <span style="float: right; color: #8492a6; font-size: 13px">{{ dict.dictType }}</span>
+                </el-option>
+              </el-select>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-tab-pane>
+      <el-tab-pane label="鐢熸垚淇℃伅" name="genInfo">
+        <gen-info-form ref="genInfo" :info="info" :tables="tables" />
+      </el-tab-pane>
+    </el-tabs>
+    <el-form label-width="100px">
+      <div style="text-align: center;margin-left:-100px;margin-top:10px;">
+        <el-button type="primary" @click="submitForm()">鎻愪氦</el-button>
+        <el-button @click="close()">杩斿洖</el-button>
+      </div>
+    </el-form>
+  </el-card>
+</template>
+
 <script setup name="GenEdit" lang="ts">
 import { getGenTable, updateGenTable } from '@/api/tool/gen';
 import { DbColumnVO, DbTableVO } from '@/api/tool/gen/types';
@@ -22,168 +136,54 @@
 
 /** 鎻愪氦鎸夐挳 */
 const submitForm = () => {
-  const basicForm = basicInfo.value.$refs.basicInfoForm;
-  const genForm = genInfo.value.$refs.genInfoForm;
+    const basicForm = basicInfo.value.$refs.basicInfoForm;
+    const genForm = genInfo.value.$refs.genInfoForm;
 
-  Promise.all([basicForm, genForm].map(getFormPromise)).then(async res => {
-    const validateResult = res.every(item => !!item);
-    if (validateResult) {
-      const genTable: any = Object.assign({}, info.value);
-      genTable.columns = columns.value;
-      genTable.params = {
-        treeCode: info.value?.treeCode,
-        treeName: info.value.treeName,
-        treeParentCode: info.value.treeParentCode,
-        parentMenuId: info.value.parentMenuId
-			};
-			console.log(genTable)
-			const response = await updateGenTable(genTable);
-			proxy?.$modal.msgSuccess(response.msg);
-			if (response.code === 200) {
-				close();
-			}
-    } else {
-      proxy?.$modal.msgError("琛ㄥ崟鏍¢獙鏈�氳繃锛岃閲嶆柊妫�鏌ユ彁浜ゅ唴瀹�");
-    }
-  });
+    Promise.all([basicForm, genForm].map(getFormPromise)).then(async res => {
+        const validateResult = res.every(item => !!item);
+        if (validateResult) {
+            const genTable: any = Object.assign({}, info.value);
+            genTable.columns = columns.value;
+            genTable.params = {
+                treeCode: info.value?.treeCode,
+                treeName: info.value.treeName,
+                treeParentCode: info.value.treeParentCode,
+                parentMenuId: info.value.parentMenuId
+            };
+            console.log(genTable)
+            const response = await updateGenTable(genTable);
+            proxy?.$modal.msgSuccess(response.msg);
+            if (response.code === 200) {
+                close();
+            }
+        } else {
+            proxy?.$modal.msgError("琛ㄥ崟鏍¢獙鏈�氳繃锛岃閲嶆柊妫�鏌ユ彁浜ゅ唴瀹�");
+        }
+    });
 }
 const getFormPromise = (form: any) => {
-  return new Promise(resolve => {
-    form.validate((res: any) => {
-      resolve(res);
+    return new Promise(resolve => {
+        form.validate((res: any) => {
+            resolve(res);
+        });
     });
-  });
 }
 const close = () => {
-  const obj = { path: "/tool/gen", query: { t: Date.now(), pageNum: route.query.pageNum } };
-  proxy?.$tab.closeOpenPage(obj);
+    const obj = { path: "/tool/gen", query: { t: Date.now(), pageNum: route.query.pageNum } };
+    proxy?.$tab.closeOpenPage(obj);
 }
 
 (async () => {
-  const tableId = route.params && route.params.tableId as string;
-  if (tableId) {
-    // 鑾峰彇琛ㄨ缁嗕俊鎭�
-		const res = await getGenTable(tableId);
-		columns.value = res.data.rows;
-		info.value = res.data.info;
-		tables.value = res.data.tables;
-    /** 鏌ヨ瀛楀吀涓嬫媺鍒楄〃 */
-		const response = await getDictOptionselect();
-		dictOptions.value = response.data;
-  }
+    const tableId = route.params && route.params.tableId as string;
+    if (tableId) {
+        // 鑾峰彇琛ㄨ缁嗕俊鎭�
+        const res = await getGenTable(tableId);
+        columns.value = res.data.rows;
+        info.value = res.data.info;
+        tables.value = res.data.tables;
+        /** 鏌ヨ瀛楀吀涓嬫媺鍒楄〃 */
+        const response = await getDictOptionselect();
+        dictOptions.value = response.data;
+    }
 })();
 </script>
-
-<template>
-	<el-card>
-		<el-tabs v-model="activeName">
-			<el-tab-pane label="鍩烘湰淇℃伅" name="basic">
-				<basic-info-form ref="basicInfo" :info="info" />
-			</el-tab-pane>
-			<el-tab-pane label="瀛楁淇℃伅" name="columnInfo">
-				<el-table ref="dragTable" :data="columns" row-key="columnId" :max-height="tableHeight">
-					<el-table-column label="搴忓彿" type="index" min-width="5%" />
-					<el-table-column label="瀛楁鍒楀悕" prop="columnName" min-width="10%" :show-overflow-tooltip="true" />
-					<el-table-column label="瀛楁鎻忚堪" min-width="10%">
-						<template #default="scope">
-							<el-input v-model="scope.row.columnComment"></el-input>
-						</template>
-					</el-table-column>
-					<el-table-column label="鐗╃悊绫诲瀷" prop="columnType" min-width="10%" :show-overflow-tooltip="true" />
-					<el-table-column label="Java绫诲瀷" min-width="11%">
-						<template #default="scope">
-							<el-select v-model="scope.row.javaType">
-								<el-option label="Long" value="Long" />
-								<el-option label="String" value="String" />
-								<el-option label="Integer" value="Integer" />
-								<el-option label="Double" value="Double" />
-								<el-option label="BigDecimal" value="BigDecimal" />
-								<el-option label="Date" value="Date" />
-								<el-option label="Boolean" value="Boolean" />
-							</el-select>
-						</template>
-					</el-table-column>
-					<el-table-column label="java灞炴��" min-width="10%">
-						<template #default="scope">
-							<el-input v-model="scope.row.javaField"></el-input>
-						</template>
-					</el-table-column>
-
-					<el-table-column label="鎻掑叆" min-width="5%">
-						<template #default="scope">
-							<el-checkbox true-label="1" false-label="0" v-model="scope.row.isInsert"></el-checkbox>
-						</template>
-					</el-table-column>
-					<el-table-column label="缂栬緫" min-width="5%">
-						<template #default="scope">
-							<el-checkbox true-label="1" false-label="0" v-model="scope.row.isEdit"></el-checkbox>
-						</template>
-					</el-table-column>
-					<el-table-column label="鍒楄〃" min-width="5%">
-						<template #default="scope">
-							<el-checkbox true-label="1" false-label="0" v-model="scope.row.isList"></el-checkbox>
-						</template>
-					</el-table-column>
-					<el-table-column label="鏌ヨ" min-width="5%">
-						<template #default="scope">
-							<el-checkbox true-label="1" false-label="0" v-model="scope.row.isQuery"></el-checkbox>
-						</template>
-					</el-table-column>
-					<el-table-column label="鏌ヨ鏂瑰紡" min-width="10%">
-						<template #default="scope">
-							<el-select v-model="scope.row.queryType">
-								<el-option label="=" value="EQ" />
-								<el-option label="!=" value="NE" />
-								<el-option label=">" value="GT" />
-								<el-option label=">=" value="GE" />
-								<el-option label="<" value="LT" />
-								<el-option label="<=" value="LE" />
-								<el-option label="LIKE" value="LIKE" />
-								<el-option label="BETWEEN" value="BETWEEN" />
-							</el-select>
-						</template>
-					</el-table-column>
-					<el-table-column label="蹇呭~" min-width="5%">
-						<template #default="scope">
-							<el-checkbox true-label="1" false-label="0" v-model="scope.row.isRequired"></el-checkbox>
-						</template>
-					</el-table-column>
-					<el-table-column label="鏄剧ず绫诲瀷" min-width="12%">
-						<template #default="scope">
-							<el-select v-model="scope.row.htmlType">
-								<el-option label="鏂囨湰妗�" value="input" />
-								<el-option label="鏂囨湰鍩�" value="textarea" />
-								<el-option label="涓嬫媺妗�" value="select" />
-								<el-option label="鍗曢�夋" value="radio" />
-								<el-option label="澶嶉�夋" value="checkbox" />
-								<el-option label="鏃ユ湡鎺т欢" value="datetime" />
-								<el-option label="鍥剧墖涓婁紶" value="imageUpload" />
-								<el-option label="鏂囦欢涓婁紶" value="fileUpload" />
-								<el-option label="瀵屾枃鏈帶浠�" value="editor" />
-							</el-select>
-						</template>
-					</el-table-column>
-					<el-table-column label="瀛楀吀绫诲瀷" min-width="12%">
-						<template #default="scope">
-							<el-select v-model="scope.row.dictType" clearable filterable placeholder="璇烽�夋嫨">
-								<el-option v-for="dict in dictOptions" :key="dict.dictType" :label="dict.dictName" :value="dict.dictType">
-									<span style="float: left">{{ dict.dictName }}</span>
-									<span style="float: right; color: #8492a6; font-size: 13px">{{ dict.dictType }}</span>
-								</el-option>
-							</el-select>
-						</template>
-					</el-table-column>
-				</el-table>
-			</el-tab-pane>
-			<el-tab-pane label="鐢熸垚淇℃伅" name="genInfo">
-				<gen-info-form ref="genInfo" :info="info" :tables="tables" />
-			</el-tab-pane>
-		</el-tabs>
-		<el-form label-width="100px">
-			<div style="text-align: center;margin-left:-100px;margin-top:10px;">
-				<el-button type="primary" @click="submitForm()">鎻愪氦</el-button>
-				<el-button @click="close()">杩斿洖</el-button>
-			</div>
-		</el-form>
-	</el-card>
-</template>
diff --git a/src/views/tool/gen/genInfoForm.vue b/src/views/tool/gen/genInfoForm.vue
index b738de8..70fb36f 100644
--- a/src/views/tool/gen/genInfoForm.vue
+++ b/src/views/tool/gen/genInfoForm.vue
@@ -41,25 +41,25 @@
 const tplSelectChange = (value: string) => {
   if (value !== "sub") {
     infoForm.value.subTableName = "";
-		infoForm.value.subTableFkName = "";
+    infoForm.value.subTableFkName = "";
   }
 }
 const setSubTableColumns = (value: string) => {
-	table.value.forEach(item => {
-		const name = item.tableName;
-		if (value === name) {
-			subColumns.value = item.columns;
-			return;
+  table.value.forEach(item => {
+    const name = item.tableName;
+    if (value === name) {
+      subColumns.value = item.columns;
+      return;
     }
-	})
+  })
 }
 /** 鏌ヨ鑿滃崟涓嬫媺鏍戠粨鏋� */
 const getMenuTreeselect = async () => {
-	const res = await listMenu();
-	const data = proxy?.handleTree<MenuOptionsType>(res.data, "menuId");
-	if (data) {
-		menuOptions.value = data
-	}
+  const res = await listMenu();
+  const data = proxy?.handleTree<MenuOptionsType>(res.data, "menuId");
+  if (data) {
+    menuOptions.value = data
+  }
 }
 
 watch(() => props.info.subTableName, val => {
@@ -67,223 +67,223 @@
 });
 
 onMounted(() => {
-	getMenuTreeselect();
+  getMenuTreeselect();
 })
 </script>
 
 <template>
-	<el-form ref="genInfoForm" :model="infoForm" :rules="rules" label-width="150px">
-		<el-row>
-			<el-col :span="12">
-				<el-form-item prop="tplCategory">
-					<template #label>鐢熸垚妯℃澘</template>
-					<el-select v-model="infoForm.tplCategory" @change="tplSelectChange">
-						<el-option label="鍗曡〃锛堝鍒犳敼鏌ワ級" value="crud" />
-						<el-option label="鏍戣〃锛堝鍒犳敼鏌ワ級" value="tree" />
-					</el-select>
-				</el-form-item>
-			</el-col>
+  <el-form ref="genInfoForm" :model="infoForm" :rules="rules" label-width="150px">
+    <el-row>
+      <el-col :span="12">
+        <el-form-item prop="tplCategory">
+          <template #label>鐢熸垚妯℃澘</template>
+          <el-select v-model="infoForm.tplCategory" @change="tplSelectChange">
+            <el-option label="鍗曡〃锛堝鍒犳敼鏌ワ級" value="crud" />
+            <el-option label="鏍戣〃锛堝鍒犳敼鏌ワ級" value="tree" />
+          </el-select>
+        </el-form-item>
+      </el-col>
 
-			<el-col :span="12">
-				<el-form-item prop="packageName">
-					<template #label>
-						鐢熸垚鍖呰矾寰�
-						<el-tooltip content="鐢熸垚鍦ㄥ摢涓猨ava鍖呬笅锛屼緥濡� com.ruoyi.system" placement="top">
-							<el-icon><question-filled /></el-icon>
-						</el-tooltip>
-					</template>
-					<el-input v-model="infoForm.packageName" />
-				</el-form-item>
-			</el-col>
+      <el-col :span="12">
+        <el-form-item prop="packageName">
+          <template #label>
+            鐢熸垚鍖呰矾寰�
+            <el-tooltip content="鐢熸垚鍦ㄥ摢涓猨ava鍖呬笅锛屼緥濡� com.ruoyi.system" placement="top">
+              <el-icon><question-filled /></el-icon>
+            </el-tooltip>
+          </template>
+          <el-input v-model="infoForm.packageName" />
+        </el-form-item>
+      </el-col>
 
-			<el-col :span="12">
-				<el-form-item prop="moduleName">
-					<template #label>
-						鐢熸垚妯″潡鍚�
-						<el-tooltip content="鍙悊瑙d负瀛愮郴缁熷悕锛屼緥濡� system" placement="top">
-							<el-icon><question-filled /></el-icon>
-						</el-tooltip>
-					</template>
-					<el-input v-model="infoForm.moduleName" />
-				</el-form-item>
-			</el-col>
+      <el-col :span="12">
+        <el-form-item prop="moduleName">
+          <template #label>
+            鐢熸垚妯″潡鍚�
+            <el-tooltip content="鍙悊瑙d负瀛愮郴缁熷悕锛屼緥濡� system" placement="top">
+              <el-icon><question-filled /></el-icon>
+            </el-tooltip>
+          </template>
+          <el-input v-model="infoForm.moduleName" />
+        </el-form-item>
+      </el-col>
 
-			<el-col :span="12">
-				<el-form-item prop="businessName">
-					<template #label>
-						鐢熸垚涓氬姟鍚�
-						<el-tooltip content="鍙悊瑙d负鍔熻兘鑻辨枃鍚嶏紝渚嬪 user" placement="top">
-							<el-icon><question-filled /></el-icon>
-						</el-tooltip>
-					</template>
-					<el-input v-model="infoForm.businessName" />
-				</el-form-item>
-			</el-col>
+      <el-col :span="12">
+        <el-form-item prop="businessName">
+          <template #label>
+            鐢熸垚涓氬姟鍚�
+            <el-tooltip content="鍙悊瑙d负鍔熻兘鑻辨枃鍚嶏紝渚嬪 user" placement="top">
+              <el-icon><question-filled /></el-icon>
+            </el-tooltip>
+          </template>
+          <el-input v-model="infoForm.businessName" />
+        </el-form-item>
+      </el-col>
 
-			<el-col :span="12">
-				<el-form-item prop="functionName">
-					<template #label>
-						鐢熸垚鍔熻兘鍚�
-						<el-tooltip content="鐢ㄤ綔绫绘弿杩帮紝渚嬪 鐢ㄦ埛" placement="top">
-							<el-icon><question-filled /></el-icon>
-						</el-tooltip>
-					</template>
-					<el-input v-model="infoForm.functionName" />
-				</el-form-item>
-			</el-col>
+      <el-col :span="12">
+        <el-form-item prop="functionName">
+          <template #label>
+            鐢熸垚鍔熻兘鍚�
+            <el-tooltip content="鐢ㄤ綔绫绘弿杩帮紝渚嬪 鐢ㄦ埛" placement="top">
+              <el-icon><question-filled /></el-icon>
+            </el-tooltip>
+          </template>
+          <el-input v-model="infoForm.functionName" />
+        </el-form-item>
+      </el-col>
 
-			<el-col :span="12">
-				<el-form-item>
-					<template #label>
-						涓婄骇鑿滃崟
-						<el-tooltip content="鍒嗛厤鍒版寚瀹氳彍鍗曚笅锛屼緥濡� 绯荤粺绠$悊" placement="top">
-							<el-icon><question-filled /></el-icon>
-						</el-tooltip>
-					</template>
-					<tree-select
-						v-model:value="infoForm.parentMenuId"
-						:options="menuOptions"
-						:objMap="{ value: 'menuId', label: 'menuName', children: 'children' }"
-						placeholder="璇烽�夋嫨绯荤粺鑿滃崟"
-					/>
-				</el-form-item>
-			</el-col>
+      <el-col :span="12">
+        <el-form-item>
+          <template #label>
+            涓婄骇鑿滃崟
+            <el-tooltip content="鍒嗛厤鍒版寚瀹氳彍鍗曚笅锛屼緥濡� 绯荤粺绠$悊" placement="top">
+              <el-icon><question-filled /></el-icon>
+            </el-tooltip>
+          </template>
+          <tree-select
+            v-model:value="infoForm.parentMenuId"
+            :options="menuOptions"
+            :objMap="{ value: 'menuId', label: 'menuName', children: 'children' }"
+            placeholder="璇烽�夋嫨绯荤粺鑿滃崟"
+          />
+        </el-form-item>
+      </el-col>
 
-			<el-col :span="12">
-				<el-form-item prop="genType">
-					<template #label>
-						鐢熸垚浠g爜鏂瑰紡
-						<el-tooltip content="榛樿涓簔ip鍘嬬缉鍖呬笅杞斤紝涔熷彲浠ヨ嚜瀹氫箟鐢熸垚璺緞" placement="top">
-							<el-icon><question-filled /></el-icon>
-						</el-tooltip>
-					</template>
-					<el-radio v-model="infoForm.genType" label="0">zip鍘嬬缉鍖�</el-radio>
-					<el-radio v-model="infoForm.genType" label="1">鑷畾涔夎矾寰�</el-radio>
-				</el-form-item>
-			</el-col>
+      <el-col :span="12">
+        <el-form-item prop="genType">
+          <template #label>
+            鐢熸垚浠g爜鏂瑰紡
+            <el-tooltip content="榛樿涓簔ip鍘嬬缉鍖呬笅杞斤紝涔熷彲浠ヨ嚜瀹氫箟鐢熸垚璺緞" placement="top">
+              <el-icon><question-filled /></el-icon>
+            </el-tooltip>
+          </template>
+          <el-radio v-model="infoForm.genType" label="0">zip鍘嬬缉鍖�</el-radio>
+          <el-radio v-model="infoForm.genType" label="1">鑷畾涔夎矾寰�</el-radio>
+        </el-form-item>
+      </el-col>
 
-			<el-col :span="24" v-if="infoForm.genType == '1'">
-				<el-form-item prop="genPath">
-					<template #label>
-						鑷畾涔夎矾寰�
-						<el-tooltip content="濉啓纾佺洏缁濆璺緞锛岃嫢涓嶅~鍐欙紝鍒欑敓鎴愬埌褰撳墠Web椤圭洰涓�" placement="top">
-							<el-icon><question-filled /></el-icon>
-						</el-tooltip>
-					</template>
-					<el-input v-model="infoForm.genPath">
-						<template #append>
-							<el-dropdown>
-								<el-button type="primary">
-									鏈�杩戣矾寰勫揩閫熼�夋嫨
-									<i class="el-icon-arrow-down el-icon--right"></i>
-								</el-button>
-								<template #dropdown>
-									<el-dropdown-menu>
-										<el-dropdown-item @click="infoForm.genPath = '/'">鎭㈠榛樿鐨勭敓鎴愬熀纭�璺緞</el-dropdown-item>
-									</el-dropdown-menu>
-								</template>
-							</el-dropdown>
-						</template>
-					</el-input>
-				</el-form-item>
-			</el-col>
-		</el-row>
+      <el-col :span="24" v-if="infoForm.genType == '1'">
+        <el-form-item prop="genPath">
+          <template #label>
+            鑷畾涔夎矾寰�
+            <el-tooltip content="濉啓纾佺洏缁濆璺緞锛岃嫢涓嶅~鍐欙紝鍒欑敓鎴愬埌褰撳墠Web椤圭洰涓�" placement="top">
+              <el-icon><question-filled /></el-icon>
+            </el-tooltip>
+          </template>
+          <el-input v-model="infoForm.genPath">
+            <template #append>
+              <el-dropdown>
+                <el-button type="primary">
+                  鏈�杩戣矾寰勫揩閫熼�夋嫨
+                  <i class="el-icon-arrow-down el-icon--right"></i>
+                </el-button>
+                <template #dropdown>
+                  <el-dropdown-menu>
+                    <el-dropdown-item @click="infoForm.genPath = '/'">鎭㈠榛樿鐨勭敓鎴愬熀纭�璺緞</el-dropdown-item>
+                  </el-dropdown-menu>
+                </template>
+              </el-dropdown>
+            </template>
+          </el-input>
+        </el-form-item>
+      </el-col>
+    </el-row>
 
-		<template v-if="info.tplCategory == 'tree'">
-			<h4 class="form-header">鍏朵粬淇℃伅</h4>
-			<el-row v-show="info.tplCategory == 'tree'">
-				<el-col :span="12">
-					<el-form-item>
-						<template #label>
-							鏍戠紪鐮佸瓧娈�
-							<el-tooltip content="鏍戞樉绀虹殑缂栫爜瀛楁鍚嶏紝 濡傦細dept_id" placement="top">
-								<el-icon><question-filled /></el-icon>
-							</el-tooltip>
-						</template>
-						<el-select v-model="infoForm.treeCode" placeholder="璇烽�夋嫨">
-							<el-option
-								v-for="(column, index) in info.columns"
-								:key="index"
-								:label="column.columnName + '锛�' + column.columnComment"
-								:value="column.columnName"
-							></el-option>
-						</el-select>
-					</el-form-item>
-				</el-col>
-				<el-col :span="12">
-					<el-form-item>
-						<template #label>
-							鏍戠埗缂栫爜瀛楁
-							<el-tooltip content="鏍戞樉绀虹殑鐖剁紪鐮佸瓧娈靛悕锛� 濡傦細parent_Id" placement="top">
-								<el-icon><question-filled /></el-icon>
-							</el-tooltip>
-						</template>
-						<el-select v-model="infoForm.treeParentCode" placeholder="璇烽�夋嫨">
-							<el-option
-								v-for="(column, index) in infoForm.columns"
-								:key="index"
-								:label="column.columnName + '锛�' + column.columnComment"
-								:value="column.columnName"
-							></el-option>
-						</el-select>
-					</el-form-item>
-				</el-col>
-				<el-col :span="12">
-					<el-form-item>
-						<template #label>
-							鏍戝悕绉板瓧娈�
-							<el-tooltip content="鏍戣妭鐐圭殑鏄剧ず鍚嶇О瀛楁鍚嶏紝 濡傦細dept_name" placement="top">
-								<el-icon><question-filled /></el-icon>
-							</el-tooltip>
-						</template>
-						<el-select v-model="infoForm.treeName" placeholder="璇烽�夋嫨">
-							<el-option
-								v-for="(column, index) in info.columns"
-								:key="index"
-								:label="column.columnName + '锛�' + column.columnComment"
-								:value="column.columnName"
-							></el-option>
-						</el-select>
-					</el-form-item>
-				</el-col>
-			</el-row>
-		</template>
+    <template v-if="info.tplCategory == 'tree'">
+      <h4 class="form-header">鍏朵粬淇℃伅</h4>
+      <el-row v-show="info.tplCategory == 'tree'">
+        <el-col :span="12">
+          <el-form-item>
+            <template #label>
+              鏍戠紪鐮佸瓧娈�
+              <el-tooltip content="鏍戞樉绀虹殑缂栫爜瀛楁鍚嶏紝 濡傦細dept_id" placement="top">
+                <el-icon><question-filled /></el-icon>
+              </el-tooltip>
+            </template>
+            <el-select v-model="infoForm.treeCode" placeholder="璇烽�夋嫨">
+              <el-option
+                v-for="(column, index) in info.columns"
+                :key="index"
+                :label="column.columnName + '锛�' + column.columnComment"
+                :value="column.columnName"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item>
+            <template #label>
+              鏍戠埗缂栫爜瀛楁
+              <el-tooltip content="鏍戞樉绀虹殑鐖剁紪鐮佸瓧娈靛悕锛� 濡傦細parent_Id" placement="top">
+                <el-icon><question-filled /></el-icon>
+              </el-tooltip>
+            </template>
+            <el-select v-model="infoForm.treeParentCode" placeholder="璇烽�夋嫨">
+              <el-option
+                v-for="(column, index) in infoForm.columns"
+                :key="index"
+                :label="column.columnName + '锛�' + column.columnComment"
+                :value="column.columnName"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item>
+            <template #label>
+              鏍戝悕绉板瓧娈�
+              <el-tooltip content="鏍戣妭鐐圭殑鏄剧ず鍚嶇О瀛楁鍚嶏紝 濡傦細dept_name" placement="top">
+                <el-icon><question-filled /></el-icon>
+              </el-tooltip>
+            </template>
+            <el-select v-model="infoForm.treeName" placeholder="璇烽�夋嫨">
+              <el-option
+                v-for="(column, index) in info.columns"
+                :key="index"
+                :label="column.columnName + '锛�' + column.columnComment"
+                :value="column.columnName"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </template>
 
-		<template v-if="info.tplCategory == 'sub'">
-			<h4 class="form-header">鍏宠仈淇℃伅</h4>
-			<el-row>
-				<el-col :span="12">
-					<el-form-item>
-						<template #label>
-							鍏宠仈瀛愯〃鐨勮〃鍚�
-							<el-tooltip content="鍏宠仈瀛愯〃鐨勮〃鍚嶏紝 濡傦細sys_user" placement="top">
-								<el-icon><question-filled /></el-icon>
-							</el-tooltip>
-						</template>
-						<el-select v-model="infoForm.subTableName" placeholder="璇烽�夋嫨" @change="subSelectChange">
-							<el-option v-for="(t, index) in table" :key="index" :label="t.tableName + '锛�' + t.tableComment" :value="t.tableName"></el-option>
-						</el-select>
-					</el-form-item>
-				</el-col>
-				<el-col :span="12">
-					<el-form-item>
-						<template #label>
-							瀛愯〃鍏宠仈鐨勫閿悕
-							<el-tooltip content="瀛愯〃鍏宠仈鐨勫閿悕锛� 濡傦細user_id" placement="top">
-								<el-icon><question-filled /></el-icon>
-							</el-tooltip>
-						</template>
-						<el-select v-model="infoForm.subTableFkName" placeholder="璇烽�夋嫨">
-							<el-option
-								v-for="(column, index) in subColumns"
-								:key="index"
-								:label="column.columnName + '锛�' + column.columnComment"
-								:value="column.columnName"
-							></el-option>
-						</el-select>
-					</el-form-item>
-				</el-col>
-			</el-row>
-		</template>
-	</el-form>
+    <template v-if="info.tplCategory == 'sub'">
+      <h4 class="form-header">鍏宠仈淇℃伅</h4>
+      <el-row>
+        <el-col :span="12">
+          <el-form-item>
+            <template #label>
+              鍏宠仈瀛愯〃鐨勮〃鍚�
+              <el-tooltip content="鍏宠仈瀛愯〃鐨勮〃鍚嶏紝 濡傦細sys_user" placement="top">
+                <el-icon><question-filled /></el-icon>
+              </el-tooltip>
+            </template>
+            <el-select v-model="infoForm.subTableName" placeholder="璇烽�夋嫨" @change="subSelectChange">
+              <el-option v-for="(t, index) in table" :key="index" :label="t.tableName + '锛�' + t.tableComment" :value="t.tableName"></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item>
+            <template #label>
+              瀛愯〃鍏宠仈鐨勫閿悕
+              <el-tooltip content="瀛愯〃鍏宠仈鐨勫閿悕锛� 濡傦細user_id" placement="top">
+                <el-icon><question-filled /></el-icon>
+              </el-tooltip>
+            </template>
+            <el-select v-model="infoForm.subTableFkName" placeholder="璇烽�夋嫨">
+              <el-option
+                v-for="(column, index) in subColumns"
+                :key="index"
+                :label="column.columnName + '锛�' + column.columnComment"
+                :value="column.columnName"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </template>
+  </el-form>
 </template>
diff --git a/src/views/tool/gen/importTable.vue b/src/views/tool/gen/importTable.vue
index 63c6d4a..5ff0145 100644
--- a/src/views/tool/gen/importTable.vue
+++ b/src/views/tool/gen/importTable.vue
@@ -1,3 +1,37 @@
+<template>
+  <!-- 瀵煎叆琛� -->
+  <el-dialog title="瀵煎叆琛�" v-model="visible" width="800px" top="5vh" append-to-body>
+    <el-form :model="queryParams" ref="queryFormRef" :inline="true">
+      <el-form-item label="琛ㄥ悕绉�" prop="tableName">
+        <el-input v-model="queryParams.tableName" placeholder="璇疯緭鍏ヨ〃鍚嶇О" clearable @keyup.enter="handleQuery" />
+      </el-form-item>
+      <el-form-item label="琛ㄦ弿杩�" prop="tableComment">
+        <el-input v-model="queryParams.tableComment" placeholder="璇疯緭鍏ヨ〃鎻忚堪" clearable @keyup.enter="handleQuery" />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+        <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+      </el-form-item>
+    </el-form>
+    <el-row>
+      <el-table @row-click="clickRow" ref="tableRef" :data="dbTableList" @selection-change="handleSelectionChange" height="260px">
+        <el-table-column type="selection" width="55"></el-table-column>
+        <el-table-column prop="tableName" label="琛ㄥ悕绉�" :show-overflow-tooltip="true"></el-table-column>
+        <el-table-column prop="tableComment" label="琛ㄦ弿杩�" :show-overflow-tooltip="true"></el-table-column>
+        <el-table-column prop="createTime" label="鍒涘缓鏃堕棿"></el-table-column>
+        <el-table-column prop="updateTime" label="鏇存柊鏃堕棿"></el-table-column>
+      </el-table>
+      <pagination v-show="total>0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+    </el-row>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button type="primary" @click="handleImportTable">纭� 瀹�</el-button>
+        <el-button @click="visible = false">鍙� 娑�</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
 <script setup lang="ts">
 import { listDbTable, importTable } from '@/api/tool/gen';
 import { DbTableQuery, DbTableVO } from '@/api/tool/gen/types';
@@ -14,93 +48,59 @@
 const queryFormRef = ref(ElForm);
 
 const queryParams = reactive<DbTableQuery>({
-  pageNum: 1,
-  pageSize: 10,
-  tableName: '',
-  tableComment: ''
+    pageNum: 1,
+    pageSize: 10,
+    tableName: '',
+    tableComment: ''
 });
 
 const emit = defineEmits(["ok"]);
 
 /** 鏌ヨ鍙傛暟鍒楄〃 */
 const show = () => {
-  getList();
-  visible.value = true;
+    getList();
+    visible.value = true;
 }
 /** 鍗曞嚮閫夋嫨琛� */
 const clickRow = (row: DbTableVO) => {
-  tableRef.value.toggleRowSelection(row);
+    tableRef.value.toggleRowSelection(row);
 }
 /** 澶氶�夋閫変腑鏁版嵁 */
 const handleSelectionChange = (selection: DbTableVO[]) => {
-  tables.value = selection.map(item => item.tableName);
+    tables.value = selection.map(item => item.tableName);
 }
 /** 鏌ヨ琛ㄦ暟鎹� */
 const getList = async () => {
-	const res = await listDbTable(queryParams);
-	dbTableList.value = res.rows;
-	total.value = res.total;
+    const res = await listDbTable(queryParams);
+    dbTableList.value = res.rows;
+    total.value = res.total;
 }
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-  queryParams.pageNum = 1;
-  getList();
+    queryParams.pageNum = 1;
+    getList();
 }
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 const resetQuery = () => {
-	queryFormRef.value.resetFields();
-  handleQuery();
+    queryFormRef.value.resetFields();
+    handleQuery();
 }
 /** 瀵煎叆鎸夐挳鎿嶄綔 */
 const handleImportTable = async () => {
-  const tableNames = tables.value.join(",");
-  if (tableNames == "") {
-    proxy?.$modal.msgError("璇烽�夋嫨瑕佸鍏ョ殑琛�");
-    return;
-  }
-	const res = await importTable({ tables: tableNames });
-	proxy?.$modal.msgSuccess(res.msg);
-	if (res.code === 200) {
-		visible.value = false;
-		emit("ok");
-	}
+    const tableNames = tables.value.join(",");
+    if (tableNames == "") {
+        proxy?.$modal.msgError("璇烽�夋嫨瑕佸鍏ョ殑琛�");
+        return;
+    }
+    const res = await importTable({ tables: tableNames });
+    proxy?.$modal.msgSuccess(res.msg);
+    if (res.code === 200) {
+        visible.value = false;
+        emit("ok");
+    }
 }
 
 defineExpose({
-  show,
+    show,
 });
 </script>
-
-<template>
-	<!-- 瀵煎叆琛� -->
-	<el-dialog title="瀵煎叆琛�" v-model="visible" width="800px" top="5vh" append-to-body>
-		<el-form :model="queryParams" ref="queryFormRef" :inline="true">
-			<el-form-item label="琛ㄥ悕绉�" prop="tableName">
-				<el-input v-model="queryParams.tableName" placeholder="璇疯緭鍏ヨ〃鍚嶇О" clearable @keyup.enter="handleQuery" />
-			</el-form-item>
-			<el-form-item label="琛ㄦ弿杩�" prop="tableComment">
-				<el-input v-model="queryParams.tableComment" placeholder="璇疯緭鍏ヨ〃鎻忚堪" clearable @keyup.enter="handleQuery" />
-			</el-form-item>
-			<el-form-item>
-				<el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
-				<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-			</el-form-item>
-		</el-form>
-		<el-row>
-			<el-table @row-click="clickRow" ref="tableRef" :data="dbTableList" @selection-change="handleSelectionChange" height="260px">
-				<el-table-column type="selection" width="55"></el-table-column>
-				<el-table-column prop="tableName" label="琛ㄥ悕绉�" :show-overflow-tooltip="true"></el-table-column>
-				<el-table-column prop="tableComment" label="琛ㄦ弿杩�" :show-overflow-tooltip="true"></el-table-column>
-				<el-table-column prop="createTime" label="鍒涘缓鏃堕棿"></el-table-column>
-				<el-table-column prop="updateTime" label="鏇存柊鏃堕棿"></el-table-column>
-			</el-table>
-			<pagination v-show="total>0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
-		</el-row>
-		<template #footer>
-			<div class="dialog-footer">
-				<el-button type="primary" @click="handleImportTable">纭� 瀹�</el-button>
-				<el-button @click="visible = false">鍙� 娑�</el-button>
-			</div>
-		</template>
-	</el-dialog>
-</template>
diff --git a/src/views/tool/gen/index.vue b/src/views/tool/gen/index.vue
index 22d15d3..f78bb0d 100644
--- a/src/views/tool/gen/index.vue
+++ b/src/views/tool/gen/index.vue
@@ -1,3 +1,111 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+          <el-form-item label="鏁版嵁婧�" prop="dataName">
+            <el-input v-model="queryParams.dataName" placeholder="璇疯緭鍏ユ暟鎹簮鍚嶇О" clearable style="width: 200px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="琛ㄥ悕绉�" prop="tableName">
+            <el-input v-model="queryParams.tableName" placeholder="璇疯緭鍏ヨ〃鍚嶇О" clearable style="width: 200px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="琛ㄦ弿杩�" prop="tableComment">
+            <el-input v-model="queryParams.tableComment" placeholder="璇疯緭鍏ヨ〃鎻忚堪" clearable style="width: 200px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="鍒涘缓鏃堕棿" style="width: 308px">
+            <el-date-picker
+              v-model="dateRange"
+              value-format="YYYY-MM-DD"
+              type="daterange"
+              range-separator="-"
+              start-placeholder="寮�濮嬫棩鏈�"
+              end-placeholder="缁撴潫鏃ユ湡"
+            ></el-date-picker>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+            <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Download" @click="handleGenTable()" v-hasPermi="['tool:gen:code']">鐢熸垚</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="info" plain icon="Upload" @click="openImportTable" v-hasPermi="['tool:gen:import']">瀵煎叆</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleEditTable()" v-hasPermi="['tool:gen:edit']">淇敼</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['tool:gen:remove']">
+              鍒犻櫎
+            </el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table v-loading="loading" :data="tableList" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" align="center" width="55"></el-table-column>
+        <el-table-column label="搴忓彿" type="index" width="50" align="center">
+          <template #default="scope">
+            <span>{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="琛ㄥ悕绉�" align="center" prop="tableName" :show-overflow-tooltip="true" />
+        <el-table-column label="琛ㄦ弿杩�" align="center" prop="tableComment" :show-overflow-tooltip="true" />
+        <el-table-column label="瀹炰綋" align="center" prop="className" :show-overflow-tooltip="true" />
+        <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="160" />
+        <el-table-column label="鏇存柊鏃堕棿" align="center" prop="updateTime" width="160" />
+        <el-table-column label="鎿嶄綔" align="center" width="330" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-tooltip content="棰勮" placement="top">
+              <el-button link type="primary" icon="View" @click="handlePreview(scope.row)" v-hasPermi="['tool:gen:preview']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="缂栬緫" placement="top">
+              <el-button link type="primary" icon="Edit" @click="handleEditTable(scope.row)" v-hasPermi="['tool:gen:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="鍒犻櫎" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['tool:gen:remove']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="鍚屾" placement="top">
+              <el-button link type="primary" icon="Refresh" @click="handleSynchDb(scope.row)" v-hasPermi="['tool:gen:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="鐢熸垚浠g爜" placement="top">
+              <el-button link type="primary" icon="Download" @click="handleGenTable(scope.row)" v-hasPermi="['tool:gen:code']"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+    </el-card>
+
+    <!-- 棰勮鐣岄潰 -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="80%" top="5vh" append-to-body class="scrollbar">
+      <el-tabs v-model="preview.activeName">
+        <el-tab-pane
+          v-for="(value, key) in preview.data"
+          :label="(key as any).substring((key as any).lastIndexOf('/') + 1, (key as any).indexOf('.vm'))"
+          :name="(key as any).substring((key as any).lastIndexOf('/') + 1, (key as any).indexOf('.vm'))"
+          :key="value"
+        >
+          <el-link :underline="false" icon="DocumentCopy" v-copyText="value" v-copyText:callback="copyTextSuccess" style="float:right"
+            >&nbsp;澶嶅埗</el-link
+          >
+          <pre>{{ value }}</pre>
+        </el-tab-pane>
+      </el-tabs>
+    </el-dialog>
+    <import-table ref="importRef" @ok="handleQuery" />
+  </div>
+</template>
+
 <script setup name="Gen" lang="ts">
 import { listTable, previewTable, delTable, genCode, synchDb } from '@/api/tool/gen';
 import { TableQuery, TableVO } from '@/api/tool/gen/types';
@@ -24,221 +132,113 @@
 const importRef = ref(importTable);
 
 const queryParams = ref<TableQuery>({
-	pageNum: 1,
-	pageSize: 10,
-	tableName: '',
-	tableComment: '',
-	dataName: "master"
+    pageNum: 1,
+    pageSize: 10,
+    tableName: '',
+    tableComment: '',
+    dataName: "master"
 })
 
 const preview = ref <any>({
-	data: {},
-	activeName: 'domain.java'
+    data: {},
+    activeName: 'domain.java'
 })
 const dialog = reactive<DialogOption>({
-  visible: false,
-  title: '浠g爜棰勮'
+    visible: false,
+    title: '浠g爜棰勮'
 });
 
 localStorage.setItem('dataName', queryParams.value.dataName);
 
 onActivated(() => {
-	const time = route.query.t;
-	if (time != null && time != uniqueId.value) {
-		uniqueId.value = time as string;
-		queryParams.value.pageNum = Number(route.query.pageNum);
-		dateRange.value = ['', ''];
-		queryFormRef.value.resetFields();
-		getList();
-	}
+    const time = route.query.t;
+    if (time != null && time != uniqueId.value) {
+        uniqueId.value = time as string;
+        queryParams.value.pageNum = Number(route.query.pageNum);
+        dateRange.value = ['', ''];
+        queryFormRef.value.resetFields();
+        getList();
+    }
 })
 
 /** 鏌ヨ琛ㄩ泦鍚� */
 const getList = async () => {
-	loading.value = true;
-	const res = await listTable(proxy?.addDateRange(queryParams.value, dateRange.value));
-	tableList.value = res.rows;
-	total.value = res.total;
-	loading.value = false;
+    loading.value = true;
+    const res = await listTable(proxy?.addDateRange(queryParams.value, dateRange.value));
+    tableList.value = res.rows;
+    total.value = res.total;
+    loading.value = false;
 }
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
-	localStorage.setItem('dataName', queryParams.value.dataName);
-	queryParams.value.pageNum = 1;
-	getList();
+    localStorage.setItem('dataName', queryParams.value.dataName);
+    queryParams.value.pageNum = 1;
+    getList();
 }
 /** 鐢熸垚浠g爜鎿嶄綔 */
 const handleGenTable = async (row?: TableVO) => {
-	const tbNames = row?.tableName || tableNames.value;
-	if (tbNames == "") {
-		proxy?.$modal.msgError('璇烽�夋嫨瑕佺敓鎴愮殑鏁版嵁');
-		return;
-	}
-	if (row?.genType === "1") {
-		await genCode(row.tableName);
-		proxy?.$modal.msgSuccess('鎴愬姛鐢熸垚鍒拌嚜瀹氫箟璺緞锛�' + row.genPath);
-	} else {
-		proxy?.$download.zip('/tool/gen/batchGenCode?tables=' + tbNames, 'ruoyi.zip');
-	}
+    const tbNames = row?.tableName || tableNames.value;
+    if (tbNames == "") {
+        proxy?.$modal.msgError('璇烽�夋嫨瑕佺敓鎴愮殑鏁版嵁');
+        return;
+    }
+    if (row?.genType === "1") {
+        await genCode(row.tableName);
+        proxy?.$modal.msgSuccess('鎴愬姛鐢熸垚鍒拌嚜瀹氫箟璺緞锛�' + row.genPath);
+    } else {
+        proxy?.$download.zip('/tool/gen/batchGenCode?tables=' + tbNames, 'ruoyi.zip');
+    }
 }
 /** 鍚屾鏁版嵁搴撴搷浣� */
 const handleSynchDb = async (row: TableVO) => {
-	const tableName = row.tableName;
-	await proxy?.$modal.confirm('纭瑕佸己鍒跺悓姝�"' + tableName + '"琛ㄧ粨鏋勫悧锛�');
-	await synchDb(tableName);
-	proxy?.$modal.msgSuccess('鍚屾鎴愬姛');
+    const tableName = row.tableName;
+    await proxy?.$modal.confirm('纭瑕佸己鍒跺悓姝�"' + tableName + '"琛ㄧ粨鏋勫悧锛�');
+    await synchDb(tableName);
+    proxy?.$modal.msgSuccess('鍚屾鎴愬姛');
 }
 /** 鎵撳紑瀵煎叆琛ㄥ脊绐� */
 const openImportTable = () => {
-	importRef.value.show();
+    importRef.value.show();
 }
 /** 閲嶇疆鎸夐挳鎿嶄綔 */
 const resetQuery = () => {
-	dateRange.value = ['', ''];
-	queryFormRef.value.resetFields();
-	handleQuery();
+    dateRange.value = ['', ''];
+    queryFormRef.value.resetFields();
+    handleQuery();
 }
 /** 棰勮鎸夐挳 */
 const handlePreview = async (row: TableVO) => {
-	const res = await previewTable(row.tableId);
-	preview.value.data = res.data;
-	dialog.visible = true;
-	preview.value.activeName = 'domain.java';
+    const res = await previewTable(row.tableId);
+    preview.value.data = res.data;
+    dialog.visible = true;
+    preview.value.activeName = 'domain.java';
 }
 /** 澶嶅埗浠g爜鎴愬姛 */
 const copyTextSuccess = () => {
-	proxy?.$modal.msgSuccess('澶嶅埗鎴愬姛');
+    proxy?.$modal.msgSuccess('澶嶅埗鎴愬姛');
 }
 // 澶氶�夋閫変腑鏁版嵁
 const handleSelectionChange = (selection: TableVO[]) => {
-	ids.value = selection.map(item => item.tableId);
-	tableNames.value = selection.map(item => item.tableName);
-	single.value = selection.length != 1;
-	multiple.value = !selection.length;
+    ids.value = selection.map(item => item.tableId);
+    tableNames.value = selection.map(item => item.tableName);
+    single.value = selection.length != 1;
+    multiple.value = !selection.length;
 }
 /** 淇敼鎸夐挳鎿嶄綔 */
 const handleEditTable = (row?: TableVO) => {
-	const tableId = row?.tableId || ids.value[0];
-	router.push({ path: '/tool/gen-edit/index/' + tableId, query: { pageNum: queryParams.value.pageNum } });
+    const tableId = row?.tableId || ids.value[0];
+    router.push({ path: '/tool/gen-edit/index/' + tableId, query: { pageNum: queryParams.value.pageNum } });
 }
 /** 鍒犻櫎鎸夐挳鎿嶄綔 */
 const handleDelete = async (row?: TableVO) => {
-	const tableIds = row?.tableId || ids.value;
-	await proxy?.$modal.confirm('鏄惁纭鍒犻櫎琛ㄧ紪鍙蜂负"' + tableIds + '"鐨勬暟鎹」锛�');
-	await delTable(tableIds);
-	getList();
-	proxy?.$modal.msgSuccess('鍒犻櫎鎴愬姛');
+    const tableIds = row?.tableId || ids.value;
+    await proxy?.$modal.confirm('鏄惁纭鍒犻櫎琛ㄧ紪鍙蜂负"' + tableIds + '"鐨勬暟鎹」锛�');
+    await delTable(tableIds);
+    getList();
+    proxy?.$modal.msgSuccess('鍒犻櫎鎴愬姛');
 }
 
 onMounted(() => {
-	getList();
+    getList();
 })
 </script>
-
-<template>
-	<div class="p-2">
-		<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
-			<div class="search" v-show="showSearch">
-				<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
-					<el-form-item label="鏁版嵁婧�" prop="dataName">
-						<el-input v-model="queryParams.dataName" placeholder="璇疯緭鍏ユ暟鎹簮鍚嶇О" clearable style="width: 200px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="琛ㄥ悕绉�" prop="tableName">
-						<el-input v-model="queryParams.tableName" placeholder="璇疯緭鍏ヨ〃鍚嶇О" clearable style="width: 200px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="琛ㄦ弿杩�" prop="tableComment">
-						<el-input v-model="queryParams.tableComment" placeholder="璇疯緭鍏ヨ〃鎻忚堪" clearable style="width: 200px" @keyup.enter="handleQuery" />
-					</el-form-item>
-					<el-form-item label="鍒涘缓鏃堕棿" style="width: 308px">
-						<el-date-picker
-							v-model="dateRange"
-							value-format="YYYY-MM-DD"
-							type="daterange"
-							range-separator="-"
-							start-placeholder="寮�濮嬫棩鏈�"
-							end-placeholder="缁撴潫鏃ユ湡"
-						></el-date-picker>
-					</el-form-item>
-					<el-form-item>
-						<el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
-						<el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-					</el-form-item>
-				</el-form>
-			</div>
-		</transition>
-
-		<el-card shadow="never">
-			<template #header>
-				<el-row :gutter="10" class="mb8">
-					<el-col :span="1.5">
-						<el-button type="primary" plain icon="Download" @click="handleGenTable()" v-hasPermi="['tool:gen:code']">鐢熸垚</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="info" plain icon="Upload" @click="openImportTable" v-hasPermi="['tool:gen:import']">瀵煎叆</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="success" plain icon="Edit" :disabled="single" @click="handleEditTable()" v-hasPermi="['tool:gen:edit']">淇敼</el-button>
-					</el-col>
-					<el-col :span="1.5">
-						<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['tool:gen:remove']">
-							鍒犻櫎
-						</el-button>
-					</el-col>
-					<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-				</el-row>
-			</template>
-
-			<el-table v-loading="loading" :data="tableList" @selection-change="handleSelectionChange">
-				<el-table-column type="selection" align="center" width="55"></el-table-column>
-				<el-table-column label="搴忓彿" type="index" width="50" align="center">
-					<template #default="scope">
-						<span>{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}</span>
-					</template>
-				</el-table-column>
-				<el-table-column label="琛ㄥ悕绉�" align="center" prop="tableName" :show-overflow-tooltip="true" />
-				<el-table-column label="琛ㄦ弿杩�" align="center" prop="tableComment" :show-overflow-tooltip="true" />
-				<el-table-column label="瀹炰綋" align="center" prop="className" :show-overflow-tooltip="true" />
-				<el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="160" />
-				<el-table-column label="鏇存柊鏃堕棿" align="center" prop="updateTime" width="160" />
-				<el-table-column label="鎿嶄綔" align="center" width="330" class-name="small-padding fixed-width">
-					<template #default="scope">
-						<el-tooltip content="棰勮" placement="top">
-							<el-button link type="primary" icon="View" @click="handlePreview(scope.row)" v-hasPermi="['tool:gen:preview']"></el-button>
-						</el-tooltip>
-						<el-tooltip content="缂栬緫" placement="top">
-							<el-button link type="primary" icon="Edit" @click="handleEditTable(scope.row)" v-hasPermi="['tool:gen:edit']"></el-button>
-						</el-tooltip>
-						<el-tooltip content="鍒犻櫎" placement="top">
-							<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['tool:gen:remove']"></el-button>
-						</el-tooltip>
-						<el-tooltip content="鍚屾" placement="top">
-							<el-button link type="primary" icon="Refresh" @click="handleSynchDb(scope.row)" v-hasPermi="['tool:gen:edit']"></el-button>
-						</el-tooltip>
-						<el-tooltip content="鐢熸垚浠g爜" placement="top">
-							<el-button link type="primary" icon="Download" @click="handleGenTable(scope.row)" v-hasPermi="['tool:gen:code']"></el-button>
-						</el-tooltip>
-					</template>
-				</el-table-column>
-			</el-table>
-			<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
-		</el-card>
-
-		<!-- 棰勮鐣岄潰 -->
-		<el-dialog :title="dialog.title" v-model="dialog.visible" width="80%" top="5vh" append-to-body class="scrollbar">
-			<el-tabs v-model="preview.activeName">
-				<el-tab-pane
-					v-for="(value, key) in preview.data"
-					:label="(key as any).substring((key as any).lastIndexOf('/') + 1, (key as any).indexOf('.vm'))"
-					:name="(key as any).substring((key as any).lastIndexOf('/') + 1, (key as any).indexOf('.vm'))"
-					:key="value"
-				>
-					<el-link :underline="false" icon="DocumentCopy" v-copyText="value" v-copyText:callback="copyTextSuccess" style="float:right"
-						>&nbsp;澶嶅埗</el-link
-					>
-					<pre>{{ value }}</pre>
-				</el-tab-pane>
-			</el-tabs>
-		</el-dialog>
-		<import-table ref="importRef" @ok="handleQuery" />
-	</div>
-</template>
diff --git a/tsconfig.json b/tsconfig.json
index 0272f98..3dc32e7 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,26 +1,26 @@
 {
-	"compilerOptions": {
-		"target": "es2022",
-		"useDefineForClassFields": true,
-		"module": "esnext",
-		"moduleResolution": "node",
-		"strict": true,
-		"jsx": "preserve",
-		"sourceMap": true,
-		"resolveJsonModule": true,
-		"esModuleInterop": true,
-		"lib": ["esnext", "dom"],
-		"baseUrl": ".",
-		"allowJs": true,
-		"paths": {
-			"@/*": ["src/*"]
-		},
-		"types": ["vite/client"],
-		"skipLibCheck": true,
-		// 鍏佽榛樿瀵煎叆
-		"allowSyntheticDefaultImports": true,
-		"forceConsistentCasingInFileNames": true
-	},
-	"include": ["src/**/*.ts", "src/**/*.vue", "src/types/**/*.d.ts"],
-	"exclude": ["node_modules", "dist", "**/*.js"]
+  "compilerOptions": {
+    "target": "es2022",
+    "useDefineForClassFields": true,
+    "module": "esnext",
+    "moduleResolution": "node",
+    "strict": true,
+    "jsx": "preserve",
+    "sourceMap": true,
+    "resolveJsonModule": true,
+    "esModuleInterop": true,
+    "lib": ["esnext", "dom"],
+    "baseUrl": ".",
+    "allowJs": true,
+    "paths": {
+      "@/*": ["src/*"]
+    },
+    "types": ["vite/client"],
+    "skipLibCheck": true,
+    // 鍏佽榛樿瀵煎叆
+    "allowSyntheticDefaultImports": true,
+    "forceConsistentCasingInFileNames": true
+  },
+  "include": ["src/**/*.ts", "src/**/*.vue", "src/types/**/*.d.ts"],
+  "exclude": ["node_modules", "dist", "**/*.js"]
 }
diff --git a/vite.config.ts b/vite.config.ts
index 2c8ced0..412e986 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,112 +1,112 @@
 import { UserConfig, ConfigEnv, loadEnv, defineConfig } from 'vite';
 
-import createPlugins from './Vite/plugins';
+import createPlugins from './vite/plugins';
 
 import path from 'path';
 export default defineConfig(({ mode, command }: ConfigEnv): UserConfig => {
-	const env = loadEnv(mode, process.cwd());
-	return {
-		// 閮ㄧ讲鐢熶骇鐜鍜屽紑鍙戠幆澧冧笅鐨刄RL銆�
-		// 榛樿鎯呭喌涓嬶紝vite 浼氬亣璁句綘鐨勫簲鐢ㄦ槸琚儴缃插湪涓�涓煙鍚嶇殑鏍硅矾寰勪笂
-		// 渚嬪 https://www.ruoyi.vip/銆傚鏋滃簲鐢ㄨ閮ㄧ讲鍦ㄤ竴涓瓙璺緞涓婏紝浣犲氨闇�瑕佺敤杩欎釜閫夐」鎸囧畾杩欎釜瀛愯矾寰勩�備緥濡傦紝濡傛灉浣犵殑搴旂敤琚儴缃插湪 https://www.ruoyi.vip/admin/锛屽垯璁剧疆 baseUrl 涓� /admin/銆�
-		base: env.VITE_APP_CONTEXT_PATH,
-		resolve: {
-			alias: {
-				'~': path.resolve(__dirname, './'),
-				'@': path.resolve(__dirname, './src'),
-				'vue-i18n': 'vue-i18n/dist/vue-i18n.cjs.js'
-			},
-			extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
-		},
-		// https://cn.vitejs.dev/config/#resolve-extensions
-		plugins: createPlugins(env, command === 'build'),
-		server: {
-			host: '0.0.0.0',
-			port: Number(env.VITE_APP_PORT),
-			open: true,
-			proxy: {
-				[env.VITE_APP_BASE_API]: {
-					target: 'http://localhost:8080',
-					changeOrigin: true,
-					rewrite: (path) => path.replace(new RegExp('^' + env.VITE_APP_BASE_API), '')
-				}
-			}
-		},
-		css: {
-			preprocessorOptions: {
-				scss: {
-					javascriptEnabled: true
-				}
-			},
-			postcss: {
-				plugins: [
-					{
-						postcssPlugin: 'internal:charset-removal',
-						AtRule: {
-							charset: (atRule) => {
-								if (atRule.name === 'charset') {
-									atRule.remove();
-								}
-							}
-						}
-					}
-				]
-			}
-		},
-		// 棰勭紪璇�
-		optimizeDeps: {
-			include: [
-				'vue',
-				'vue-router',
-				'pinia',
-				'axios',
-				'@vueuse/core',
-				'path-to-regexp',
-				'echarts',
-				'@wangeditor/editor',
-				'@wangeditor/editor-for-vue',
-				'vue-i18n',
+  const env = loadEnv(mode, process.cwd());
+  return {
+    // 閮ㄧ讲鐢熶骇鐜鍜屽紑鍙戠幆澧冧笅鐨刄RL銆�
+    // 榛樿鎯呭喌涓嬶紝vite 浼氬亣璁句綘鐨勫簲鐢ㄦ槸琚儴缃插湪涓�涓煙鍚嶇殑鏍硅矾寰勪笂
+    // 渚嬪 https://www.ruoyi.vip/銆傚鏋滃簲鐢ㄨ閮ㄧ讲鍦ㄤ竴涓瓙璺緞涓婏紝浣犲氨闇�瑕佺敤杩欎釜閫夐」鎸囧畾杩欎釜瀛愯矾寰勩�備緥濡傦紝濡傛灉浣犵殑搴旂敤琚儴缃插湪 https://www.ruoyi.vip/admin/锛屽垯璁剧疆 baseUrl 涓� /admin/銆�
+    base: env.VITE_APP_CONTEXT_PATH,
+    resolve: {
+      alias: {
+        '~': path.resolve(__dirname, './'),
+        '@': path.resolve(__dirname, './src'),
+        'vue-i18n': 'vue-i18n/dist/vue-i18n.cjs.js'
+      },
+      extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
+    },
+    // https://cn.vitejs.dev/config/#resolve-extensions
+    plugins: createPlugins(env, command === 'build'),
+    server: {
+      host: '0.0.0.0',
+      port: Number(env.VITE_APP_PORT),
+      open: true,
+      proxy: {
+        [env.VITE_APP_BASE_API]: {
+          target: 'http://localhost:8080',
+          changeOrigin: true,
+          rewrite: (path) => path.replace(new RegExp('^' + env.VITE_APP_BASE_API), '')
+        }
+      }
+    },
+    css: {
+      preprocessorOptions: {
+        scss: {
+          javascriptEnabled: true
+        }
+      },
+      postcss: {
+        plugins: [
+          {
+            postcssPlugin: 'internal:charset-removal',
+            AtRule: {
+              charset: (atRule) => {
+                if (atRule.name === 'charset') {
+                  atRule.remove();
+                }
+              }
+            }
+          }
+        ]
+      }
+    },
+    // 棰勭紪璇�
+    optimizeDeps: {
+      include: [
+        'vue',
+        'vue-router',
+        'pinia',
+        'axios',
+        '@vueuse/core',
+        'path-to-regexp',
+        'echarts',
+        '@wangeditor/editor',
+        '@wangeditor/editor-for-vue',
+        'vue-i18n',
 
-				'@iconify/iconify',
+        '@iconify/iconify',
 
-				'element-plus/es/components/form/style/css',
-				'element-plus/es/components/form-item/style/css',
-				'element-plus/es/components/button/style/css',
-				'element-plus/es/components/input/style/css',
-				'element-plus/es/components/input-number/style/css',
-				'element-plus/es/components/switch/style/css',
-				'element-plus/es/components/upload/style/css',
-				'element-plus/es/components/menu/style/css',
-				'element-plus/es/components/col/style/css',
-				'element-plus/es/components/icon/style/css',
-				'element-plus/es/components/row/style/css',
-				'element-plus/es/components/tag/style/css',
-				'element-plus/es/components/dialog/style/css',
-				'element-plus/es/components/loading/style/css',
-				'element-plus/es/components/radio/style/css',
-				'element-plus/es/components/radio-group/style/css',
-				'element-plus/es/components/popover/style/css',
-				'element-plus/es/components/scrollbar/style/css',
-				'element-plus/es/components/tooltip/style/css',
-				'element-plus/es/components/dropdown/style/css',
-				'element-plus/es/components/dropdown-menu/style/css',
-				'element-plus/es/components/dropdown-item/style/css',
-				'element-plus/es/components/sub-menu/style/css',
-				'element-plus/es/components/menu-item/style/css',
-				'element-plus/es/components/divider/style/css',
-				'element-plus/es/components/card/style/css',
-				'element-plus/es/components/link/style/css',
-				'element-plus/es/components/breadcrumb/style/css',
-				'element-plus/es/components/breadcrumb-item/style/css',
-				'element-plus/es/components/table/style/css',
-				'element-plus/es/components/tree-select/style/css',
-				'element-plus/es/components/table-column/style/css',
-				'element-plus/es/components/select/style/css',
-				'element-plus/es/components/option/style/css',
-				'element-plus/es/components/pagination/style/css',
-				'element-plus/es/components/tree/style/css',
-				'element-plus/es/components/alert/style/css'
-			]
-		}
-	};
+        'element-plus/es/components/form/style/css',
+        'element-plus/es/components/form-item/style/css',
+        'element-plus/es/components/button/style/css',
+        'element-plus/es/components/input/style/css',
+        'element-plus/es/components/input-number/style/css',
+        'element-plus/es/components/switch/style/css',
+        'element-plus/es/components/upload/style/css',
+        'element-plus/es/components/menu/style/css',
+        'element-plus/es/components/col/style/css',
+        'element-plus/es/components/icon/style/css',
+        'element-plus/es/components/row/style/css',
+        'element-plus/es/components/tag/style/css',
+        'element-plus/es/components/dialog/style/css',
+        'element-plus/es/components/loading/style/css',
+        'element-plus/es/components/radio/style/css',
+        'element-plus/es/components/radio-group/style/css',
+        'element-plus/es/components/popover/style/css',
+        'element-plus/es/components/scrollbar/style/css',
+        'element-plus/es/components/tooltip/style/css',
+        'element-plus/es/components/dropdown/style/css',
+        'element-plus/es/components/dropdown-menu/style/css',
+        'element-plus/es/components/dropdown-item/style/css',
+        'element-plus/es/components/sub-menu/style/css',
+        'element-plus/es/components/menu-item/style/css',
+        'element-plus/es/components/divider/style/css',
+        'element-plus/es/components/card/style/css',
+        'element-plus/es/components/link/style/css',
+        'element-plus/es/components/breadcrumb/style/css',
+        'element-plus/es/components/breadcrumb-item/style/css',
+        'element-plus/es/components/table/style/css',
+        'element-plus/es/components/tree-select/style/css',
+        'element-plus/es/components/table-column/style/css',
+        'element-plus/es/components/select/style/css',
+        'element-plus/es/components/option/style/css',
+        'element-plus/es/components/pagination/style/css',
+        'element-plus/es/components/tree/style/css',
+        'element-plus/es/components/alert/style/css'
+      ]
+    }
+  };
 });
diff --git a/vite/plugins/auto-import.ts b/vite/plugins/auto-import.ts
new file mode 100644
index 0000000..072ef61
--- /dev/null
+++ b/vite/plugins/auto-import.ts
@@ -0,0 +1,24 @@
+import AutoImport from 'unplugin-auto-import/vite';
+import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
+import IconsResolver from 'unplugin-icons/resolver';
+
+export default (path: any) => {
+  return AutoImport({
+    // 鑷姩瀵煎叆 Vue 鐩稿叧鍑芥暟
+    imports: ['vue', 'vue-router', '@vueuse/core', 'pinia'],
+    eslintrc: {
+      enabled: false,
+      filepath: './.eslintrc-auto-import.json',
+      globalsPropValue: true
+    },
+    resolvers: [
+      // 鑷姩瀵煎叆 Element Plus 鐩稿叧鍑芥暟ElMessage, ElMessageBox... (甯︽牱寮�)
+      ElementPlusResolver(),
+      IconsResolver({
+        prefix: 'Icon'
+      })
+    ],
+    vueTemplate: true, // 鏄惁鍦� vue 妯℃澘涓嚜鍔ㄥ鍏�
+    dts: path.resolve(path.resolve(__dirname, '../../src'), 'types', 'auto-imports.d.ts')
+  });
+};
diff --git a/vite/plugins/components.ts b/vite/plugins/components.ts
new file mode 100644
index 0000000..336f5cf
--- /dev/null
+++ b/vite/plugins/components.ts
@@ -0,0 +1,17 @@
+import Components from 'unplugin-vue-components/vite';
+import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
+import IconsResolver from 'unplugin-icons/resolver';
+
+export default (path: any) => {
+  return Components({
+    resolvers: [
+      // 鑷姩瀵煎叆 Element Plus 缁勪欢
+      ElementPlusResolver(),
+      // 鑷姩娉ㄥ唽鍥炬爣缁勪欢
+      IconsResolver({
+        enabledCollections: ['ep']
+      })
+    ],
+    dts: path.resolve(path.resolve(__dirname, '../../src'), 'types', 'components.d.ts')
+  });
+};
diff --git a/vite/plugins/compression.ts b/vite/plugins/compression.ts
new file mode 100644
index 0000000..123ff3a
--- /dev/null
+++ b/vite/plugins/compression.ts
@@ -0,0 +1,28 @@
+import compression from 'vite-plugin-compression';
+
+export default function createCompression(env: any) {
+  const { VITE_BUILD_COMPRESS } = env;
+  const plugin: any[] = [];
+  if (VITE_BUILD_COMPRESS) {
+    const compressList = VITE_BUILD_COMPRESS.split(',');
+    if (compressList.includes('gzip')) {
+      // http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#浣跨敤gzip瑙e帇缂╅潤鎬佹枃浠�
+      plugin.push(
+        compression({
+          ext: '.gz',
+          deleteOriginFile: false
+        })
+      );
+    }
+    if (compressList.includes('brotli')) {
+      plugin.push(
+        compression({
+          ext: '.br',
+          algorithm: 'brotliCompress',
+          deleteOriginFile: false
+        })
+      );
+    }
+  }
+  return plugin;
+}
diff --git a/vite/plugins/icons.ts b/vite/plugins/icons.ts
new file mode 100644
index 0000000..883f230
--- /dev/null
+++ b/vite/plugins/icons.ts
@@ -0,0 +1,8 @@
+import Icons from 'unplugin-icons/vite';
+
+export default () => {
+  return Icons({
+    // 鑷姩瀹夎鍥炬爣搴�
+    autoInstall: true
+  });
+};
diff --git a/vite/plugins/index.ts b/vite/plugins/index.ts
new file mode 100644
index 0000000..2f5e430
--- /dev/null
+++ b/vite/plugins/index.ts
@@ -0,0 +1,20 @@
+import vue from '@vitejs/plugin-vue';
+import createUnoCss from './unocss';
+import createAutoImport from './auto-import';
+import createComponents from './components';
+import createIcons from './icons';
+import createSvgIconsPlugin from './svg-icon';
+import createCompression from './compression';
+import path from 'path';
+
+export default (viteEnv: any, isBuild = false): [] => {
+  const vitePlusgins: any = [];
+  vitePlusgins.push(vue());
+  vitePlusgins.push(createUnoCss());
+  vitePlusgins.push(createAutoImport(path));
+  vitePlusgins.push(createComponents(path));
+  vitePlusgins.push(createCompression(viteEnv));
+  vitePlusgins.push(createIcons());
+  vitePlusgins.push(createSvgIconsPlugin(path, isBuild));
+  return vitePlusgins;
+};
diff --git a/vite/plugins/svg-icon.ts b/vite/plugins/svg-icon.ts
new file mode 100644
index 0000000..70296da
--- /dev/null
+++ b/vite/plugins/svg-icon.ts
@@ -0,0 +1,10 @@
+import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
+export default (path: any, isBuild: boolean) => {
+  return createSvgIconsPlugin({
+    // 鎸囧畾闇�瑕佺紦瀛樼殑鍥炬爣鏂囦欢澶�
+    iconDirs: [path.resolve(path.resolve(__dirname, '../../src'), 'assets/icons/svg')],
+    // 鎸囧畾symbolId鏍煎紡
+    symbolId: 'icon-[dir]-[name]',
+    svgoOptions: isBuild
+  });
+};
diff --git a/vite/plugins/unocss.ts b/vite/plugins/unocss.ts
new file mode 100644
index 0000000..997335a
--- /dev/null
+++ b/vite/plugins/unocss.ts
@@ -0,0 +1,13 @@
+import UnoCss from 'unocss/vite';
+import { presetUno, presetAttributify, presetIcons } from 'unocss';
+
+export default () => {
+  return UnoCss({
+    presets: [presetUno(), presetAttributify(), presetIcons()],
+    // rules: [['search', {}]],
+    shortcuts: {
+      'panel-title':
+        'pb-[5px] font-sans leading-[1.1] font-medium text-base text-[#6379bb] border-b border-b-solid border-[var(--el-border-color-light)] mb-5 mt-0'
+    }
+  });
+};

--
Gitblit v1.9.3