Sfoglia il codice sorgente

refactor: 清理未使用的代码并调整 TypeScript 配置

- 移除多个组件中未使用的导入、变量和方法
- 禁用 TypeScript 的 noUnusedLocals 和 noUnusedParameters 规则以提升开发体验
- 添加 vite-plugin-svg-icons 虚拟模块的类型声明文件
- 统一代码格式,如引号和逗号风格
piks 4 ore fa
parent
commit
3960458961

+ 0 - 2
components.d.ts

@@ -29,13 +29,11 @@ declare module 'vue' {
     ElFormItem: typeof import('element-plus/es')['ElFormItem']
     ElIcon: typeof import('element-plus/es')['ElIcon']
     ElInput: typeof import('element-plus/es')['ElInput']
-    ElLink: typeof import('element-plus/es')['ElLink']
     ElMenu: typeof import('element-plus/es')['ElMenu']
     ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
     ElOption: typeof import('element-plus/es')['ElOption']
     ElPagination: typeof import('element-plus/es')['ElPagination']
     ElPopover: typeof import('element-plus/es')['ElPopover']
-    ElProgress: typeof import('element-plus/es')['ElProgress']
     ElRadio: typeof import('element-plus/es')['ElRadio']
     ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
     ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']

+ 82 - 88
src/components/Breadcrumb/index.vue

@@ -1,66 +1,60 @@
 <script setup lang="ts">
-import { computed } from 'vue'
-import { useRoute, useRouter } from 'vue-router'
-import { ArrowLeft } from '@element-plus/icons-vue'
-
-const route = useRoute()
-const router = useRouter()
-
-interface BreadcrumbItem {
-  title: string
-  path?: string
-  isCurrent?: boolean
-}
-
-const breadcrumbs = computed<BreadcrumbItem[]>(() => {
-  const matched = route.matched.filter(item => item.meta?.title)
-  const items: BreadcrumbItem[] = []
-
-  matched.forEach((item, index) => {
-    // 如果有父路由信息,先添加父路由
-    if (item.meta?.parentPath && item.meta?.parentTitle) {
-      // 检查是否已经添加过父路由
-      const parentExists = items.some(b => b.path === item.meta?.parentPath)
-      if (!parentExists) {
-        items.push({
-          title: item.meta.parentTitle as string,
-          path: item.meta.parentPath as string,
-          isCurrent: false
-        })
+  import { computed } from 'vue'
+  import { useRoute, useRouter } from 'vue-router'
+  const route = useRoute()
+  const router = useRouter()
+
+  interface BreadcrumbItem {
+    title: string
+    path?: string
+    isCurrent?: boolean
+  }
+
+  const breadcrumbs = computed<BreadcrumbItem[]>(() => {
+    const matched = route.matched.filter((item) => item.meta?.title)
+    const items: BreadcrumbItem[] = []
+
+    matched.forEach((item, index) => {
+      // 如果有父路由信息,先添加父路由
+      if (item.meta?.parentPath && item.meta?.parentTitle) {
+        // 检查是否已经添加过父路由
+        const parentExists = items.some((b) => b.path === item.meta?.parentPath)
+        if (!parentExists) {
+          items.push({
+            title: item.meta.parentTitle as string,
+            path: item.meta.parentPath as string,
+            isCurrent: false,
+          })
+        }
       }
-    }
 
-    // 添加当前路由
-    items.push({
-      title: item.meta?.title as string,
-      path: item.path,
-      isCurrent: index === matched.length - 1
+      // 添加当前路由
+      items.push({
+        title: item.meta?.title as string,
+        path: item.path,
+        isCurrent: index === matched.length - 1,
+      })
     })
-  })
-
-  return items
-})
 
-const canGoBack = computed(() => {
-  return window.history.length > 1
-})
-
-function goBack() {
-  router.back()
-}
+    return items
+  })
 
-function handleClick(item: BreadcrumbItem) {
-  if (item.isCurrent || !item.path) return
-  router.push(item.path)
-}
+  function handleClick(item: BreadcrumbItem) {
+    if (item.isCurrent || !item.path) return
+    router.push(item.path)
+  }
 </script>
 
 <template>
   <div class="breadcrumb-wrapper">
     <!-- <el-button v-if="canGoBack" class="back-btn" :icon="ArrowLeft" circle size="small" @click="goBack" /> -->
     <el-breadcrumb separator="/">
-      <el-breadcrumb-item v-for="item in breadcrumbs" :key="item.path"
-        :class="{ 'is-clickable': !item.isCurrent && item.path }" @click="handleClick(item)">
+      <el-breadcrumb-item
+        v-for="item in breadcrumbs"
+        :key="item.path"
+        :class="{ 'is-clickable': !item.isCurrent && item.path }"
+        @click="handleClick(item)"
+      >
         <span :class="{ 'current-title': item.isCurrent }">
           {{ item.title }}
         </span>
@@ -70,56 +64,56 @@ function handleClick(item: BreadcrumbItem) {
 </template>
 
 <style scoped lang="scss">
-.breadcrumb-wrapper {
-  display: flex;
-  align-items: center;
-  gap: 12px;
-  margin-bottom: 20px;
-}
-
-.back-btn {
-  border: none;
-  background: transparent;
-  color: var(--admin-text-secondary);
-
-  &:hover {
-    background: rgba(255, 255, 255, 0.1);
-    color: var(--admin-text-primary);
+  .breadcrumb-wrapper {
+    display: flex;
+    align-items: center;
+    gap: 12px;
+    margin-bottom: 20px;
   }
-}
 
-:deep(.el-breadcrumb) {
-  font-size: 14px;
+  .back-btn {
+    border: none;
+    background: transparent;
+    color: var(--admin-text-secondary);
 
-  .el-breadcrumb__item {
-    .el-breadcrumb__inner {
-      color: var(--admin-text-secondary);
+    &:hover {
+      background: rgba(255, 255, 255, 0.1);
+      color: var(--admin-text-primary);
     }
+  }
 
-    &.is-clickable {
+  :deep(.el-breadcrumb) {
+    font-size: 14px;
+
+    .el-breadcrumb__item {
       .el-breadcrumb__inner {
-        cursor: pointer;
-        transition: color 0.2s;
+        color: var(--admin-text-secondary);
+      }
+
+      &.is-clickable {
+        .el-breadcrumb__inner {
+          cursor: pointer;
+          transition: color 0.2s;
 
-        &:hover {
-          color: var(--el-color-primary);
+          &:hover {
+            color: var(--el-color-primary);
+          }
         }
       }
-    }
 
-    &:last-child {
-      .el-breadcrumb__inner {
-        color: var(--admin-text-primary);
+      &:last-child {
+        .el-breadcrumb__inner {
+          color: var(--admin-text-primary);
+        }
       }
     }
-  }
 
-  .el-breadcrumb__separator {
-    color: var(--admin-text-secondary);
+    .el-breadcrumb__separator {
+      color: var(--admin-text-secondary);
+    }
   }
-}
 
-.current-title {
-  font-weight: 500;
-}
+  .current-title {
+    font-weight: 500;
+  }
 </style>

+ 42 - 45
src/layout/index.vue

@@ -1,13 +1,10 @@
 <script setup lang="ts">
-import { computed } from 'vue'
-import SiderBar from './components/Sidebar/index.vue'
-import Header from './components/Header.vue'
-import AppMain from './components/AppMain.vue'
-import { useAppStore } from '@/store/modules/app'
+  import SiderBar from './components/Sidebar/index.vue'
+  import Header from './components/Header.vue'
+  import AppMain from './components/AppMain.vue'
+  import { useAppStore } from '@/store/modules/app'
 
-const appStore = useAppStore()
-
-const sidebarWidth = computed(() => appStore.sidebarCollapsed ? '64px' : '300px')
+  const appStore = useAppStore()
 </script>
 
 <template>
@@ -21,42 +18,42 @@ const sidebarWidth = computed(() => appStore.sidebarCollapsed ? '64px' : '300px'
 </template>
 
 <style lang="scss" scoped>
-.app-wrapper {
-  --sidebar-width: 300px;
-  display: grid;
-  width: 100%;
-  height: 100vh;
-  grid-template-columns: var(--sidebar-width) 1fr;
-  grid-template-rows: 88px 1fr;
-  grid-template-areas:
-    "sidebar header"
-    "sidebar main";
-  overflow: hidden;
-  transition: grid-template-columns 0.3s ease;
-
-  &.is-collapsed {
-    --sidebar-width: 64px;
+  .app-wrapper {
+    --sidebar-width: 300px;
+    display: grid;
+    width: 100%;
+    height: 100vh;
+    grid-template-columns: var(--sidebar-width) 1fr;
+    grid-template-rows: 88px 1fr;
+    grid-template-areas:
+      'sidebar header'
+      'sidebar main';
+    overflow: hidden;
+    transition: grid-template-columns 0.3s ease;
+
+    &.is-collapsed {
+      --sidebar-width: 64px;
+    }
+  }
+
+  .sidebar-container {
+    grid-area: sidebar;
+    border-right: 1px solid var(--admin-border-color);
+  }
+
+  .main-wrapper {
+    display: contents; // 让子元素直接参与 grid 布局
+  }
+
+  .header-container {
+    grid-area: header;
+    background-color: var(--admin-header-bg);
+    border-bottom: 1px solid var(--admin-border-color);
+  }
+
+  .main-container {
+    grid-area: main;
+    background-color: var(--admin-bg);
+    overflow: auto;
   }
-}
-
-.sidebar-container {
-  grid-area: sidebar;
-  border-right: 1px solid var(--admin-border-color);
-}
-
-.main-wrapper {
-  display: contents; // 让子元素直接参与 grid 布局
-}
-
-.header-container {
-  grid-area: header;
-  background-color: var(--admin-header-bg);
-  border-bottom: 1px solid var(--admin-border-color);
-}
-
-.main-container {
-  grid-area: main;
-  background-color: var(--admin-bg);
-  overflow: auto;
-}
 </style>

+ 5 - 0
src/types/svg-icons-register.d.ts

@@ -0,0 +1,5 @@
+// vite-plugin-svg-icons 虚拟模块类型声明
+declare module 'virtual:svg-icons-register' {
+  const script: string
+  export default script
+}

+ 72 - 68
src/views/sdk/components/ConnectionList.vue

@@ -1,25 +1,32 @@
 <template>
-  <TableCard :data="tableData" :columns="columns" v-model:page-no="queryParams.pageNo"
-    v-model:page-size="queryParams.pageSize" @change="handleChange" :total="total"
-    @selection-change="handleSelectionChange">
+  <TableCard
+    v-model:page-no="queryParams.pageNo"
+    v-model:page-size="queryParams.pageSize"
+    :data="tableData"
+    :columns="columns"
+    :total="total"
+    @change="handleChange"
+    @selection-change="handleSelectionChange"
+  >
     <template #toolbar-left>
       <el-button plain type="warning" size="large" @click="dialogForm.visible = true">
         <template #icon>
-          <SvgIcon iconClass="Harm" />
+          <SvgIcon icon-class="Harm" />
         </template>
         一键加入风险名单
       </el-button>
       <el-button plain type="danger" size="large">
         <template #icon>
-          <SvgIcon iconClass="Reduce-one" />
+          <SvgIcon icon-class="Reduce-one" />
         </template>
         一键加入黑名单
       </el-button>
       <el-button plain type="success" size="large">
         <template #icon>
-          <SvgIcon iconClass="Link-right" />
+          <SvgIcon icon-class="Link-right" />
         </template>
-        一键解除封禁名单</el-button>
+        一键解除封禁名单</el-button
+      >
       <el-button type="primary" :icon="Refresh" size="large" class="is-solid">刷新</el-button>
     </template>
     <template #toolbar-right>
@@ -36,76 +43,73 @@
       </el-tag>
     </template>
 
-
-    <template #column-operation="{ row }">
+    <template #column-operation>
       <el-button type="primary" link>编辑</el-button>
       <el-button type="danger" link>删除</el-button>
     </template>
   </TableCard>
 </template>
 <script setup lang="ts">
-import { CirclePlus, Delete, Refresh, Search, Upload } from '@element-plus/icons-vue'
-
-const dialogForm = reactive({
-  visible: false,
-})
-
-const state = reactive({
-  queryParams: {
-    pageNo: 1,
-    pageSize: 10,
-    searchKeyword: '',
-  },
-  total: 20,
-  tableData: [
-    {
-      id: 1,
-      instanceId: '123456',
-      protocolType: 'TCP',
-      sourceIp: '192.168.1.100',
-      sourcePort: 8080,
-      targetIp: '192.168.1.200',
-      targetPort: 8080,
-      enableStatus: '启用',
-      sourceIpMethod: '不获取',
-      priority: 1,
-      createTime: '2023-08-01 10:00:00',
-      updateTime: '2023-08-01 10:00:00'
-    }
-  ],
-  selectedList: [] as any[]
-})
+  import { Refresh, Upload } from '@element-plus/icons-vue'
 
+  const dialogForm = reactive({
+    visible: false,
+  })
 
-const columns = [
-  { type: 'selection', width: 55 },
-  { label: '设备ID', prop: 'id' },
-  { label: 'SDK版本', prop: 'instanceId' },
-  { label: '在线状态', prop: 'protocolType' },
-  { label: '调度状态', prop: 'sourceIp' },
-  { label: '请求次数', prop: 'sourcePort' },
-  { label: '设备IP', prop: 'targetIp' },
-  { label: '设备唯一ID', prop: 'enableStatus' },
-  { label: '客户备注', prop: 'sourceIpMethod' },
-  { label: '客户端地区', prop: 'priority', },
-  { label: '操作系统', prop: 'createTime' },
-  { label: '当前客户端版本号', prop: 'updateTime' },
-  { label: '上传流量汇总', prop: 'updateTime' },
-  { label: '下载流量汇总', prop: 'updateTime' },
-  { label: '创建时间', prop: 'updateTime' },
-  { label: '更新时间', prop: 'updateTime' },
-  { label: '操作', prop: 'operation', minWidth: 120, isAction: true }
-]
-function handleSelectionChange(selection: any[]) {
-  state.selectedList = selection
-}
+  const state = reactive({
+    queryParams: {
+      pageNo: 1,
+      pageSize: 10,
+      searchKeyword: '',
+    },
+    total: 20,
+    tableData: [
+      {
+        id: 1,
+        instanceId: '123456',
+        protocolType: 'TCP',
+        sourceIp: '192.168.1.100',
+        sourcePort: 8080,
+        targetIp: '192.168.1.200',
+        targetPort: 8080,
+        enableStatus: '启用',
+        sourceIpMethod: '不获取',
+        priority: 1,
+        createTime: '2023-08-01 10:00:00',
+        updateTime: '2023-08-01 10:00:00',
+      },
+    ],
+    selectedList: [] as any[],
+  })
 
-const handleChange = (val: any) => {
-  state.queryParams.pageNo = val.pageNo
-  state.queryParams.pageSize = val.pageSize
-}
+  const columns = [
+    { type: 'selection', width: 55 },
+    { label: '设备ID', prop: 'id' },
+    { label: 'SDK版本', prop: 'instanceId' },
+    { label: '在线状态', prop: 'protocolType' },
+    { label: '调度状态', prop: 'sourceIp' },
+    { label: '请求次数', prop: 'sourcePort' },
+    { label: '设备IP', prop: 'targetIp' },
+    { label: '设备唯一ID', prop: 'enableStatus' },
+    { label: '客户备注', prop: 'sourceIpMethod' },
+    { label: '客户端地区', prop: 'priority' },
+    { label: '操作系统', prop: 'createTime' },
+    { label: '当前客户端版本号', prop: 'updateTime' },
+    { label: '上传流量汇总', prop: 'updateTime' },
+    { label: '下载流量汇总', prop: 'updateTime' },
+    { label: '创建时间', prop: 'updateTime' },
+    { label: '更新时间', prop: 'updateTime' },
+    { label: '操作', prop: 'operation', minWidth: 120, isAction: true },
+  ]
+  function handleSelectionChange(selection: any[]) {
+    state.selectedList = selection
+  }
 
-const { queryParams, total, tableData } = toRefs(state)
+  const handleChange = (val: any) => {
+    state.queryParams.pageNo = val.pageNo
+    state.queryParams.pageSize = val.pageSize
+  }
 
+  const { queryParams, total, tableData } = toRefs(state)
 </script>
-<style lang="scss" scoped></style>
+<style lang="scss" scoped></style>

+ 82 - 65
src/views/sdk/components/ForwardRules.vue

@@ -1,16 +1,36 @@
 <template>
-  <TableCard :data="tableData" :columns="columns" v-model:page-no="queryParams.pageNo"
-    v-model:page-size="queryParams.pageSize" @change="handleChange" :total="total"
-    @selection-change="handleSelectionChange">
+  <TableCard
+    v-model:page-no="queryParams.pageNo"
+    v-model:page-size="queryParams.pageSize"
+    :data="tableData"
+    :columns="columns"
+    :total="total"
+    @change="handleChange"
+    @selection-change="handleSelectionChange"
+  >
     <template #toolbar-left>
-      <el-button type="primary" :icon="CirclePlus" size="large" class="is-solid"
-        @click="dialogForm.visible = true">添加</el-button>
-      <el-button type="primary" disabled :icon="Delete" size="large" class="is-solid">删除</el-button>
+      <el-button
+        type="primary"
+        :icon="CirclePlus"
+        size="large"
+        class="is-solid"
+        @click="dialogForm.visible = true"
+        >添加</el-button
+      >
+      <el-button type="primary" disabled :icon="Delete" size="large" class="is-solid"
+        >删除</el-button
+      >
       <el-button type="primary" :icon="Refresh" size="large" class="is-solid">刷新</el-button>
     </template>
     <template #toolbar-right>
-      <el-input :prefix-icon="Search" v-model="queryParams.searchKeyword" size="large" placeholder="请输入关键词搜索"
-        style="width: 300px" clearable />
+      <el-input
+        v-model="queryParams.searchKeyword"
+        :prefix-icon="Search"
+        size="large"
+        placeholder="请输入关键词搜索"
+        style="width: 300px"
+        clearable
+      />
       <el-button :icon="Search" type="primary" class="is-solid" size="large">搜索</el-button>
       <el-button :icon="Upload" type="primary" class="is-solid" size="large">导出</el-button>
     </template>
@@ -25,72 +45,69 @@
       </el-tag>
     </template>
 
-
-    <template #column-operation="{ row }">
+    <template #column-operation>
       <el-button type="primary" link>编辑</el-button>
       <el-button type="danger" link>删除</el-button>
     </template>
   </TableCard>
 </template>
 <script setup lang="ts">
-import { CirclePlus, Delete, Refresh, Search, Upload } from '@element-plus/icons-vue'
-
-const dialogForm = reactive({
-  visible: false,
-})
-
-const state = reactive({
-  queryParams: {
-    pageNo: 1,
-    pageSize: 10,
-    searchKeyword: '',
-  },
-  total: 20,
-  tableData: [
-    {
-      id: 1,
-      instanceId: '123456',
-      protocolType: 'TCP',
-      sourceIp: '192.168.1.100',
-      sourcePort: 8080,
-      targetIp: '192.168.1.200',
-      targetPort: 8080,
-      enableStatus: '启用',
-      sourceIpMethod: '不获取',
-      priority: 1,
-      createTime: '2023-08-01 10:00:00',
-      updateTime: '2023-08-01 10:00:00'
-    }
-  ],
-  selectedList: [] as any[]
-})
+  import { CirclePlus, Delete, Refresh, Search, Upload } from '@element-plus/icons-vue'
 
+  const dialogForm = reactive({
+    visible: false,
+  })
 
-const columns = [
-  { type: 'selection', width: 55 },
-  { label: '序号', prop: 'id' },
-  { label: '所属实例ID', prop: 'instanceId' },
-  { label: '协议类型', prop: 'protocolType' },
-  { label: '源IP', prop: 'sourceIp' },
-  { label: '源端口', prop: 'sourcePort' },
-  { label: '目标IP', prop: 'targetIp' },
-  { label: '规则启用状态', prop: 'enableStatus' },
-  { label: '源IP获取方式', prop: 'sourceIpMethod' },
-  { label: '优先级(数值越小优先级越高)', prop: 'priority', minWidth: 160 },
-  { label: '创建时间', prop: 'createTime' },
-  { label: '更新时间', prop: 'updateTime' },
-  { label: '操作', prop: 'operation', minWidth: 120, isAction: true }
-]
-function handleSelectionChange(selection: any[]) {
-  state.selectedList = selection
-}
+  const state = reactive({
+    queryParams: {
+      pageNo: 1,
+      pageSize: 10,
+      searchKeyword: '',
+    },
+    total: 20,
+    tableData: [
+      {
+        id: 1,
+        instanceId: '123456',
+        protocolType: 'TCP',
+        sourceIp: '192.168.1.100',
+        sourcePort: 8080,
+        targetIp: '192.168.1.200',
+        targetPort: 8080,
+        enableStatus: '启用',
+        sourceIpMethod: '不获取',
+        priority: 1,
+        createTime: '2023-08-01 10:00:00',
+        updateTime: '2023-08-01 10:00:00',
+      },
+    ],
+    selectedList: [] as any[],
+  })
 
-const handleChange = (val: any) => {
-  state.queryParams.pageNo = val.pageNo
-  state.queryParams.pageSize = val.pageSize
-}
+  const columns = [
+    { type: 'selection', width: 55 },
+    { label: '序号', prop: 'id' },
+    { label: '所属实例ID', prop: 'instanceId' },
+    { label: '协议类型', prop: 'protocolType' },
+    { label: '源IP', prop: 'sourceIp' },
+    { label: '源端口', prop: 'sourcePort' },
+    { label: '目标IP', prop: 'targetIp' },
+    { label: '规则启用状态', prop: 'enableStatus' },
+    { label: '源IP获取方式', prop: 'sourceIpMethod' },
+    { label: '优先级(数值越小优先级越高)', prop: 'priority', minWidth: 160 },
+    { label: '创建时间', prop: 'createTime' },
+    { label: '更新时间', prop: 'updateTime' },
+    { label: '操作', prop: 'operation', minWidth: 120, isAction: true },
+  ]
+  function handleSelectionChange(selection: any[]) {
+    state.selectedList = selection
+  }
 
-const { queryParams, total, tableData } = toRefs(state)
+  const handleChange = (val: any) => {
+    state.queryParams.pageNo = val.pageNo
+    state.queryParams.pageSize = val.pageSize
+  }
 
+  const { queryParams, total, tableData } = toRefs(state)
 </script>
-<style lang="scss" scoped></style>
+<style lang="scss" scoped></style>

+ 54 - 58
src/views/sdk/components/SDKModal.vue

@@ -1,6 +1,12 @@
 <template>
-  <el-dialog title="1" v-model="dialogVisible" width="50%">
-    <el-form ref="formRef" :model="formData" :rules="rules" label-position="top" class="instance-form">
+  <el-dialog v-model="dialogVisible" title="1" width="50%">
+    <el-form
+      ref="formRef"
+      :model="formData"
+      :rules="rules"
+      label-position="top"
+      class="instance-form"
+    >
       <el-row :gutter="24">
         <!-- 第1行 -->
         <el-col :span="12">
@@ -104,67 +110,57 @@
   </el-dialog>
 </template>
 <script setup lang="ts">
-import type { FormInstance, FormRules } from 'element-plus'
-const dialogVisible = defineModel<boolean>('visible', {
-  default: false
-})
-const formRef = ref<FormInstance>()
-
-const formData = reactive({
-  instanceId: '',
-  userId: '',
-  orderId: '',
-  instanceName: '',
-  instanceType: '',
-  noDataTimeout: '',
-  status: 1, // 1:正常 0:禁用
-  noHeartbeat: true,
-  enableLts: false,
-  autoReconnect: true,
-  flowLimit: '',
-  packetLimit: '',
-  maxConcurrency: '',
-  remark: ''
-})
-
-const rules = reactive<FormRules>({
-  userId: [{ required: true, message: '请选择所属用户', trigger: 'change' }],
-  orderId: [{ required: true, message: '请选择所属订单', trigger: 'change' }],
-  instanceName: [{ required: true, message: '请输入实例名称', trigger: 'blur' }]
-})
-
-
-const close = () => {
-  dialogVisible.value = false
-}
+  import type { FormInstance, FormRules } from 'element-plus'
+  const dialogVisible = defineModel<boolean>('visible', {
+    default: false,
+  })
+  const formRef = ref<FormInstance>()
 
-const confirm = () => {
-  dialogVisible.value = false
-}
+  const formData = reactive({
+    instanceId: '',
+    userId: '',
+    orderId: '',
+    instanceName: '',
+    instanceType: '',
+    noDataTimeout: '',
+    status: 1, // 1:正常 0:禁用
+    noHeartbeat: true,
+    enableLts: false,
+    autoReconnect: true,
+    flowLimit: '',
+    packetLimit: '',
+    maxConcurrency: '',
+    remark: '',
+  })
 
-const handleSubmit = async () => {
-  if (!formRef.value) return
-  await formRef.value.validate((valid, fields) => {
-    if (valid) {
-      console.log('提交的数据:', formData)
-      dialogVisible.value = false
-    } else {
-      console.log('校验失败:', fields)
-    }
+  const rules = reactive<FormRules>({
+    userId: [{ required: true, message: '请选择所属用户', trigger: 'change' }],
+    orderId: [{ required: true, message: '请选择所属订单', trigger: 'change' }],
+    instanceName: [{ required: true, message: '请输入实例名称', trigger: 'blur' }],
   })
-}
 
+  const handleSubmit = async () => {
+    if (!formRef.value) return
+    await formRef.value.validate((valid, fields) => {
+      if (valid) {
+        console.log('提交的数据:', formData)
+        dialogVisible.value = false
+      } else {
+        console.log('校验失败:', fields)
+      }
+    })
+  }
 </script>
 <style lang="scss" scoped>
-.switch-group {
-  display: flex;
-  justify-content: space-between;
-  gap: 16px;
+  .switch-group {
+    display: flex;
+    justify-content: space-between;
+    gap: 16px;
 
-  /* 让组内的 form-item 占满剩余空间 */
-  :deep(.el-form-item) {
-    flex: 1;
-    margin-bottom: 0; // 消除多余的底部边距
+    /* 让组内的 form-item 占满剩余空间 */
+    :deep(.el-form-item) {
+      flex: 1;
+      margin-bottom: 0; // 消除多余的底部边距
+    }
   }
-}
-</style>
+</style>

+ 6 - 16
tsconfig.app.json

@@ -2,28 +2,18 @@
   "extends": "@vue/tsconfig/tsconfig.dom.json",
   "compilerOptions": {
     "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
-    "types": [
-      "vite/client"
-    ],
+    "types": ["vite/client"],
     "baseUrl": ".",
     "paths": {
-      "@/*": [
-        "src/*"
-      ]
+      "@/*": ["src/*"]
     },
     /* Linting */
     "strict": true,
-    "noUnusedLocals": true,
-    "noUnusedParameters": true,
+    "noUnusedLocals": false,
+    "noUnusedParameters": false,
     "erasableSyntaxOnly": true,
     "noFallthroughCasesInSwitch": true,
     "noUncheckedSideEffectImports": true
   },
-  "include": [
-    "src/**/*.ts",
-    "src/**/*.tsx",
-    "src/**/*.vue",
-    "auto-imports.d.ts",
-    "src/main.ts"
-  ]
-}
+  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "auto-imports.d.ts", "src/main.ts"]
+}