Преглед изворни кода

[Feat 0000] 初版CAD viewer组件开发

houzekong пре 11 месеци
родитељ
комит
06ab458af1

+ 2 - 0
package.json

@@ -60,6 +60,8 @@
     "mky-svg": "^1.0.2",
     "mockjs": "^1.1.0",
     "moment": "^2.29.4",
+    "mxcad": "^1.0.195",
+    "mxdraw": "^0.1.263",
     "nprogress": "^0.2.0",
     "path-to-regexp": "^6.2.1",
     "pinia": "2.1.6",

+ 81 - 27
pnpm-lock.yaml

@@ -122,6 +122,12 @@ dependencies:
   moment:
     specifier: ^2.29.4
     version: 2.30.1
+  mxcad:
+    specifier: ^1.0.195
+    version: 1.0.195(three@0.162.0)
+  mxdraw:
+    specifier: ^0.1.263
+    version: 0.1.263(three@0.162.0)
   nprogress:
     specifier: ^0.2.0
     version: 0.2.0
@@ -207,14 +213,14 @@ dependencies:
     specifier: 3.5.13
     version: 3.5.13
   xgplayer:
-    specifier: ^3.0.13
-    version: 3.0.13(core-js@3.33.1)
+    specifier: ^3.0.14
+    version: 3.0.14(core-js@3.33.1)
   xgplayer-flv:
-    specifier: ^3.0.13
-    version: 3.0.13(core-js@3.33.1)(xgplayer@3.0.13)
+    specifier: ^3.0.14
+    version: 3.0.14(core-js@3.33.1)(xgplayer@3.0.14)
   xgplayer-hls:
-    specifier: ^3.0.13
-    version: 3.0.13(core-js@3.33.1)(xgplayer@3.0.13)
+    specifier: ^3.0.14
+    version: 3.0.14(core-js@3.33.1)(xgplayer@3.0.14)
   xss:
     specifier: ^1.0.14
     version: 1.0.14
@@ -2276,6 +2282,12 @@ packages:
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dev: true
 
+  /@fingerprintjs/fingerprintjs@4.2.2:
+    resolution: {integrity: sha512-scD+pDgNZW78LuFAr7ms2yxmDx2NWC4+K5iiOjPT2ZlTlHFbLsORUzLJI2rcKicxxLtHbvf3A7BU1drVr4iHGg==}
+    dependencies:
+      tslib: 2.6.2
+    dev: false
+
   /@fullcalendar/common@5.10.1:
     resolution: {integrity: sha512-EumKIJcQTvQdTs75/9dmeREFgjcRVWzqHJS1Xvlz5mNsmB+w9EINCHETRjChtAQg1WD/lTQyVj4sHsKO7vCMSw==, tarball: http://registry.npm.taobao.org/@fullcalendar/common/-/common-5.10.1.tgz}
     dependencies:
@@ -6815,6 +6827,12 @@ packages:
       batch-processor: 1.0.0
     dev: false
 
+  /element-resize-event-polyfill@1.0.5:
+    resolution: {integrity: sha512-HWjhWQIi8Ilw8YWyX5O4b7L2AIQE9SMP+LFoHrr6b1ZLIUIpqybA5eU3v2uWAnE0ptCxyLTT92IgLTehWldIfQ==}
+    dependencies:
+      resize-observer-polyfill: 1.5.1
+    dev: false
+
   /emittery@0.13.1:
     resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==, tarball: http://registry.npm.taobao.org/emittery/-/emittery-0.13.1.tgz}
     engines: {node: '>=12'}
@@ -7491,7 +7509,7 @@ packages:
     dev: false
 
   /eventemitter3@4.0.7:
-    resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==, tarball: http://registry.npm.taobao.org/eventemitter3/-/eventemitter3-4.0.7.tgz}
+    resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==}
 
   /eventemitter3@5.0.1:
     resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==, tarball: http://registry.npm.taobao.org/eventemitter3/-/eventemitter3-5.0.1.tgz}
@@ -9906,6 +9924,10 @@ packages:
     hasBin: true
     dev: true
 
