Selaa lähdekoodia

feat: 封装插件

Gaokun Wang 1 kuukausi sitten
vanhempi
sitoutus
05c4adc2ed

+ 319 - 0
.eslintrc-auto-import.json

@@ -0,0 +1,319 @@
+{
+  "globals": {
+    "Component": true,
+    "ComponentPublicInstance": true,
+    "ComputedRef": true,
+    "DirectiveBinding": true,
+    "EffectScope": true,
+    "ExtractDefaultPropTypes": true,
+    "ExtractPropTypes": true,
+    "ExtractPublicPropTypes": true,
+    "InjectionKey": true,
+    "MaybeRef": true,
+    "MaybeRefOrGetter": true,
+    "PropType": true,
+    "Ref": true,
+    "Slot": true,
+    "Slots": true,
+    "VNode": true,
+    "WritableComputedRef": true,
+    "acceptHMRUpdate": 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,
+    "createPinia": true,
+    "createReactiveFn": true,
+    "createRef": true,
+    "createReusableTemplate": true,
+    "createSharedComposable": true,
+    "createTemplatePromise": true,
+    "createUnrefFn": true,
+    "customRef": true,
+    "debouncedRef": true,
+    "debouncedWatch": true,
+    "defineAsyncComponent": true,
+    "defineComponent": true,
+    "defineStore": true,
+    "eagerComputed": true,
+    "effectScope": true,
+    "extendRef": true,
+    "getActivePinia": true,
+    "getCurrentInstance": true,
+    "getCurrentScope": true,
+    "h": true,
+    "ignorableWatch": true,
+    "inject": true,
+    "injectLocal": true,
+    "isDefined": true,
+    "isProxy": true,
+    "isReactive": true,
+    "isReadonly": true,
+    "isRef": true,
+    "makeDestructurable": true,
+    "mapActions": true,
+    "mapGetters": true,
+    "mapState": true,
+    "mapStores": true,
+    "mapWritableState": true,
+    "markRaw": true,
+    "nextTick": true,
+    "onActivated": true,
+    "onBeforeMount": true,
+    "onBeforeRouteLeave": true,
+    "onBeforeRouteUpdate": true,
+    "onBeforeUnmount": true,
+    "onBeforeUpdate": true,
+    "onClickOutside": true,
+    "onDeactivated": true,
+    "onElementRemoval": true,
+    "onErrorCaptured": true,
+    "onKeyStroke": true,
+    "onLongPress": true,
+    "onMounted": true,
+    "onRenderTracked": true,
+    "onRenderTriggered": true,
+    "onScopeDispose": true,
+    "onServerPrefetch": true,
+    "onStartTyping": true,
+    "onUnmounted": true,
+    "onUpdated": true,
+    "onWatcherCleanup": true,
+    "pausableWatch": true,
+    "provide": true,
+    "provideLocal": 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,
+    "resolveRef": true,
+    "resolveUnref": true,
+    "setActivePinia": true,
+    "setMapStoreSuffix": true,
+    "shallowReactive": true,
+    "shallowReadonly": true,
+    "shallowRef": true,
+    "storeToRefs": true,
+    "syncRef": true,
+    "syncRefs": true,
+    "templateRef": true,
+    "throttledRef": true,
+    "throttledWatch": true,
+    "toRaw": true,
+    "toReactive": true,
+    "toRef": true,
+    "toRefs": true,
+    "toValue": true,
+    "triggerRef": true,
+    "tryOnBeforeMount": true,
+    "tryOnBeforeUnmount": true,
+    "tryOnMounted": true,
+    "tryOnScopeDispose": true,
+    "tryOnUnmounted": true,
+    "unref": true,
+    "unrefElement": true,
+    "until": true,
+    "useActiveElement": true,
+    "useAnimate": true,
+    "useArrayDifference": true,
+    "useArrayEvery": true,
+    "useArrayFilter": true,
+    "useArrayFind": true,
+    "useArrayFindIndex": true,
+    "useArrayFindLast": true,
+    "useArrayIncludes": 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,
+    "useClipboardItems": true,
+    "useCloned": true,
+    "useColorMode": true,
+    "useConfirmDialog": true,
+    "useCountdown": 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,
+    "useId": true,
+    "useIdle": true,
+    "useImage": true,
+    "useInfiniteScroll": true,
+    "useIntersectionObserver": true,
+    "useInterval": true,
+    "useIntervalFn": true,
+    "useKeyModifier": true,
+    "useLastChanged": true,
+    "useLink": true,
+    "useLocalStorage": true,
+    "useMagicKeys": true,
+    "useManualRefHistory": true,
+    "useMediaControls": true,
+    "useMediaQuery": true,
+    "useMemoize": true,
+    "useMemory": true,
+    "useModel": 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,
+    "useParentElement": true,
+    "usePerformanceObserver": true,
+    "usePermission": true,
+    "usePointer": true,
+    "usePointerLock": true,
+    "usePointerSwipe": true,
+    "usePreferredColorScheme": true,
+    "usePreferredContrast": true,
+    "usePreferredDark": true,
+    "usePreferredLanguages": true,
+    "usePreferredReducedMotion": true,
+    "usePreferredReducedTransparency": true,
+    "usePrevious": true,
+    "useRafFn": true,
+    "useRefHistory": true,
+    "useResizeObserver": true,
+    "useRoute": true,
+    "useRouter": true,
+    "useSSRWidth": 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,
+    "useTemplateRef": 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,
+    "watchDeep": true,
+    "watchEffect": true,
+    "watchIgnorable": true,
+    "watchImmediate": true,
+    "watchOnce": true,
+    "watchPausable": true,
+    "watchPostEffect": true,
+    "watchSyncEffect": true,
+    "watchThrottled": true,
+    "watchTriggerable": true,
+    "watchWithFilter": true,
+    "whenever": true
+  }
+}

+ 14 - 0
env.d.ts

@@ -0,0 +1,14 @@
+/// <reference types="vite/client" />
+
+declare module '*.vue' {
+  import { DefineComponent } from 'vue'
+
+  const component: DefineComponent<{}, {}, any>
+  export default component
+}
+
+declare global {
+  interface ImportMeta {
+    readonly env: ImportMetaEnv
+  }
+}

+ 1 - 1
eslint.config.mjs

