From c493779a8504fe1eb548c865ff268a7f7436ec01 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期四, 19 三月 2026 11:43:36 +0800
Subject: [PATCH] feat: 集成机械手客户端并重构模拟器前端工作台

---
 Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Web/src/views/DetailsView.vue |  251 ++++++++++++++++++++++++++++---------------------
 1 files changed, 142 insertions(+), 109 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 c336b5a..83ea82c 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,6 @@
 锘�<template>
   <div
+    class="admin-page"
     v-loading.fullscreen.lock="startActionLoading"
     element-loading-text="姝e湪鍚姩瀹炰緥锛岃绋嶅��..."
   >
@@ -31,44 +32,64 @@
         </el-button>
       </div>
 
-      <el-row :gutter="20" class="status-cards">
-        <el-col :xs="12" :sm="6">
-          <el-card shadow="hover" class="status-card">
-            <el-statistic title="鐘舵��">
-              <template #default>
-                <el-tag :type="getStatusTagType(instance.status)" size="large">
-                  {{ getStatusText(instance.status) }}
-                </el-tag>
-              </template>
-            </el-statistic>
-          </el-card>
-        </el-col>
-        <el-col :xs="12" :sm="6">
-          <el-card shadow="hover" class="status-card">
-            <el-statistic title="杩炴帴瀹㈡埛绔�" :value="instance.clientCount">
-              <template #suffix>
-                <el-icon><User /></el-icon>
-              </template>
-            </el-statistic>
-          </el-card>
-        </el-col>
-        <el-col :xs="12" :sm="6">
-          <el-card shadow="hover" class="status-card">
-            <el-statistic title="鎬昏姹傛暟" :value="instance.totalRequests" />
-          </el-card>
-        </el-col>
-        <el-col :xs="12" :sm="6">
-          <el-card shadow="hover" class="status-card">
-            <el-statistic title="绔彛" :value="instance.port" />
-          </el-card>
-        </el-col>
-      </el-row>
+      <section class="section-block">
+        <div class="section-head">
+          <div>
+            <h3 class="section-title">淇℃伅鍖�</h3>
+            <p class="section-desc">瀹炰緥杩愯鐘舵�佷笌杩炴帴姒傝</p>
+          </div>
+        </div>
+        <div class="section-body">
+          <el-row :gutter="12" class="status-cards">
+            <el-col :xs="12" :sm="6">
+              <el-card shadow="hover" class="status-card panel-card">
+                <el-statistic title="鐘舵��">
+                  <template #default>
+                    <el-tag :type="getStatusTagType(instance.status)" size="large">
+                      {{ getStatusText(instance.status) }}
+                    </el-tag>
+                  </template>
+                </el-statistic>
+              </el-card>
+            </el-col>
+            <el-col :xs="12" :sm="6">
+              <el-card shadow="hover" class="status-card panel-card">
+                <el-statistic title="杩炴帴瀹㈡埛绔�" :value="instance.clientCount">
+                  <template #suffix>
+                    <el-icon><User /></el-icon>
+                  </template>
+                </el-statistic>
+              </el-card>
+            </el-col>
+            <el-col :xs="12" :sm="6">
+              <el-card shadow="hover" class="status-card panel-card">
+                <el-statistic title="鎬昏姹傛暟" :value="instance.totalRequests" />
+              </el-card>
+            </el-col>
+            <el-col :xs="12" :sm="6">
+              <el-card shadow="hover" class="status-card panel-card">
+                <el-statistic title="绔彛" :value="instance.port" />
+              </el-card>
+            </el-col>
+          </el-row>
+        </div>
+      </section>
 
-      <el-card class="mt-4" shadow="never">
+      <section class="section-block detail-section">
+        <div class="section-head">
+          <div>
+            <h3 class="section-title">鎿嶄綔鍖�</h3>
+            <p class="section-desc">宸︿晶瀹炰緥淇℃伅涓庢搷浣滐紝鍙充晶瀹炴椂 DB 鏁版嵁</p>
+          </div>
+        </div>
+        <div class="section-body">
+      <el-row :gutter="16" class="detail-main">
+        <el-col :xs="24" :lg="8">
+      <el-card class="panel-card" shadow="never">
         <template #header>
           <span class="card-header-title">鍩烘湰淇℃伅</span>
         </template>
