From 14763d895151f3ddad09906f2233057b8b967881 Mon Sep 17 00:00:00 2001
From: huang <1532065656@qq.com>
Date: 星期五, 19 十二月 2025 17:06:18 +0800
Subject: [PATCH] 添加plc通讯协议工厂,支持后续多种plc协议

---
 mes-web/src/views/device/components/DeviceLogicConfig/LoadVehicleConfig.vue |  167 ++++++++++++++++++++++++++-----------------------------
 1 files changed, 78 insertions(+), 89 deletions(-)

diff --git a/mes-web/src/views/device/components/DeviceLogicConfig/LoadVehicleConfig.vue b/mes-web/src/views/device/components/DeviceLogicConfig/LoadVehicleConfig.vue
index 5c2a3a7..e1b672b 100644
--- a/mes-web/src/views/device/components/DeviceLogicConfig/LoadVehicleConfig.vue
+++ b/mes-web/src/views/device/components/DeviceLogicConfig/LoadVehicleConfig.vue
@@ -9,6 +9,7 @@
             :max="10000"
             :step="100"
             style="width: 100%;"
+            @change="emitConfigUpdate"
           />
           <span class="form-tip">杞﹁締鏈�澶у閲�</span>
         </el-form-item>
@@ -22,6 +23,7 @@
             :step="0.1"
             :precision="1"
             style="width: 100%;"
+            @change="emitConfigUpdate"
           />
           <span class="form-tip">杞﹁締杩愬姩閫熷害锛岄粯璁�1鏍�/绉�</span>
         </el-form-item>
@@ -30,28 +32,16 @@
 
     <el-row :gutter="20">
       <el-col :span="12">
-        <el-form-item label="鐜荤拑闂撮殧(绉�)">
+        <el-form-item label="鐜荤拑闂撮殭(mm)">
           <el-input-number
-            v-model="glassIntervalSeconds"
-            :min="0.1"
-            :max="10"
-            :step="0.1"
-            :precision="1"
+            v-model="config.glassGap"
+            :min="0"
+            :max="1000"
+            :step="10"
             style="width: 100%;"
+            @change="emitConfigUpdate"
           />
-          <span class="form-tip">鐜荤拑涓婃枡闂撮殧鏃堕棿锛堢锛�</span>
-        </el-form-item>
-      </el-col>
-      <el-col :span="12">
-        <el-form-item label="榛樿鐜荤拑闀垮害(mm)">
-          <el-input-number
-            v-model="config.defaultGlassLength"
-            :min="100"
-            :max="10000"
-            :step="100"
-            style="width: 100%;"
-          />
-          <span class="form-tip">褰撶幓鐠冩湭鎻愪緵闀垮害鏃朵娇鐢ㄧ殑榛樿鍊�</span>
+          <span class="form-tip">澶氬潡鐜荤拑涔嬮棿鐨勭墿鐞嗛棿闅旂┖闅欙紝榛樿200mm</span>
         </el-form-item>
       </el-col>
     </el-row>
@@ -65,6 +55,7 @@
             :max="1000"
             :step="1"
             style="width: 100%;"
+            @change="emitConfigUpdate"
           />
           <span class="form-tip">杞﹁締鍒濆浣嶇疆锛堟牸瀛愶級</span>
         </el-form-item>
@@ -78,6 +69,7 @@
             :step="1"
             style="width: 40%;"
             placeholder="鏈�灏�"
+            @change="emitConfigUpdate"
           />
           <span style="margin: 0 2%;">~</span>
           <el-input-number
@@ -87,6 +79,7 @@
             :step="1"
             style="width: 40%;"
             placeholder="鏈�澶�"
+            @change="emitConfigUpdate"
           />
           <span class="form-tip">杩愬姩璺濈鑼冨洿锛堟牸瀛愶級</span>
         </el-form-item>
@@ -137,22 +130,8 @@
       </el-col>
       <el-col :span="12">
         <el-form-item label="鑷姩涓婃枡">
-          <el-switch v-model="config.autoFeed" />
+          <el-switch v-model="config.autoFeed" @change="emitConfigUpdate" />
           <span class="form-tip">鏄惁鑷姩瑙﹀彂涓婃枡璇锋眰</span>