@@ -55,7 +55,7 @@ export default tseslint.config({
     '@typescript-eslint/no-non-null-assertion': 0, // 不允许使用后缀运算符的非空断言(!)
     '@typescript-eslint/no-unused-expressions': 0, // 方法可以不返回
     // vue (https://eslint.vuejs.org/rules)
-    'vue/script-setup-uses-vars': 'error', // 防止<script setup>使用的变量<template>被标记为未使用,此规则仅在启用该 no-unused-vars 规则时有效
+    // 'vue/script-setup-uses-vars': 'error', // 防止<script setup>使用的变量<template>被标记为未使用,此规则仅在启用该 no-unused-vars 规则时有效
     'vue/v-slot-style': 'error', // 强制执行 v-slot 指令样式
     'vue/no-mutating-props': 'error', // 不允许改变组件 prop
     'vue/custom-event-name-casing': 'error', // 为自定义事件名称强制使用特定大小写

+ 42 - 0
getEnv.ts

@@ -0,0 +1,42 @@
+import path from 'path'
+
+export function isDevFn(mode: string): boolean {
+  return mode === 'development'
+}
+
+export function isProdFn(mode: string): boolean {
+  return mode === 'production'
+}
+
+/**
+ * Whether to generate package preview
+ */
+export function isReportMode(): boolean {
+  return process.env.VITE_REPORT === 'true'
+}
+
+// Read all environment variable configuration files to process.env
+export function wrapperEnv(envConf: Recordable): ImportMetaEnv {
+  const ret: any = {}
+
+  for (const envName of Object.keys(envConf)) {
+    let realName = envConf[envName].replace(/\\n/g, '\n')
+    realName = realName === 'true' ? true : realName === 'false' ? false : realName
+    if (envName === 'VITE_PORT') realName = Number(realName)
+    if (envName === 'VITE_PROXY') {
+      try {
+        realName = JSON.parse(realName)
+      } catch (error) {}
+    }
+    ret[envName] = realName
+  }
+  return ret
+}
+
+/**
+ * Get user root directory
+ * @param dir file path
+ */
+export function getRootPath(...dir: string[]) {
+  return path.resolve(process.cwd(), ...dir)
+}

+ 13 - 0
package.json

@@ -24,6 +24,7 @@
   },
   "dependencies": {
     "@element-plus/icons-vue": "^2.3.1",
+    "@vueuse/core": "^13.5.0",
     "axios": "^1.10.0",
     "element-plus": "^2.10.3",
     "js-cookie": "^3.0.5",
@@ -31,11 +32,14 @@
     "pinia": "^3.0.3",
     "pinia-plugin-persistedstate": "^4.4.1",
     "vue": "^3.5.17",
+    "vue-eslint-parser": "^10.2.0",
     "vue-router": "^4.5.1"
   },
   "devDependencies": {
     "@commitlint/cli": "^19.8.1",
     "@commitlint/config-conventional": "^19.8.1",
+    "@eslint/js": "^9.30.1",
+    "@types/node": "^24.0.12",
     "@vitejs/plugin-vue": "^6.0.0",
     "@vitejs/plugin-vue-jsx": "^5.0.1",
     "@vue/eslint-config-prettier": "^10.2.0",
@@ -44,6 +48,8 @@
     "commitizen": "^4.3.1",
     "cz-git": "^1.11.2",
     "eslint": "^9.30.1",
+    "eslint-plugin-prettier": "^5.5.1",
+    "eslint-plugin-vue": "^10.3.0",
     "husky": "^9.1.7",
     "lint-staged": "^16.1.2",
     "postcss": "^8.5.6",
@@ -57,7 +63,14 @@
     "stylelint-config-standard": "^38.0.0",
     "stylelint-config-standard-scss": "^15.0.1",
     "typescript": "~5.8.3",
+    "typescript-eslint": "^8.36.0",
+    "unplugin-auto-import": "^19.3.0",
+    "unplugin-icons": "^22.1.0",
+    "unplugin-vue-components": "^28.8.0",
     "vite": "^7.0.3",
+    "vite-plugin-ejs": "^1.7.0",
+    "vite-plugin-svg-icons": "^2.0.1",
+    "vite-plugin-vue-setup-extend": "^0.4.0",
     "vue-tsc": "^2.2.12"
   },
   "engines": {

+ 27 - 0
plugins/app-use.ts

@@ -0,0 +1,27 @@
+// import { setupRouter } from '@/router'
+// import { setupPinia } from '@/stores'
+// import { setupAuthRoutes } from '@/router/modules/authRouts'
+// import Icon from '@/components/Icon/index.vue'
+// import { setupDirectives } from '@/directives/index'
+import { setupElIcons } from './el-icons'
+import ElementPlus from 'element-plus'
+// import { setupI18n } from '@/lang'
+import type { App } from 'vue'
+export default {
+  install(app: App<Element>) {
+    app.use(ElementPlus)
+    // 自定义指令
+    // setupDirectives(app)
+    // // 路由(router)
+    // setupRouter(app)
+    // // 状态管理(store)
+    // setupPinia(app)
+
+    // setupI18n(app)
+    // 自定义icon
+    // app.component('Icon', Icon)
+    setupElIcons(app)
+    // 路由
+    // setupAuthRoutes()
+  }
+}

+ 25 - 0
plugins/auto-import.ts

@@ -0,0 +1,25 @@
+import AutoImport from 'unplugin-auto-import/vite'
+import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
+import IconsResolver from 'unplugin-icons/resolver'
+
+export default () => {
+  return AutoImport({
+    // 自动导入 Vue 相关函数
+    imports: ['vue', 'vue-router', '@vueuse/core', 'pinia'],
+    eslintrc: {
+      // false true
+      enabled: true,
+      filepath: './.eslintrc-auto-import.json',
+      globalsPropValue: true
+    },
+    resolvers: [
+      // 自动导入 Element Plus 相关函数,如:ElMessage, ElMessageBox... (带样式)
+      ElementPlusResolver(),
+      // 自动导入图标组件
+      IconsResolver({})
+    ],
+    vueTemplate: true, // 是否在 vue 模板中自动导入
+    // dts: false
+    dts: 'src/types/auto-imports.d.ts'
+  })
+}

+ 9 - 0
plugins/el-icons.ts

@@ -0,0 +1,9 @@
+import type { App } from 'vue'
+import * as ElementPlusIconsVue from '@element-plus/icons-vue'
+
+// 注册所有图标
+export function setupElIcons(app: App<Element>) {
+  for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
+    app.component(key, component)
+  }
+}

+ 8 - 0
plugins/import-icons.ts

@@ -0,0 +1,8 @@
+import Icons from 'unplugin-icons/vite'
+
+export default () => {
+  return Icons({
+    // 自动安装图标库
+    autoInstall: true
+  })
+}

+ 31 - 0
plugins/index.ts

@@ -0,0 +1,31 @@
+import { type PluginOption } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import initAutoImport from './auto-import'
+import initComponents from './vue-components'
+import VueSetupExtend from 'vite-plugin-vue-setup-extend'
+import initIcons from './import-icons'
+// import initAutoTinyImport from './plugins/tiny-vue'
+import initSvgIcons from './svg-icon'
+import { ViteEjsPlugin } from 'vite-plugin-ejs'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+/**
+ * 初始创建 vite 插件
+ * @param viteEnv
+ */
+export const initVitePlugins = (viteEnv: ImportMetaEnv, isBuild = false): (PluginOption | PluginOption[])[] => {
+  const { VITE_APP_TITLE } = viteEnv
+  return [
+    vue(),
+    vueJsx(),
+    ViteEjsPlugin({
+      title: VITE_APP_TITLE
+    }),
+    VueSetupExtend(),
+    // 自动导入
+    initAutoImport(),
+    // initAutoTinyImport(),
+    initComponents(),
+    initIcons(),
+    initSvgIcons(isBuild)
+  ]
+}

+ 29 - 0
plugins/proxy.ts

@@ -0,0 +1,29 @@
+import type { ProxyOptions } from 'vite'
+
+type ProxyItem = [string, string]
+
+type ProxyList = ProxyItem[]
+
+type ProxyTargetList = Record<string, ProxyOptions>
+
+/**
+ * 创建代理,用于解析 .env.development 代理配置
+ * @param list
+ */
+export function initProxy(list: ProxyList = []) {
+  const ret: ProxyTargetList = {}
+  for (const [prefix, target] of list) {
+    const httpsRE = /^https:\/\//
+    const isHttps = httpsRE.test(target)
+    console.log('代理配置', list)
+    ret[prefix] = {
+      target: target,
+      changeOrigin: true,
+      ws: true,
+      rewrite: path => path.replace(new RegExp(`^${prefix}`), ''),
+      // https is require secure=false
+      ...(isHttps ? { secure: false } : {})
+    }
+  }
+  return ret
+}

+ 11 - 0
plugins/svg-icon.ts

@@ -0,0 +1,11 @@
+import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
+import { resolve } from 'path'
+export default (isBuild: boolean) => {
+  return createSvgIconsPlugin({
+    // 指定需要缓存的图标文件夹
+    iconDirs: [resolve(process.cwd(), 'src/assets/svg/icons')],
+    // 指定symbolId格式
+    symbolId: 'icon-[dir]-[name]',
+    svgoOptions: isBuild
+  })
+}

+ 22 - 0
plugins/vue-components.ts

@@ -0,0 +1,22 @@
+import Components from 'unplugin-vue-components/vite'
+import { TDesignResolver } from 'unplugin-vue-components/resolvers'
+import IconsResolver from 'unplugin-icons/resolver'
+export default () => {
+  return Components({
+    resolvers: [
+      TDesignResolver({
+        library: 'vue-next'
+      }),
+      // 自动注册图标组件
+      IconsResolver({
+        // 图标库,其他图标库 https://icon-sets.iconify.design/
+        enabledCollections: ['ep']
+      })
+    ],
+    // 指定自定义组件位置(默认:src/components)
+    dirs: ['src/components', 'src/**/components', 'src/**/container', 'src/**/components/**/*.vue', 'src/**/container/**/*.vue'],
+    // 指定自动导入组件TS类型声明文件路径 (false:关闭自动生成)
+    // dts: false
+    dts: 'src/typings/auto-components.d.ts'
+  })
+}

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 555 - 0
pnpm-lock.yaml


+ 3 - 0
src/assets/styles/color.scss

@@ -0,0 +1,3 @@
+body {
+  --div-bg-box: #f5f7fa;
+}

+ 131 - 0
src/assets/styles/common.scss

@@ -0,0 +1,131 @@
+/* flex */
+.flx-center {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.flx-justify-between {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.flx-align-center {
+  display: flex;
+  align-items: center;
+}
+
+/* clearfix */
+.clearfix::after {
+  display: block;
+  height: 0;
+  overflow: hidden;
+  clear: both;
+  content: '';
+}
+
+/* 文字单行省略号 */
+.sle {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+/* 文字多行省略号 */
+.mle {
+  display: -webkit-box;
+  overflow: hidden;
+  -webkit-box-orient: vertical;
+  -webkit-line-clamp: 2;
+}
+
+/* 文字多了自动換行 */
+.break-word {
+  word-break: break-all;
+  word-wrap: break-word;
+}
+
+/* fade-transform */
+.fade-transform-leave-active,
+.fade-transform-enter-active {
+  transition: all 0.2s;
+}
+
+.fade-transform-enter-from {
+  opacity: 0;
+  transition: all 0.2s;
+  transform: translateX(-30px);
+}
+
+.fade-transform-leave-to {
+  opacity: 0;
+  transition: all 0.2s;
+  transform: translateX(30px);
+}
+
+/* breadcrumb-transform */
+.breadcrumb-enter-active {
+  transition: all 0.2s;
+}
+
+.breadcrumb-enter-from,
+.breadcrumb-leave-active {
+  opacity: 0;
+  transform: translateX(10px);
+}
+
+/* scroll bar */
+::-webkit-scrollbar {
+  width: 6px;
+  height: 6px;
+}
+
+::-webkit-scrollbar-thumb {
+  background-color: var(--el-border-color-darker);
+  border-radius: 20px;
+}
+
+/* nprogress */
+#nprogress .bar {
+  background: var(--el-color-primary) !important;
+}
+
+#nprogress .spinner-icon {
+  border-top-color: var(--el-color-primary) !important;
+  border-left-color: var(--el-color-primary) !important;
+}
+
+#nprogress .peg {
+  box-shadow:
+    0 0 10px var(--el-color-primary),
+    0 0 5px var(--el-color-primary) !important;
+}
+
+/* 外边距、内边距全局样式 */
+@for $i from 0 through 100 {
+  .mt#{$i} {
+    margin-top: #{$i}px !important;
+  }
+  .mr#{$i} {
+    margin-right: #{$i}px !important;
+  }
+  .mb#{$i} {
+    margin-bottom: #{$i}px !important;
+  }
+  .ml#{$i} {
+    margin-left: #{$i}px !important;
+  }
+  .pt#{$i} {
+    padding-top: #{$i}px !important;
+  }
+  .pr#{$i} {
+    padding-right: #{$i}px !important;
+  }
+  .pb#{$i} {
+    padding-bottom: #{$i}px !important;
+  }
+  .pl#{$i} {
+    padding-left: #{$i}px !important;
+  }
+}

+ 32 - 0
src/assets/styles/element-dark.scss

@@ -0,0 +1,32 @@
+/* 自定义 element 暗黑模式 */
+html.dark {
+  /* wangEditor */
+  --w-e-toolbar-color: #eeeeee;
+  --w-e-toolbar-bg-color: #141414;
+  --w-e-textarea-bg-color: #141414;
+  --w-e-textarea-color: #eeeeee;
+  --w-e-toolbar-active-bg-color: #464646;
+  --w-e-toolbar-border-color: var(--el-border-color-darker);
+
+  .w-e-bar-item button:hover,
+  .w-e-menu-tooltip-v5::before {
+    color: #eeeeee;
+  }
+
+  /* login */
+  .login-container {
+    background-color: #191919 !important;
+
+    .login-box {
+      background-color: rgb(0 0 0 / 80%) !important;
+
+      .login-form {
+        box-shadow: rgb(255 255 255 / 12%) 0 2px 10px 2px !important;
+
+        .logo-text {
+          color: var(--el-text-color-primary) !important;
+        }
+      }
+    }
+  }
+}

+ 311 - 0
src/assets/styles/element.scss