-        <el-descriptions :column="2" border>
+        <el-descriptions :column="1" border>
           <el-descriptions-item label="瀹炰緥ID">{{ instance.instanceId }}</el-descriptions-item>
           <el-descriptions-item label="瀹炰緥鍚嶇О">{{ instance.name }}</el-descriptions-item>
           <el-descriptions-item label="PLC鍨嬪彿">{{ getPlcTypeText(instance.plcType) }}</el-descriptions-item>
@@ -79,17 +100,18 @@
           <el-descriptions-item v-if="instance.lastActivityTime" label="鏈�鍚庢椿鍔ㄦ椂闂�">
             {{ formatDate(instance.lastActivityTime) }}
           </el-descriptions-item>
-          <el-descriptions-item v-if="instance.errorMessage" label="閿欒淇℃伅" :span="2">
+          <el-descriptions-item v-if="instance.errorMessage" label="閿欒淇℃伅">
             <el-text type="danger">{{ instance.errorMessage }}</el-text>
           </el-descriptions-item>
         </el-descriptions>
       </el-card>
 
-      <el-card class="mt-4" shadow="never">
+      <el-card class="panel-card left-actions" shadow="never">
         <div class="action-buttons">
           <el-button
             v-if="instance.status === 'Stopped' || instance.status === 'Error'"
             type="success"
+           
             @click="handleStart"
           >
             <el-icon><VideoPlay /></el-icon>
@@ -98,6 +120,7 @@
           <el-button
             v-if="instance.status === 'Running'"
             type="warning"
+           
             @click="handleStop"
           >
             <el-icon><VideoPause /></el-icon>
@@ -114,13 +137,15 @@
         </div>
       </el-card>
 
-      <el-card class="mt-4" shadow="never">
+        </el-col>
+        <el-col :xs="24" :lg="16">
+      <el-card class="panel-card" shadow="never">
         <template #header>
           <div class="db-header">
             <span class="card-header-title">DB鍧楀疄鏃舵暟鎹�</span>
             <div class="db-toolbar">
               <el-switch v-model="autoRefreshDb" active-text="鑷姩鍒锋柊" />
-              <el-button size="small" @click="loadMemoryData(true)">鎵嬪姩鍒锋柊</el-button>
+              <el-button @click="loadMemoryData(true)">鎵嬪姩鍒锋柊</el-button>
             </div>
           </div>
         </template>
@@ -131,7 +156,7 @@
             <template #default>
               <div v-if="deviceDbViews.length === 0" class="text-muted">褰撳墠璁惧妯℃澘鏈尮閰嶅埌鍙樉绀虹殑DB鍧�</div>
               <div v-else>
-                <el-tabs type="border-card" class="db-tabs">
+                    <el-tabs type="border-card" class="db-tabs">
                   <el-tab-pane
                     v-for="view in deviceDbViews"
                     :key="view.templateDbNumber"
@@ -149,25 +174,27 @@
                         :key="`${view.templateDbNumber}-${group.key}`"
                       >
                         <template #label>
-                          <el-tag :type="getFieldGroupTagType(group.key)" size="small">{{ group.key }}</el-tag>
+                          <el-tag :type="getFieldGroupTagType(group.key)">{{ group.key }}</el-tag>
                         </template>
+                        <div class="field-table-wrap">
                         <el-table
                           :data="group.fields"
                           border
-                          size="small"
+                          class="field-table"
+                          table-layout="auto"
                           empty-text="褰撳墠鍒嗙粍鏃犲瓧娈垫槧灏�"
                         >
