Pārlūkot izejas kodu

fix:基础数据

wyj0522 5 dienas atpakaļ
vecāks
revīzija
75c9329bca

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

@@ -5,8 +5,6 @@
     "ComputedRef": true,
     "DirectiveBinding": true,
     "EffectScope": true,
-    "ElMessage": true,
-    "ElMessageBox": true,
     "ExtractDefaultPropTypes": true,
     "ExtractPropTypes": true,
     "ExtractPublicPropTypes": true,

+ 46 - 0
src/api/interface/configs/configs.ts

@@ -0,0 +1,46 @@
+/**
+ * 查询参数
+ */
+export interface ConfigsQuery extends PageQuery {
+    id?: string
+    aircraftModel?: string
+    major?: string
+    status?: string
+    systems?: string
+    machineType?: string
+    statisticsDate?: string
+}
+
+/**
+ * 接收后端返回信息
+ */
+export interface ConfigsVO extends BaseEntity {
+    faultyPartsName: string
+    faultyPlace: string
+    faultyPhenomenon: string
+    status: string
+    major: string
+    findOpportunity: string
+    systems: string
+    installationTime: string
+    faultyReason:string
+    exclusionMethod:string
+    remark: string
+    createByName:string
+    createTime:string
+}
+export interface ConfigsBO{
+    faultyPartsName: string
+    faultyPlace: string
+    faultyPhenomenon: string
+    status: string
+    major: string
+    findOpportunity: string
+    systems: string
+    installationTime: string
+    faultyReason:string
+    exclusionMethod:string
+    remark: string
+    createByName:string
+    createTime:string
+}

+ 59 - 0
src/api/interface/construct/construct.ts

@@ -0,0 +1,59 @@
+/**
+ * 查询参数
+ */
+export interface ConstructQuery extends PageQuery {
+    id?: string
+    parentId?: string
+    configName?: string
+    aircraftNo?: string
+    configType?: string
+    configCode?: string
+    description?: string
+}
+
+/**
+ * 接收后端返回信息
+ */
+export interface ConstructVO extends BaseEntity {
+    id: string
+    parentId: string
+    faultyPhenomenon: string
+    status: string
+    aircraftNo: string
+    configType: string
+    configCode: string
+    description: string
+    remark: string
+    createByName:string
+    createTime:string
+    children: any
+}
+export interface ConstructBO{
+    id: string
+    model:string
+    system: string
+    aircraftSystem: string
+    component: string
+    countNumber:string
+}
+export interface ConstructBO{
+    id: string
+    model:string
+    system: string
+    aircraftSystem: string
+    component: string
+    countNumber:string
+}
+export interface ImportExcel{
+    id: string
+    model:string
+    system: string
+    aircraftSystem: string
+    component: string
+    countNumber:string
+}
+
+export interface updataBO{
+    id: string
+    countNum:string
+}

+ 48 - 0
src/api/module/configs/configs.ts

@@ -0,0 +1,48 @@
+import http from '@/axios'
+import { ConfigsBO, ConfigsQuery, ConfigsVO } from '@/api/interface/configs/configs'
+
+class ConfigApi {
+    /**
+     * @name 查询分页
+     * @returns returns
+     */
+    static page = (params: ConfigsQuery): Promise<ResultData<any>> => {
+        return http.get<ConfigsVO>({ url: '/fault/page', params })
+    }
+
+    /**
+     * @name 查询列表
+     * @returns returns
+     */
+    static list = (params: ConfigsBO): Promise<ResultData<any>> => {
+        return http.get<ConfigsVO>({ url: '/fault/list', params })
+    }
+
+    /**
+     * @name 添加
+     * @returns returns
+     */
+    static add = (data: ConfigsBO): Promise<ResultData<any>> => {
+        return http.post({ url: '/fault/add', data })
+    }
+    /**
+     * @name 更新
+     * @returns returns
+     */
+    static edit = (data: ConfigsBO): Promise<ResultData<any>> => {
+        return http.put({ url: '/fault/edit', data })
+    }
+
+    /**
+     * @name 删除
+     * @returns returns
+     */
+    static delete = (data: string[]): Promise<ResultData<any>> => {
+        return http.delete({ url: '/fault/delete', data })
+    }
+
+    static getExtraStatistics = (): Promise<ResultData<any>> => {
+        return http.get({ url: '/fault/extra/statistics' })
+    }
+}
+export default ConfigApi

+ 77 - 0
src/api/module/construct/Construct.ts

@@ -0,0 +1,77 @@
+import http from '@/axios'
+import {ConstructBO, ConstructVO, ConstructQuery, updataBO} from "@/api/interface/construct/construct";
+
+class ConstructApi {
+    /**
+     * @name 查询分页
+     * @returns returns
+     */
+    static page = (params: ConstructQuery): Promise<ResultData<any>> => {
+        return http.get<ConstructVO>({ url: '/construct/page', params })
+    }
+
+    /**
+     * @name 查询列表
+     * @returns returns
+     */
+    static selectOne = (params: ConstructBO): Promise<ResultData<any>> => {
+        return http.get<ConstructVO>({ url: '/construct/selectOne', params })
+    }
+    /**
+     * 查询树结构
+     * @param data 请求参数
+     * @returns Promise<ResultData<any>> 树结构数据
+     */
+    static tree = (data: ConstructBO): Promise<ResultData<any>> => {
+        return http.get<ResultData<any>>({ url: '/construct/tree', params: data });
+    };
+    /**
+     * @name 添加
+     * @returns returns
+     */
+    static add = (data: ConstructBO): Promise<ResultData<any>> => {
+        return http.post({ url: '/construct/add', data })
+    }
+    /**
+     * @name 更新
+     * @returns returns
+     */
+    static edit = (data: updataBO): Promise<ResultData<any>> => {
+        return http.put({ url: '/construct/edit', data })
+    }
+    /**
+     * @name 模板
+     * @returns returns
+     */
+    static template = (): Promise<ResultData<any>> => {
+        return http.post({ url: '/construct/template', responseType: 'blob' })
+    }
+    /**
+     * @name 导入
+     * @returns returns
+     */
+    static import = (data: FormData): Promise<ResultData<any>> => {
+        return http.post({ url: '/construct/import', data })
+    }
+    /**
+     * @name 导出
+     * @returns returns
+     */
+    static export = (data: ConstructBO): Promise<ResultData<any>> => {
+        return http.post({ url: '/construct/export', data,  responseType: 'blob'  })
+    }
+    /**
+     * @name 删除
+     * @returns returns
+     */
+    static delete = (data: string[]): Promise<ResultData<any>> => {
+        return http.delete({ url: '/construct/delete', data })
+    }
+
+    static getExtraStatistics = (): Promise<ResultData<any>> => {
+        return http.get({ url: '/construct/extra/statistics' })
+    }
+}
+
+
+export default ConstructApi