@@ -0,0 +1,311 @@
+/* 设置 notification、message 层级在 loading 之上 */
+.el-message,
+.el-notification {
+  z-index: 4000 !important;
+}
+
+/* el-alert */
+.el-alert {
+  border: 1px solid;
+}
+
+/* 当前页面最大化 css */
+.main-maximize {
+  .aside-split,
+  .el-aside,
+  .el-header,
+  .el-footer,
+  .tabs-box {
+    display: none !important;
+  }
+}
+
+/* mask image */
+.mask-image {
+  padding-right: 50px;
+  mask-image: linear-gradient(90deg, #000000 0%, #000000 calc(100% - 50px), transparent);
+}
+
+/* custom card */
+.card {
+  box-sizing: border-box;
+  padding: 20px;
+  overflow-x: hidden;
+  background-color: var(--el-bg-color);
+  border: 1px solid var(--el-border-color-light);
+  border-radius: 6px;
+  box-shadow: 0 0 12px rgb(0 0 0 / 5%);
+}
+
+/* ProTable 不需要 card 样式(在组件内使用 ProTable 会使用到) */
+.no-card {
+  .card {
+    padding: 0;
+    background-color: transparent;
+    border: none;
+    border-radius: 0;
+    box-shadow: none;
+  }
+
+  .table-search {
+    padding: 18px 0 0 !important;
+    margin-bottom: 0 !important;
+  }
+}
+
+/* content-box (常用内容盒子) */
+.content-box {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  height: 100%;
+
+  .text {
+    margin: 20px 0 30px;
+    font-size: 23px;
+    font-weight: bold;
+    color: var(--el-text-color-regular);
+  }
+
+  .el-descriptions {
+    width: 100%;
+    padding: 40px 0 0;
+
+    .el-descriptions__title {
+      font-size: 18px;
+    }
+
+    .el-descriptions__label {
+      width: 200px;
+    }
+  }
+}
+
+/* main-box (树形表格 DeptTree 页面会使用,左右布局 flex) */
+.main-box {
+  display: flex;
+  width: 100%;
+  height: 100%;
+
+  .table-box {
+    // 这里减去的是 DeptTree 组件宽度
+    width: calc(100% - 230px);
+  }
+}
+
+/* proTable */
+.table-box,
+.table-main {
+  display: flex;
+  flex: 1;
+  flex-direction: column;
+  width: 100%;
+  height: 100%;
+
+  // table-search 表格搜索样式
+  .table-search {
+    padding: 18px 18px 0;
+    margin-bottom: 10px;
+
+    .el-form {
+      .el-form-item__content > * {
+        width: 100%;
+      }
+
+      // 去除时间选择器上下 padding
+      .el-range-editor.el-input__wrapper {
+        padding: 0 10px;
+      }
+    }
+
+    .operation {
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+      margin-bottom: 18px;
+    }
+  }
+
+  // 表格 header 样式
+  .table-header {
+    .header-button-lf {
+      float: left;
+    }
+
+    .header-button-ri {
+      float: right;
+    }
+
+    .el-button {
+      margin-bottom: 15px;
+    }
+  }
+
+  // el-table 表格样式
+  .el-table {
+    flex: 1;
+
+    // 修复 safari 浏览器表格错位 https://github.com/HalseySpicy/Geeker-Admin/issues/83
+    table {
+      width: 100%;
+    }
+
+    .el-table__header th {
+      height: 45px;
+      font-size: 15px;
+      font-weight: bold;
+      color: var(--el-text-color-primary);
+      background: var(--el-fill-color-light);
+    }
+
+    .el-table__row {
+      height: 45px;
+      font-size: 14px;
+
+      .move {
+        cursor: move;
+
+        .el-icon {
+          cursor: move;
+        }
+      }
+    }
+
+    // 设置 el-table 中 header 文字不换行,并省略
+    .el-table__header .el-table__cell > .cell {
+      white-space: nowrap;
+    }
+
+    // 解决表格数据为空时样式不居中问题(仅在element-plus中)
+    .el-table__empty-block {
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+
+      .table-empty {
+        line-height: 30px;
+      }
+    }
+
+    &.is-scrolling-none {
+      th.el-table-fixed-column--left,
+      th.el-table-fixed-column--right {
+        background-color: var(--el-fill-color-light);
+      }
+    }
+
+    // table 中 image 图片样式
+    .table-image {
+      width: 50px;
+      height: 50px;
+      border-radius: 50%;
+    }
+  }
+
+  // 表格 pagination 样式
+  .el-pagination {
+    display: flex;
+    justify-content: flex-end;
+    margin-top: 20px;
+  }
+}
+
+.el-dialog {
+  .table-box,
+  .table-main {
+    .el-table {
+      .el-table__empty-block {
+        position: relative;
+        transform: translateX(-50%);
+        margin: 40px 0;
+      }
+    }
+  }
+}
+
+/* el-table 组件大小 */
+.el-table--small {
+  .el-table__header th {
+    height: 40px !important;
+    font-size: 14px !important;
+  }
+
+  .el-table__row {
+    height: 40px !important;
+    font-size: 13px !important;
+  }
+}
+
+.el-table--large {
+  .el-table__header th {
+    height: 50px !important;
+    font-size: 16px !important;
+  }
+
+  .el-table__row {
+    height: 50px !important;
+    font-size: 15px !important;
+  }
+}
+
+/* el-drawer */
+.el-drawer {
+  .el-drawer__header {
+    padding: 16px 20px;
+    margin-bottom: 0;
+    border-bottom: 1px solid var(--el-border-color-lighter);
+
+    span {
+      font-size: 17px;
+      line-height: 17px;
+      color: var(--el-text-color-primary) !important;
+    }
+  }
+
+  .el-drawer__footer {
+    border-top: 1px solid var(--el-border-color-lighter);
+  }
+
+  // select 样式
+  .el-select {
+    width: 100%;
+  }
+
+  // drawer-form 中存在两列 form-item 样式
+  .drawer-multiColumn-form {
+    display: flex;
+    flex-wrap: wrap;
+
+    .el-form-item {
+      width: 47%;
+
+      &:nth-child(2n-1) {
+        margin-right: 5%;
+      }
+    }
+  }
+}
+
+/* el-dialog */
+.el-dialog {
+  .el-dialog__header {
+    padding: 15px 20px;
+    margin-bottom: 20px;
+    border-bottom: 1px solid var(--el-border-color-lighter);
+
+    .el-dialog__title {
+      font-size: 17px;
+    }
+  }
+}
+
+.el-upload-list.is-disabled {
+  .el-upload {
+    display: none;
+  }
+}
+
+.form__label {
+  font-weight: 700;
+}

+ 22 - 0
src/assets/styles/element/index.scss

@@ -0,0 +1,22 @@
+@forward 'element-plus/theme-chalk/src/common/var.scss' with (
+  $colors: (
+    'primary': (
+      'base': #009688
+    ),
+    'success': (
+      'base': #52c41a
+    ),
+    'warning': (
+      'base': #faad14
+    ),
+    'danger': (
+      'base': #ff4d4f
+    ),
+    'error': (
+      'base': #ff4d4f
+    )
+  )
+);
+
+// 引入暗黑模式
+@use 'element-plus/theme-chalk/src/dark/css-vars.scss';

BIN
src/assets/styles/fonts/DIN.otf


BIN
src/assets/styles/fonts/MetroDF.ttf


BIN
src/assets/styles/fonts/YouSheBiaoTiHei.ttf


+ 14 - 0
src/assets/styles/fonts/font.scss

@@ -0,0 +1,14 @@
+@font-face {
+  font-family: YouSheBiaoTiHei;
+  src: url('./YouSheBiaoTiHei.ttf');
+}
+
+@font-face {
+  font-family: MetroDF;
+  src: url('./MetroDF.ttf');
+}
+
+@font-face {
+  font-family: DIN;
+  src: url('./DIN.otf');
+}

+ 60 - 0
src/assets/styles/iconfont/iconfont.scss

@@ -0,0 +1,60 @@
+@font-face {
+  font-family: iconfont; /* Project id 2667653 */
+  src: url('iconfont.ttf?t=1691032190261') format('truetype');
+}
+
+.iconfont {
+  font-family: iconfont !important;
+  font-size: 20px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  cursor: pointer;
+}
+
+.icon-yiwen::before {
+  font-size: 15px;
+  content: '\e693';
+}
+
+.icon-xiala::before {
+  content: '\e62b';
+}
+
+.icon-tuichu::before {
+  content: '\e645';
+}
+
+.icon-xiaoxi::before {
+  font-size: 21.2px;
+  content: '\e61f';
+}
+
+.icon-zhuti::before {
+  font-size: 22.4px;
+  content: '\e638';
+}
+
+.icon-sousuo::before {
+  content: '\e611';
+}
+
+.icon-contentright::before {
+  content: '\e8c9';
+}
+
+.icon-contentleft::before {
+  content: '\e8ca';
+}
+
+.icon-fangda::before {
+  content: '\e826';
+}
+
+.icon-suoxiao::before {
+  content: '\e641';
+}
+
+.icon-zhongyingwen::before {
+  content: '\e8cb';
+}

BIN
src/assets/styles/iconfont/iconfont.ttf


+ 14 - 0
src/assets/styles/index.scss

@@ -0,0 +1,14 @@
+// reset style sheet
+// color css
+@use '@/assets/styles/color';
+@use '@/assets/styles/reset';
+// CSS common style sheet
+@use '@/assets/styles/common';
+// iconfont css
+@use '@/assets/styles/iconfont/iconfont';
+// font css
+@use '@/assets/styles/fonts/font';
+// custom element dark css
+@use '@/assets/styles/element-dark';
+// custom element css
+@use '@/assets/styles/element';

+ 14 - 0
src/assets/styles/reset.scss

@@ -0,0 +1,14 @@
+/* Reset style sheet */
+html,
+body,
+#app {
+  width: 100%;
+  height: 100%;
+  padding: 0;
+  margin: 0;
+}
+
+/* 解决 h1 标签在 webkit 内核浏览器中文字大小失效问题 */
+:-webkit-any(article, aside, nav, section) h1 {
+  font-size: 2em;
+}

+ 16 - 0
src/assets/styles/theme/aside.ts

@@ -0,0 +1,16 @@
+import type { ThemeType } from '@/hooks/types'
+
+export const asideTheme: Record<ThemeType, { [key: string]: string }> = {
+  light: {
+    '--el-aside-logo-text-color': '#303133',
+    '--el-aside-border-color': '#e4e7ed'
+  },
+  inverted: {
+    '--el-aside-logo-text-color': '#dadada',
+    '--el-aside-border-color': '#414243'
+  },
+  dark: {
+    '--el-aside-logo-text-color': '#dadada',
+    '--el-aside-border-color': '#414243'
+  }
+}

+ 25 - 0
src/assets/styles/theme/header.ts

@@ -0,0 +1,25 @@
+import type { ThemeType } from '@/hooks/types'
+
+export const headerTheme: Record<ThemeType, { [key: string]: string }> = {
+  light: {
+    '--el-header-logo-text-color': '#303133',
+    '--el-header-bg-color': '#ffffff',
+    '--el-header-text-color': '#303133',
+    '--el-header-text-color-regular': '#606266',
+    '--el-header-border-color': '#e4e7ed'
+  },
+  inverted: {
+    '--el-header-logo-text-color': '#dadada',
+    '--el-header-bg-color': '#191a20',
+    '--el-header-text-color': '#e5eaf3',
+    '--el-header-text-color-regular': '#cfd3dc',
+    '--el-header-border-color': '#414243'
+  },
+  dark: {
+    '--el-header-logo-text-color': '#dadada',
+    '--el-header-bg-color': '#141414',
+    '--el-header-text-color': '#e5eaf3',
+    '--el-header-text-color-regular': '#cfd3dc',
+    '--el-header-border-color': '#414243'
+  }
+}

+ 31 - 0
src/assets/styles/theme/menu.ts

@@ -0,0 +1,31 @@
+import type { ThemeType } from '@/hooks/types'
+
+export const menuTheme: Record<ThemeType, { [key: string]: string }> = {
+  light: {
+    '--el-menu-bg-color': '#ffffff',
+    '--el-menu-hover-bg-color': '#cccccc',
+    '--el-menu-active-bg-color': 'var(--el-color-primary-light-9)',
+    '--el-menu-text-color': '#333333',
+    '--el-menu-active-color': 'var(--el-color-primary)',
+    '--el-menu-hover-text-color': '#333333',
+    '--el-menu-horizontal-sub-item-height': '50px'
+  },
+  inverted: {
+    '--el-menu-bg-color': '#191a20',
+    '--el-menu-hover-bg-color': '#000000',
+    '--el-menu-active-bg-color': '#000000',
+    '--el-menu-text-color': '#bdbdc0',
+    '--el-menu-active-color': '#ffffff',
+    '--el-menu-hover-text-color': '#ffffff',
+    '--el-menu-horizontal-sub-item-height': '50px'
+  },
+  dark: {
+    '--el-menu-bg-color': '#141414',
+    '--el-menu-hover-bg-color': '#000000',
+    '--el-menu-active-bg-color': '#000000',
+    '--el-menu-text-color': '#bdbdc0',
+    '--el-menu-active-color': '#ffffff',
+    '--el-menu-hover-text-color': '#ffffff',
+    '--el-menu-horizontal-sub-item-height': '50px'
+  }
+}

+ 2 - 0
src/assets/styles/var.scss

@@ -0,0 +1,2 @@
+/* global css variable */
+$primary-color: var(--el-color-primary);

+ 2 - 0
src/main.ts

@@ -1,5 +1,7 @@
 import { createApp } from 'vue'
 import './style.css'
+
+import '@/assets/styles/index.scss'
 import App from './App.vue'
 
 createApp(App).mount('#app')

+ 638 - 0
src/types/auto-imports.d.ts