-                          <el-table-column prop="fieldKey" label="瀛楁" min-width="140" />
-                          <el-table-column prop="address" label="鍦板潃" width="130" />
-                          <el-table-column prop="mappedDb" label="鏄犲皠鍧�" width="120">
+                          <el-table-column prop="fieldKey" label="瀛楁" />
+                          <el-table-column prop="address" label="鍦板潃" />
+                          <el-table-column prop="mappedDb" label="鏄犲皠鍧�">
                             <template #default="{ row }">
-                              <el-tag :type="getDbTagType(row.mappedDb)" size="small">{{ row.mappedDb }}</el-tag>
+                              <el-tag :type="getDbTagType(row.mappedDb)">{{ row.mappedDb }}</el-tag>
                             </template>
                           </el-table-column>
-                          <el-table-column prop="dataType" label="绫诲瀷" width="90" />
-                          <el-table-column prop="direction" label="鏂瑰悜" width="130" />
-                          <el-table-column prop="value" label="褰撳墠鍊�" min-width="220" />
-                          <el-table-column label="淇敼鍊�" min-width="220">
+                          <el-table-column prop="dataType" label="绫诲瀷" />
+                          <el-table-column prop="direction" label="鏂瑰悜" />
+                          <el-table-column prop="value" label="褰撳墠鍊�" />
+                          <el-table-column label="淇敼鍊�">
                             <template #default="{ row }">
                               <el-switch
                                 v-if="row.dataType === 'Bool'"
@@ -181,17 +208,18 @@
                                 @change="markFieldDirty(row)"
                                 :disabled="!isFieldWritable(row)"
                                 :controls="false"
-                                style="width: 100%"
+                                class="editable-control"
                               />
                               <el-input
                                 v-else
                                 v-model="fieldEditValues[getFieldEditKey(row)]"
                                 @input="markFieldDirty(row)"
                                 :disabled="!isFieldWritable(row)"
+                                class="editable-control"
                               />
                             </template>
                           </el-table-column>
-                          <el-table-column label="鎿嶄綔" width="90" fixed="right">
+                          <el-table-column label="鎿嶄綔" width="88" fixed="right">
                             <template #default="{ row }">
                               <el-button
                                 type="primary"
@@ -205,26 +233,29 @@
                             </template>
                           </el-table-column>
                         </el-table>
+                        </div>
                       </el-tab-pane>
                     </el-tabs>
+                    <template v-else-if="view.fields.length > 0">
+                    <div class="field-table-wrap">
                     <el-table
-                      v-else-if="view.fields.length > 0"
                       :data="view.fields"
                       border
-                      size="small"
+                      class="field-table"
+                      table-layout="auto"
                       empty-text="褰撳墠DB鍧楁棤瀛楁鏄犲皠"
                     >
-                      <el-table-column prop="fieldKey" label="瀛楁" min-width="140" />
-                      <el-table-column prop="address" label="鍦板潃" width="130" />
-                      <el-table-column prop="mappedDb" label="鏄犲皠鍧�" width="120">
+                      <el-table-column prop="fieldKey" label="瀛楁" />
+                      <el-table-column prop="address" label="鍦板潃" />
+                      <el-table-column prop="mappedDb" label="鏄犲皠鍧�">
                         <template #default="{ row }">
-                          <el-tag :type="getDbTagType(row.mappedDb)" size="small">{{ row.mappedDb }}</el-tag>
+                          <el-tag :type="getDbTagType(row.mappedDb)">{{ row.mappedDb }}</el-tag>
                         </template>
                       </el-table-column>
-                      <el-table-column prop="dataType" label="绫诲瀷" width="90" />
-                      <el-table-column prop="direction" label="鏂瑰悜" width="130" />
-                      <el-table-column prop="value" label="褰撳墠鍊�" min-width="220" />
-                      <el-table-column label="淇敼鍊�" min-width="220">
+                      <el-table-column prop="dataType" label="绫诲瀷" />
+                      <el-table-column prop="direction" label="鏂瑰悜" />
+                      <el-table-column prop="value" label="褰撳墠鍊�" />
+                      <el-table-column label="淇敼鍊�">
                         <template #default="{ row }">
                           <el-switch
                             v-if="row.dataType === 'Bool'"