+  /jquery@3.7.1:
+    resolution: {integrity: sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==}
+    dev: false
+
   /js-base64@2.6.4:
     resolution: {integrity: sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==, tarball: http://registry.npm.taobao.org/js-base64/-/js-base64-2.6.4.tgz}
     dev: true
@@ -10713,6 +10735,30 @@ packages:
     engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
     dev: true
 
+  /mxcad@1.0.195(three@0.162.0):
+    resolution: {integrity: sha512-bMQPRMt4jIHvHK4ixWUflHdZYri8u4zIYihA2UDyraLA1IYUeExgRNDtOocOsE/NfuH39L+xSDUtnpEIiS3zHQ==}
+    dependencies:
+      '@fingerprintjs/fingerprintjs': 4.2.2
+      iconv-lite: 0.6.3
+      mxdraw: 0.1.263(three@0.162.0)
+      threebox-plugin: 2.2.7
+    transitivePeerDependencies:
+      - three
+    dev: false
+
+  /mxdraw@0.1.263(three@0.162.0):
+    resolution: {integrity: sha512-pE25TfSc4y3dOCbpyPFHkfFz+UyZHV59yEqMZzYlPkYCUrpHjvbeeWz6A8j3rxzifLMMX2maPT8ocyzlZwuqHA==}
+    engines: {node: '>=6.0.0'}
+    peerDependencies:
+      three: ^0.113.2
+    dependencies:
+      element-resize-event-polyfill: 1.0.5
+      jquery: 3.7.1
+      lodash: 4.17.21
+      three: 0.162.0
+      three-gif-texture: 1.0.15
+    dev: false
+
   /nanoid@3.3.6:
     resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==}
     engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@@ -12807,10 +12853,18 @@ packages:
     resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==, tarball: http://registry.npm.taobao.org/text-table/-/text-table-0.2.0.tgz}
     dev: true
 
+  /three-gif-texture@1.0.15:
+    resolution: {integrity: sha512-GzTF6OtgdjqKOF+AtA0WgLguJ8/iqE5u9KQQadmgWLusM2ML82XvQJuoGD6MqQalC33prUeaf2zqTWCP8fR4rw==}
+    dev: false
+
   /three@0.162.0:
     resolution: {integrity: sha512-xfCYj4RnlozReCmUd+XQzj6/5OjDNHBy5nT6rVwrOKGENAvpXe2z1jL+DZYaMu4/9pNsjH/4Os/VvS9IrH7IOQ==}
     dev: false
 