@@ -0,0 +1,638 @@
+/* eslint-disable */
+/* prettier-ignore */
+// @ts-nocheck
+// noinspection JSUnusedGlobalSymbols
+// Generated by unplugin-auto-import
+// biome-ignore lint: disable
+export {}
+declare global {
+  const EffectScope: (typeof import('vue'))['EffectScope']
+  const acceptHMRUpdate: (typeof import('pinia'))['acceptHMRUpdate']
+  const asyncComputed: (typeof import('@vueuse/core'))['asyncComputed']
+  const autoResetRef: (typeof import('@vueuse/core'))['autoResetRef']
+  const computed: (typeof import('vue'))['computed']
+  const computedAsync: (typeof import('@vueuse/core'))['computedAsync']
+  const computedEager: (typeof import('@vueuse/core'))['computedEager']
+  const computedInject: (typeof import('@vueuse/core'))['computedInject']
+  const computedWithControl: (typeof import('@vueuse/core'))['computedWithControl']
+  const controlledComputed: (typeof import('@vueuse/core'))['controlledComputed']
+  const controlledRef: (typeof import('@vueuse/core'))['controlledRef']
+  const createApp: (typeof import('vue'))['createApp']
+  const createEventHook: (typeof import('@vueuse/core'))['createEventHook']
+  const createGlobalState: (typeof import('@vueuse/core'))['createGlobalState']
+  const createInjectionState: (typeof import('@vueuse/core'))['createInjectionState']
+  const createPinia: (typeof import('pinia'))['createPinia']
+  const createReactiveFn: (typeof import('@vueuse/core'))['createReactiveFn']
+  const createRef: (typeof import('@vueuse/core'))['createRef']
+  const createReusableTemplate: (typeof import('@vueuse/core'))['createReusableTemplate']
+  const createSharedComposable: (typeof import('@vueuse/core'))['createSharedComposable']
+  const createTemplatePromise: (typeof import('@vueuse/core'))['createTemplatePromise']
+  const createUnrefFn: (typeof import('@vueuse/core'))['createUnrefFn']
+  const customRef: (typeof import('vue'))['customRef']
+  const debouncedRef: (typeof import('@vueuse/core'))['debouncedRef']
+  const debouncedWatch: (typeof import('@vueuse/core'))['debouncedWatch']
+  const defineAsyncComponent: (typeof import('vue'))['defineAsyncComponent']
+  const defineComponent: (typeof import('vue'))['defineComponent']
+  const defineStore: (typeof import('pinia'))['defineStore']
+  const eagerComputed: (typeof import('@vueuse/core'))['eagerComputed']
+  const effectScope: (typeof import('vue'))['effectScope']
+  const extendRef: (typeof import('@vueuse/core'))['extendRef']
+  const getActivePinia: (typeof import('pinia'))['getActivePinia']
+  const getCurrentInstance: (typeof import('vue'))['getCurrentInstance']
+  const getCurrentScope: (typeof import('vue'))['getCurrentScope']
+  const h: (typeof import('vue'))['h']
+  const ignorableWatch: (typeof import('@vueuse/core'))['ignorableWatch']
+  const inject: (typeof import('vue'))['inject']
+  const injectLocal: (typeof import('@vueuse/core'))['injectLocal']
+  const isDefined: (typeof import('@vueuse/core'))['isDefined']
+  const isProxy: (typeof import('vue'))['isProxy']
+  const isReactive: (typeof import('vue'))['isReactive']
+  const isReadonly: (typeof import('vue'))['isReadonly']
+  const isRef: (typeof import('vue'))['isRef']
+  const makeDestructurable: (typeof import('@vueuse/core'))['makeDestructurable']
+  const mapActions: (typeof import('pinia'))['mapActions']
+  const mapGetters: (typeof import('pinia'))['mapGetters']
+  const mapState: (typeof import('pinia'))['mapState']
+  const mapStores: (typeof import('pinia'))['mapStores']
+  const mapWritableState: (typeof import('pinia'))['mapWritableState']
+  const markRaw: (typeof import('vue'))['markRaw']
+  const nextTick: (typeof import('vue'))['nextTick']
+  const onActivated: (typeof import('vue'))['onActivated']
+  const onBeforeMount: (typeof import('vue'))['onBeforeMount']
+  const onBeforeRouteLeave: (typeof import('vue-router'))['onBeforeRouteLeave']
+  const onBeforeRouteUpdate: (typeof import('vue-router'))['onBeforeRouteUpdate']
+  const onBeforeUnmount: (typeof import('vue'))['onBeforeUnmount']
+  const onBeforeUpdate: (typeof import('vue'))['onBeforeUpdate']
+  const onClickOutside: (typeof import('@vueuse/core'))['onClickOutside']
+  const onDeactivated: (typeof import('vue'))['onDeactivated']
+  const onElementRemoval: (typeof import('@vueuse/core'))['onElementRemoval']
+  const onErrorCaptured: (typeof import('vue'))['onErrorCaptured']
+  const onKeyStroke: (typeof import('@vueuse/core'))['onKeyStroke']
+  const onLongPress: (typeof import('@vueuse/core'))['onLongPress']
+  const onMounted: (typeof import('vue'))['onMounted']
+  const onRenderTracked: (typeof import('vue'))['onRenderTracked']
+  const onRenderTriggered: (typeof import('vue'))['onRenderTriggered']
+  const onScopeDispose: (typeof import('vue'))['onScopeDispose']
+  const onServerPrefetch: (typeof import('vue'))['onServerPrefetch']
+  const onStartTyping: (typeof import('@vueuse/core'))['onStartTyping']
+  const onUnmounted: (typeof import('vue'))['onUnmounted']
+  const onUpdated: (typeof import('vue'))['onUpdated']
+  const onWatcherCleanup: (typeof import('vue'))['onWatcherCleanup']
+  const pausableWatch: (typeof import('@vueuse/core'))['pausableWatch']
+  const provide: (typeof import('vue'))['provide']
+  const provideLocal: (typeof import('@vueuse/core'))['provideLocal']
+  const reactify: (typeof import('@vueuse/core'))['reactify']
+  const reactifyObject: (typeof import('@vueuse/core'))['reactifyObject']
+  const reactive: (typeof import('vue'))['reactive']
+  const reactiveComputed: (typeof import('@vueuse/core'))['reactiveComputed']
+  const reactiveOmit: (typeof import('@vueuse/core'))['reactiveOmit']
+  const reactivePick: (typeof import('@vueuse/core'))['reactivePick']
+  const readonly: (typeof import('vue'))['readonly']
+  const ref: (typeof import('vue'))['ref']
+  const refAutoReset: (typeof import('@vueuse/core'))['refAutoReset']
+  const refDebounced: (typeof import('@vueuse/core'))['refDebounced']
+  const refDefault: (typeof import('@vueuse/core'))['refDefault']
+  const refThrottled: (typeof import('@vueuse/core'))['refThrottled']
+  const refWithControl: (typeof import('@vueuse/core'))['refWithControl']
+  const resolveComponent: (typeof import('vue'))['resolveComponent']
+  const resolveRef: (typeof import('@vueuse/core'))['resolveRef']
+  const resolveUnref: (typeof import('@vueuse/core'))['resolveUnref']
+  const setActivePinia: (typeof import('pinia'))['setActivePinia']
+  const setMapStoreSuffix: (typeof import('pinia'))['setMapStoreSuffix']
+  const shallowReactive: (typeof import('vue'))['shallowReactive']
+  const shallowReadonly: (typeof import('vue'))['shallowReadonly']
+  const shallowRef: (typeof import('vue'))['shallowRef']
+  const storeToRefs: (typeof import('pinia'))['storeToRefs']
+  const syncRef: (typeof import('@vueuse/core'))['syncRef']
+  const syncRefs: (typeof import('@vueuse/core'))['syncRefs']
+  const templateRef: (typeof import('@vueuse/core'))['templateRef']
+  const throttledRef: (typeof import('@vueuse/core'))['throttledRef']
+  const throttledWatch: (typeof import('@vueuse/core'))['throttledWatch']
+  const toRaw: (typeof import('vue'))['toRaw']
+  const toReactive: (typeof import('@vueuse/core'))['toReactive']
+  const toRef: (typeof import('vue'))['toRef']
+  const toRefs: (typeof import('vue'))['toRefs']
+  const toValue: (typeof import('vue'))['toValue']
+  const triggerRef: (typeof import('vue'))['triggerRef']
+  const tryOnBeforeMount: (typeof import('@vueuse/core'))['tryOnBeforeMount']
+  const tryOnBeforeUnmount: (typeof import('@vueuse/core'))['tryOnBeforeUnmount']
+  const tryOnMounted: (typeof import('@vueuse/core'))['tryOnMounted']
+  const tryOnScopeDispose: (typeof import('@vueuse/core'))['tryOnScopeDispose']
+  const tryOnUnmounted: (typeof import('@vueuse/core'))['tryOnUnmounted']
+  const unref: (typeof import('vue'))['unref']
+  const unrefElement: (typeof import('@vueuse/core'))['unrefElement']
+  const until: (typeof import('@vueuse/core'))['until']
+  const useActiveElement: (typeof import('@vueuse/core'))['useActiveElement']
+  const useAnimate: (typeof import('@vueuse/core'))['useAnimate']
+  const useArrayDifference: (typeof import('@vueuse/core'))['useArrayDifference']
+  const useArrayEvery: (typeof import('@vueuse/core'))['useArrayEvery']
+  const useArrayFilter: (typeof import('@vueuse/core'))['useArrayFilter']
+  const useArrayFind: (typeof import('@vueuse/core'))['useArrayFind']
+  const useArrayFindIndex: (typeof import('@vueuse/core'))['useArrayFindIndex']
+  const useArrayFindLast: (typeof import('@vueuse/core'))['useArrayFindLast']
+  const useArrayIncludes: (typeof import('@vueuse/core'))['useArrayIncludes']
+  const useArrayJoin: (typeof import('@vueuse/core'))['useArrayJoin']
+  const useArrayMap: (typeof import('@vueuse/core'))['useArrayMap']
+  const useArrayReduce: (typeof import('@vueuse/core'))['useArrayReduce']
+  const useArraySome: (typeof import('@vueuse/core'))['useArraySome']
+  const useArrayUnique: (typeof import('@vueuse/core'))['useArrayUnique']
+  const useAsyncQueue: (typeof import('@vueuse/core'))['useAsyncQueue']
+  const useAsyncState: (typeof import('@vueuse/core'))['useAsyncState']
+  const useAttrs: (typeof import('vue'))['useAttrs']
+  const useBase64: (typeof import('@vueuse/core'))['useBase64']
+  const useBattery: (typeof import('@vueuse/core'))['useBattery']
+  const useBluetooth: (typeof import('@vueuse/core'))['useBluetooth']
+  const useBreakpoints: (typeof import('@vueuse/core'))['useBreakpoints']
+  const useBroadcastChannel: (typeof import('@vueuse/core'))['useBroadcastChannel']
+  const useBrowserLocation: (typeof import('@vueuse/core'))['useBrowserLocation']
+  const useCached: (typeof import('@vueuse/core'))['useCached']
+  const useClipboard: (typeof import('@vueuse/core'))['useClipboard']
+  const useClipboardItems: (typeof import('@vueuse/core'))['useClipboardItems']
+  const useCloned: (typeof import('@vueuse/core'))['useCloned']
+  const useColorMode: (typeof import('@vueuse/core'))['useColorMode']
+  const useConfirmDialog: (typeof import('@vueuse/core'))['useConfirmDialog']
+  const useCountdown: (typeof import('@vueuse/core'))['useCountdown']
+  const useCounter: (typeof import('@vueuse/core'))['useCounter']
+  const useCssModule: (typeof import('vue'))['useCssModule']
+  const useCssVar: (typeof import('@vueuse/core'))['useCssVar']
+  const useCssVars: (typeof import('vue'))['useCssVars']
+  const useCurrentElement: (typeof import('@vueuse/core'))['useCurrentElement']
+  const useCycleList: (typeof import('@vueuse/core'))['useCycleList']
+  const useDark: (typeof import('@vueuse/core'))['useDark']
+  const useDateFormat: (typeof import('@vueuse/core'))['useDateFormat']
+  const useDebounce: (typeof import('@vueuse/core'))['useDebounce']
+  const useDebounceFn: (typeof import('@vueuse/core'))['useDebounceFn']
+  const useDebouncedRefHistory: (typeof import('@vueuse/core'))['useDebouncedRefHistory']
+  const useDeviceMotion: (typeof import('@vueuse/core'))['useDeviceMotion']
+  const useDeviceOrientation: (typeof import('@vueuse/core'))['useDeviceOrientation']
+  const useDevicePixelRatio: (typeof import('@vueuse/core'))['useDevicePixelRatio']
+  const useDevicesList: (typeof import('@vueuse/core'))['useDevicesList']
+  const useDisplayMedia: (typeof import('@vueuse/core'))['useDisplayMedia']
+  const useDocumentVisibility: (typeof import('@vueuse/core'))['useDocumentVisibility']
+  const useDraggable: (typeof import('@vueuse/core'))['useDraggable']
+  const useDropZone: (typeof import('@vueuse/core'))['useDropZone']
+  const useElementBounding: (typeof import('@vueuse/core'))['useElementBounding']
+  const useElementByPoint: (typeof import('@vueuse/core'))['useElementByPoint']
+  const useElementHover: (typeof import('@vueuse/core'))['useElementHover']
+  const useElementSize: (typeof import('@vueuse/core'))['useElementSize']
+  const useElementVisibility: (typeof import('@vueuse/core'))['useElementVisibility']
+  const useEventBus: (typeof import('@vueuse/core'))['useEventBus']
+  const useEventListener: (typeof import('@vueuse/core'))['useEventListener']
+  const useEventSource: (typeof import('@vueuse/core'))['useEventSource']
+  const useEyeDropper: (typeof import('@vueuse/core'))['useEyeDropper']
+  const useFavicon: (typeof import('@vueuse/core'))['useFavicon']
+  const useFetch: (typeof import('@vueuse/core'))['useFetch']
+  const useFileDialog: (typeof import('@vueuse/core'))['useFileDialog']
+  const useFileSystemAccess: (typeof import('@vueuse/core'))['useFileSystemAccess']
+  const useFocus: (typeof import('@vueuse/core'))['useFocus']
+  const useFocusWithin: (typeof import('@vueuse/core'))['useFocusWithin']
+  const useFps: (typeof import('@vueuse/core'))['useFps']
+  const useFullscreen: (typeof import('@vueuse/core'))['useFullscreen']
+  const useGamepad: (typeof import('@vueuse/core'))['useGamepad']
+  const useGeolocation: (typeof import('@vueuse/core'))['useGeolocation']
+  const useId: (typeof import('vue'))['useId']
+  const useIdle: (typeof import('@vueuse/core'))['useIdle']
+  const useImage: (typeof import('@vueuse/core'))['useImage']
+  const useInfiniteScroll: (typeof import('@vueuse/core'))['useInfiniteScroll']
+  const useIntersectionObserver: (typeof import('@vueuse/core'))['useIntersectionObserver']
+  const useInterval: (typeof import('@vueuse/core'))['useInterval']
+  const useIntervalFn: (typeof import('@vueuse/core'))['useIntervalFn']
+  const useKeyModifier: (typeof import('@vueuse/core'))['useKeyModifier']
+  const useLastChanged: (typeof import('@vueuse/core'))['useLastChanged']
+  const useLink: (typeof import('vue-router'))['useLink']
+  const useLocalStorage: (typeof import('@vueuse/core'))['useLocalStorage']
+  const useMagicKeys: (typeof import('@vueuse/core'))['useMagicKeys']
+  const useManualRefHistory: (typeof import('@vueuse/core'))['useManualRefHistory']
+  const useMediaControls: (typeof import('@vueuse/core'))['useMediaControls']
+  const useMediaQuery: (typeof import('@vueuse/core'))['useMediaQuery']
+  const useMemoize: (typeof import('@vueuse/core'))['useMemoize']
+  const useMemory: (typeof import('@vueuse/core'))['useMemory']
+  const useModel: (typeof import('vue'))['useModel']
+  const useMounted: (typeof import('@vueuse/core'))['useMounted']
+  const useMouse: (typeof import('@vueuse/core'))['useMouse']
+  const useMouseInElement: (typeof import('@vueuse/core'))['useMouseInElement']
+  const useMousePressed: (typeof import('@vueuse/core'))['useMousePressed']
+  const useMutationObserver: (typeof import('@vueuse/core'))['useMutationObserver']
+  const useNavigatorLanguage: (typeof import('@vueuse/core'))['useNavigatorLanguage']
+  const useNetwork: (typeof import('@vueuse/core'))['useNetwork']
+  const useNow: (typeof import('@vueuse/core'))['useNow']
+  const useObjectUrl: (typeof import('@vueuse/core'))['useObjectUrl']
+  const useOffsetPagination: (typeof import('@vueuse/core'))['useOffsetPagination']
+  const useOnline: (typeof import('@vueuse/core'))['useOnline']
+  const usePageLeave: (typeof import('@vueuse/core'))['usePageLeave']
+  const useParallax: (typeof import('@vueuse/core'))['useParallax']
+  const useParentElement: (typeof import('@vueuse/core'))['useParentElement']
+  const usePerformanceObserver: (typeof import('@vueuse/core'))['usePerformanceObserver']
+  const usePermission: (typeof import('@vueuse/core'))['usePermission']
+  const usePointer: (typeof import('@vueuse/core'))['usePointer']
+  const usePointerLock: (typeof import('@vueuse/core'))['usePointerLock']
+  const usePointerSwipe: (typeof import('@vueuse/core'))['usePointerSwipe']
+  const usePreferredColorScheme: (typeof import('@vueuse/core'))['usePreferredColorScheme']
+  const usePreferredContrast: (typeof import('@vueuse/core'))['usePreferredContrast']
+  const usePreferredDark: (typeof import('@vueuse/core'))['usePreferredDark']
+  const usePreferredLanguages: (typeof import('@vueuse/core'))['usePreferredLanguages']
+  const usePreferredReducedMotion: (typeof import('@vueuse/core'))['usePreferredReducedMotion']
+  const usePreferredReducedTransparency: (typeof import('@vueuse/core'))['usePreferredReducedTransparency']
+  const usePrevious: (typeof import('@vueuse/core'))['usePrevious']
+  const useRafFn: (typeof import('@vueuse/core'))['useRafFn']
+  const useRefHistory: (typeof import('@vueuse/core'))['useRefHistory']
+  const useResizeObserver: (typeof import('@vueuse/core'))['useResizeObserver']
+  const useRoute: (typeof import('vue-router'))['useRoute']
+  const useRouter: (typeof import('vue-router'))['useRouter']
+  const useSSRWidth: (typeof import('@vueuse/core'))['useSSRWidth']
+  const useScreenOrientation: (typeof import('@vueuse/core'))['useScreenOrientation']
+  const useScreenSafeArea: (typeof import('@vueuse/core'))['useScreenSafeArea']
+  const useScriptTag: (typeof import('@vueuse/core'))['useScriptTag']
+  const useScroll: (typeof import('@vueuse/core'))['useScroll']
+  const useScrollLock: (typeof import('@vueuse/core'))['useScrollLock']
+  const useSessionStorage: (typeof import('@vueuse/core'))['useSessionStorage']
+  const useShare: (typeof import('@vueuse/core'))['useShare']
+  const useSlots: (typeof import('vue'))['useSlots']
+  const useSorted: (typeof import('@vueuse/core'))['useSorted']
+  const useSpeechRecognition: (typeof import('@vueuse/core'))['useSpeechRecognition']
+  const useSpeechSynthesis: (typeof import('@vueuse/core'))['useSpeechSynthesis']
+  const useStepper: (typeof import('@vueuse/core'))['useStepper']
+  const useStorage: (typeof import('@vueuse/core'))['useStorage']
+  const useStorageAsync: (typeof import('@vueuse/core'))['useStorageAsync']
+  const useStyleTag: (typeof import('@vueuse/core'))['useStyleTag']
+  const useSupported: (typeof import('@vueuse/core'))['useSupported']
+  const useSwipe: (typeof import('@vueuse/core'))['useSwipe']
+  const useTemplateRef: (typeof import('vue'))['useTemplateRef']
+  const useTemplateRefsList: (typeof import('@vueuse/core'))['useTemplateRefsList']
+  const useTextDirection: (typeof import('@vueuse/core'))['useTextDirection']
+  const useTextSelection: (typeof import('@vueuse/core'))['useTextSelection']
+  const useTextareaAutosize: (typeof import('@vueuse/core'))['useTextareaAutosize']
+  const useThrottle: (typeof import('@vueuse/core'))['useThrottle']
+  const useThrottleFn: (typeof import('@vueuse/core'))['useThrottleFn']
+  const useThrottledRefHistory: (typeof import('@vueuse/core'))['useThrottledRefHistory']
+  const useTimeAgo: (typeof import('@vueuse/core'))['useTimeAgo']
+  const useTimeout: (typeof import('@vueuse/core'))['useTimeout']
+  const useTimeoutFn: (typeof import('@vueuse/core'))['useTimeoutFn']
+  const useTimeoutPoll: (typeof import('@vueuse/core'))['useTimeoutPoll']
+  const useTimestamp: (typeof import('@vueuse/core'))['useTimestamp']
+  const useTitle: (typeof import('@vueuse/core'))['useTitle']
+  const useToNumber: (typeof import('@vueuse/core'))['useToNumber']
+  const useToString: (typeof import('@vueuse/core'))['useToString']
+  const useToggle: (typeof import('@vueuse/core'))['useToggle']
+  const useTransition: (typeof import('@vueuse/core'))['useTransition']
+  const useUrlSearchParams: (typeof import('@vueuse/core'))['useUrlSearchParams']
+  const useUserMedia: (typeof import('@vueuse/core'))['useUserMedia']
+  const useVModel: (typeof import('@vueuse/core'))['useVModel']
+  const useVModels: (typeof import('@vueuse/core'))['useVModels']
+  const useVibrate: (typeof import('@vueuse/core'))['useVibrate']
+  const useVirtualList: (typeof import('@vueuse/core'))['useVirtualList']
+  const useWakeLock: (typeof import('@vueuse/core'))['useWakeLock']
+  const useWebNotification: (typeof import('@vueuse/core'))['useWebNotification']
+  const useWebSocket: (typeof import('@vueuse/core'))['useWebSocket']
+  const useWebWorker: (typeof import('@vueuse/core'))['useWebWorker']
+  const useWebWorkerFn: (typeof import('@vueuse/core'))['useWebWorkerFn']
+  const useWindowFocus: (typeof import('@vueuse/core'))['useWindowFocus']
+  const useWindowScroll: (typeof import('@vueuse/core'))['useWindowScroll']
+  const useWindowSize: (typeof import('@vueuse/core'))['useWindowSize']
+  const watch: (typeof import('vue'))['watch']
+  const watchArray: (typeof import('@vueuse/core'))['watchArray']
+  const watchAtMost: (typeof import('@vueuse/core'))['watchAtMost']
+  const watchDebounced: (typeof import('@vueuse/core'))['watchDebounced']
+  const watchDeep: (typeof import('@vueuse/core'))['watchDeep']
+  const watchEffect: (typeof import('vue'))['watchEffect']
+  const watchIgnorable: (typeof import('@vueuse/core'))['watchIgnorable']
+  const watchImmediate: (typeof import('@vueuse/core'))['watchImmediate']
+  const watchOnce: (typeof import('@vueuse/core'))['watchOnce']
+  const watchPausable: (typeof import('@vueuse/core'))['watchPausable']
+  const watchPostEffect: (typeof import('vue'))['watchPostEffect']
+  const watchSyncEffect: (typeof import('vue'))['watchSyncEffect']
+  const watchThrottled: (typeof import('@vueuse/core'))['watchThrottled']
+  const watchTriggerable: (typeof import('@vueuse/core'))['watchTriggerable']
+  const watchWithFilter: (typeof import('@vueuse/core'))['watchWithFilter']
+  const whenever: (typeof import('@vueuse/core'))['whenever']
+}
+// for type re-export
+declare global {
+  // @ts-ignore
+  export type {
+    Component,
+    Slot,
+    Slots,
+    ComponentPublicInstance,
+    ComputedRef,
+    DirectiveBinding,
+    ExtractDefaultPropTypes,
+    ExtractPropTypes,
+    ExtractPublicPropTypes,
+    InjectionKey,
+    PropType,
+    Ref,
+    MaybeRef,
+    MaybeRefOrGetter,
+    VNode,
+    WritableComputedRef
+  } from 'vue'
+  import('vue')
+}
+
+// for vue template auto import
+import { UnwrapRef } from 'vue'
+declare module 'vue' {
+  interface GlobalComponents {}
+  interface ComponentCustomProperties {
+    readonly EffectScope: UnwrapRef<(typeof import('vue'))['EffectScope']>
+    readonly acceptHMRUpdate: UnwrapRef<(typeof import('pinia'))['acceptHMRUpdate']>
+    readonly asyncComputed: UnwrapRef<(typeof import('@vueuse/core'))['asyncComputed']>
+    readonly autoResetRef: UnwrapRef<(typeof import('@vueuse/core'))['autoResetRef']>
+    readonly computed: UnwrapRef<(typeof import('vue'))['computed']>
+    readonly computedAsync: UnwrapRef<(typeof import('@vueuse/core'))['computedAsync']>
+    readonly computedEager: UnwrapRef<(typeof import('@vueuse/core'))['computedEager']>
+    readonly computedInject: UnwrapRef<(typeof import('@vueuse/core'))['computedInject']>
+    readonly computedWithControl: UnwrapRef<(typeof import('@vueuse/core'))['computedWithControl']>
+    readonly controlledComputed: UnwrapRef<(typeof import('@vueuse/core'))['controlledComputed']>
+    readonly controlledRef: UnwrapRef<(typeof import('@vueuse/core'))['controlledRef']>
+    readonly createApp: UnwrapRef<(typeof import('vue'))['createApp']>
+    readonly createEventHook: UnwrapRef<(typeof import('@vueuse/core'))['createEventHook']>
+    readonly createGlobalState: UnwrapRef<(typeof import('@vueuse/core'))['createGlobalState']>
+    readonly createInjectionState: UnwrapRef<(typeof import('@vueuse/core'))['createInjectionState']>
+    readonly createPinia: UnwrapRef<(typeof import('pinia'))['createPinia']>
+    readonly createReactiveFn: UnwrapRef<(typeof import('@vueuse/core'))['createReactiveFn']>
+    readonly createRef: UnwrapRef<(typeof import('@vueuse/core'))['createRef']>
+    readonly createReusableTemplate: UnwrapRef<(typeof import('@vueuse/core'))['createReusableTemplate']>
+    readonly createSharedComposable: UnwrapRef<(typeof import('@vueuse/core'))['createSharedComposable']>
+    readonly createTemplatePromise: UnwrapRef<(typeof import('@vueuse/core'))['createTemplatePromise']>
+    readonly createUnrefFn: UnwrapRef<(typeof import('@vueuse/core'))['createUnrefFn']>
+    readonly customRef: UnwrapRef<(typeof import('vue'))['customRef']>
+    readonly debouncedRef: UnwrapRef<(typeof import('@vueuse/core'))['debouncedRef']>
+    readonly debouncedWatch: UnwrapRef<(typeof import('@vueuse/core'))['debouncedWatch']>
+    readonly defineAsyncComponent: UnwrapRef<(typeof import('vue'))['defineAsyncComponent']>
+    readonly defineComponent: UnwrapRef<(typeof import('vue'))['defineComponent']>
+    readonly defineStore: UnwrapRef<(typeof import('pinia'))['defineStore']>
+    readonly eagerComputed: UnwrapRef<(typeof import('@vueuse/core'))['eagerComputed']>
+    readonly effectScope: UnwrapRef<(typeof import('vue'))['effectScope']>
+    readonly extendRef: UnwrapRef<(typeof import('@vueuse/core'))['extendRef']>
+    readonly getActivePinia: UnwrapRef<(typeof import('pinia'))['getActivePinia']>
+    readonly getCurrentInstance: UnwrapRef<(typeof import('vue'))['getCurrentInstance']>
+    readonly getCurrentScope: UnwrapRef<(typeof import('vue'))['getCurrentScope']>
+    readonly h: UnwrapRef<(typeof import('vue'))['h']>
+    readonly ignorableWatch: UnwrapRef<(typeof import('@vueuse/core'))['ignorableWatch']>
+    readonly inject: UnwrapRef<(typeof import('vue'))['inject']>
+    readonly injectLocal: UnwrapRef<(typeof import('@vueuse/core'))['injectLocal']>
+    readonly isDefined: UnwrapRef<(typeof import('@vueuse/core'))['isDefined']>
+    readonly isProxy: UnwrapRef<(typeof import('vue'))['isProxy']>
+    readonly isReactive: UnwrapRef<(typeof import('vue'))['isReactive']>
+    readonly isReadonly: UnwrapRef<(typeof import('vue'))['isReadonly']>
+    readonly isRef: UnwrapRef<(typeof import('vue'))['isRef']>
+    readonly makeDestructurable: UnwrapRef<(typeof import('@vueuse/core'))['makeDestructurable']>
+    readonly mapActions: UnwrapRef<(typeof import('pinia'))['mapActions']>
+    readonly mapGetters: UnwrapRef<(typeof import('pinia'))['mapGetters']>
+    readonly mapState: UnwrapRef<(typeof import('pinia'))['mapState']>
+    readonly mapStores: UnwrapRef<(typeof import('pinia'))['mapStores']>
+    readonly mapWritableState: UnwrapRef<(typeof import('pinia'))['mapWritableState']>
+    readonly markRaw: UnwrapRef<(typeof import('vue'))['markRaw']>
+    readonly nextTick: UnwrapRef<(typeof import('vue'))['nextTick']>
+    readonly onActivated: UnwrapRef<(typeof import('vue'))['onActivated']>
+    readonly onBeforeMount: UnwrapRef<(typeof import('vue'))['onBeforeMount']>
+    readonly onBeforeRouteLeave: UnwrapRef<(typeof import('vue-router'))['onBeforeRouteLeave']>
+    readonly onBeforeRouteUpdate: UnwrapRef<(typeof import('vue-router'))['onBeforeRouteUpdate']>
+    readonly onBeforeUnmount: UnwrapRef<(typeof import('vue'))['onBeforeUnmount']>
+    readonly onBeforeUpdate: UnwrapRef<(typeof import('vue'))['onBeforeUpdate']>
+    readonly onClickOutside: UnwrapRef<(typeof import('@vueuse/core'))['onClickOutside']>
+    readonly onDeactivated: UnwrapRef<(typeof import('vue'))['onDeactivated']>
+    readonly onElementRemoval: UnwrapRef<(typeof import('@vueuse/core'))['onElementRemoval']>
+    readonly onErrorCaptured: UnwrapRef<(typeof import('vue'))['onErrorCaptured']>
+    readonly onKeyStroke: UnwrapRef<(typeof import('@vueuse/core'))['onKeyStroke']>
+    readonly onLongPress: UnwrapRef<(typeof import('@vueuse/core'))['onLongPress']>
+    readonly onMounted: UnwrapRef<(typeof import('vue'))['onMounted']>
+    readonly onRenderTracked: UnwrapRef<(typeof import('vue'))['onRenderTracked']>
+    readonly onRenderTriggered: UnwrapRef<(typeof import('vue'))['onRenderTriggered']>
+    readonly onScopeDispose: UnwrapRef<(typeof import('vue'))['onScopeDispose']>
+    readonly onServerPrefetch: UnwrapRef<(typeof import('vue'))['onServerPrefetch']>
+    readonly onStartTyping: UnwrapRef<(typeof import('@vueuse/core'))['onStartTyping']>
+    readonly onUnmounted: UnwrapRef<(typeof import('vue'))['onUnmounted']>
+    readonly onUpdated: UnwrapRef<(typeof import('vue'))['onUpdated']>
+    readonly onWatcherCleanup: UnwrapRef<(typeof import('vue'))['onWatcherCleanup']>
+    readonly pausableWatch: UnwrapRef<(typeof import('@vueuse/core'))['pausableWatch']>
+    readonly provide: UnwrapRef<(typeof import('vue'))['provide']>
+    readonly provideLocal: UnwrapRef<(typeof import('@vueuse/core'))['provideLocal']>
+    readonly reactify: UnwrapRef<(typeof import('@vueuse/core'))['reactify']>
+    readonly reactifyObject: UnwrapRef<(typeof import('@vueuse/core'))['reactifyObject']>
+    readonly reactive: UnwrapRef<(typeof import('vue'))['reactive']>
+    readonly reactiveComputed: UnwrapRef<(typeof import('@vueuse/core'))['reactiveComputed']>
+    readonly reactiveOmit: UnwrapRef<(typeof import('@vueuse/core'))['reactiveOmit']>
+    readonly reactivePick: UnwrapRef<(typeof import('@vueuse/core'))['reactivePick']>
+    readonly readonly: UnwrapRef<(typeof import('vue'))['readonly']>
+    readonly ref: UnwrapRef<(typeof import('vue'))['ref']>
+    readonly refAutoReset: UnwrapRef<(typeof import('@vueuse/core'))['refAutoReset']>
+    readonly refDebounced: UnwrapRef<(typeof import('@vueuse/core'))['refDebounced']>
+    readonly refDefault: UnwrapRef<(typeof import('@vueuse/core'))['refDefault']>
+    readonly refThrottled: UnwrapRef<(typeof import('@vueuse/core'))['refThrottled']>
+    readonly refWithControl: UnwrapRef<(typeof import('@vueuse/core'))['refWithControl']>
+    readonly resolveComponent: UnwrapRef<(typeof import('vue'))['resolveComponent']>
+    readonly resolveRef: UnwrapRef<(typeof import('@vueuse/core'))['resolveRef']>
+    readonly resolveUnref: UnwrapRef<(typeof import('@vueuse/core'))['resolveUnref']>
+    readonly setActivePinia: UnwrapRef<(typeof import('pinia'))['setActivePinia']>
+    readonly setMapStoreSuffix: UnwrapRef<(typeof import('pinia'))['setMapStoreSuffix']>
+    readonly shallowReactive: UnwrapRef<(typeof import('vue'))['shallowReactive']>
+    readonly shallowReadonly: UnwrapRef<(typeof import('vue'))['shallowReadonly']>
+    readonly shallowRef: UnwrapRef<(typeof import('vue'))['shallowRef']>
+    readonly storeToRefs: UnwrapRef<(typeof import('pinia'))['storeToRefs']>
+    readonly syncRef: UnwrapRef<(typeof import('@vueuse/core'))['syncRef']>
+    readonly syncRefs: UnwrapRef<(typeof import('@vueuse/core'))['syncRefs']>
+    readonly templateRef: UnwrapRef<(typeof import('@vueuse/core'))['templateRef']>
+    readonly throttledRef: UnwrapRef<(typeof import('@vueuse/core'))['throttledRef']>
+    readonly throttledWatch: UnwrapRef<(typeof import('@vueuse/core'))['throttledWatch']>
+    readonly toRaw: UnwrapRef<(typeof import('vue'))['toRaw']>
+    readonly toReactive: UnwrapRef<(typeof import('@vueuse/core'))['toReactive']>
+    readonly toRef: UnwrapRef<(typeof import('vue'))['toRef']>
+    readonly toRefs: UnwrapRef<(typeof import('vue'))['toRefs']>
+    readonly toValue: UnwrapRef<(typeof import('vue'))['toValue']>
+    readonly triggerRef: UnwrapRef<(typeof import('vue'))['triggerRef']>
+    readonly tryOnBeforeMount: UnwrapRef<(typeof import('@vueuse/core'))['tryOnBeforeMount']>
+    readonly tryOnBeforeUnmount: UnwrapRef<(typeof import('@vueuse/core'))['tryOnBeforeUnmount']>
+    readonly tryOnMounted: UnwrapRef<(typeof import('@vueuse/core'))['tryOnMounted']>
+    readonly tryOnScopeDispose: UnwrapRef<(typeof import('@vueuse/core'))['tryOnScopeDispose']>
+    readonly tryOnUnmounted: UnwrapRef<(typeof import('@vueuse/core'))['tryOnUnmounted']>
+    readonly unref: UnwrapRef<(typeof import('vue'))['unref']>
+    readonly unrefElement: UnwrapRef<(typeof import('@vueuse/core'))['unrefElement']>
+    readonly until: UnwrapRef<(typeof import('@vueuse/core'))['until']>
+    readonly useActiveElement: UnwrapRef<(typeof import('@vueuse/core'))['useActiveElement']>
+    readonly useAnimate: UnwrapRef<(typeof import('@vueuse/core'))['useAnimate']>
+    readonly useArrayDifference: UnwrapRef<(typeof import('@vueuse/core'))['useArrayDifference']>
+    readonly useArrayEvery: UnwrapRef<(typeof import('@vueuse/core'))['useArrayEvery']>
+    readonly useArrayFilter: UnwrapRef<(typeof import('@vueuse/core'))['useArrayFilter']>
+    readonly useArrayFind: UnwrapRef<(typeof import('@vueuse/core'))['useArrayFind']>
+    readonly useArrayFindIndex: UnwrapRef<(typeof import('@vueuse/core'))['useArrayFindIndex']>
+    readonly useArrayFindLast: UnwrapRef<(typeof import('@vueuse/core'))['useArrayFindLast']>
+    readonly useArrayIncludes: UnwrapRef<(typeof import('@vueuse/core'))['useArrayIncludes']>
+    readonly useArrayJoin: UnwrapRef<(typeof import('@vueuse/core'))['useArrayJoin']>
+    readonly useArrayMap: UnwrapRef<(typeof import('@vueuse/core'))['useArrayMap']>
+    readonly useArrayReduce: UnwrapRef<(typeof import('@vueuse/core'))['useArrayReduce']>
+    readonly useArraySome: UnwrapRef<(typeof import('@vueuse/core'))['useArraySome']>
+    readonly useArrayUnique: UnwrapRef<(typeof import('@vueuse/core'))['useArrayUnique']>
+    readonly useAsyncQueue: UnwrapRef<(typeof import('@vueuse/core'))['useAsyncQueue']>
+    readonly useAsyncState: UnwrapRef<(typeof import('@vueuse/core'))['useAsyncState']>
+    readonly useAttrs: UnwrapRef<(typeof import('vue'))['useAttrs']>
+    readonly useBase64: UnwrapRef<(typeof import('@vueuse/core'))['useBase64']>
+    readonly useBattery: UnwrapRef<(typeof import('@vueuse/core'))['useBattery']>
+    readonly useBluetooth: UnwrapRef<(typeof import('@vueuse/core'))['useBluetooth']>
+    readonly useBreakpoints: UnwrapRef<(typeof import('@vueuse/core'))['useBreakpoints']>
+    readonly useBroadcastChannel: UnwrapRef<(typeof import('@vueuse/core'))['useBroadcastChannel']>
+    readonly useBrowserLocation: UnwrapRef<(typeof import('@vueuse/core'))['useBrowserLocation']>
+    readonly useCached: UnwrapRef<(typeof import('@vueuse/core'))['useCached']>
+    readonly useClipboard: UnwrapRef<(typeof import('@vueuse/core'))['useClipboard']>
+    readonly useClipboardItems: UnwrapRef<(typeof import('@vueuse/core'))['useClipboardItems']>
+    readonly useCloned: UnwrapRef<(typeof import('@vueuse/core'))['useCloned']>
+    readonly useColorMode: UnwrapRef<(typeof import('@vueuse/core'))['useColorMode']>
+    readonly useConfirmDialog: UnwrapRef<(typeof import('@vueuse/core'))['useConfirmDialog']>
+    readonly useCountdown: UnwrapRef<(typeof import('@vueuse/core'))['useCountdown']>
+    readonly useCounter: UnwrapRef<(typeof import('@vueuse/core'))['useCounter']>
+    readonly useCssModule: UnwrapRef<(typeof import('vue'))['useCssModule']>
+    readonly useCssVar: UnwrapRef<(typeof import('@vueuse/core'))['useCssVar']>
+    readonly useCssVars: UnwrapRef<(typeof import('vue'))['useCssVars']>
+    readonly useCurrentElement: UnwrapRef<(typeof import('@vueuse/core'))['useCurrentElement']>
+    readonly useCycleList: UnwrapRef<(typeof import('@vueuse/core'))['useCycleList']>
+    readonly useDark: UnwrapRef<(typeof import('@vueuse/core'))['useDark']>
+    readonly useDateFormat: UnwrapRef<(typeof import('@vueuse/core'))['useDateFormat']>
+    readonly useDebounce: UnwrapRef<(typeof import('@vueuse/core'))['useDebounce']>
+    readonly useDebounceFn: UnwrapRef<(typeof import('@vueuse/core'))['useDebounceFn']>
+    readonly useDebouncedRefHistory: UnwrapRef<(typeof import('@vueuse/core'))['useDebouncedRefHistory']>
+    readonly useDeviceMotion: UnwrapRef<(typeof import('@vueuse/core'))['useDeviceMotion']>
+    readonly useDeviceOrientation: UnwrapRef<(typeof import('@vueuse/core'))['useDeviceOrientation']>
+    readonly useDevicePixelRatio: UnwrapRef<(typeof import('@vueuse/core'))['useDevicePixelRatio']>
+    readonly useDevicesList: UnwrapRef<(typeof import('@vueuse/core'))['useDevicesList']>
+    readonly useDisplayMedia: UnwrapRef<(typeof import('@vueuse/core'))['useDisplayMedia']>
+    readonly useDocumentVisibility: UnwrapRef<(typeof import('@vueuse/core'))['useDocumentVisibility']>
+    readonly useDraggable: UnwrapRef<(typeof import('@vueuse/core'))['useDraggable']>
+    readonly useDropZone: UnwrapRef<(typeof import('@vueuse/core'))['useDropZone']>
+    readonly useElementBounding: UnwrapRef<(typeof import('@vueuse/core'))['useElementBounding']>
+    readonly useElementByPoint: UnwrapRef<(typeof import('@vueuse/core'))['useElementByPoint']>
+    readonly useElementHover: UnwrapRef<(typeof import('@vueuse/core'))['useElementHover']>
+    readonly useElementSize: UnwrapRef<(typeof import('@vueuse/core'))['useElementSize']>
+    readonly useElementVisibility: UnwrapRef<(typeof import('@vueuse/core'))['useElementVisibility']>
+    readonly useEventBus: UnwrapRef<(typeof import('@vueuse/core'))['useEventBus']>
+    readonly useEventListener: UnwrapRef<(typeof import('@vueuse/core'))['useEventListener']>
+    readonly useEventSource: UnwrapRef<(typeof import('@vueuse/core'))['useEventSource']>
+    readonly useEyeDropper: UnwrapRef<(typeof import('@vueuse/core'))['useEyeDropper']>
+    readonly useFavicon: UnwrapRef<(typeof import('@vueuse/core'))['useFavicon']>
+    readonly useFetch: UnwrapRef<(typeof import('@vueuse/core'))['useFetch']>
+    readonly useFileDialog: UnwrapRef<(typeof import('@vueuse/core'))['useFileDialog']>
+    readonly useFileSystemAccess: UnwrapRef<(typeof import('@vueuse/core'))['useFileSystemAccess']>
+    readonly useFocus: UnwrapRef<(typeof import('@vueuse/core'))['useFocus']>
+    readonly useFocusWithin: UnwrapRef<(typeof import('@vueuse/core'))['useFocusWithin']>
+    readonly useFps: UnwrapRef<(typeof import('@vueuse/core'))['useFps']>
+    readonly useFullscreen: UnwrapRef<(typeof import('@vueuse/core'))['useFullscreen']>
+    readonly useGamepad: UnwrapRef<(typeof import('@vueuse/core'))['useGamepad']>
+    readonly useGeolocation: UnwrapRef<(typeof import('@vueuse/core'))['useGeolocation']>
+    readonly useId: UnwrapRef<(typeof import('vue'))['useId']>
+    readonly useIdle: UnwrapRef<(typeof import('@vueuse/core'))['useIdle']>
+    readonly useImage: UnwrapRef<(typeof import('@vueuse/core'))['useImage']>
+    readonly useInfiniteScroll: UnwrapRef<(typeof import('@vueuse/core'))['useInfiniteScroll']>
+    readonly useIntersectionObserver: UnwrapRef<(typeof import('@vueuse/core'))['useIntersectionObserver']>
+    readonly useInterval: UnwrapRef<(typeof import('@vueuse/core'))['useInterval']>
+    readonly useIntervalFn: UnwrapRef<(typeof import('@vueuse/core'))['useIntervalFn']>
+    readonly useKeyModifier: UnwrapRef<(typeof import('@vueuse/core'))['useKeyModifier']>
+    readonly useLastChanged: UnwrapRef<(typeof import('@vueuse/core'))['useLastChanged']>
+    readonly useLink: UnwrapRef<(typeof import('vue-router'))['useLink']>
+    readonly useLocalStorage: UnwrapRef<(typeof import('@vueuse/core'))['useLocalStorage']>
+    readonly useMagicKeys: UnwrapRef<(typeof import('@vueuse/core'))['useMagicKeys']>
+    readonly useManualRefHistory: UnwrapRef<(typeof import('@vueuse/core'))['useManualRefHistory']>
+    readonly useMediaControls: UnwrapRef<(typeof import('@vueuse/core'))['useMediaControls']>
+    readonly useMediaQuery: UnwrapRef<(typeof import('@vueuse/core'))['useMediaQuery']>
+    readonly useMemoize: UnwrapRef<(typeof import('@vueuse/core'))['useMemoize']>
+    readonly useMemory: UnwrapRef<(typeof import('@vueuse/core'))['useMemory']>
+    readonly useModel: UnwrapRef<(typeof import('vue'))['useModel']>
+    readonly useMounted: UnwrapRef<(typeof import('@vueuse/core'))['useMounted']>
+    readonly useMouse: UnwrapRef<(typeof import('@vueuse/core'))['useMouse']>
+    readonly useMouseInElement: UnwrapRef<(typeof import('@vueuse/core'))['useMouseInElement']>
+    readonly useMousePressed: UnwrapRef<(typeof import('@vueuse/core'))['useMousePressed']>
+    readonly useMutationObserver: UnwrapRef<(typeof import('@vueuse/core'))['useMutationObserver']>
+    readonly useNavigatorLanguage: UnwrapRef<(typeof import('@vueuse/core'))['useNavigatorLanguage']>
+    readonly useNetwork: UnwrapRef<(typeof import('@vueuse/core'))['useNetwork']>
+    readonly useNow: UnwrapRef<(typeof import('@vueuse/core'))['useNow']>
+    readonly useObjectUrl: UnwrapRef<(typeof import('@vueuse/core'))['useObjectUrl']>
+    readonly useOffsetPagination: UnwrapRef<(typeof import('@vueuse/core'))['useOffsetPagination']>
+    readonly useOnline: UnwrapRef<(typeof import('@vueuse/core'))['useOnline']>
+    readonly usePageLeave: UnwrapRef<(typeof import('@vueuse/core'))['usePageLeave']>
+    readonly useParallax: UnwrapRef<(typeof import('@vueuse/core'))['useParallax']>
+    readonly useParentElement: UnwrapRef<(typeof import('@vueuse/core'))['useParentElement']>
+    readonly usePerformanceObserver: UnwrapRef<(typeof import('@vueuse/core'))['usePerformanceObserver']>
+    readonly usePermission: UnwrapRef<(typeof import('@vueuse/core'))['usePermission']>
+    readonly usePointer: UnwrapRef<(typeof import('@vueuse/core'))['usePointer']>
+    readonly usePointerLock: UnwrapRef<(typeof import('@vueuse/core'))['usePointerLock']>
+    readonly usePointerSwipe: UnwrapRef<(typeof import('@vueuse/core'))['usePointerSwipe']>
+    readonly usePreferredColorScheme: UnwrapRef<(typeof import('@vueuse/core'))['usePreferredColorScheme']>
+    readonly usePreferredContrast: UnwrapRef<(typeof import('@vueuse/core'))['usePreferredContrast']>
+    readonly usePreferredDark: UnwrapRef<(typeof import('@vueuse/core'))['usePreferredDark']>
+    readonly usePreferredLanguages: UnwrapRef<(typeof import('@vueuse/core'))['usePreferredLanguages']>
+    readonly usePreferredReducedMotion: UnwrapRef<(typeof import('@vueuse/core'))['usePreferredReducedMotion']>
+    readonly usePreferredReducedTransparency: UnwrapRef<(typeof import('@vueuse/core'))['usePreferredReducedTransparency']>
+    readonly usePrevious: UnwrapRef<(typeof import('@vueuse/core'))['usePrevious']>
+    readonly useRafFn: UnwrapRef<(typeof import('@vueuse/core'))['useRafFn']>
+    readonly useRefHistory: UnwrapRef<(typeof import('@vueuse/core'))['useRefHistory']>
+    readonly useResizeObserver: UnwrapRef<(typeof import('@vueuse/core'))['useResizeObserver']>
+    readonly useRoute: UnwrapRef<(typeof import('vue-router'))['useRoute']>
+    readonly useRouter: UnwrapRef<(typeof import('vue-router'))['useRouter']>
+    readonly useSSRWidth: UnwrapRef<(typeof import('@vueuse/core'))['useSSRWidth']>
+    readonly useScreenOrientation: UnwrapRef<(typeof import('@vueuse/core'))['useScreenOrientation']>
+    readonly useScreenSafeArea: UnwrapRef<(typeof import('@vueuse/core'))['useScreenSafeArea']>
+    readonly useScriptTag: UnwrapRef<(typeof import('@vueuse/core'))['useScriptTag']>
+    readonly useScroll: UnwrapRef<(typeof import('@vueuse/core'))['useScroll']>
+    readonly useScrollLock: UnwrapRef<(typeof import('@vueuse/core'))['useScrollLock']>
+    readonly useSessionStorage: UnwrapRef<(typeof import('@vueuse/core'))['useSessionStorage']>
+    readonly useShare: UnwrapRef<(typeof import('@vueuse/core'))['useShare']>
+    readonly useSlots: UnwrapRef<(typeof import('vue'))['useSlots']>
+    readonly useSorted: UnwrapRef<(typeof import('@vueuse/core'))['useSorted']>
+    readonly useSpeechRecognition: UnwrapRef<(typeof import('@vueuse/core'))['useSpeechRecognition']>
+    readonly useSpeechSynthesis: UnwrapRef<(typeof import('@vueuse/core'))['useSpeechSynthesis']>
+    readonly useStepper: UnwrapRef<(typeof import('@vueuse/core'))['useStepper']>
+    readonly useStorage: UnwrapRef<(typeof import('@vueuse/core'))['useStorage']>
+    readonly useStorageAsync: UnwrapRef<(typeof import('@vueuse/core'))['useStorageAsync']>
+    readonly useStyleTag: UnwrapRef<(typeof import('@vueuse/core'))['useStyleTag']>
+    readonly useSupported: UnwrapRef<(typeof import('@vueuse/core'))['useSupported']>
+    readonly useSwipe: UnwrapRef<(typeof import('@vueuse/core'))['useSwipe']>
+    readonly useTemplateRef: UnwrapRef<(typeof import('vue'))['useTemplateRef']>
+    readonly useTemplateRefsList: UnwrapRef<(typeof import('@vueuse/core'))['useTemplateRefsList']>
+    readonly useTextDirection: UnwrapRef<(typeof import('@vueuse/core'))['useTextDirection']>
+    readonly useTextSelection: UnwrapRef<(typeof import('@vueuse/core'))['useTextSelection']>
+    readonly useTextareaAutosize: UnwrapRef<(typeof import('@vueuse/core'))['useTextareaAutosize']>
+    readonly useThrottle: UnwrapRef<(typeof import('@vueuse/core'))['useThrottle']>
+    readonly useThrottleFn: UnwrapRef<(typeof import('@vueuse/core'))['useThrottleFn']>
+    readonly useThrottledRefHistory: UnwrapRef<(typeof import('@vueuse/core'))['useThrottledRefHistory']>
+    readonly useTimeAgo: UnwrapRef<(typeof import('@vueuse/core'))['useTimeAgo']>
+    readonly useTimeout: UnwrapRef<(typeof import('@vueuse/core'))['useTimeout']>
+    readonly useTimeoutFn: UnwrapRef<(typeof import('@vueuse/core'))['useTimeoutFn']>
+    readonly useTimeoutPoll: UnwrapRef<(typeof import('@vueuse/core'))['useTimeoutPoll']>
+    readonly useTimestamp: UnwrapRef<(typeof import('@vueuse/core'))['useTimestamp']>
+    readonly useTitle: UnwrapRef<(typeof import('@vueuse/core'))['useTitle']>
+    readonly useToNumber: UnwrapRef<(typeof import('@vueuse/core'))['useToNumber']>
+    readonly useToString: UnwrapRef<(typeof import('@vueuse/core'))['useToString']>
+    readonly useToggle: UnwrapRef<(typeof import('@vueuse/core'))['useToggle']>
+    readonly useTransition: UnwrapRef<(typeof import('@vueuse/core'))['useTransition']>
+    readonly useUrlSearchParams: UnwrapRef<(typeof import('@vueuse/core'))['useUrlSearchParams']>
+    readonly useUserMedia: UnwrapRef<(typeof import('@vueuse/core'))['useUserMedia']>
+    readonly useVModel: UnwrapRef<(typeof import('@vueuse/core'))['useVModel']>
+    readonly useVModels: UnwrapRef<(typeof import('@vueuse/core'))['useVModels']>
+    readonly useVibrate: UnwrapRef<(typeof import('@vueuse/core'))['useVibrate']>
+    readonly useVirtualList: UnwrapRef<(typeof import('@vueuse/core'))['useVirtualList']>
+    readonly useWakeLock: UnwrapRef<(typeof import('@vueuse/core'))['useWakeLock']>
+    readonly useWebNotification: UnwrapRef<(typeof import('@vueuse/core'))['useWebNotification']>
+    readonly useWebSocket: UnwrapRef<(typeof import('@vueuse/core'))['useWebSocket']>
+    readonly useWebWorker: UnwrapRef<(typeof import('@vueuse/core'))['useWebWorker']>
+    readonly useWebWorkerFn: UnwrapRef<(typeof import('@vueuse/core'))['useWebWorkerFn']>
+    readonly useWindowFocus: UnwrapRef<(typeof import('@vueuse/core'))['useWindowFocus']>
+    readonly useWindowScroll: UnwrapRef<(typeof import('@vueuse/core'))['useWindowScroll']>
+    readonly useWindowSize: UnwrapRef<(typeof import('@vueuse/core'))['useWindowSize']>
+    readonly watch: UnwrapRef<(typeof import('vue'))['watch']>
+    readonly watchArray: UnwrapRef<(typeof import('@vueuse/core'))['watchArray']>
+    readonly watchAtMost: UnwrapRef<(typeof import('@vueuse/core'))['watchAtMost']>
+    readonly watchDebounced: UnwrapRef<(typeof import('@vueuse/core'))['watchDebounced']>
+    readonly watchDeep: UnwrapRef<(typeof import('@vueuse/core'))['watchDeep']>
+    readonly watchEffect: UnwrapRef<(typeof import('vue'))['watchEffect']>
+    readonly watchIgnorable: UnwrapRef<(typeof import('@vueuse/core'))['watchIgnorable']>
+    readonly watchImmediate: UnwrapRef<(typeof import('@vueuse/core'))['watchImmediate']>
+    readonly watchOnce: UnwrapRef<(typeof import('@vueuse/core'))['watchOnce']>
+    readonly watchPausable: UnwrapRef<(typeof import('@vueuse/core'))['watchPausable']>
+    readonly watchPostEffect: UnwrapRef<(typeof import('vue'))['watchPostEffect']>
+    readonly watchSyncEffect: UnwrapRef<(typeof import('vue'))['watchSyncEffect']>
+    readonly watchThrottled: UnwrapRef<(typeof import('@vueuse/core'))['watchThrottled']>
+    readonly watchTriggerable: UnwrapRef<(typeof import('@vueuse/core'))['watchTriggerable']>
+    readonly watchWithFilter: UnwrapRef<(typeof import('@vueuse/core'))['watchWithFilter']>
+    readonly whenever: UnwrapRef<(typeof import('@vueuse/core'))['whenever']>
+  }
+}