+ 152 - 0
src/components/importExcel/index.vue

@@ -0,0 +1,152 @@
+<template>
+  <el-dialog v-model="dialogVisible" :width="parameter.width" :top="parameter.top" :title="`${parameter.title}`" :destroy-on-close="true" draggable>
+    <el-upload
+      ref="uploadRef"
+      action="#"
+      class="upload"
+      :drag="true"
+      :auto-upload="false"
+      :limit="parameter.limit"
+      :multiple="parameter.multiple"
+      :show-file-list="true"
+      :http-request="uploadExcel"
+      :before-upload="beforeExcelUpload"
+      :on-exceed="handleExceed"
+      :on-success="excelUploadSuccess"
+      :on-error="excelUploadError"
+      :accept="parameter.fileType!.join(',')">
+      <slot name="empty">
+        <el-icon class="el-icon--upload">
+          <upload-filled />
+        </el-icon>
+        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
+      </slot>
+      <template #tip>
+        <slot name="tip">
+          <div class="el-upload__tip text-center">
+            <el-checkbox v-model="isCover">是否更新已存在的数据</el-checkbox>
+          </div>
+          <div class="el-upload__tip text-center">
+            请上传 .xls , .xlsx 标准格式文件,文件最大为 {{ parameter.fileSize }}M。
+            <el-link type="primary" underline="always" style="font-size: 12px; vertical-align: baseline" @click="downloadTemp"> 模板下载 </el-link>
+          </div>
+        </slot>
+      </template>
+    </el-upload>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button type="primary" @click="handleSubmit">确认</el-button>
+        <el-button @click="dialogVisible = false">取消</el-button>
+      </span>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup lang="ts" name="ImportExcel">
+import { useDownload } from '@/hooks/useDownload'
+import { ElNotification, UploadRequestOptions, UploadRawFile, UploadInstance } from 'element-plus'
+export interface ExcelParameterProps {
+  title: string // 标题
+  fileSize?: number // 上传文件的大小
+  limit?: number // 上传文件个数
+  top?: string // 离顶部距离
+  width?: number // 弹框宽度
+  multiple?: boolean // 是否支持多选文件
+  fileType?: File.ExcelMimeType[] // 上传文件的类型
+  tempApi?: (params: any) => Promise<any> // 下载模板的Api
+  importApi?: (params: any) => Promise<any> // 批量导入的Api
+  getTableList?: () => void // 获取表格数据的Api
+}
+
+// 是否覆盖数据
+const isCover = ref(false)
+// dialog状态
+const dialogVisible = ref(false)
+// 父组件传过来的参数
+const parameter = ref<ExcelParameterProps>({
+  title: '',
+  limit: 1,
+  width: 500,
+  top: '20vh',
+  multiple: false,
+  fileSize: 5,
+  fileType: ['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']
+})
+
+// 接收父组件参数
+const acceptParams = (params: ExcelParameterProps) => {
+  parameter.value = { ...parameter.value, ...params }
+  dialogVisible.value = true
+}
+
+// Excel 导入模板下载
+const downloadTemp = () => {
+  if (!parameter.value.tempApi) return
+  useDownload(parameter.value.tempApi, `${parameter.value.title}_template_${new Date().getTime()}`)
+}
+const uploadRef = ref<UploadInstance>()
+const handleSubmit = () => {
+  uploadRef.value!.submit()
+}
+
+// 文件上传
+const uploadExcel = async (param: UploadRequestOptions) => {
+  const formData = new FormData()
+  formData.append('file', param.file)
+  formData.append('isCover', isCover.value as unknown as Blob)
+  await parameter.value.importApi!(formData)
+  parameter.value.getTableList && parameter.value.getTableList()
+  dialogVisible.value = false
+}
+
+/**
+ * @description 文件上传之前判断
+ * @param file 上传的文件
+ * */
+const beforeExcelUpload = (file: UploadRawFile) => {
+  const isExcel = parameter.value.fileType!.includes(file.type as File.ExcelMimeType)
+  const fileSize = file.size / 1024 / 1024 < parameter.value.fileSize!
+  if (!isExcel)
+    ElNotification({
+      title: '温馨提示',
+      message: '上传文件只能是 xls / xlsx 格式!',
+      type: 'warning'
+    })
+  if (!fileSize)
+    setTimeout(() => {
+      ElNotification({
+        title: '温馨提示',
+        message: `上传文件大小不能超过 ${parameter.value.fileSize}MB!`,
+        type: 'warning'
+      })
+    }, 0)
+  return isExcel && fileSize
+}
+
+// 文件数超出提示
+const handleExceed = () => {
+  ElNotification({
+    title: '温馨提示',
+    message: '最多只能上传一个文件!',
+    type: 'warning'
+  })
+}
+
+// 上传错误提示
+const excelUploadError = () => {
+  ElNotification({
+    title: '温馨提示',
+    message: `批量添加${parameter.value.title}失败,请您重新上传!`,
+    type: 'error'
+  })
+}
+// 上传成功提示
+const excelUploadSuccess = () => {
+  dialogVisible.value = false
+}
+
+defineExpose({
+  acceptParams
+})
+</script>
+<style lang="scss" scoped></style>

+ 4 - 4
src/hooks/useDownload.ts

