From 9571229a2013472dc701ecf5767f2873b36d8f90 Mon Sep 17 00:00:00 2001
From: huang <1532065656@qq.com>
Date: 星期四, 11 十二月 2025 17:07:19 +0800
Subject: [PATCH] 修复导入Excel功能工程号自增; 添加选择工程号自动填写玻璃id列表

---
 mes-web/src/views/device/DeviceEditDialog.vue |  405 +++++++++++++++------------------------------------------
 1 files changed, 108 insertions(+), 297 deletions(-)

diff --git a/mes-web/src/views/device/DeviceEditDialog.vue b/mes-web/src/views/device/DeviceEditDialog.vue
index 881ab73..2845239 100644
--- a/mes-web/src/views/device/DeviceEditDialog.vue
+++ b/mes-web/src/views/device/DeviceEditDialog.vue
@@ -40,10 +40,13 @@
             </el-form-item>
 
             <el-form-item label="璁惧绫诲瀷" prop="deviceType">
-              <el-select v-model="deviceForm.deviceType" placeholder="閫夋嫨璁惧绫诲瀷" style="width: 100%;">
-                <el-option label="涓婂ぇ杞�" value="涓婂ぇ杞�" />
-                <el-option label="澶х悊鐗�" value="澶х悊鐗�" />
-                <el-option label="鐜荤拑瀛樺偍" value="鐜荤拑瀛樺偍" />
+              <el-select v-model="deviceForm.deviceType" placeholder="閫夋嫨璁惧绫诲瀷" style="width: 100%;" :loading="deviceTypesLoading">
+                <el-option 
+                  v-for="type in deviceTypes" 
+                  :key="type" 
+                  :label="type" 
+                  :value="type" 
+                />
               </el-select>
             </el-form-item>
 
@@ -51,10 +54,7 @@
               <el-select v-model="deviceForm.plcType" placeholder="閫夋嫨PLC绫诲瀷" style="width: 100%;" clearable>
                 <el-option label="瑗块棬瀛� S7-1200" value="S1200" />
                 <el-option label="瑗块棬瀛� S7-1500" value="S1500" />
-                <el-option label="瑗块棬瀛� S7-400" value="S400" />
-                <el-option label="瑗块棬瀛� S7-300" value="S300" />
-                <el-option label="瑗块棬瀛� S7-200" value="S200" />
-                <el-option label="瑗块棬瀛� S7-200 SMART" value="S200_SMART" />
+                <el-option label="Modbus 鎺у埗鍣�" value="MODBUS" />
               </el-select>
             </el-form-item>
 
@@ -254,190 +254,19 @@
           <span class="form-tip">鏍规嵁璁惧绫诲瀷閰嶇疆鐗瑰畾鐨勪笟鍔¢�昏緫鍙傛暟</span>
         </template>
 
-        <!-- 涓婂ぇ杞﹁澶囬�昏緫閰嶇疆 -->
-        <div v-if="deviceForm.deviceType === '涓婂ぇ杞�'">
-          <el-row :gutter="20">
-            <el-col :span="12">
-              <el-form-item label="杞﹁締瀹归噺">
-                <el-input-number
-                  v-model="deviceLogicParams.vehicleCapacity"
-                  :min="1"
-                  :max="10000"
-                  :step="100"
-                  style="width: 100%;"
+        <!-- 浣跨敤鍔ㄦ�佺粍浠跺姞杞藉搴旇澶囩被鍨嬬殑閰嶇疆缁勪欢 -->
+        <component
+          :is="deviceConfigComponent"
+          v-if="deviceConfigComponent"
+          v-model="deviceLogicParams"
                 />
-                <span class="form-tip">杞﹁締鏈�澶у閲�</span>
-              </el-form-item>
-            </el-col>
-            <el-col :span="12">
-              <el-form-item label="鐜荤拑闂撮殧(ms)">
-                <el-input-number
-                  v-model="deviceLogicParams.glassIntervalMs"
-                  :min="100"
-                  :max="10000"
-                  :step="100"
-                  style="width: 100%;"
-                />
-                <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-switch v-model="deviceLogicParams.autoFeed" />
-                <span class="form-tip">鏄惁鑷姩瑙﹀彂涓婃枡璇锋眰</span>
-              </el-form-item>
-            </el-col>
-            <el-col :span="12">
-              <el-form-item label="鏈�澶ч噸璇曟鏁�">
-                <el-input-number
-                  v-model="deviceLogicParams.maxRetryCount"
-                  :min="0"
-                  :max="10"
-                  :step="1"
-                  style="width: 100%;"
-                />
-              </el-form-item>
-            </el-col>
-          </el-row>
-          <el-form-item label="浣嶇疆鏄犲皠">
-            <div class="position-mapping">
-              <div
-                v-for="(value, key, index) in deviceLogicParams.positionMapping"
-                :key="index"
-                class="mapping-item"
-              >
-                <el-input
-                  v-model="mappingKeys[index]"
-                  placeholder="浣嶇疆浠g爜"
-                  size="small"
-                  style="width: 150px; margin-right: 10px;"
-                  @input="updatePositionMapping(index, $event, value)"
-                />
-                <el-input-number
-                  v-model="deviceLogicParams.positionMapping[mappingKeys[index] || key]"
-                  :min="0"
-                  :max="100"
-                  size="small"
-                  style="width: 120px; margin-right: 10px;"
-                />
-                <el-button
-                  type="danger"
-                  size="small"
-                  @click="removePositionMapping(key)"
-                >
-                  鍒犻櫎
-                </el-button>
-              </div>
-              <el-button type="primary" size="small" @click="addPositionMapping">
-                娣诲姞浣嶇疆鏄犲皠
-              </el-button>
-            </div>
-          </el-form-item>
-        </div>
-
-        <!-- 澶х悊鐗囪澶囬�昏緫閰嶇疆 -->
-        <div v-if="deviceForm.deviceType === '澶х悊鐗�'">
-          <el-row :gutter="20">
-            <el-col :span="12">
-              <el-form-item label="鐜荤拑灏哄">
-                <el-input-number
-                  v-model="deviceLogicParams.glassSize"
-                  :min="100"
-                  :max="5000"
-                  :step="100"
-                  style="width: 100%;"
-                />
-                <span class="form-tip">鐜荤拑灏哄锛坢m锛�</span>
-              </el-form-item>
-            </el-col>
-            <el-col :span="12">
-              <el-form-item label="澶勭悊鏃堕棿(ms)">
-                <el-input-number
-                  v-model="deviceLogicParams.processingTime"
-                  :min="1000"
-                  :max="60000"
-                  :step="1000"
-                  style="width: 100%;"
-                />
-                <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-switch v-model="deviceLogicParams.autoProcess" />
-                <span class="form-tip">鏄惁鑷姩瑙﹀彂澶勭悊璇锋眰</span>
-              </el-form-item>
-            </el-col>
-            <el-col :span="12">
-              <el-form-item label="鏈�澶ч噸璇曟鏁�">
-                <el-input-number
-                  v-model="deviceLogicParams.maxRetryCount"
-                  :min="0"
-                  :max="10"
-                  :step="1"
-                  style="width: 100%;"
-                />
-              </el-form-item>
-            </el-col>
-          </el-row>
-        </div>
-
-        <!-- 鐜荤拑瀛樺偍璁惧閫昏緫閰嶇疆 -->
-        <div v-if="deviceForm.deviceType === '鐜荤拑瀛樺偍'">
-          <el-row :gutter="20">
-            <el-col :span="12">
-              <el-form-item label="瀛樺偍瀹归噺">
-                <el-input-number
-                  v-model="deviceLogicParams.storageCapacity"
-                  :min="1"
-                  :max="1000"
-                  :step="1"
-                  style="width: 100%;"
-                />
-                <span class="form-tip">鏈�澶у瓨鍌ㄦ暟閲�</span>
-              </el-form-item>
-            </el-col>
-            <el-col :span="12">
-              <el-form-item label="鍙栬揣妯″紡">
-                <el-select v-model="deviceLogicParams.retrievalMode" style="width: 100%;">
-                  <el-option label="鍏堣繘鍏堝嚭 (FIFO)" value="FIFO" />
-                  <el-option label="鍚庤繘鍏堝嚭 (LIFO)" value="LIFO" />
-                  <el-option label="闅忔満 (RANDOM)" value="RANDOM" />
-                </el-select>
-              </el-form-item>
-            </el-col>
-          </el-row>
-          <el-row :gutter="20">
-            <el-col :span="12">
-              <el-form-item label="鑷姩瀛樺偍">
-                <el-switch v-model="deviceLogicParams.autoStore" />
-                <span class="form-tip">鏄惁鑷姩瑙﹀彂瀛樺偍璇锋眰</span>
-              </el-form-item>
-            </el-col>
-            <el-col :span="12">
-              <el-form-item label="鑷姩鍙栬揣">
-                <el-switch v-model="deviceLogicParams.autoRetrieve" />
-                <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="deviceLogicParams.maxRetryCount"
-                  :min="0"
-                  :max="10"
-                  :step="1"
-                  style="width: 100%;"
-                />
-              </el-form-item>
-            </el-col>
-          </el-row>
+        <div v-else class="no-config-tip">
+          <el-alert
+            :title="`璁惧绫诲瀷銆�${deviceForm.deviceType}銆嶆殏鏃犻厤缃粍浠禶"
+            type="info"
+            :closable="false"
+            show-icon
+          />
         </div>
       </el-card>
 
@@ -496,6 +325,7 @@
 import { ref, reactive, watch, computed } from 'vue'
 import { ElMessage } from 'element-plus'
 import { deviceConfigApi } from '@/api/device/deviceManagement'
+import { getDeviceConfigComponent } from './components/DeviceLogicConfig'
 
 // Props瀹氫箟
 const props = defineProps({
@@ -519,27 +349,23 @@
 const testing = ref(false)
 const testResult = ref(null)
 
-// 璁惧閫昏緫鍙傛暟锛堟牴鎹澶囩被鍨嬪姩鎬佹樉绀猴級
-const deviceLogicParams = reactive({
-  // 涓婂ぇ杞﹀弬鏁�
-  vehicleCapacity: 6000,
-  glassIntervalMs: 1000,
-  autoFeed: true,
-  maxRetryCount: 5,
-  positionMapping: {},
-  // 澶х悊鐗囧弬鏁�
-  glassSize: 2000,
-  processingTime: 5000,
-  autoProcess: true,
-  // 鐜荤拑瀛樺偍鍙傛暟
-  storageCapacity: 100,
-  retrievalMode: 'FIFO',
-  autoStore: true,
-  autoRetrieve: true
-})
+// 璁惧绫诲瀷鍒楄〃
+const deviceTypes = ref([])
+const deviceTypesLoading = ref(false)
 
-// 浣嶇疆鏄犲皠鐨勯敭鏁扮粍锛堢敤浜巚-for锛�
-const mappingKeys = ref([])
+// 璁惧閫昏緫鍙傛暟锛堟牴鎹澶囩被鍨嬪姩鎬佹樉绀猴級
+const deviceLogicParams = ref({})
+
+const S7_PLC_TYPES = ['S1200', 'S1500']
+const MODBUS_PLC_TYPES = ['MODBUS']
+
+// 璁$畻灞炴�э細鏍规嵁璁惧绫诲瀷鑾峰彇瀵瑰簲鐨勯厤缃粍浠�
+const deviceConfigComponent = computed(() => {
+  if (!deviceForm.deviceType) {
+    return null
+  }
+  return getDeviceConfigComponent(deviceForm.deviceType)
+})
 
 // 璁惧琛ㄥ崟鏁版嵁
 const getDefaultForm = () => ({
@@ -627,6 +453,8 @@
 watch(() => props.modelValue, (newVal) => {
   dialogVisible.value = newVal
   if (newVal) {
+    // 鍔犺浇璁惧绫诲瀷鍒楄〃
+    loadDeviceTypes()
     if (isEdit.value && props.deviceData) {
       loadDeviceData(props.deviceData)
     } else {
@@ -645,26 +473,73 @@
 
 // 鐩戝惉PLC绫诲瀷鍙樺寲锛岃嚜鍔ㄨ缃�氳鍗忚
 watch(() => deviceForm.plcType, (newPlcType) => {
-  // 濡傛灉閫夋嫨鐨勬槸S7绯诲垪PLC锛岃嚜鍔ㄨ缃�氳鍗忚涓篠7 Communication
-  if (newPlcType && (newPlcType.startsWith('S') || newPlcType.includes('S7'))) {
-    if (!deviceForm.protocolType || deviceForm.protocolType === '鍏朵粬') {
+  if (!newPlcType) {
+    return
+  }
+
+  if (S7_PLC_TYPES.includes(newPlcType)) {
+    if (!deviceForm.protocolType || deviceForm.protocolType === '鍏朵粬' || deviceForm.protocolType === 'Modbus TCP') {
       deviceForm.protocolType = 'S7 Communication'
+    }
+    return
+  }
+
+  if (MODBUS_PLC_TYPES.includes(newPlcType)) {
+    if (!deviceForm.protocolType || deviceForm.protocolType === '鍏朵粬' || deviceForm.protocolType === 'S7 Communication') {
+      deviceForm.protocolType = 'Modbus TCP'
     }
   }
 })
 
 // 澶勭悊閫氳鍗忚鍙樺寲
 const handleProtocolTypeChange = (value) => {
-  // 濡傛灉閫夋嫨浜嗛潪S7鍗忚锛屼絾PLC绫诲瀷鏄疭7绯诲垪锛岀粰鍑烘彁绀�
-  if (value && value !== 'S7 Communication' && deviceForm.plcType) {
-    const s7Types = ['S1200', 'S1500', 'S400', 'S300', 'S200', 'S200_SMART']
-    if (s7Types.includes(deviceForm.plcType)) {
+  if (!deviceForm.plcType || !value) {
+    return
+  }
+
+  if (value !== 'S7 Communication' && S7_PLC_TYPES.includes(deviceForm.plcType)) {
       ElMessage.warning('S7绯诲垪PLC閫氬父浣跨敤S7 Communication鍗忚锛岃纭鍗忚閫夋嫨鏄惁姝g‘')
+    return
     }
+
+  if (value !== 'Modbus TCP' && MODBUS_PLC_TYPES.includes(deviceForm.plcType)) {
+    ElMessage.warning('Modbus 绫诲瀷PLC閫氬父浣跨敤 Modbus TCP 鍗忚锛岃纭鍗忚閫夋嫨鏄惁姝g‘')
   }
 }
 
 // 鏂规硶瀹氫箟
+// 鍔犺浇璁惧绫诲瀷鍒楄〃
+const loadDeviceTypes = async () => {
+  if (deviceTypes.value.length > 0) {
+    // 濡傛灉宸茬粡鍔犺浇杩囷紝涓嶅啀閲嶅鍔犺浇
+    return
+  }
+  // 鎵�鏈夋敮鎸佺殑璁惧绫诲瀷锛堢‘淇濆寘鍚墍鏈夋湁閰嶇疆缁勪欢鐨勭被鍨嬶級
+  const supportedTypes = ['澶ц溅璁惧', '澶х悊鐗囩', '鍗ц浆绔嬫壂鐮�', '鍗ц浆绔�']
+  
+  try {
+    deviceTypesLoading.value = true
+    const res = await deviceConfigApi.getDeviceTypes()
+    if (res?.data && Array.isArray(res.data)) {
+      // 鍚堝苟鏁版嵁搴撲腑鐨勭被鍨嬪拰鏀寔鐨勭被鍨嬶紝鍘婚噸骞舵帓搴�
+      const dbTypes = res.data
+      const allTypes = [...new Set([...supportedTypes, ...dbTypes])].sort()
+      deviceTypes.value = allTypes
+    } else {
+      // 濡傛灉API杩斿洖澶辫触锛屼娇鐢ㄩ粯璁ょ被鍨�
+      deviceTypes.value = supportedTypes
+      console.warn('鑾峰彇璁惧绫诲瀷鍒楄〃澶辫触锛屼娇鐢ㄩ粯璁ょ被鍨�')
+    }
+  } catch (error) {
+    console.error('鍔犺浇璁惧绫诲瀷鍒楄〃澶辫触:', error)
+    // 澶辫触鏃朵娇鐢ㄩ粯璁ょ被鍨�
+    deviceTypes.value = supportedTypes
+    ElMessage.warning('鍔犺浇璁惧绫诲瀷鍒楄〃澶辫触锛屼娇鐢ㄩ粯璁ょ被鍨�')
+  } finally {
+    deviceTypesLoading.value = false
+  }
+}
+
 const parseJsonSafe = (str, defaultValue = null) => {
   if (!str) return defaultValue
   try {
@@ -808,71 +683,21 @@
 }
 
 // 鍔犺浇璁惧閫昏緫鍙傛暟
-const loadDeviceLogicParams = (deviceLogic, deviceType) => {
-  if (deviceType === '涓婂ぇ杞�') {
-    deviceLogicParams.vehicleCapacity = deviceLogic.vehicleCapacity ?? 6000
-    deviceLogicParams.glassIntervalMs = deviceLogic.glassIntervalMs ?? 1000
-    deviceLogicParams.autoFeed = deviceLogic.autoFeed ?? true
-    deviceLogicParams.maxRetryCount = deviceLogic.maxRetryCount ?? 5
-    deviceLogicParams.positionMapping = deviceLogic.positionMapping || {}
-    mappingKeys.value = Object.keys(deviceLogicParams.positionMapping)
-  } else if (deviceType === '澶х悊鐗�') {
-    deviceLogicParams.glassSize = deviceLogic.glassSize ?? 2000
-    deviceLogicParams.processingTime = deviceLogic.processingTime ?? 5000
-    deviceLogicParams.autoProcess = deviceLogic.autoProcess ?? true
-    deviceLogicParams.maxRetryCount = deviceLogic.maxRetryCount ?? 3
-  } else if (deviceType === '鐜荤拑瀛樺偍') {
-    deviceLogicParams.storageCapacity = deviceLogic.storageCapacity ?? 100
-    deviceLogicParams.retrievalMode = deviceLogic.retrievalMode || 'FIFO'
-    deviceLogicParams.autoStore = deviceLogic.autoStore ?? true
-    deviceLogicParams.autoRetrieve = deviceLogic.autoRetrieve ?? true
-    deviceLogicParams.maxRetryCount = deviceLogic.maxRetryCount ?? 3
+const loadDeviceLogicParams = (deviceLogic) => {
+  if (deviceLogic && Object.keys(deviceLogic).length > 0) {
+    deviceLogicParams.value = { ...deviceLogic }
+  } else {
+    deviceLogicParams.value = {}
   }
 }
 
-// 浣嶇疆鏄犲皠鐩稿叧鏂规硶
-const addPositionMapping = () => {
-  const newKey = `POS${Object.keys(deviceLogicParams.positionMapping).length + 1}`
-  deviceLogicParams.positionMapping[newKey] = 1
-  mappingKeys.value.push(newKey)
-}
-
-const removePositionMapping = (key) => {
-  delete deviceLogicParams.positionMapping[key]
-  mappingKeys.value = mappingKeys.value.filter(k => k !== key)
-}
-
-const updatePositionMapping = (index, newKey, oldValue) => {
-  const oldKey = mappingKeys.value[index]
-  if (oldKey && oldKey !== newKey) {
-    delete deviceLogicParams.positionMapping[oldKey]
-  }
-  mappingKeys.value[index] = newKey
-  if (newKey) {
-    deviceLogicParams.positionMapping[newKey] = oldValue || 1
-  }
-}
 
 const resetForm = () => {
   Object.assign(deviceForm, getDefaultForm())
   deviceFormRef.value?.clearValidate()
   
   // 閲嶇疆璁惧閫昏緫鍙傛暟
-  deviceLogicParams.vehicleCapacity = 6000
-  deviceLogicParams.glassIntervalMs = 1000
-  deviceLogicParams.autoFeed = true
-  deviceLogicParams.maxRetryCount = 5
-  deviceLogicParams.positionMapping = {}
-  mappingKeys.value = []
-  
-  deviceLogicParams.glassSize = 2000
-  deviceLogicParams.processingTime = 5000
-  deviceLogicParams.autoProcess = true
-  
-  deviceLogicParams.storageCapacity = 100
-  deviceLogicParams.retrievalMode = 'FIFO'
-  deviceLogicParams.autoStore = true
-  deviceLogicParams.autoRetrieve = true
+  deviceLogicParams.value = {}
 }
 
 const addConfigParam = () => {
@@ -946,29 +771,11 @@
     plcType: deviceForm.plcType
   }
 
-    // 淇濆瓨璁惧閫昏緫鍙傛暟
-    const deviceLogic = {}
-    if (deviceForm.deviceType === '涓婂ぇ杞�') {
-      deviceLogic.vehicleCapacity = deviceLogicParams.vehicleCapacity
-      deviceLogic.glassIntervalMs = deviceLogicParams.glassIntervalMs
-      deviceLogic.autoFeed = deviceLogicParams.autoFeed
-      deviceLogic.maxRetryCount = deviceLogicParams.maxRetryCount
-      deviceLogic.positionMapping = deviceLogicParams.positionMapping
-    } else if (deviceForm.deviceType === '澶х悊鐗�') {
-      deviceLogic.glassSize = deviceLogicParams.glassSize
-      deviceLogic.processingTime = deviceLogicParams.processingTime
-      deviceLogic.autoProcess = deviceLogicParams.autoProcess
-      deviceLogic.maxRetryCount = deviceLogicParams.maxRetryCount
-    } else if (deviceForm.deviceType === '鐜荤拑瀛樺偍') {
-      deviceLogic.storageCapacity = deviceLogicParams.storageCapacity
-      deviceLogic.retrievalMode = deviceLogicParams.retrievalMode
-      deviceLogic.autoStore = deviceLogicParams.autoStore
-      deviceLogic.autoRetrieve = deviceLogicParams.autoRetrieve
-      deviceLogic.maxRetryCount = deviceLogicParams.maxRetryCount
-    }
-    
-    if (Object.keys(deviceLogic).length > 0) {
-      extraObj.deviceLogic = deviceLogic
+    // 淇濆瓨璁惧閫昏緫鍙傛暟锛堢洿鎺ヤ娇鐢╠eviceLogicParams锛岀敱鍚勪釜閰嶇疆缁勪欢绠$悊锛�
+    if (deviceLogicParams.value && Object.keys(deviceLogicParams.value).length > 0) {
+      extraObj.deviceLogic = { ...deviceLogicParams.value }
+    } else {
+      delete extraObj.deviceLogic
     }
 
     // 鏋勫缓 configJson锛氬皢 configParams 鏁扮粍杞崲涓� JSON 瀛楃涓�
@@ -1124,4 +931,8 @@
   border-radius: 6px;
   background-color: #fafafa;
 }
+
+.no-config-tip {
+  padding: 20px;
+}
 </style>
\ No newline at end of file

--
Gitblit v1.8.0