+ 73 - 0
src/types/global.d.ts

@@ -0,0 +1,73 @@
+declare interface ImportMetaEnv {
+  VITE_PROXY: ProxyList | undefined
+  readonly VITE_APP_TITLE: string
+  readonly VITE_NODE_ENV: 'development' | 'production'
+  readonly VITE_ROUTER_MODE: 'hash' | 'history'
+  readonly VITE_PORT: number
+  readonly VITE_OPEN: boolean
+  readonly VITE_USE_MOCK: boolean
+  readonly VITE_API_PREFIX_PATH: string
+  readonly VITE_MOCK_API_PREFIX_PATH: string
+}
+
+declare type Recordable<T = any> = Record<string, T>
+declare type LayoutType = 'classic'
+declare interface AxiosConfig {
+  params?: any
+  data?: any
+  url?: string
+  method?: AxiosMethod
+  headers?: RawAxiosRequestHeaders
+  responseType?: AxiosResponseType
+}
+
+// 请求响应参数(包含data)
+declare interface ResultData<T = any> extends Result {
+  data: T
+}
+
+// 请求响应参数(不包含data)
+declare interface Result {
+  code: string | number
+  msg: string
+}
+
+// BaseEntity
+declare interface BaseEntity {
+  /** 乐观锁 */
+  version?: number
+  createBy?: any
+  createDept?: any
+  createTime?: string
+  updateBy?: any
+  updateTime?: any
+}
+
+// 分页请求参数
+declare interface PageQuery {
+  pageNum: number
+  pageSize: number
+}
+
+// 分页响应参数
+declare interface ResPage<T> {
+  list: T[]
+  pageNum: number
+  pageSize: number
+  total: number
+}
+
+declare type Nullable<T> = T | null
+
+declare type ElRef<T extends HTMLElement = HTMLDivElement> = Nullable<T>
+
+declare interface Fn<T = any> {
+  (...arg: T[]): T
+}
+type ObjToKeyValArray<T> = {
+  [K in keyof T]: [K, T[K]]
+}[keyof T]
+
+declare type keyOnPrefix<T> = {
+  [K in keyof T as `on${Capitalize<K>}`]: T[K] extends readonly any[] ? (...t: T[K]) => void : never
+}