@@ -24,7 +24,7 @@ export const useDownload = async (
   if (isNotify) {
     ElNotification({
       title: '温馨提示',
-      message: '如果数据庞大会导致下载缓慢,请您耐心等待!',
+      message: '如果数据庞大会导致下载缓慢,请您耐心等待!',
       type: 'info',
       duration: 3000
     })
@@ -38,11 +38,11 @@ export const useDownload = async (
     checkStatus(rspObj.code)
   }
   try {
-    const data = await api(params)
+    const {data} = await api(params)
     const isBlob = await blobValidate(data)
     if (isBlob) {
-      const blob = fileType == 'zip' ? new Blob([data], { type: 'application/zip' }) : new Blob([data])
-      const name = fileType == 'zip' ? fileName : `${tempName}_${new Date().getTime()}${fileType}`
+      const blob = new Blob([data])
+      const name = fileName || `${tempName}_${new Date().getTime()}${fileType}`
       saveAsFn(blob, name, null)
       console.log('%s ====>>>导出成功', tempName)
     } else {

+ 1 - 0
src/types/auto-components.d.ts

@@ -73,6 +73,7 @@ declare module 'vue' {
     Grid: typeof import('./../components/Grid/index.vue')['default']
     GridItem: typeof import('./../components/Grid/GridItem.vue')['default']
     IconChoose: typeof import('./../components/IconChoose/index.vue')['default']
+    ImportExcel: typeof import('./../components/importExcel/index.vue')['default']
     Loading: typeof import('./../components/Loading/index.vue')['default']
     MenuDrawer: typeof import('./../views/system/menu/components/MenuDrawer.vue')['default']
     MoreButton: typeof import('./../layouts/components/AppTabs/MoreButton.vue')['default']

+ 602 - 621
src/types/auto-imports.d.ts

@@ -6,329 +6,312 @@
 // biome-ignore lint: disable
 export {}
 declare global {
-  const EffectScope: (typeof import('vue'))['EffectScope']
-  const ElMessage: (typeof import('element-plus/es'))['ElMessage']
-  const ElMessageBox: (typeof import('element-plus/es'))['ElMessageBox']
-  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']
+  const EffectScope: typeof import('vue')['EffectScope']
+  const ElMessage: typeof import('element-plus/es')['ElMessage']
+  const ElMessageBox: typeof import('element-plus/es')['ElMessageBox']
+  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'
+  export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
   import('vue')
 }
 
@@ -337,306 +320,304 @@ import { UnwrapRef } from 'vue'
 declare module 'vue' {
   interface GlobalComponents {}
   interface ComponentCustomProperties {
-    readonly EffectScope: UnwrapRef<(typeof import('vue'))['EffectScope']>
-    readonly ElMessage: UnwrapRef<(typeof import('element-plus/es'))['ElMessage']>
-    readonly ElMessageBox: UnwrapRef<(typeof import('element-plus/es'))['ElMessageBox']>
-    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']>
+    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']>
   }
-}
+}

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

@@ -45,7 +45,29 @@ declare interface BaseEntity {
   updateBy?: string
   updateTime?: any
 }
+/* FileType */
+declare namespace File {
+  type FileUploadType = 'img-upload-s3' | 'img-upload' | 'file-upload-s3' | 'file-upload'
+  type ImageMimeType =
+      | 'image/apng'
+      | 'image/bmp'
+      | 'image/gif'
+      | 'image/jpeg'
+      | 'image/pjpeg'
+      | 'image/png'
+      | 'image/svg+xml'
+      | 'image/tiff'
+      | 'image/webp'
+      | 'image/x-icon'
 
+  type ExcelMimeType = 'application/vnd.ms-excel' | 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+  type WordMimeType = 'application/msword' | 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
+  type PdfMimeType = 'application/pdf'
+  type PptMimeType = 'application/vnd.ms-powerpoint' | 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
+  type TxtMimeType = 'text/plain'
+  type ZipMimeType = 'application/zip'
+  type FileMimeType = ExcelMimeType | WordMimeType | PdfMimeType | PptMimeType | TxtMimeType | ZipMimeType
+}
 // 分页请求参数
 declare interface PageQuery {
   pageNum: number

+ 290 - 0
src/utils/data.ts

@@ -0,0 +1,290 @@
+class DateTimeUtils {
+
+
+    /**
+     * 计算指定日期往前推指定月数后的日期
+     * @param dateStr 格式为"YYYY-MM"的日期字符串
+     * @param months 要往前推的月数
+     * @param format
+     * @returns 往前推指定月数后的日期,格式为"YYYY-MM"
+     * @example DateTimeUtils.subtractMonths("2023-10", 12) => "2022-10"
+     */
+    static subtractMonths(dateStr: string, months: number,format: string): string {
+        // 解析输入日期
+        const [year, month] = dateStr.split('-').map(Number);
+        if (isNaN(year) || isNaN(month) || month < 1 || month > 12) {
+            throw new Error(`Invalid date format: ${dateStr}. Expected "YYYY-MM"`);
+        }
+
+        // 创建日期对象
+        const date = new Date(year, month - 1, 1); // 月份从0开始
+
+        // 向前推指定月数
+        const newDate = this.subtract(date, months, 'month');
+        // 格式化结果
+        return this.format(newDate, format);
+    }
+    /**
+     * 格式化日期时间
+     * @param date 日期对象或时间戳
+     * @param format 格式化字符串,例如:'yyyy-MM-dd HH:mm:ss'
+     * @returns 格式化后的日期时间字符串
+     */
+    static format(date: Date | number, format: string): string {
+        if (typeof date === 'number') {
+            date = new Date(date);
+        }
+
+        if (!(date instanceof Date) || isNaN(date.getTime())) {
+            throw new Error('Invalid date');
+        }
+
+        const year = date.getFullYear();
+        const month = date.getMonth() + 1;
+        const day = date.getDate();
+        const hour = date.getHours();
+        const minute = date.getMinutes();
+        const second = date.getSeconds();
+
+        // 补零函数
+        const pad = (num: number): string => num.toString().padStart(2, '0');
+
+        return format
+            .replace('yyyy', year.toString())
+            .replace('MM', pad(month))
+            .replace('dd', pad(day))
+            .replace('HH', pad(hour))
+            .replace('mm', pad(minute))
+            .replace('ss', pad(second));
+    }
+
+    /**
+     * 解析日期时间字符串
+     * @param dateString 日期时间字符串
+     * @returns 日期对象
+     */
+    static parse(dateString: string): Date {
+        const date = new Date(dateString);
+        if (isNaN(date.getTime())) {
+            throw new Error('Invalid date string');
+        }
+        return date;
+    }
+
+    /**
+     * 获取相对时间(如:3分钟前,2天前)
+     * @param date 日期对象或时间戳
+     * @returns 相对时间字符串
+     */
+    static getRelativeTime(date: Date | number): string {
+        if (typeof date === 'number') {
+            date = new Date(date);
+        }
+
+        if (!(date instanceof Date) || isNaN(date.getTime())) {
+            throw new Error('Invalid date');
+        }
+
+        const now = new Date();
+        const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);
+
+        if (diffInSeconds < 60) {
+            return `${diffInSeconds}秒前`;
+        }
+
+        const diffInMinutes = Math.floor(diffInSeconds / 60);
+        if (diffInMinutes < 60) {
+            return `${diffInMinutes}分钟前`;
+        }
+
+        const diffInHours = Math.floor(diffInMinutes / 60);
+        if (diffInHours < 24) {
+            return `${diffInHours}小时前`;
+        }
+
+        const diffInDays = Math.floor(diffInHours / 24);
+        if (diffInDays < 30) {
+            return `${diffInDays}天前`;
+        }
+
+        const diffInMonths = Math.floor(diffInDays / 30);
+        if (diffInMonths < 12) {
+            return `${diffInMonths}个月前`;
+        }
+
+        const diffInYears = Math.floor(diffInMonths / 12);
+        return `${diffInYears}年前`;
+    }
+
+    /**
+     * 计算两个日期之间的差值
+     * @param date1 第一个日期
+     * @param date2 第二个日期
+     * @returns 包含年、月、日等差值的对象
+     */
+    static getDiff(date1: Date | number, date2: Date | number): {
+        years: number;
+        months: number;
+        days: number;
+        hours: number;
+        minutes: number;
+        seconds: number;
+    } {
+        if (typeof date1 === 'number') {
+            date1 = new Date(date1);
+        }
+        if (typeof date2 === 'number') {
+            date2 = new Date(date2);
+        }
+
+        if (!(date1 instanceof Date) || isNaN(date1.getTime()) ||
+            !(date2 instanceof Date) || isNaN(date2.getTime())) {
+            throw new Error('Invalid date');
+        }
+
+        // 确保date1在date2之后,以便计算正值差值
+        let laterDate = date1;
+        let earlierDate = date2;
+        if (date1.getTime() < date2.getTime()) {
+            laterDate = date2;
+            earlierDate = date1;
+        }
+
+        const diffInMs = laterDate.getTime() - earlierDate.getTime();
+        const diffInSeconds = Math.floor(diffInMs / 1000);
+        const diffInMinutes = Math.floor(diffInSeconds / 60);
+        const diffInHours = Math.floor(diffInMinutes / 60);
+        const diffInDays = Math.floor(diffInHours / 24);
+
+        // 计算年和月的差值(近似)
+        let years = laterDate.getFullYear() - earlierDate.getFullYear();
+        let months = laterDate.getMonth() - earlierDate.getMonth();
+
+        if (months < 0) {
+            years--;
+            months += 12;
+        }
+
+        // 调整天数计算(更精确但复杂,这里简化处理)
+        const days = diffInDays % 30;
+
+        return {
+            years,
+            months,
+            days,
+            hours: diffInHours % 24,
+            minutes: diffInMinutes % 60,
+            seconds: diffInSeconds % 60
+        };
+    }
+
+    /**
+     * 获取指定日期所在月份的第一天
+     * @param date 日期对象或时间戳
+     * @returns 该月第一天的日期对象
+     */
+    static getFirstDayOfMonth(date: Date | number): Date {
+        if (typeof date === 'number') {
+            date = new Date(date);
+        }
+
+        if (!(date instanceof Date) || isNaN(date.getTime())) {
+            throw new Error('Invalid date');
+        }
+
+        return new Date(date.getFullYear(), date.getMonth(), 1);
+    }
+
+    /**
+     * 获取指定日期所在月份的最后一天
+     * @param date 日期对象或时间戳
+     * @returns 该月最后一天的日期对象
+     */
+    static getLastDayOfMonth(date: Date | number): Date {
+        if (typeof date === 'number') {
+            date = new Date(date);
+        }
+
+        if (!(date instanceof Date) || isNaN(date.getTime())) {
+            throw new Error('Invalid date');
+        }
+
+        return new Date(date.getFullYear(), date.getMonth() + 1, 0);
+    }
+
+    /**
+     * 给日期增加指定的时间
+     * @param date 日期对象或时间戳
+     * @param amount 增加的数量
+     * @param unit 单位:'year', 'month', 'day', 'hour', 'minute', 'second'
+     * @returns 增加后的日期对象
+     */
+    static add(date: Date | number, amount: number, unit: 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second'): Date {
+        if (typeof date === 'number') {
+            date = new Date(date);
+        }
+
+        if (!(date instanceof Date) || isNaN(date.getTime())) {
+            throw new Error('Invalid date');
+        }
+
+        const newDate = new Date(date);
+
+        switch (unit) {
+            case 'year':
+                newDate.setFullYear(newDate.getFullYear() + amount);
+                break;
+            case 'month':
+                newDate.setMonth(newDate.getMonth() + amount);
+                break;
+            case 'day':
+                newDate.setDate(newDate.getDate() + amount);
+                break;
+            case 'hour':
+                newDate.setHours(newDate.getHours() + amount);
+                break;
+            case 'minute':
+                newDate.setMinutes(newDate.getMinutes() + amount);
+                break;
+            case 'second':
+                newDate.setSeconds(newDate.getSeconds() + amount);
+                break;
+            default:
+                throw new Error('Invalid unit');
+        }
+
+        return newDate;
+    }
+
+    /**
+     * 给日期减少指定的时间
+     * @param date 日期对象或时间戳
+     * @param amount 减少的数量
+     * @param unit 单位:'year', 'month', 'day', 'hour', 'minute', 'second'
+     * @returns 减少后的日期对象
+     */
+    static subtract(date: Date | number, amount: number, unit: 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second'): Date {
+        return this.add(date, -amount, unit);
+    }
+
+    /**
+     * 判断是否为闰年
+     * @param year 年份或日期对象
+     * @returns 是否为闰年
+     */
+    static isLeapYear(year: number | Date): boolean {
+        let yearNum: number;
+
+        if (year instanceof Date) {
+            yearNum = year.getFullYear();
+        } else if (typeof year === 'number') {
+            yearNum = year;
+        } else {
+            throw new Error('Invalid year');
+        }
+
+        return (yearNum % 4 === 0 && yearNum % 100 !== 0) || (yearNum % 400 === 0);
+    }
+}
+
+export default DateTimeUtils;

+ 67 - 11
src/views/models/configs/index.vue

@@ -1,14 +1,70 @@
 <template>
-  <!--  <div class="contrent-count">-->
-  <!--    <div class="count-header">-->
-  <!--        <span>{{1111111111}}</span>-->
-  <!--    </div>-->
-  <!--  </div>-->
-  <div>管理</div>
-</template>
-<!--<script>-->
+  <div class="table-box">
+    <ProTable ref="proTableRef" title="参数配置" row-key="id" :columns="columns" :search-columns="searchColumns" :request-api="getTableList">
+      <template #tableHeader>
+        <el-button type="primary" icon="Plus" @click="">計算</el-button>
+      </template>
 
-<!--</script>-->
-<!--<style>-->
+    </ProTable>
 
-<!--</style>-->
+  </div>
+</template>
+<script lang="tsx" setup name="Configs">
+import { defineProps } from 'vue';
+import ConfigApi from '@/api/module/configs/configs'
+import { ColumnProps, ProTableInstance, SearchProps } from '@/components/ProTable/interface'
+import { useDictOptions } from '@/hooks'
+import DateTimeUtils from "@/utils/data";
+import {ConfigsVO} from "@/api/interface/configs/configs";
+const aircraftNumList = useDictOptions('AIRCRAFT_NUM_ARRAY')
+interface Props {
+  model: string;
+  system:string;
+  aircraftSystem:string
+  component:string
+}
+const props = defineProps<Props>();
+const getTableList = (params: any) => {
+  let newParams = JSON.parse(JSON.stringify(params));
+  newParams.model = props.model;
+  newParams.system = props.system;
+  newParams.aircraftSystem = props.aircraftSystem;
+  newParams.component = props.component;
+  if(params.endTime!=null && newParams.dataNumber!=null){
+    newParams.endTime = DateTimeUtils.format(params.endTime,'yyyy-MM-dd')
+    newParams.upTime = DateTimeUtils.subtractMonths(newParams.endTime,newParams.dataNumber,'yyyy-MM-dd')
+  }
+  console.log('params',aircraftNumList)
+  delete newParams.dataNumber;
+  return ConfigApi.page(newParams);
+};
+const proTableRef = ref<ProTableInstance>()
+const columns: ColumnProps<ConfigsVO>[] = [
+  { prop: 'faultyPartsName', label: '故障件名称', width: 200 },
+  { prop: 'faultyPlace', label: '故障发生地点', tag: true, width: 200 },
+  { prop: 'faultyPhenomenon', label: '故障现象' },
+  {
+    prop: 'status',
+    label: '状态',
+    tag: true,
+    enum: useDictOptions('COMMON_STATUS'),
+    width: 80,
+    fieldNames: { label: 'dictLabel', value: 'dictValue', tagType: 'callbackShowStyle' }
+  },
+  { prop: 'major', label: '专业', width: 80 },
+  { prop: 'findOpportunity', label: '发现时机' },
+  { prop: 'systems', label: '创建人' },
+  { prop: 'installationTime', label: '故障件装本机工作时次' },
+  { prop: 'faultyReason', label: '故障原因' },
+  { prop: 'exclusionMethod', label: '排除方法' },
+  { prop: 'remark', label: '说明' },
+  { prop: 'createTime', label: '创建时间' },
+]
+const searchColumns: SearchProps[] = [
+  { prop: 'endTime', label: '时间', el: 'date-picker', },
+  { prop: 'dataNumber', label: '月数', el: 'input' },
+  { prop: 'faultyPartsName', label: '故障件名称', el: 'input' },
+  { prop: 'aircraftNum', label: '飞机号码', el: 'select', enum: useDictOptions('AIRCRAFT_NUM_ARRAY').value,
+    fieldNames: { label: 'dictLabel', value: 'dictValue' }}
+]
+</script>

+ 367 - 0
src/views/models/conponents/ImportExportComponent.vue

@@ -0,0 +1,367 @@
+<template>
+  <div class="import-export-toolbar">
+    <!-- 下载模板按钮 -->
+    <el-button
+        v-if="showDownloadTemplate"
+        type="primary"
+        icon="Download"
+        @click="handleDownloadTemplate"
+        :loading="downloadLoading"
+        size="small"
+        class="operation-btn"
+    >
+      下载模板
+    </el-button>
+
+    <!-- 导入按钮与上传组件 -->
+    <el-upload
+        v-if="showImport"
+        class="import-upload"
+        :headers="headers"
+        :show-file-list="false"
+        :on-success="handleImportSuccess"
+        :on-error="handleImportError"
+        :before-upload="beforeImport"
+        :http-request="customImportRequest"
+        accept=".xlsx,.xls"
+    >
+      <el-button
+          type="success"
+          icon="Upload"
+          :loading="importLoading"
+          size="small"
+          class="operation-btn"
+      >
+        导入数据
+      </el-button>
+    </el-upload>
+
+    <!-- 导出按钮 -->
+    <el-button
+        v-if="showExport"
+        type="warning"
+        icon="Document"
+        @click="handleExport"
+        :loading="exportLoading"
+        size="small"
+        class="operation-btn"
+    >
+      导出数据
+    </el-button>
+
+    <!-- 导入结果对话框 -->
+    <el-dialog
+        v-model="importResultVisible"
+        title="导入结果"
+        width="500px"
+    >
+      <div class="result-stats">
+        <div v-if="importSuccessCount > 0" class="success-stat">
+          <i class="el-icon-success" />
+          成功导入: {{ importSuccessCount }} 条数据
+        </div>
+        <div v-if="importErrorCount > 0" class="error-stat">
+          <i class="el-icon-error" />
+          导入失败: {{ importErrorCount }} 条数据
+        </div>
+      </div>
+
+      <div v-if="importErrors.length > 0" class="error-details">
+        <h4>错误详情:</h4>
+        <el-scrollbar height="200px">
+          <ul>
+            <li v-for="(error, index) in importErrors" :key="index" class="error-item">
+              {{ error }}
+            </li>
+          </ul>
+        </el-scrollbar>
+      </div>
+
+      <template #footer>
+        <el-button @click="importResultVisible = false">关闭</el-button>
+        <el-button
+            v-if="importErrorCount > 0"
+            type="primary"
+            @click="downloadErrorLog"
+        >
+          下载错误日志
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, computed, onMounted } from 'vue';
+import { ElMessage, ElNotification } from 'element-plus';
+import axios, { AxiosRequestConfig } from 'axios';
+import type { UploadRequestOptions, UploadRawFile } from 'element-plus';
+import {useUserStore} from "@/stores";
+
+// 定义组件的props
+const props = defineProps<{
+  baseApi: string;
+  exportParams?: Record<string, any>;
+  isCover?: boolean;
+  showDownloadTemplate?: boolean;
+  showImport?: boolean;
+  showExport?: boolean;
+  // 按钮尺寸
+  size?: 'mini' | 'small' | 'medium' | 'large';
+}>();
+
+// 默认值处理
+const {
+  showDownloadTemplate = true,
+  showImport = true,
+  showExport = true,
+  isCover = false,
+  size = 'small'
+} = props;
+// 状态管理
+const downloadLoading = ref(false);
+const importLoading = ref(false);
+const exportLoading = ref(false);
+const importResultVisible = ref(false);
+const importSuccessCount = ref(0);
+const importErrorCount = ref(0);
+const importErrors = ref<string[]>([]);
+const errorLogUrl = ref('');
+const templateUrl = computed(() => `/dev-api${props.baseApi}/template`);
+const importUrl = computed(() => `/dev-api${props.baseApi}/import`);
+const exportUrl = computed(() => `/dev-api${props.baseApi}/export`);
+const userStore = useUserStore()
+// 构建请求头(包含认证信息)
+const headers = computed(() => {
+  return {
+    Authorization: `Bearer ${userStore.token}`,
+    clientId: import.meta.env.VITE_APP_CLIENT_ID
+  };
+});
+// 获取认证请求配置
+const getAuthConfig = (responseType: AxiosRequestConfig['responseType'] = 'json'): AxiosRequestConfig => {
+  const token = localStorage.getItem('token') || '';
+  return {
+    headers: {
+      Authorization: `Bearer ${userStore.token}`,
+      clientId: import.meta.env.VITE_APP_CLIENT_ID
+    },
+    responseType
+  };
+};
+// 下载模板处理函数
+const handleDownloadTemplate = async () => {
+    downloadLoading.value = true;
+    const response = await axios.post(
+        templateUrl.value,
+        {},
+        getAuthConfig('blob')
+    );
+    // 处理文件下载
+    handleFileDownload(response, '参数配置模板.xlsx');
+    ElMessage.success('模板下载成功');
+};
+
+// 导入前的校验
+const beforeImport = (file: UploadRawFile) => {
+  const fileExt = file.name.split('.').pop()?.toLowerCase();
+  if (!['xlsx', 'xls'].includes(fileExt || '')) {
+    ElMessage.error('请上传Excel文件(.xlsx或.xls格式)');
+    return false;
+  }
+
+  const fileSizeMB = file.size / 1024 / 1024;
+  if (fileSizeMB > 10) {
+    ElMessage.error('上传文件大小不能超过10MB');
+    return false;
+  }
+
+  return true;
+};
+// 自定义导入请求(因为需要额外参数isCover)
+const customImportRequest = async (options: UploadRequestOptions) => {
+  if (!options.file) return;
+
+  importLoading.value = true;
+
+    const formData = new FormData();
+    formData.append('file', options.file);
+    formData.append('isCover', props.isCover ? 'true' : 'false');
+    await axios.post(importUrl.value, formData, {
+      headers: {
+        Authorization: `Bearer ${userStore.token}`,
+        clientId: import.meta.env.VITE_APP_CLIENT_ID
+      }
+    });
+};
+
+// 处理导入成功
+const handleImportSuccess = (response: any) => {
+  importLoading.value = false;
+
+  if (response && response.data) {
+    const result = response.data;
+    importSuccessCount.value = result.successCount || 0;
+    importErrorCount.value = result.errorCount || 0;
+    importErrors.value = result.errors || [];
+    errorLogUrl.value = result.errorLogUrl || '';
+
+    importResultVisible.value = true;
+
+    // 通知父组件刷新数据
+    emit('refreshData');
+
+    ElNotification.success({
+      title: '导入完成',
+      message: `成功导入 ${importSuccessCount.value} 条数据`
+    });
+  }
+};
+
+// 处理导入失败
+const handleImportError = (error: any) => {
+  importLoading.value = false;
+  console.error('导入失败:', error);
+  ElMessage.error(error.message || '导入数据失败,请检查文件格式和内容');
+};
+
+// 下载错误日志
+const downloadErrorLog = () => {
+  if (!errorLogUrl.value) {
+    ElMessage.warning('没有错误日志可下载');
+    return;
+  }
+
+  // 如果错误日志是URL
+  if (errorLogUrl.value.startsWith('http')) {
+    window.open(errorLogUrl.value, '_blank');
+    return;
+  }
+
+  // 如果错误日志是文件流(根据实际后端实现调整)
+  axios.get(errorLogUrl.value, getAuthConfig('blob'))
+      .then(response => {
+        handleFileDownload(response, '导入错误日志.xlsx');
+      })
+      .catch(error => {
+        console.error('下载错误日志失败:', error);
+        ElMessage.error('下载错误日志失败');
+      });
+};
+
+// 处理导出数据
+const handleExport = async () => {
+  try {
+    exportLoading.value = true;
+
+    const response = await axios.post(
+        exportUrl.value,
+        props.exportParams || {},
+        getAuthConfig('blob')
+    );
+
+    handleFileDownload(response, '参数配置.xlsx');
+    ElMessage.success('数据导出成功');
+  } catch (error) {
+    console.error('数据导出失败:', error);
+    ElMessage.error('数据导出失败,请稍后重试');
+  } finally {
+    exportLoading.value = false;
+  }
+};
+
+// 通用文件下载处理
+const handleFileDownload = (response: any, defaultFileName: string) => {
+  const blob = new Blob([response.data], {
+    type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+  });
+
+  // 尝试从响应头获取文件名
+  let fileName = defaultFileName;
+  const contentDisposition = response.headers['content-disposition'];
+  if (contentDisposition) {
+    try {
+      fileName = decodeURIComponent(
+          contentDisposition.split('filename=')[1].replace(/"/g, '')
+      );
+    } catch (e) {
+      console.warn('解析文件名失败,使用默认文件名');
+    }
+  }
+
+  // 创建下载链接
+  const url = window.URL.createObjectURL(blob);
+  const a = document.createElement('a');
+  a.href = url;
+  a.download = fileName;
+  document.body.appendChild(a);
+  a.click();
+
+  // 清理资源
+  window.URL.revokeObjectURL(url);
+  document.body.removeChild(a);
+};
+
+// 定义组件的事件
+const emit = defineEmits<{
+  (e: 'refreshData'): void;
+  (e: 'importSuccess', data: any): void;
+  (e: 'importError', error: any): void;
+}>();
+</script>
+
+<style scoped>
+.import-export-toolbar {
+  display: flex;
+  gap: 8px;
+  margin-bottom: 16px;
+  align-items: center;
+}
+
+.operation-btn {
+  transition: all 0.2s ease;
+}
+
+.operation-btn:hover {
+  transform: translateY(-1px);
+}
+
+.result-stats {
+  margin-bottom: 16px;
+}
+
+.success-stat {
+  color: #67c23a;
+  margin-bottom: 8px;
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.error-stat {
+  color: #f56c6c;
+  margin-bottom: 8px;
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.error-details {
+  border-top: 1px solid #eee;
+  padding-top: 16px;
+}
+
+.error-details h4 {
+  margin-top: 0;
+  margin-bottom: 12px;
+  color: #f56c6c;
+  font-size: 14px;
+}
+
+.error-item {
+  color: #606266;
+  padding: 4px 0;
+  border-bottom: 1px dashed #eee;
+  font-size: 13px;
+}
+</style>

+ 358 - 0
src/views/models/construct/construct.vue

@@ -0,0 +1,358 @@
+<template>
+  <div class="table-box">
+    <ProTable
+        ref="proTableRef"
+        title="结构数据管理"
+        row-key="id"
+        :pagination="false"
+        :indent="20"
+        :columns="columns"
+        :request-api="getTreeList"
+        :default-expand-all="defaultExpandAllKey">
+      <template #tableHeader>
+        <el-button type="primary" icon="Plus" @click="saveVisible = true">新增</el-button>
+        <el-button type="primary" v-auth="['system:config:import']" icon="Upload" plain @click="batchAdd">导入</el-button>
+        <el-button type="primary" v-auth="['system:config:export']" icon="Download" plain @click="batchExport">导出</el-button>
+        <el-button type="info" icon="Sort" @click="changeExpand"> 展开/折叠</el-button>
+      </template>
+      <template #configType="scope">
+        {{ getConfigLabel(scope.row.configType) }}
+      </template>
+      <!-- 数量列自定义插槽 -->
+      <template #countNum="scope">
+        <div v-if="scope.row.configType==='component'">
+          <div
+              v-if="!scope.row.editingQuantity"
+              @dblclick="handleQuantityDblClick(scope.row)"
+              class="quantity-cell"
+          >
+            {{ scope.row.countNum || 0 }}
+          </div>
+          <el-input
+              v-else
+              v-model="scope.row.countNum"
+              @blur="handleQuantityBlur(scope.row)"
+              @keyup.enter="handleQuantityBlur(scope.row)"
+              ref="quantityInputRef"
+              auto-focus
+          />
+        </div>
+        <div v-else></div>
+      </template>
+      <!-- 操作列 -->
+      <template #operation="{ row }">
+        <el-button type="primary" link icon="EditPen" @click="openDrawer('编辑', row)">查看故障信息</el-button>
+      </template>
+    </ProTable>
+    <el-dialog
+        v-model="saveVisible"
+        title="新增构型"
+        width="700"
+        :before-close="handleClose"
+    >
+      <el-form ref="formData" :model="form" :rules="rules" @submit.enter.prevent="saveSubmit" :inline="true" class="demo-form-inline" style="max-width: 600px;padding-left: 40px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="机型"  prop="model">
+              <el-input v-model="form.model"
+                        style="width: 240px"
+                        size="large"
+                        placeholder="请输入机型"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12"  >
+            <el-form-item label="系统" prop="system">
+              <el-input v-model="form.system"
+                        style="width: 240px"
+                        size="large"
+                        placeholder="请输入系统"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12"  >
+            <el-form-item label="子系统" prop="aircraftSystem">
+              <el-input v-model="form.aircraftSystem"
+                        style="width: 240px"
+                        size="large"
+                        placeholder="请输入子系统"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="部件"  prop="component">
+              <el-input v-model="form.component"
+                        style="width: 240px"
+                        size="large"
+
+                        placeholder="请输入部件"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="数量" prop="countNumber">
+              <el-input v-model="form.countNumber"
+                        style="width: 240px"
+                        size="large"
+                        placeholder="请输入部件数量"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="saveVisible = false">取消</el-button>
+          <el-button type="primary" @click="saveSubmit() ">
+            确定
+          </el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <el-dialog
+        v-model="dialogVisible"
+        title="故障详情信息"
+        width="1600"
+        :before-close="handleClose"
+    >
+      <ConfigTable
+          v-if="currentModel"
+          :model="currentModel"
+          :system="currentSystem"
+          :aircraftSystem="currentAircraftSystem"
+          :component="currentComponent"
+      />
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="dialogVisible = false">取消</el-button>
+          <el-button type="primary" @click="dialogVisible = false">
+            确定
+          </el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <ImportExcel ref="dialogRef" />
+  </div>
+
+</template>
+
+<script lang="tsx" setup name="ConstructTable">
+import {ref, nextTick} from 'vue'
+import {ColumnProps, ProTableInstance, SearchProps} from '@/components/ProTable/interface'
+import {useHandleData,useDownload} from '@/hooks'
+import {ConstructVO, ConstructBO, ConstructQuery, updataBO} from '@/api/interface/construct/construct' // 根据实际路径调整
+import ConstructApi from '@/api/module/construct/Construct'
+import ConfigTable from '@/views/models/configs/index.vue'
+import {FormInstance} from "element-plus";
+import ImportExcel from '@/components/importExcel/index.vue'
+// 扩展ConstructVO类型以支持编辑状态
+interface EditableConstructVO extends ConstructVO {
+  editingQuantity?: boolean; // 用于控制数量编辑状态
+}
+const form = reactive({
+  id: '',
+  model: '',
+  system: '',
+  aircraftSystem: '',
+  component: '',
+  countNumber: '',
+})
+const rules = reactive({
+  model: [{ required: true, message: '请填写所属机型名称' }],
+  system: [{ required: true, message: '请填所属系统名称' }],
+  aircraftSystem: [{ required: true, message: '请填所属子系统名称' }],
+  component: [{ required: true, message: '请填所属部件名称' }],
+  countNumber: [{ required: true, message: '请填所数量' }]
+})
+// 状态管理
+const defaultExpandAllKey = ref(true)
+const proTableRef = ref<ProTableInstance>()
+const quantityInputRef = ref<HTMLInputElement | null>(null)
+const currentModel = ref('')         // 当前机型
+const currentSystem = ref('')        // 当前系统
+const currentComponent= ref('')
+const currentAircraftSystem = ref('') // 当前子系统
+//故障信息弹窗
+const dialogVisible = ref(false);
+//新增弹窗
+const saveVisible = ref(false);
+// 表格列配置(添加了数量列)
+const columns: ColumnProps<EditableConstructVO[]>[] = [
+  {type: 'index', label: '序号', width: 100},
+  {prop: 'configName', label: '部件名称', align: 'left'},
+  {
+    prop: 'configType',
+    label: '类型',
+    slot: 'configType'
+  },
+  {
+    prop: 'countNum',
+    label: '数量',
+    slot: 'countNum',
+    width: 150,
+    align: 'center'
+  },
+  {prop: 'operation', label: '操作', fixed: 'right', slot: 'operation'}
+]
+
+const searchColumns: SearchProps[] = [
+  {prop: 'configCode', label: '机号', el: 'input'},
+  {prop: 'configName', label: '构型名称', el: 'input'}
+]
+const formData = ref<FormInstance>()
+//新增方法
+const saveSubmit = () => {
+  formData.value?.validate( valid => {
+    if (!valid) return
+    try {
+      ConstructApi.add(form).then(res=>{
+        if(res.code==='200'){
+          ElMessage.success({message: `新增构型成功!`})
+          saveVisible.value = false;  // 关闭弹窗
+        }else{
+          ElMessage.error({message: `新增构型失败!`})
+        }
+      })
+    } catch (error) {
+      console.log(error)
+    }
+  });
+}
+// 展开/折叠切换
+const changeExpand = () => {
+  defaultExpandAllKey.value = !defaultExpandAllKey.value
+  proTableRef.value?.refresh()
+}
+// 批量添加
+const dialogRef = ref<InstanceType<typeof ImportExcel> | null>(null)
+const batchAdd = () => {
+  const params = {
+    title: '系统参数',
+    tempApi: ConstructApi.template,
+    importApi: ConstructApi.import,
+    getTableList: proTableRef.value?.getTableList
+  }
+  dialogRef.value?.acceptParams(params)
+}
+const batchExport = () => {
+  ElMessageBox.confirm('确认导出构型参数数据?', '温馨提示', { type: 'warning' }).then(() =>
+      useDownload(ConstructApi.export, '构型参数配置', proTableRef.value?.searchParam)
+  )
+}
+const getTableList = (data: ConstructBO): Promise<ResultData<any>> => {
+  return ConstructApi.tree(data); // 实际API调用,返回Promise
+};
+// 获取类型标签
+const getConfigLabel = (type: string) => {
+  const configtypeMap: Record<string, string> = {
+    'model': '机型',
+    'system': '系统',
+    'aircraftSystem': '子系统',
+    'component': '部件'
+  }
+  return configtypeMap[type] || type
+}
+
+// 双击数量单元格进入编辑模式
+const handleQuantityDblClick = async (row: EditableConstructVO) => {
+  // 只允许编辑部件类型的数量
+  if (row.configType !== 'component') return;
+  console.log(row)
+  row.editingQuantity = true;
+  // 等待DOM更新后聚焦输入框
+  await nextTick();
+  (quantityInputRef.value as HTMLInputElement)?.focus();
+}
+
+// 数量输入框失焦或回车时保存
+const handleQuantityBlur = async (row: EditableConstructVO) => {
+  // 关闭编辑状态
+  row.editingQuantity = false;
+
+  // 验证输入值
+  if (row.countNum === undefined || row.countNum === null || row.countNum === '') {
+    row.countNum = '0';
+  }
+
+  // 调用API保存修改
+  try {
+    const data: updataBO = {
+      id: row.id,
+      countNum: row.countNum
+    }
+    await ConstructApi.edit(data);
+    // 可以添加成功提示
+  } catch (error) {
+    console.error('保存数量失败:', error);
+    // 可以添加失败提示并回滚值
+  }
+}
+
+// 获取表格数据
+const getTreeList = (data: ConstructBO): Promise<ResultData<any>> => {
+  return ConstructApi.tree(data); // 实际API调用,返回Promise
+};
+
+// 单行删除
+const deleteRow = async (row: EditableConstructVO) => {
+  await useHandleData(
+      ConstructApi.delete,
+      [row.id],
+      `删除【${row.faultyPhenomenon}】数据`
+  )
+  proTableRef.value?.getTableList()
+}
+
+// 打开抽屉
+const openDrawer = (title: string, row: Partial<EditableConstructVO> = {}) => {
+    findNames(row);
+    ConstructApi.selectOne({id:row.id}).then(res=>{
+      res.data.forEach(item=>{
+        findNames(item);
+      })
+    })
+  dialogVisible.value = true;
+}
+
+const findNames = (data) =>{
+  if(data.configType==='aircraftSystem'){
+    currentAircraftSystem.value = data.configName
+  }else if(data.configType==='system'){
+    currentSystem.value= data.configName
+  }else if(data.configType==='model'){
+    currentModel.value = data.configName
+  }else{
+    currentComponent.value= data.configName
+  }
+}
+
+const handleClose = (done: () => void) => {
+  ElMessageBox.confirm('确定关闭弹框?')
+      .then(() => {
+        done()
+      })
+      .catch(() => {
+        // catch error
+      })
+}
+</script>
+
+<style scoped>
+.quantity-cell {
+  padding: 5px 0;
+  cursor: default;
+  user-select: none;
+}
+
+/* 可以添加一些样式美化编辑状态 */
+:deep(.el-input) {
+  width: 80px;
+}
+
+.demo-form-inline .el-input {
+  --el-input-width: 220px;
+}
+
+.demo-form-inline .el-select {
+  --el-select-width: 220px;
+}
+</style>

+ 5 - 5
src/views/system/config/components/ConfigDrawer.vue

@@ -51,11 +51,11 @@ const commonStatus = useDictOptions('COMMON_STATUS')
 
 import { FormInstance } from 'element-plus'
 const rules = reactive({
-  name: [{ required: true, message: '请填写参数名称' }],
-  configKey: [{ required: true, message: '请填参数Key' }],
-  configValue: [{ required: true, message: '请填参数Value' }],
-  orderNum: [{ required: true, message: '排序不能为空' }],
-  status: [{ required: true, message: '状态不能为空' }]
+  name: [{ required: true, message: '请填写参数名称', trigger: 'blur' }],
+  configKey: [{ required: true, message: '请填参数Key', trigger: 'blur' }],
+  configValue: [{ required: true, message: '请填参数Value', trigger: 'blur' }],
+  orderNum: [{ required: true, message: '排序不能为空', trigger: 'blur' }],
+  status: [{ required: true, message: '状态不能为空', trigger: 'blur' }]
 })
 
 interface EcoDrawerProps {