@@ -238,17 +269,18 @@
                             @change="markFieldDirty(row)"
                             :disabled="!isFieldWritable(row)"
                             :controls="false"
-                            style="width: 100%"
+                            class="editable-control"
                           />
                           <el-input
                             v-else
                             v-model="fieldEditValues[getFieldEditKey(row)]"
                             @input="markFieldDirty(row)"
                             :disabled="!isFieldWritable(row)"
+                            class="editable-control"
                           />
                         </template>
                       </el-table-column>
-                      <el-table-column label="鎿嶄綔" width="90" fixed="right">
+                      <el-table-column label="鎿嶄綔" width="88" fixed="right">
                         <template #default="{ row }">
                           <el-button
                             type="primary"
@@ -262,6 +294,8 @@
                         </template>
                       </el-table-column>
                     </el-table>
+                    </div>
+                    </template>
                     <div v-else class="text-muted">褰撳墠DB鍧楁棤瀛楁鏄犲皠</div>
 
                     <div class="card-header-title field-title">鍘熷鏁版嵁</div>
@@ -300,6 +334,10 @@
           />
         </div>
       </el-card>
+        </el-col>
+      </el-row>
+        </div>
+      </section>
     </div>
   </div>
 </template>
@@ -1065,48 +1103,8 @@
 </script>
 
 <style scoped>
-.page-header {
-  display: flex;
-  justify-content: space-between;
-  align-items: flex-start;
-  margin-bottom: 20px;
-  flex-wrap: wrap;
-  gap: 16px;
-}
-
-.header-left h2 {
-  display: flex;
-  align-items: center;
-  gap: 8px;
-  margin: 0 0 8px 0;
-}
-
-.text-muted {
-  color: #909399;
-  margin: 0;
-}
-
-.loading-container {
-  text-align: center;
-  padding: 60px 0;
-  color: #909399;
-}
-
-.loading-icon {
-  animation: spin 1s linear infinite;
-}
-
-@keyframes spin {
-  from {
-    transform: rotate(0deg);
-  }
-  to {
-    transform: rotate(360deg);
-  }
-}
-
 .status-cards {
-  margin-bottom: 20px;
+  margin-bottom: 8px;
 }
 
 .status-card {
@@ -1119,13 +1117,17 @@
 }
 
 .mt-4 {
-  margin-top: 16px;
+  margin-top: 14px;
 }
 
 .action-buttons {
   display: flex;
-  gap: 12px;
+  gap: 10px;
   flex-wrap: wrap;
+}
+
+.left-actions {
+  margin-top: 14px;
 }
 
 .db-header {
@@ -1142,7 +1144,7 @@
 
 .db-content {
   margin: 0;
-  max-height: 180px;
+  max-height: 168px;
   overflow: auto;
   white-space: pre-wrap;
   font-family: Consolas, Monaco, 'Courier New', monospace;
@@ -1168,11 +1170,11 @@
 }
 
 .db-tabs {
-  margin-top: 8px;
+  margin-top: 10px;
 }
 
 .data-view-tabs {
-  margin-top: 8px;
+  margin-top: 10px;
 }
 
 .db-raw-toolbar {
@@ -1189,4 +1191,35 @@
   margin-top: 12px;
   margin-bottom: 8px;
 }
+
+.field-table-wrap {
+  width: 100%;
+  overflow-x: auto;
+}
+
+:deep(.field-table) {
+  width: max-content;
+  min-width: 100%;
+}
+
+:deep(.editable-control) {
+  width: 100%;
+}
+
+:deep(.status-card .el-card__body) {
+  padding: 14px 16px;
+}
+
+:deep(.action-buttons .el-button) {
+  min-width: 82px;
+}
+
+:deep(.panel-card > .el-card__header) {
+  padding: 14px 18px;
+}
+
+:deep(.panel-card > .el-card__body) {
+  padding: 14px 18px;
+}
 </style>
+

--
Gitblit v1.9.3