-        </el-form-item>
-      </el-col>
-    </el-row>
-
-    <el-row :gutter="20">
-      <el-col :span="12">
-        <el-form-item label="鏈�澶ч噸璇曟鏁�">
-          <el-input-number
-            v-model="config.maxRetryCount"
-            :min="0"
-            :max="10"
-            :step="1"
-            style="width: 100%;"
-          />
         </el-form-item>
       </el-col>
     </el-row>
@@ -160,30 +139,31 @@
     <el-form-item label="浣嶇疆鏄犲皠">
       <div class="position-mapping">
         <div
-          v-for="(value, key, index) in config.positionMapping"
-          :key="index"
+          v-for="(item, index) in positionList"
+          :key="item.id"
           class="mapping-item"
         >
           <el-input
-            v-model="mappingKeys[index]"
-            placeholder="浣嶇疆浠g爜锛堝900/901锛�"
+            v-model="item.key"
+            placeholder="浣嶇疆浠g爜锛堝1001/1002锛�"
             size="small"
             style="width: 150px; margin-right: 10px;"
-            @input="updatePositionMapping(index, $event, value)"
+            @change="handlePositionKeyChange(index)"
           />
           <el-input-number
-            v-model="config.positionMapping[mappingKeys[index] || key]"
+            v-model="item.value"
             :min="0"
             :max="1000"
             :step="1"
             size="small"
             style="width: 120px; margin-right: 10px;"
             placeholder="浣嶇疆鍊硷紙鏍硷級"
+            @change="handlePositionValueChange(index)"
           />
           <el-button
             type="danger"
             size="small"
-            @click="removePositionMapping(key)"
+            @click="removePositionMapping(index)"
           >
             鍒犻櫎
           </el-button>
@@ -213,8 +193,7 @@
 const config = ref({
   vehicleCapacity: 6000,
   vehicleSpeed: 1.0,
-  glassIntervalMs: 1000,
-  defaultGlassLength: 2000,
+  glassGap: 200,
   homePosition: 0,
   minRange: 1,
   maxRange: 100,
@@ -222,15 +201,45 @@
   taskMonitorIntervalMs: 1000,
   mesConfirmTimeoutMs: 30000,
   autoFeed: true,
-  maxRetryCount: 5,
   positionMapping: {}
 })
 
-// 浣嶇疆鏄犲皠鐨勯敭鏁扮粍
-const mappingKeys = ref([])
+// 浣嶇疆鏄犲皠缂栬緫鍒楄〃
+const positionList = ref([])
+let suppressPositionSync = false
+let suppressEmit = false
+
+const emitConfigUpdate = () => {
+  if (suppressEmit) return
+  emit('update:modelValue', { ...config.value })
+}
+
+const syncPositionListFromConfig = () => {
+  suppressPositionSync = true
+  const entries = Object.entries(config.value.positionMapping || {})
+  positionList.value = entries.map(([key, value], idx) => ({
+    id: `${key}_${idx}_${Date.now()}`,
+    key,
+    value: value ?? 1
+  }))
+  suppressPositionSync = false
+}
+
+const applyPositionListToConfig = () => {
+  if (suppressPositionSync) return
+  const mapping = {}
+  positionList.value.forEach((item) => {
+    if (item.key && item.key.trim()) {
+      mapping[item.key.trim()] = item.value ?? 1
+    }
+  })
+  config.value.positionMapping = mapping
+  emitConfigUpdate()
+}
+
+syncPositionListFromConfig()
 
 // 鏃堕棿瀛楁锛堢锛�- 鐢ㄤ簬鍓嶇鏄剧ず鍜岃緭鍏�
-const glassIntervalSeconds = ref(1.0)
 const idleMonitorIntervalSeconds = ref(2.0)
 const taskMonitorIntervalSeconds = ref(1.0)
 const mesConfirmTimeoutSeconds = ref(30)
