From a7bd6e538027d876b3122f21c3b1d34663fb2f07 Mon Sep 17 00:00:00 2001
From: xiazhengtongxue <133085197+xiazhengtongxue@users.noreply.github.com>
Date: 星期日, 25 一月 2026 14:18:51 +0800
Subject: [PATCH] 优化前端,修复库存托盘编号重复和WCS任务重发

---
 项目代码/WMS/WIDESEA_WMSClient/src/views/stock/stockView.vue |  404 ++++++++++++++++++++++++++++++++-------------------------
 1 files changed, 228 insertions(+), 176 deletions(-)

diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS/WIDESEA_WMSClient/src/views/stock/stockView.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS/WIDESEA_WMSClient/src/views/stock/stockView.vue"
index b8a864d..aeba5a1 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS/WIDESEA_WMSClient/src/views/stock/stockView.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS/WIDESEA_WMSClient/src/views/stock/stockView.vue"
@@ -20,8 +20,8 @@
 
           <div class="form-group">
             <label class="form-label">宸烽亾锛�</label>
-            <el-select size="mini" clearable filterable v-model="selectedRoadwayNo" placeholder="璇烽�夋嫨宸烽亾" class="full-width"
-              @change="handleRoadwayNoChange">
+            <el-select size="mini" clearable filterable v-model="selectedRoadwayNo" placeholder="璇烽�夋嫨宸烽亾"
+              class="full-width" @change="handleRoadwayNoChange">
               <el-option v-for="item in roadwayNoList" :key="item" :value="item" :label="'宸烽亾 ' + item"></el-option>
             </el-select>
           </div>
@@ -59,6 +59,7 @@
           </div>
 
           <div class="layers-container">
+            <!-- 閬嶅巻姣忎竴灞� -->
             <div class="layer-row" v-for="layer in sortedLayerData" :key="layer.layer">
               <div class="layer-title-area">
                 <h3 class="layer-title">灞� {{ layer.layer }}</h3>
@@ -66,19 +67,29 @@
               </div>
 
               <div class="layer-content-wrap">
-                <div class="layer-content">
-                  <div class="location-column" v-for="column in sortedColumns(layer.columns)" :key="column.column">
-                    <div class="column-label">鍒� {{ column.column }}</div>
-                    <div class="locations-wrapper">
-                      <div class="location-item" v-for="depth in sortedDepthsByRow(column.depths)" :key="depth.depth"
-                        :class="getLocationStatusClass(depth)"
-                        @mouseenter="showTooltip(depth, column.column, layer.layer, $event)" @mouseleave="hideTooltip"
-                        @click="handleLocationClick(depth)">
-                        <div class="location-code">
-                          {{ depth.row || '?' }}鎺�-{{ column.column }}鍒�-{{ layer.layer }}灞�-{{ depth.depth == 1 ? '娴�' : '娣�' }}
-                        </div>
-                        <div class="location-status" v-if="depth.enableStatus !== 0">
-                          绂佺敤
+                <!-- 鎸夎鍒嗙粍鏄剧ず -->
+                <div class="row-group" v-for="rowGroup in getRowGroups(layer)" :key="rowGroup.row">
+                  <div class="row-title">
+                    <span class="row-label">{{ rowGroup.row }}鎺�</span>
+                    <span class="row-count">{{ rowGroup.locations.length }} 涓揣浣�</span>
+                  </div>
+                  
+                  <div class="row-content">
+                    <!-- 鍦ㄦ瘡鎺掑唴鏄剧ず鍒楋紙涓嶆樉绀哄垪鏍囩锛� -->
+                    <div class="location-column" v-for="column in sortedColumns(rowGroup.columns)" :key="column.column">
+                      <div class="locations-wrapper">
+                        <!-- 姣忓垪鏄剧ず娣卞害锛堟祬/娣憋級 -->
+                        <div class="location-item" v-for="depth in column.depths" :key="depth.depth"
+                          :class="getLocationStatusClass(depth)"
+                          @mouseenter="showTooltip(depth, column.column, layer.layer, $event)" 
+                          @mouseleave="hideTooltip"
+                          @click="handleLocationClick(depth)">
+                          <div class="location-code">
+                            {{ getLocationPositionForDisplay(depth, column.column, layer.layer) }}
+                          </div>
+                          <div class="location-status" v-if="depth.enableStatus !== 0">
+                            绂佺敤
+                          </div>
                         </div>
                       </div>
                     </div>
@@ -109,31 +120,35 @@
             </div>
             <div class="tooltip-body">
               <div class="tooltip-row">
-                <span class="tooltip-label">浣嶇疆锛�</span>
-                <span class="tooltip-value">{{ getLocationCode(currentLocation) }}</span>
+                <span class="tooltip-label">浠撳簱锛�</span>
+                <span class="tooltip-value">{{ getWarehouseName(selectedWarehouse) }}</span>
               </div>
               <div class="tooltip-row">
                 <span class="tooltip-label">宸烽亾锛�</span>
                 <span class="tooltip-value">{{ selectedRoadwayNo }}</span>
               </div>
               <div class="tooltip-row">
-                <span class="tooltip-label">娣卞害锛�</span>
-                <span class="tooltip-value">{{ currentLocation.depth === 1 ? '娴�' : '娣�' }}</span>
+                <span class="tooltip-label">璐т綅缂栧彿锛�</span>
+                <span class="tooltip-value">{{ currentLocation?.locationCode || '--' }}</span>
+              </div>
+              <div class="tooltip-row">
+                <span class="tooltip-label">浣嶇疆锛�</span>
+                <span class="tooltip-value">{{ getLocationPosition(currentLocation) }}</span>
               </div>
               <div class="tooltip-row">
                 <span class="tooltip-label">绫诲瀷锛�</span>
-                <span class="tooltip-value">{{ getLocationTypeText(currentLocation.locationType) }}</span>
+                <span class="tooltip-value">{{ getLocationTypeText(currentLocation?.locationType) }}</span>
               </div>
               <div class="tooltip-row">
                 <span class="tooltip-label">鐘舵�侊細</span>
-                <span class="tooltip-value" :class="getStatusClass(currentLocation.locationStatus)">
-                  {{ getStatusText(currentLocation.locationStatus) }}
+                <span class="tooltip-value" :class="getStatusClass(currentLocation?.locationStatus)">
+                  {{ getStatusText(currentLocation?.locationStatus) }}
                 </span>
               </div>
               <div class="tooltip-row">
                 <span class="tooltip-label">鍚敤鐘舵�侊細</span>
-                <span class="tooltip-value" :class="{ 'status-disabled': currentLocation.enableStatus !== 0 }">
-                  {{ getEnableStatusText(currentLocation.enableStatus) }}
+                <span class="tooltip-value" :class="{ 'status-disabled': currentLocation?.enableStatus !== 0 }">
+                  {{ getEnableStatusText(currentLocation?.enableStatus) }}
                 </span>
               </div>
             </div>
@@ -154,12 +169,12 @@
       roadwayNoList: [],
       selectedWarehouse: null,
       selectedRoadwayNo: null,
+      selectedLocationCode: null,
       infoMsg: [
-        { bgcolor: "lightgreen", msg: "绌鸿揣浣�" },
+        { bgcolor: "#2BB3D5", msg: "绌鸿揣浣�" },
         { bgcolor: "orange", msg: "鏈夎揣" },
-        { bgcolor: "#2BB3D5", msg: "閿佸畾" },
-        { bgcolor: "#ccc", msg: "绂佺敤" },
-        { bgcolor: "#b7ba6b", msg: "鍏跺畠" },
+        { bgcolor: "lightgreen", msg: "閿佸畾" },
+        { bgcolor: "#ccc", msg: "绂佺敤" }
       ],
       locationData: [],
       showTooltipFlag: false,
@@ -204,21 +219,51 @@
     }
   },
   methods: {
-    sortedColumns(columns) {
-      // 鎸夊垪鍙锋帓搴�
-      return columns?.sort((a, b) => a.column - b.column) || [];
+    // 鎸夎鍒嗙粍鏁版嵁
+    getRowGroups(layer) {
+      const rowMap = {};
+      
+      // 閬嶅巻鎵�鏈夊垪鍜屾繁搴︼紝鎸夎鍒嗙粍
+      layer.columns?.forEach(column => {
+        column.depths?.forEach(depth => {
+          const row = depth.row || '?';
+          
+          if (!rowMap[row]) {
+            rowMap[row] = {
+              row: row,
+              locations: [],
+              columns: {}
+            };
+          }
+          
+          // 娣诲姞鍒拌琛岀殑浣嶇疆鍒楄〃
+          rowMap[row].locations.push({
+            ...depth,
+            column: column.column,
+            layer: layer.layer
+          });
+          
+          // 鎸夊垪缁勭粐鏁版嵁
+          if (!rowMap[row].columns[column.column]) {
+            rowMap[row].columns[column.column] = {
+              column: column.column,
+              depths: []
+            };
+          }
+          
+          rowMap[row].columns[column.column].depths.push(depth);
+        });
+      });
+      
+      // 杞崲涓烘暟缁勫苟鎸夎鎺掑簭
+      return Object.values(rowMap)
+        .sort((a, b) => this.compareRows(a.row, b.row));
     },
 
-    sortedDepthsByRow(depths) {
-      // 棣栧厛鎸夎(row)鎺掑簭锛岀劧鍚庢寜娣卞害(depth)鎺掑簭
-      return depths?.sort((a, b) => {
-        // 濡傛灉琛屽彿鐩稿悓锛屾寜娣卞害鎺掑簭
-        if (a.row === b.row) {
-          return a.depth - b.depth;
-        }
-        // 鎸夎鍙锋帓搴忥紙杩欓噷鍋囪琛屽彿鏄暟瀛楁垨鍙瘮杈冪殑瀛楃涓诧級
-        return this.compareRows(a.row, b.row);
-      }) || [];
+    sortedColumns(columnsObj) {
+      // 灏嗗璞¤浆鎹负鏁扮粍骞舵寜鍒楀彿鎺掑簭
+      const columns = Object.values(columnsObj || {});
+      return columns.sort((a, b) => a.column - b.column);
     },
 
     // 姣旇緝琛屽彿鐨勮緟鍔╂柟娉�
@@ -229,6 +274,22 @@
       }
       // 鍚﹀垯鎸夊瓧绗︿覆姣旇緝
       return String(rowA).localeCompare(String(rowB));
+    },
+
+    // 鑾峰彇浣嶇疆淇℃伅鐢ㄤ簬鏄剧ず
+    getLocationPositionForDisplay(location, column, layer) {
+      if (!location) return '';
+      const row = location.row || '?';
+      const depthText = location.depth === 1 ? '娴�' : '娣�';
+      return `${row}鎺�${column}鍒�${layer}灞�${depthText}`;
+    },
+
+    // 鑾峰彇浣嶇疆淇℃伅锛堢敤浜庢偓娴彁绀烘锛�
+    getLocationPosition(location) {
+      if (!location || !this.currentColumn || !this.currentLayer) return '--';
+      const row = location.row || '?';
+      const depthText = location.depth === 1 ? '娴�' : '娣�';
+      return `${row}鎺�-${this.currentColumn}鍒�-${this.currentLayer}灞�-${depthText}`;
     },
 
     async fetchWarehouseData() {
@@ -270,13 +331,13 @@
 
         if (response.data && response.status) {
           this.locationData = response.data || [];
-          
-          // 楠岃瘉鏁版嵁涓槸鍚︽湁row瀛楁
-          console.log("璐т綅鏁版嵁绀轰緥:", this.locationData[0]);
+
+          // 楠岃瘉鏁版嵁
+          console.log("璐т綅鏁版嵁:", this.locationData);
           if (this.locationData.length > 0 && this.locationData[0].columns) {
-            console.log("绗竴涓揣浣嶇殑row瀛楁:", this.locationData[0].columns[0]?.depths?.[0]?.row);
+            console.log("绀轰緥璐т綅:", this.locationData[0].columns[0]?.depths?.[0]);
           }
-          
+
           if (this.locationData.length === 0) {
             ElMessage.info("璇ュ贩閬撴病鏈夎揣浣嶆暟鎹�");
           }
@@ -320,10 +381,10 @@
       }
 
       switch (depth.locationStatus) {
-        case 0: return 'location-empty';    // 绌鸿揣浣�
-        case 1: return 'location-locked';   // 閿佸畾
+        case 0: return 'location-empty';     // 绌鸿揣浣�
+        case 1: return 'location-locked';    // 閿佸畾
         case 100: return 'location-occupied'; // 鏈夎揣
-        default: return 'location-other';   // 鍏朵粬鐘舵��
+        default: return 'location-other';
       }
     },
 
@@ -358,11 +419,8 @@
 
     handleLocationClick(depth) {
       console.log('鐐瑰嚮璐т綅:', depth);
-    },
-
-    getLocationCode(location) {
-      if (!location) return '';
-      return `${location.row || '?'}鎺�-${this.currentColumn}鍒�-${this.currentLayer}灞�-${location.depth === 1 ? '娴�' : '娣�'}`;
+      // 杩欓噷鍙互娣诲姞鐐瑰嚮璐т綅鐨勫鐞嗛�昏緫
+      ElMessage.info(`閫変腑璐т綅: ${depth.locationCode || '鏈煡璐т綅'}`);
     },
 
     getStatusText(status) {
@@ -410,7 +468,7 @@
 </script>
 
 <style scoped>
-/* 鏍峰紡閮ㄥ垎淇濇寔涓嶅彉锛屼笌涔嬪墠鐩稿悓 */
+/* 鏍峰紡閮ㄥ垎 */
 .container {
   display: flex;
   flex-direction: column;
@@ -418,20 +476,6 @@
   padding: 16px;
   box-sizing: border-box;
   background-color: #f0f2f5;
-}
-
-.header {
-  text-align: center;
-  margin-bottom: 20px;
-  padding-bottom: 16px;
-  border-bottom: 1px solid #e8e8e8;
-}
-
-.title {
-  font-size: 22px;
-  font-weight: 600;
-  margin: 0;
-  color: #1890ff;
 }
 
 .content-wrapper {
@@ -525,16 +569,6 @@
   border-radius: 4px;
   border: 1px solid rgba(0, 0, 0, 0.1);
   flex-shrink: 0;
-}
-
-.depth-shallow-legend {
-  background-color: rgba(255, 255, 255, 0.7);
-  border: 1px solid #2c3e50;
-}
-
-.depth-deep-legend {
-  background-color: rgba(0, 0, 0, 0.7);
-  border: 1px solid #000;
 }
 
 .legend-label {
@@ -638,48 +672,74 @@
   width: 100%;
   overflow: hidden;
   flex: 1;
+  padding: 16px;
 }
 
-.layer-content {
+/* 琛岀粍鏍峰紡 */
+.row-group {
+  margin-bottom: 10px;
+  padding: 12px;
+  background: white;
+  border-radius: 6px;
+  border: 1px solid #e8e8e8;
+  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
+}
+
+.row-group:last-child {
+  margin-bottom: 0;
+}
+
+.row-title {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 12px;
+  padding-bottom: 8px;
+  border-bottom: 1px dashed #e8e8e8;
+}
+
+.row-label {
+  font-size: 14px;
+  font-weight: 600;
+  color: #333;
+}
+
+.row-count {
+  font-size: 12px;
+  color: #666;
+  background: #f0f0f0;
+  padding: 2px 8px;
+  border-radius: 10px;
+}
+
+.row-content {
   display: flex;
   flex-wrap: wrap;
-  gap: 16px;
-  padding: 16px;
-  min-width: 0;
-  box-sizing: border-box;
+  gap: 8px; /* 鍑忓皬闂磋窛 */
 }
 
+/* 缂╁皬璐т綅妗嗗昂瀵� */
 .location-column {
   flex: 0 0 auto;
-  width: 140px;
-  min-height: 120px;
+  width: 70px; /* 鍑忓皬瀹藉害 */
+  min-height: 30px; /* 鍑忓皬楂樺害 */
   display: flex;
   flex-direction: column;
   box-sizing: border-box;
-}
-
-.column-label {
-  font-size: 13px;
-  font-weight: 600;
-  color: #666;
-  text-align: center;
-  margin-bottom: 8px;
-  padding-bottom: 4px;
-  border-bottom: 1px dashed #ddd;
-  flex-shrink: 0;
 }
 
 .locations-wrapper {
   display: flex;
   flex-direction: column;
-  gap: 6px;
+  gap: 4px; /* 鍑忓皬闂磋窛 */
   flex: 1;
   min-height: 0;
 }
 
+/* 缂╁皬璐т綅椤� */
 .location-item {
-  min-height: 40px;
-  padding: 6px 4px;
+  min-height: 32px; /* 鍑忓皬楂樺害 */
+  padding: 4px 2px; /* 鍑忓皬鍐呰竟璺� */
   border-radius: 4px;
   text-align: center;
   cursor: pointer;
@@ -690,7 +750,7 @@
   flex-direction: column;
   align-items: center;
   justify-content: center;
-  gap: 2px;
+  gap: 1px;
   flex: 1;
 }
 
@@ -700,46 +760,29 @@
   z-index: 10;
 }
 
+/* 缂╁皬璐т綅缂栧彿瀛椾綋 */
 .location-code {
-  font-size: 11px;
+  font-size: 9px; /* 鍑忓皬瀛椾綋 */
   font-weight: 500;
   line-height: 1.2;
   word-break: break-all;
-}
-
-.depth-indicator {
-  font-size: 10px;
-  padding: 2px 4px;
-  border-radius: 3px;
-  margin-top: 2px;
-  font-weight: bold;
-  transition: all 0.2s;
-}
-
-.depth-shallow {
-  background-color: rgba(255, 255, 255, 0.7);
-  color: #2c3e50;
-}
-
-.depth-deep {
-  background-color: rgba(0, 0, 0, 0.7);
-  color: white;
-}
-
-.location-item:hover .depth-indicator {
-  transform: scale(1.1);
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  max-width: 100%;
 }
 
 .location-status {
-  font-size: 10px;
-  padding: 1px 4px;
+  font-size: 8px; /* 鍑忓皬瀛椾綋 */
+  padding: 1px 3px;
   border-radius: 2px;
   background: rgba(0, 0, 0, 0.1);
 }
 
+/* 璐т綅鐘舵�侀鑹� */
 .location-empty {
-  background-color: lightgreen;
-  color: #333;
+  background-color: #2BB3D5;
+  color: white;
 }
 
 .location-occupied {
@@ -748,8 +791,8 @@
 }
 
 .location-locked {
-  background-color: #2BB3D5;
-  color: white;
+  background-color: lightgreen;
+  color: #333;
 }
 
 .location-disabled {
@@ -831,51 +874,7 @@
   color: #f5222d;
 }
 
-@media (max-width: 1200px) {
-  .location-column {
-    width: 130px;
-  }
-}
-
-@media (max-width: 768px) {
-  .content-wrapper {
-    flex-direction: column;
-  }
-
-  .control-panel {
-    width: 100%;
-  }
-
-  .location-column {
-    width: 120px;
-  }
-
-  .layer-content {
-    gap: 12px;
-  }
-}
-
-@media (max-width: 480px) {
-  .location-column {
-    width: 110px;
-  }
-
-  .location-code {
-    font-size: 10px;
-  }
-
-  .layer-content {
-    gap: 10px;
-    padding: 12px;
-  }
-
-  @media (max-width: 380px) {
-    .location-column {
-      width: 100px;
-    }
-  }
-}
-
+/* 婊氬姩鏉℃牱寮� */
 .layers-container::-webkit-scrollbar {
   width: 8px;
 }
@@ -893,4 +892,57 @@
 .layers-container::-webkit-scrollbar-thumb:hover {
   background: #a8a8a8;
 }
+
+/* 鍝嶅簲寮忚璁� */
+@media (max-width: 1200px) {
+  .location-column {
+    width: 95px;
+  }
+}
+
+@media (max-width: 768px) {
+  .content-wrapper {
+    flex-direction: column;
+  }
+
+  .control-panel {
+    width: 100%;
+  }
+
+  .location-column {
+    width: 90px;
+  }
+
+  .row-content {
+    gap: 6px;
+  }
+}
+
+@media (max-width: 480px) {
+  .location-column {
+    width: 80px;
+  }
+
+  .location-code {
+    font-size: 8px;
+  }
+
+  .row-content {
+    gap: 4px;
+  }
+
+  .row-group {
+    padding: 8px;
+  }
+}
+
+@media (max-width: 380px) {
+  .location-column {
+    width: 70px;
+  }
+  
+  .location-code {
+    font-size: 7px;
+  }
+}
 </style>
\ No newline at end of file

--
Gitblit v1.9.3