+ 15 - 0
src/typings/auto-components.d.ts

@@ -0,0 +1,15 @@
+/* eslint-disable */
+// @ts-nocheck
+// Generated by unplugin-vue-components
+// Read more: https://github.com/vuejs/core/pull/3399
+// biome-ignore lint: disable
+export {}
+
+/* prettier-ignore */
+declare module 'vue' {
+  export interface GlobalComponents {
+    HelloWorld: typeof import('./../components/HelloWorld.vue')['default']
+    RouterLink: typeof import('vue-router')['RouterLink']
+    RouterView: typeof import('vue-router')['RouterView']
+  }
+}

+ 1 - 1
tsconfig.app.json

@@ -11,5 +11,5 @@
     "noFallthroughCasesInSwitch": true,
     "noUncheckedSideEffectImports": true
   },
-  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
+  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "src/types/*.d.ts"]
 }

+ 1 - 1
tsconfig.node.json

@@ -21,5 +21,5 @@
     "noFallthroughCasesInSwitch": true,
     "noUncheckedSideEffectImports": true
   },
-  "include": ["vite.config.ts"]
+  "include": ["vite.config.ts", "src/types/*.d.ts"]
 }

+ 38 - 5
vite.config.ts

@@ -1,7 +1,40 @@
-import { defineConfig } from 'vite'
-import vue from '@vitejs/plugin-vue'
-
+import { defineConfig, loadEnv, type ConfigEnv, type UserConfig } from 'vite'
+import { initVitePlugins } from './plugins'
+import { initProxy } from './plugins/proxy'
+import { resolve } from 'path'
+import { wrapperEnv } from './getEnv'
+const pathSrc = resolve(__dirname, 'src')
 // https://vite.dev/config/
-export default defineConfig({
-  plugins: [vue()],
+export default defineConfig(({ mode, command }: ConfigEnv): UserConfig => {
+  const root = process.cwd()
+  const env = loadEnv(mode, root)
+  const viteEnv = wrapperEnv(env)
+  return {
+    server: {
+      port: viteEnv.VITE_PORT,
+      open: viteEnv.VITE_OPEN,
+      proxy: initProxy(viteEnv.VITE_PROXY)
+    },
+    resolve: {
+      alias: {
+        '@': pathSrc
+      }
+    },
+    plugins: initVitePlugins(viteEnv, command === 'build'),
+    build: {
+      outDir: 'dist',
+      minify: 'esbuild',
+      sourcemap: false
+    },
+    css: {
+      preprocessorOptions: {
+        scss: {
+          additionalData: `@use "@/assets/styles/element/index.scss" as *;`
+        }
+      }
+    },
+    optimizeDeps: {
+      include: ['vue', 'vue-router', 'pinia', 'vue-i18n', 'axios', '@vueuse/core']
+    }
+  }
 })

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä