From 94ad631d316da04c46266ddb1fc6e63e6f8f2fae Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期二, 17 三月 2026 17:34:15 +0800
Subject: [PATCH] feat: 同步协议处理、前端交互与业务联调改动

---
 Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Web/src/views/DetailsView.vue |   46 ++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Web/src/views/DetailsView.vue b/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Web/src/views/DetailsView.vue
index a472d99..c336b5a 100644
--- a/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Web/src/views/DetailsView.vue
+++ b/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Web/src/views/DetailsView.vue
@@ -1,5 +1,8 @@
 锘�<template>
-  <div>
+  <div
+    v-loading.fullscreen.lock="startActionLoading"
+    element-loading-text="姝e湪鍚姩瀹炰緥锛岃绋嶅��..."
+  >
     <div v-if="loading" class="loading-container">
       <el-icon class="loading-icon" :size="40"><Loading /></el-icon>
       <p>鍔犺浇涓�...</p>
@@ -169,11 +172,13 @@
                               <el-switch
                                 v-if="row.dataType === 'Bool'"
                                 v-model="fieldEditValues[getFieldEditKey(row)]"
+                                @change="markFieldDirty(row)"
                                 :disabled="!isFieldWritable(row)"
                               />
                               <el-input-number
                                 v-else-if="row.dataType === 'Int' || row.dataType === 'DInt' || row.dataType === 'Byte'"
                                 v-model="fieldEditValues[getFieldEditKey(row)]"
+                                @change="markFieldDirty(row)"
                                 :disabled="!isFieldWritable(row)"
                                 :controls="false"
                                 style="width: 100%"
@@ -181,6 +186,7 @@
                               <el-input
                                 v-else
                                 v-model="fieldEditValues[getFieldEditKey(row)]"
+                                @input="markFieldDirty(row)"
                                 :disabled="!isFieldWritable(row)"
                               />
                             </template>
@@ -223,11 +229,13 @@
                           <el-switch
                             v-if="row.dataType === 'Bool'"
                             v-model="fieldEditValues[getFieldEditKey(row)]"
+                            @change="markFieldDirty(row)"
                             :disabled="!isFieldWritable(row)"
                           />
                           <el-input-number
                             v-else-if="row.dataType === 'Int' || row.dataType === 'DInt' || row.dataType === 'Byte'"
                             v-model="fieldEditValues[getFieldEditKey(row)]"
+                            @change="markFieldDirty(row)"
                             :disabled="!isFieldWritable(row)"
                             :controls="false"
                             style="width: 100%"
@@ -235,6 +243,7 @@
                           <el-input
                             v-else
                             v-model="fieldEditValues[getFieldEditKey(row)]"
+                            @input="markFieldDirty(row)"
                             :disabled="!isFieldWritable(row)"
                           />
                         </template>
@@ -311,6 +320,7 @@
 const protocolTemplate = ref<ProtocolTemplate | null>(null)
 const loading = ref(true)
 const errorMsg = ref('')
+const startActionLoading = ref(false)
 
 const memoryLoading = ref(false)
 const autoRefreshDb = ref(true)
@@ -322,6 +332,7 @@
 const expandedDbViews = ref<Record<number, boolean>>({})
 const fieldEditValues = ref<Record<string, string | number | boolean>>({})
 const writingFieldKeys = ref<Record<string, boolean>>({})
+const dirtyFieldKeys = ref<Record<string, boolean>>({})
 
 let refreshTimer: number | null = null
 
@@ -413,11 +424,29 @@
 })
 
 watch(parsedFields, () => {
-  const next: Record<string, string | number | boolean> = {}
+  // 杞鍒锋柊鏃讹紝淇濈暀鐢ㄦ埛姝e湪缂栬緫鐨勫瓧娈碉紝閬垮厤杈撳叆鍊艰瑕嗙洊銆�
+  const next: Record<string, string | number | boolean> = { ...fieldEditValues.value }
+  const validKeys = new Set<string>()
   for (const field of parsedFields.value) {
     const key = buildFieldEditKey(field.templateDbNumber, field.fieldKey)
+    validKeys.add(key)
+    if (dirtyFieldKeys.value[key] === true) {
+      continue
+    }
     next[key] = coerceEditValueByType(field.dataType, field.value)
   }
+
+  for (const key of Object.keys(next)) {
+    if (!validKeys.has(key)) {
+      delete next[key]
+    }
+  }
+  for (const key of Object.keys(dirtyFieldKeys.value)) {
+    if (!validKeys.has(key)) {
+      delete dirtyFieldKeys.value[key]
+    }
+  }
+
   fieldEditValues.value = next
 }, { immediate: true })
 
@@ -530,6 +559,8 @@
       cancelButtonText: '鍙栨秷',
       type: 'info'
     })
+
+    startActionLoading.value = true
     await api.startInstance(id)
     await loadInstance()
     await loadMemoryData(true)
@@ -539,6 +570,8 @@
       console.error('鍚姩瀹炰緥澶辫触:', err)
       ElMessage.error('鍚姩澶辫触锛岃鏌ョ湅鎺у埗鍙�')
     }
+  } finally {
+    startActionLoading.value = false
   }
 }
 
@@ -662,6 +695,14 @@
   return buildFieldEditKey(row.templateDbNumber, row.fieldKey)
 }
 
+function markFieldDirty(row: { templateDbNumber: number; fieldKey: string }): void {
+  dirtyFieldKeys.value[getFieldEditKey(row)] = true
+}
+
+function clearFieldDirty(row: { templateDbNumber: number; fieldKey: string }): void {
+  delete dirtyFieldKeys.value[getFieldEditKey(row)]
+}
+
 function isFieldWritable(row: { resolvedDbNumber: number | null }): boolean {
   return row.resolvedDbNumber !== null
 }
@@ -727,6 +768,7 @@
     const dbBlockCount = instanceConfig.value?.memoryConfig.dbBlockCount || dbBlockNumbers.length || 1
     const dbBlockSize = instanceConfig.value?.memoryConfig.dbBlockSize || nextBytes.length
     dbBlocks.value = splitDbBlocks(nextBytes, dbBlockCount, dbBlockSize, dbBlockNumbers)
+    clearFieldDirty(row)
     ElMessage.success(`瀛楁 ${row.fieldKey} 鍐欏叆鎴愬姛`)
   } finally {
     writingFieldKeys.value[editKey] = false

--
Gitblit v1.9.3