+  /threebox-plugin@2.2.7:
+    resolution: {integrity: sha512-H87Nm4w1PfisHPHzavTGXlwIoJpx2+QU57GooQYIhF51lsg+U5A0KGf3Jrv/HWsLCGOwV2BTnv7UTLfpO1EccQ==}
+    dev: false
+
   /throat@6.0.2:
     resolution: {integrity: sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==, tarball: http://registry.npm.taobao.org/throat/-/throat-6.0.2.tgz}
     dev: false
@@ -14098,34 +14152,34 @@ packages:
     resolution: {integrity: sha512-ORT6ghCRk0mUVavMBxetcPzUPskS6NGfntzpWazJ86e+XU0uK4HwHfDhN/jKATiyInrOH5RwQo9SO/+DB8XeBw==, tarball: http://registry.npm.taobao.org/xe-utils/-/xe-utils-3.5.13.tgz}
     dev: false
 
-  /xgplayer-flv@3.0.13(core-js@3.33.1)(xgplayer@3.0.13):
-    resolution: {integrity: sha512-oRQyTCWgV9KKLqnQztkd5l2jChjVwqGSfjBYAN8330XtMCaMgek6WEdHF64C6vP3q72ZbnFvDmTyb3Uot5brHQ==}
+  /xgplayer-flv@3.0.14(core-js@3.33.1)(xgplayer@3.0.14):
+    resolution: {integrity: sha512-9mSBUbbzkJhFjQOaU8SvnEzDj4Y9tkHsW0IaIxCDi/DlDcHzSubdiuuTVNf1A5cgUSTnFHxwDJtzqVm6FhmTeg==}
     peerDependencies:
       core-js: '>=3.12.1'
       xgplayer: '>=3.0.1'
     dependencies:
       core-js: 3.33.1
       eventemitter3: 4.0.7
-      xgplayer: 3.0.13(core-js@3.33.1)
-      xgplayer-streaming-shared: 3.0.13(core-js@3.33.1)
-      xgplayer-transmuxer: 3.0.13(core-js@3.33.1)
+      xgplayer: 3.0.14(core-js@3.33.1)
+      xgplayer-streaming-shared: 3.0.14(core-js@3.33.1)
+      xgplayer-transmuxer: 3.0.14(core-js@3.33.1)
     dev: false
 
-  /xgplayer-hls@3.0.13(core-js@3.33.1)(xgplayer@3.0.13):
-    resolution: {integrity: sha512-bOS6ocB8FWRYdKhg08AL4a/QZGNplDE1H2OZJxvuF/DF6muokxIajWC3kyqzxxbGOkUSIdr4wtDiA5rfMV5SJg==}
+  /xgplayer-hls@3.0.14(core-js@3.33.1)(xgplayer@3.0.14):
+    resolution: {integrity: sha512-UiVDiDcIzQ6kiDZitbyXqRx5nX/Pi69S9Vfh5lc+6R8SsA2ZyvxWtGOQ6XfpZyXYHfl56JMbyNObOgMT1iRNLw==}
     peerDependencies:
       core-js: '>=3.12.1'
-      xgplayer: '>=3.0.0'
+      xgplayer: 3.0.14
     dependencies:
       core-js: 3.33.1
       eventemitter3: 4.0.7
-      xgplayer: 3.0.13(core-js@3.33.1)
-      xgplayer-streaming-shared: 3.0.13(core-js@3.33.1)
-      xgplayer-transmuxer: 3.0.13(core-js@3.33.1)
+      xgplayer: 3.0.14(core-js@3.33.1)
+      xgplayer-streaming-shared: 3.0.14(core-js@3.33.1)
+      xgplayer-transmuxer: 3.0.14(core-js@3.33.1)
     dev: false
 
-  /xgplayer-streaming-shared@3.0.13(core-js@3.33.1):
-    resolution: {integrity: sha512-ovNk439/+6uVpMBKDzKq00bXMrDX6s+YHVt/Nl1vpawlgM3IoHKxezBki2FETlXvMYXF4X42/KVtbM3qTd2ScA==}
+  /xgplayer-streaming-shared@3.0.14(core-js@3.33.1):
+    resolution: {integrity: sha512-XBXNjnMfFDl15kQfXNgmAkaDqRdN0PhxVFBm7+TezillpTdLmqj+HD90F6BargdZVJ4I20/YHYdb9qBg+hUDhg==}
     peerDependencies:
       core-js: '>=3.12.1'
     dependencies:
@@ -14133,8 +14187,8 @@ packages:
       eventemitter3: 4.0.7
     dev: false
 
-  /xgplayer-subtitles@3.0.13(core-js@3.33.1):
-    resolution: {integrity: sha512-VlcPg6Ne66mwB6uIlE6gT28WG9u2vugMuho0mVMsB/uQ+XOin5xtH3Jpf2Ewx5CTf3SRfg4VmqUCuuMT7Z1qJg==}
+  /xgplayer-subtitles@3.0.14(core-js@3.33.1):
+    resolution: {integrity: sha512-w6H1h+g3kOI477kv2QBRMZe3M/1dHLXttHBwq4LwKTPGVQ19fLIDGwkfn+HeKwe1ocGDaaq96bS+l+BadnP9TA==}
     peerDependencies:
       core-js: '>=3.12.1'
     dependencies:
@@ -14142,8 +14196,8 @@ packages:
       eventemitter3: 4.0.7
     dev: false
 
-  /xgplayer-transmuxer@3.0.13(core-js@3.33.1):
-    resolution: {integrity: sha512-xncc9HYIRK9glHpalQRXlfLoeJkoq7OimvhWZ+CXdJFWYNG2toHCI5ttSRs8R0nRm07X3sxkXzQUJcZy7y6qNA==}
+  /xgplayer-transmuxer@3.0.14(core-js@3.33.1):
+    resolution: {integrity: sha512-lMS2EwuA6tToCC4NuyJ5Ax0UDaaWU/YuaSkI/Bsj+vHkEzO42vgi2EerSPr91Moz05KhG/+4Vt8qMKUVFjhGTw==}
     peerDependencies:
       core-js: '>=3.12.1'
     dependencies:
@@ -14153,8 +14207,8 @@ packages:
       crypto-es: 1.2.7
     dev: false
 
-  /xgplayer@3.0.13(core-js@3.33.1):
-    resolution: {integrity: sha512-tHmwsB49J5mYuGd+JjaILoJB/m+M7F5BxwjBaAWJ/PIEtYuhN69rOkkdph2/pzAg4to1rhwMPVTklIoXYd6xKw==}
+  /xgplayer@3.0.14(core-js@3.33.1):
+    resolution: {integrity: sha512-TPS77hUIcM1zVx6FSpGG+OzfMwjwxxWihd+YxVx82DQ22QK60v8TXWSZlWISbmS1+fAlFneesvXDjwy60tC37w==}
     peerDependencies:
       core-js: '>=3.12.1'
     dependencies:
@@ -14163,7 +14217,7 @@ packages:
       delegate: 3.2.0
       downloadjs: 1.4.7
       eventemitter3: 4.0.7
-      xgplayer-subtitles: 3.0.13(core-js@3.33.1)
+      xgplayer-subtitles: 3.0.14(core-js@3.33.1)
     dev: false
 
   /xlsx@0.17.5:

BIN
public/model/mxweb/demo.mxweb


+ 4 - 0
src/components/CADViewer/index.ts

@@ -0,0 +1,4 @@
+import CADViewer from './src/CADViewer.vue';
+
+export { CADViewer };
+export * from './src/types';

+ 29 - 0
src/components/CADViewer/src/CADViewer.vue

@@ -0,0 +1,29 @@
+<template>
+  <div>
+    <OperationBar v-if="showOperations" :allowed-operations="allowedOperations" :denied-operations="deniedOperations" />
+    <BasicViewer class="w-100% cad-viewer__viewer" :style="{ height: `${height}px` }" />
+  </div>
+</template>
+<script setup lang="ts">
+  import OperationBar from './components/OperationBar.vue';
+  import { SupportedOperationName } from './types';
+  import BasicViewer from './components/BasicViewer.vue';
+
+  withDefaults(
+    defineProps<{
+      /** CAD viewer 的高度,注意不是整个组件的高度 */
+      height?: number;
+      showOperations?: boolean;
+      /** 设置允许展示的操作按钮,优先级高于 deniedOperations */
+      allowedOperations?: SupportedOperationName[];
+      /** 设置拒绝展示的操作按钮,优先级低于 allowedOperations */
+      deniedOperations?: SupportedOperationName[];
+    }>(),
+    {
+      height: 980,
+      showOperations: false,
+    }
+  );
+</script>
+
+<style scoped></style>

+ 26 - 0
src/components/CADViewer/src/components/BasicViewer.vue

@@ -0,0 +1,26 @@
+<template>
+  <!-- Viewer的宽/高等其他样式由使用者定义 -->
+  <div class="overflow-hidden">
+    <canvas id="cad_base_viewer"></canvas>
+  </div>
+</template>
+<script setup lang="ts">
+  import { onMounted } from 'vue';
+  import { createMxCad } from 'mxcad';
+
+  onMounted(() => {
+    // SharedArrayBuffer可以提供多个Worker共享一个内存块的功能,以增强性能
+    const mode = 'SharedArrayBuffer' in window ? '2d' : '2d-st';
+    createMxCad({
+      canvas: '#cad_base_viewer',
+      locateFile: (fileName) => {
+        console.log('debug fileName', fileName);
+        return new URL(`../../../../../node_modules/mxcad/dist/wasm/${mode}/${fileName}`, import.meta.url).href;
+      },
+      fontspath: new URL('../../../../../node_modules/mxcad/dist/fonts', import.meta.url).href,
+      fileUrl: new URL('/model/mxweb/demo.mxweb', import.meta.url).href,
+    });
+  });
+</script>
+
+<style scoped></style>

+ 26 - 0
src/components/CADViewer/src/components/OpenFile.vue

@@ -0,0 +1,26 @@
+<template>
+  <Upload
+    v-model:file-list="fileList"
+    accept=".mxweb, .dwg"
+    name="file"
+    action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
+    :show-upload-list="false"
+    :custom-request="customRequest"
+  >
+    <Button> 选择文件 </Button>
+  </Upload>
+</template>
+<script lang="ts" setup>
+  import { Upload, Button, message } from 'ant-design-vue';
+  import { ref } from 'vue';
+  import { MxCpp } from 'mxcad';
+  import type { UploadProps } from 'ant-design-vue';
+
+  const customRequest: UploadProps['customRequest'] = ({ file }) => {
+    if (typeof file === 'string') return message.warn('不支持所选择的文件', 2000);
+    const filePath = URL.createObjectURL(file);
+    MxCpp.getCurrentMxCAD().openWebFile(filePath);
+  };
+
+  const fileList = ref<UploadProps['fileList']>([]);
+</script>

+ 41 - 0
src/components/CADViewer/src/components/OperationBar.vue

@@ -0,0 +1,41 @@
+<template>
+  <div class="p-10px bg-#00000088">
+    <span v-for="item in operationList" :key="item.name" class="mr-5px">
+      <component :is="item.component" v-bind="item.prop" v-on="item.on">{{ item.alias }}</component>
+    </span>
+    <slot></slot>
+  </div>
+</template>
+<script setup lang="ts">
+  import { computed } from 'vue';
+  import { SupportedOperationName, SupportedOperation } from '../types';
+  import { operationMap } from '../operationMap';
+
+  const props = defineProps<{
+    /** 设置允许展示的操作项,优先级高于 deniedOperations */
+    allowedOperations?: SupportedOperationName[];
+    /** 设置拒绝展示的操作项,优先级低于 allowedOperations */
+    deniedOperations?: SupportedOperationName[];
+  }>();
+
+  // 筛选最终可以展示到页面上的操作项配置
+  const operationList = computed(() => {
+    if (props.allowedOperations) {
+      return props.allowedOperations.map((op) => {
+        return operationMap.get(op) as SupportedOperation;
+      });
+    }
+    if (props.deniedOperations) {
+      const list: SupportedOperation[] = [];
+      operationMap.forEach((val, key) => {
+        if (!props.deniedOperations?.includes(key)) {
+          list.push(val);
+        }
+      });
+      return list;
+    }
+    return [...operationMap.values()];
+  });
+</script>
+
+<style scoped></style>

+ 34 - 0
src/components/CADViewer/src/operationMap.ts

@@ -0,0 +1,34 @@
+import type { SupportedOperation, SupportedOperationName } from './types';
+import { MxCpp } from 'mxcad';
+import OpenFile from './components/OpenFile.vue';
+
+/** CAD Viewer 所支持的全部操作映射表 */
+const operationMap = new Map<SupportedOperationName, SupportedOperation>();
+
+// 打开 webmx 格式的 CAD 文件
+operationMap.set('open-file', {
+  name: 'open-file',
+  alias: '打开文件',
+  component: OpenFile,
+});
+
+operationMap.set('download-file', {
+  name: 'download-file',
+  alias: '导出文件',
+  component: 'a-button',
+  on: {
+    click() {
+      MxCpp.getCurrentMxCAD().saveFile();
+    },
+  },
+});
+
+export function add(opName: SupportedOperationName, operation: SupportedOperation) {
+  operationMap.set(opName, operation);
+}
+
+export function del(opName: SupportedOperationName) {
+  operationMap.delete(opName);
+}
+
+export { operationMap };

+ 13 - 0
src/components/CADViewer/src/types/index.ts

@@ -0,0 +1,13 @@
+import { Component } from 'vue';
+
+export type SupportedOperationName = 'open-file' | 'download-file';
+export type SupportedOperation = {
+  name: SupportedOperationName;
+  alias: string;
+  /** 操作项使用的组件 */
+  component: string | Component;
+  /** 操作项组件对应的 props,譬如组件为 AButton,prop 可以是 { type: 'primary' } */
+  prop?: any;
+  /** 操作项组件对应的事件,譬如组件为 AButton,on 可以是 { click: () => {} } */
+  on?: any;
+};

+ 1 - 1
src/views/vent/gas/gasHome/components/gasMonitor.vue

@@ -50,7 +50,7 @@
 <script setup lang="ts" name="gas-pump-monitor">
   import { ref, onMounted, defineProps } from 'vue';
   import ventBox1 from '/@/components/vent/ventBox1.vue';
-  import ListItem from '@/views/vent/gas/gasPumpMonitor/components/listItem.vue';
+  import ListItem from '@/views/vent/gas/components/list/listItem.vue';
 
   const props = defineProps({
     deviceId: {

+ 4 - 2
src/views/vent/gas/gasPumpMonitor/components/monitor.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="monitor-container">
+  <!-- <div class="monitor-container">
     <div class="lr left-box">
       <ventBox1>
         <template #title>
@@ -41,7 +41,8 @@
         </ventBox1>
       </div>
     </div>
-  </div>
+  </div> -->
+  <PumpForm />
 </template>
 
 <script setup lang="ts" name="gas-pump-monitor">
@@ -51,6 +52,7 @@
   import BaseTab from '@/views/vent/gas/components/tab/baseTab.vue';
   import Button from '@/views/vent/gas/components/form/button.vue';
   import CategoryBoard from '@/views/vent/gas/components/board/categoryBoard.vue';
+  import PumpForm from './pumpForm.vue';
   import {
     pumpListConfig,
     pumpStationListConfig,

+ 3 - 3
src/views/vent/gas/gasPumpMonitor/components/pumpForm.vue

@@ -4,7 +4,7 @@
       <FormTitle icon="gas-pump" title="工作面参数" />
       <BasicForm :schemas="workSurfaceFormSchema" @register="regWSForm" @submit="submitHandler">
         <template #input="{ model, field, schema }">
-          <ListItem class="w-100%" v-model:value="model[field]" type="input" :label="schema.label" bordered />
+          <ListItem class="w-100%" v-model:value="model[field]" type="input" :label="schema.label" bordered :label-width="200" />
         </template>
       </BasicForm>
     </div>
@@ -12,7 +12,7 @@
       <FormTitle icon="pump" title="抽采单元参数" />
       <BasicForm :schemas="extractionUnitFormSchema" @register="regEUForm" @submit="submitHandler">
         <template #input="{ model, field, schema }">
-          <ListItem class="w-100%" v-model:value="model[field]" type="input" :label="schema.label" bordered />
+          <ListItem class="w-100%" v-model:value="model[field]" type="input" :label="schema.label" bordered :label-width="200" />
         </template>
       </BasicForm>
     </div>
@@ -28,7 +28,7 @@
           </ListItem>
         </template>
         <template #input="{ model, field, schema }">
-          <ListItem class="w-100%" v-model:value="model[field]" type="input" :label="schema.label" bordered />
+          <ListItem class="w-100%" v-model:value="model[field]" type="input" :label="schema.label" bordered :label-width="200" />
         </template>
       </BasicForm>
     </div>

+ 2 - 2
src/views/vent/monitorManager/deviceMonitor/components/device/device.data.ts

@@ -63,9 +63,9 @@ export function getMonitorComponent() {
   const BundleModal = defineAsyncComponent(() => import('./modal/bundle.modal.vue'));
   const DustModal = defineAsyncComponent(() => import('./modal/dust.modal.vue'));
   const BallvalveModal = defineAsyncComponent(() => import('./modal/ballvalve.modal.vue'));
-  const AtomizingModal = defineAsyncComponent(() => import('./modal/atomizing.modal.vue'));
+  // const AtomizingModal = defineAsyncComponent(() => import('./modal/atomizing.modal.vue'));
 
-  return { FiberModal, BundleModal, DustModal, BallvalveModal, AtomizingModal };
+  return { FiberModal, BundleModal, DustModal, BallvalveModal, /** AtomizingModal */ };
 }
 
 // export const searchFormSchema: FormSchema[] = [