@@ -238,11 +247,11 @@
 // 鐩戝惉props鍙樺寲
 watch(() => props.modelValue, (newVal) => {
   if (newVal && Object.keys(newVal).length > 0) {
+    suppressEmit = true
     config.value = {
       vehicleCapacity: newVal.vehicleCapacity ?? 6000,
       vehicleSpeed: newVal.vehicleSpeed ?? 1.0,
-      glassIntervalMs: newVal.glassIntervalMs ?? 1000,
-      defaultGlassLength: newVal.defaultGlassLength ?? 2000,
+      glassGap: newVal.glassGap ?? 200,
       homePosition: newVal.homePosition ?? 0,
       minRange: newVal.minRange ?? 1,
       maxRange: newVal.maxRange ?? 100,
@@ -250,75 +259,55 @@
       taskMonitorIntervalMs: newVal.taskMonitorIntervalMs ?? 1000,
       mesConfirmTimeoutMs: newVal.mesConfirmTimeoutMs ?? 30000,
       autoFeed: newVal.autoFeed ?? true,
-      maxRetryCount: newVal.maxRetryCount ?? 5,
       positionMapping: newVal.positionMapping || {}
     }
     // 灏嗘绉掕浆鎹负绉掔敤浜庢樉绀�
-    glassIntervalSeconds.value = (config.value.glassIntervalMs ?? 1000) / 1000
     idleMonitorIntervalSeconds.value = (config.value.idleMonitorIntervalMs ?? 2000) / 1000
     taskMonitorIntervalSeconds.value = (config.value.taskMonitorIntervalMs ?? 1000) / 1000
     mesConfirmTimeoutSeconds.value = (config.value.mesConfirmTimeoutMs ?? 30000) / 1000
-    mappingKeys.value = Object.keys(config.value.positionMapping)
+    syncPositionListFromConfig()
+    suppressEmit = false
   }
 }, { immediate: true, deep: true })
 
 // 鐩戝惉绉掑瓧娈靛彉鍖栵紝杞崲涓烘绉掑苟鏇存柊config
-watch(glassIntervalSeconds, (val) => {
-  config.value.glassIntervalMs = Math.round(val * 1000)
-  emit('update:modelValue', { ...config.value })
-})
-
 watch(idleMonitorIntervalSeconds, (val) => {
   config.value.idleMonitorIntervalMs = Math.round(val * 1000)
-  emit('update:modelValue', { ...config.value })
+  emitConfigUpdate()
 })
 
 watch(taskMonitorIntervalSeconds, (val) => {
   config.value.taskMonitorIntervalMs = Math.round(val * 1000)
-  emit('update:modelValue', { ...config.value })
+  emitConfigUpdate()
 })
 
 watch(mesConfirmTimeoutSeconds, (val) => {
   config.value.mesConfirmTimeoutMs = Math.round(val * 1000)
-  emit('update:modelValue', { ...config.value })
+  emitConfigUpdate()
 })
 
 // 鐩戝惉config鍏朵粬瀛楁鍙樺寲锛屽悓姝ュ埌鐖剁粍浠�
-watch(() => [
-  config.value.vehicleCapacity,
-  config.value.vehicleSpeed,
-  config.value.defaultGlassLength,
-  config.value.homePosition,
-  config.value.minRange,
-  config.value.maxRange,
-  config.value.autoFeed,
-  config.value.maxRetryCount,
-  config.value.positionMapping
-], () => {
-  emit('update:modelValue', { ...config.value })
-}, { deep: true })
-
 // 浣嶇疆鏄犲皠鐩稿叧鏂规硶
 const addPositionMapping = () => {
-  const newKey = `POS${Object.keys(config.value.positionMapping).length + 1}`
-  config.value.positionMapping[newKey] = 1
-  mappingKeys.value.push(newKey)
+  const nextIndex = positionList.value.length + 1
+  positionList.value.push({
+    id: `POS_${Date.now()}_${nextIndex}`,
+    key: '',
+    value: 1
+  })
 }
 
-const removePositionMapping = (key) => {
-  delete config.value.positionMapping[key]
-  mappingKeys.value = mappingKeys.value.filter(k => k !== key)
+const removePositionMapping = (idx) => {
+  positionList.value.splice(idx, 1)
+  applyPositionListToConfig()
 }
 
-const updatePositionMapping = (index, newKey, oldValue) => {
-  const oldKey = mappingKeys.value[index]
-  if (oldKey && oldKey !== newKey) {
-    delete config.value.positionMapping[oldKey]
-  }
-  mappingKeys.value[index] = newKey
-  if (newKey) {
-    config.value.positionMapping[newKey] = oldValue || 1
-  }
+const handlePositionKeyChange = () => {
+  applyPositionListToConfig()
+}
+
+const handlePositionValueChange = () => {
+  applyPositionListToConfig()
 }
 </script>
 

--
Gitblit v1.8.0