From 1bf0068b7931ff7de7233ffb219fed5d87fe66b1 Mon Sep 17 00:00:00 2001
From: pan <antony1029@163.com>
Date: 星期四, 04 十二月 2025 10:19:25 +0800
Subject: [PATCH] 提交

---
 项目代码/WIDESEA_WMSClient/src/views/outbound/BatchPickingConfirm.vue | 1223 ++++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 771 insertions(+), 452 deletions(-)

diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/BatchPickingConfirm.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/BatchPickingConfirm.vue"
index 243b5dc..c98438a 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/BatchPickingConfirm.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/BatchPickingConfirm.vue"
@@ -4,29 +4,8 @@
       <el-page-header @back="goBack">
         <template #content>
           <span class="title">鍑哄簱鎷i�夌‘璁� - {{ this.$route.query.orderNo }}</span>
-          <el-tag v-if="currentBatchNo" type="success" style="margin-left: 10px;">
-            褰撳墠鎵规: {{ currentBatchNo }}
-          </el-tag>
         </template>
       </el-page-header>
-    </div>
-
-    <!-- 鎵规鎿嶄綔鍖哄煙 -->
-    <div class="batch-operations">
-      <el-card>
-        <div class="batch-actions">
-          <el-button type="primary" @click="openBatchAllocateDialog">鍒嗘壒鍒嗛厤</el-button>
-          <el-select v-model="selectedBatchNo" placeholder="閫夋嫨鎵规" @change="onBatchChange" style="width: 200px; margin-left: 10px;">
-            <el-option
-              v-for="batch in batchList"
-              :key="batch.batchNo"
-              :label="`${batch.batchNo} (${batch.batchStatusText})`"
-              :value="batch.batchNo">
-            </el-option>
-          </el-select>
-          <el-button type="info" @click="refreshBatchList">鍒锋柊鎵规</el-button>
-        </div>
-      </el-card>
     </div>
 
     <!-- 鎵爜鍖哄煙 -->
@@ -52,21 +31,6 @@
           <el-button type="info" @click="openRevertSplitDialog">鎾ら攢鎷嗗寘</el-button>
           <el-button type="info" @click="handleEmptyPallet">鍙栫┖绠�</el-button>
           <el-button type="primary" @click="openBatchReturnDialog">鍥炲簱</el-button>
-        </div>
-      </el-card>
-    </div>
-
-    <!-- 鎵规姹囨�讳俊鎭� -->
-    <div class="batch-summary-area" v-if="currentBatchNo">
-      <el-card>
-        <div class="batch-summary-info">
-          <el-tag type="info">鎵规鍙�: {{ batchSummary.batchNo }}</el-tag>
-          <el-tag :type="getBatchStatusType(batchSummary.batchStatus)">
-            {{ batchSummary.batchStatusText }}
-          </el-tag>
-          <el-tag type="warning">鍒嗛厤鏁伴噺: {{ batchSummary.batchQuantity }}</el-tag>
-          <el-tag type="success">瀹屾垚鏁伴噺: {{ batchSummary.completedQuantity }}</el-tag>
-          <el-tag type="danger">鍓╀綑鏁伴噺: {{ batchSummary.remainingQuantity }}</el-tag>
         </div>
       </el-card>
     </div>
@@ -119,7 +83,7 @@
               <el-table-column type="selection" width="55"></el-table-column>
               <el-table-column prop="materielCode" label="鐗╂枡缂栫爜" width="120"></el-table-column>
               <el-table-column prop="pickedQty" label="宸叉嫞鏁伴噺" width="100"></el-table-column>
-              <el-table-column prop="locationCode" label="璐т綅" width="100"></el-table-column>
+              <!-- <el-table-column prop="locationCode" label="璐т綅" width="100"></el-table-column> -->
               <el-table-column prop="currentBarcode" label="鏉$爜"></el-table-column>
             </el-table>
           </el-card>
@@ -127,54 +91,8 @@
       </el-row>
     </div>
 
-    <!-- 鍒嗘壒鍒嗛厤寮圭獥 -->
-    <div v-if="showBatchAllocateDialog" class="custom-dialog-overlay">
-      <div class="custom-dialog-wrapper">
-        <div class="custom-dialog">
-          <div class="custom-dialog-header">
-            <h3>鍒嗘壒鍒嗛厤搴撳瓨</h3>
-            <el-button type="text" @click="closeBatchAllocateDialog" class="close-button">脳</el-button>
-          </div>
-          <div class="custom-dialog-body">
-            <el-form :model="batchAllocateForm" :rules="batchAllocateFormRules" ref="batchAllocateFormRef" label-width="100px">
-              <el-form-item label="璁㈠崟缂栧彿">
-                <el-input v-model="batchAllocateForm.orderNo" disabled></el-input>
-              </el-form-item>
-              <el-form-item label="鐗╂枡鏄庣粏" prop="orderDetailId">
-                <el-select v-model="batchAllocateForm.orderDetailId" placeholder="閫夋嫨鐗╂枡鏄庣粏" style="width: 100%">
-                  <el-option
-                    v-for="detail in allocatableDetails"
-                    :key="detail.id"
-                    :label="`${detail.materielCode} - 闇�姹�:${detail.needOutQuantity} 宸插垎閰�:${detail.allocatedQuantity} 鍙垎閰�:${detail.availableQuantity}`"
-                    :value="detail.id">
-                  </el-option>
-                </el-select>
-              </el-form-item>
-              <el-form-item label="鍒嗛厤鏁伴噺" prop="batchQuantity">
-                <el-input-number 
-                  v-model="batchAllocateForm.batchQuantity" 
-                  :min="0.01" 
-                  :precision="2"
-                  :step="1"
-                  style="width: 100%"
-                  placeholder="杈撳叆鍒嗛厤鏁伴噺">
-                </el-input-number>
-              </el-form-item>
-              <el-form-item label="鍙垎閰嶆暟閲�">
-                <el-input :value="getAvailableQuantity()" disabled></el-input>
-              </el-form-item>
-            </el-form>
-          </div>
-          <div class="custom-dialog-footer">
-            <el-button @click="closeBatchAllocateDialog">鍙栨秷</el-button>
-            <el-button type="primary" @click="handleBatchAllocate" :loading="batchAllocateLoading">纭鍒嗛厤</el-button>
-          </div>
-        </div>
-      </div>
-    </div>
-
     <!-- 鎷嗗寘寮圭獥 -->
-    <div v-if="showCustomSplitDialog" class="custom-dialog-overlay">
+    <div  v-show="showCustomSplitDialog" class="custom-dialog-overlay">
       <div class="custom-dialog-wrapper">
         <div class="custom-dialog">
           <div class="custom-dialog-header">
@@ -186,20 +104,28 @@
               <el-form-item label="璁㈠崟缂栧彿">
                 <el-input v-model="splitForm.orderNo" disabled></el-input>
               </el-form-item>
-              <el-form-item label="鎵规缂栧彿">
-                <el-input v-model="splitForm.batchNo" disabled></el-input>
-              </el-form-item>
               <el-form-item label="鎵樼洏缂栧彿">
                 <el-input v-model="splitForm.palletCode" disabled></el-input>
               </el-form-item>
               <el-form-item label="鍘熸潯鐮�" prop="originalBarcode">
-                <el-input 
-                  v-model="splitForm.originalBarcode" 
-                  placeholder="鎵弿鍘熸潯鐮�"
-                  @keyup.enter.native="onSplitBarcodeScan"
-                  @change="onSplitBarcodeScan"
-                  clearable>
-                </el-input>
+                <div style="display: flex; align-items: center; gap: 10px;">
+                  <el-input 
+                    v-model="splitForm.originalBarcode" 
+                    placeholder="鎵弿鍘熸潯鐮�"
+                    @keyup.enter.native="onSplitBarcodeScan"
+                    @change="onSplitBarcodeScan"
+                    clearable
+                    style="flex: 1;">
+                  </el-input>
+                  <!-- 鏂板锛氭煡鐪嬫媶鍖呴摼鎸夐挳 -->
+                  <el-button 
+  type="primary" 
+  @click="viewSplitChainFromSplit(splitForm.originalBarcode)" 
+  :disabled="!splitForm.originalBarcode"
+  :loading="splitChainLoading">
+  鏌ョ湅鎷嗗寘閾�
+</el-button>
+                </div>
               </el-form-item>
               <el-form-item label="鐗╂枡缂栫爜">
                 <el-input v-model="splitForm.materielCode" disabled></el-input>
@@ -228,7 +154,7 @@
     </div>
 
     <!-- 鎾ら攢鎷嗗寘寮圭獥 -->
-    <div v-if="showRevertSplitDialog" class="custom-dialog-overlay">
+    <div  v-show="showRevertSplitDialog" class="custom-dialog-overlay">
       <div class="custom-dialog-wrapper">
         <div class="custom-dialog">
           <div class="custom-dialog-header">
@@ -238,15 +164,46 @@
           <div class="custom-dialog-body">
             <el-form :model="revertSplitForm" :rules="revertSplitFormRules" ref="revertSplitFormRef" label-width="100px">
               <el-form-item label="鏂版潯鐮�" prop="newBarcode">
-                <el-input 
-                  v-model="revertSplitForm.newBarcode" 
-                  placeholder="鎵弿鏂版潯鐮�"
-                  @keyup.enter.native="onRevertSplitBarcodeScan"
-                  @change="onRevertSplitBarcodeScan"
-                  clearable>
-                </el-input>
+                <div style="display: flex; align-items: center; gap: 10px;">
+                  <el-input 
+                    v-model="revertSplitForm.newBarcode" 
+                    placeholder="鎵弿鏂版潯鐮�"
+                    @keyup.enter.native="onRevertSplitBarcodeScan"
+                    @change="onRevertSplitBarcodeScan"
+                    clearable
+                    style="flex: 1;">
+                  </el-input>
+                  <!-- 鏂板锛氭煡鐪嬫媶鍖呴摼鎸夐挳 -->
+                  <el-button 
+                    type="primary" 
+                    @click="viewSplitChain(revertSplitForm.newBarcode)" 
+                    :disabled="!revertSplitForm.newBarcode">
+                    鏌ョ湅鎷嗗寘閾�
+                  </el-button>
+                </div>
               </el-form-item>
             </el-form>
+            
+            <!-- 鏂板锛氭媶鍖呴摼绠�瑕佷俊鎭樉绀� -->
+            <div v-if="splitChainInfo.splitChain && splitChainInfo.splitChain.length > 0" 
+                 style="margin-top: 15px; padding: 10px; background: #f0f9ff; border-radius: 4px;">
+              <div style="font-size: 14px; color: #606266;">
+                <div>鎷嗗寘閾句俊鎭�: 鍏� {{ splitChainInfo.totalSplitTimes }} 娆℃媶鍖�</div>
+                <div style="margin-top: 5px;">
+                  <el-tag 
+                    v-for="item in splitChainInfo.splitChain.slice(0, 3)" 
+                    :key="item.newBarcode"
+                    :type="item.isReverted ? 'success' : 'primary'"
+                    size="small"
+                    style="margin-right: 5px;">
+                    {{ item.newBarcode }} ({{ item.splitQuantity }})
+                  </el-tag>
+                  <span v-if="splitChainInfo.splitChain.length > 3" style="color: #909399;">
+                    绛� {{ splitChainInfo.splitChain.length }} 涓潯鐮�
+                  </span>
+                </div>
+              </div>
+            </div>
           </div>
           <div class="custom-dialog-footer">
             <el-button @click="closeRevertSplitDialog">鍙栨秷</el-button>
@@ -256,12 +213,136 @@
       </div>
     </div>
 
+    <!-- 鎷嗗寘閾句俊鎭脊绐� -->
+<div v-show="showSplitChainDialog" class="custom-dialog-overlay">
+  <div class="custom-dialog-wrapper">
+    <div class="custom-dialog" style="width: 750px;">
+      <div class="custom-dialog-header">
+        <h3>鎷嗗寘閾句俊鎭�</h3>
+        <el-button type="text" @click="closeSplitChainDialog" class="close-button">脳</el-button>
+      </div>
+      <div class="custom-dialog-body">
+        <!-- 鏂板锛氭媶鍖呴摼璇存槑 -->
+        <div style="margin-bottom: 15px; padding: 10px; background: #f0f9ff; border-radius: 4px;">
+          <div style="display: flex; justify-content: space-between; align-items: center;">
+            <div>
+              <div style="font-weight: bold; color: #303133;">鎷嗗寘閾捐鏄�</div>
+              <div style="font-size: 12px; color: #606266; margin-top: 5px;">
+                褰撳墠鏄剧ず鐨勬槸浠� <el-tag type="primary" size="small">{{ splitChainInfo.originalBarcode }}</el-tag> 寮�濮嬬殑鎷嗗寘閾�
+                <br>鍏� {{ splitChainInfo.totalSplitTimes }} 娆℃媶鍖呮搷浣滐紝娑夊強 {{ splitChainInfo.splitChain.length }} 涓潯鐮�
+              </div>
+            </div>
+            <el-button 
+              type="primary" 
+              size="small" 
+              @click="findRootChain(splitChainInfo.originalBarcode)"
+              v-if="splitChainInfo.chainType !== 'root'">
+              鏌ユ壘瀹屾暣鎷嗗寘閾�
+            </el-button>
+          </div>
+        </div>
+        
+        <div style="margin-bottom: 15px;">
+          <el-tag type="info">鎬绘媶鍖呮鏁�: {{ splitChainInfo.totalSplitTimes }}</el-tag>
+          <el-tag type="warning" style="margin-left: 10px;">
+            鍘熷鏉$爜: {{ splitChainInfo.originalBarcode }}
+          </el-tag>
+          <el-tag :type="splitChainInfo.chainType === 'root' ? 'success' : 'warning'" style="margin-left: 10px;">
+            {{ splitChainInfo.chainType === 'root' ? '瀹屾暣閾�' : '鍒嗘敮閾�' }}
+          </el-tag>
+        </div>
+        
+        <el-table :data="splitChainInfo.splitChain" border height="300">
+          <el-table-column type="index" label="搴忓彿" width="60" align="center"></el-table-column>
+          <el-table-column prop="splitTime" label="鎷嗗寘鏃堕棿" width="160">
+            <template #default="scope">
+              {{ formatDateTime(scope.row.splitTime) }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="originalBarcode" label="鍘熸潯鐮�" width="140">
+            <template #default="scope">
+              <el-tag 
+                :type="scope.row.originalBarcode === splitChainInfo.rootBarcode ? 'success' : 'primary'" 
+                size="small">
+                {{ scope.row.originalBarcode }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column prop="newBarcode" label="鏂版潯鐮�" width="140">
+            <template #default="scope">
+              <el-tag 
+                :type="scope.row.isReverted ? 'info' : 'warning'" 
+                size="small">
+                {{ scope.row.newBarcode }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column prop="splitQuantity" label="鎷嗗寘鏁伴噺" width="100" align="right">
+            <template #default="scope">
+              {{ scope.row.splitQuantity.toFixed(2) }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="operator" label="鎿嶄綔鍛�" width="100"></el-table-column>
+          <el-table-column prop="isReverted" label="鐘舵��" width="80" align="center">
+            <template #default="scope">
+              <el-tag 
+                :type="scope.row.isReverted ? 'success' : 'danger'" 
+                size="small">
+                {{ scope.row.isReverted ? '宸叉挙閿�' : '鏈夋晥' }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="鎿嶄綔" width="120" align="center">
+            <template #default="scope">
+              <el-button 
+                v-if="!scope.row.isReverted"
+                type="danger" 
+                size="mini" 
+                @click="cancelSingleSplit(scope.row.newBarcode)"
+                :disabled="hasPicked(scope.row.newBarcode)">
+                鍙栨秷
+              </el-button>
+              <span v-else style="color: #909399;">宸叉挙閿�</span>
+            </template>
+          </el-table-column>
+        </el-table>
+        
+        <!-- 鎵归噺鎿嶄綔鍖哄煙 -->
+        <div style="margin-top: 15px; padding: 10px; background: #f5f7fa; border-radius: 4px;">
+          <div style="display: flex; justify-content: space-between; align-items: center;">
+            <div>
+              <span style="font-size: 14px; color: #606266;">
+                鎵归噺鎿嶄綔: 鍙互鍙栨秷鏁翠釜鎷嗗寘閾炬垨閫夋嫨鍗曚釜鎷嗗寘璁板綍鍙栨秷
+              </span>
+              <div style="font-size: 12px; color: #909399; margin-top: 5px;">
+                瀹屾暣鎷嗗寘閾惧寘鍚粠鏈�鍘熷鏉$爜寮�濮嬬殑鎵�鏈夋媶鍖呮搷浣�
+              </div>
+            </div>
+            <div>
+              <el-button 
+                type="danger" 
+                @click="cancelWholeSplitChain"
+                :disabled="!canCancelWholeChain"
+                :loading="revertSplitLoading">
+                鍙栨秷鏁翠釜鎷嗗寘閾�
+              </el-button>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="custom-dialog-footer">
+        <el-button @click="closeSplitChainDialog">鍏抽棴</el-button>
+      </div>
+    </div>
+  </div>
+</div>
+
     <!-- 鎵归噺鍥炲簱寮圭獥 -->
     <div v-if="showBatchReturnDialog" class="custom-dialog-overlay">
       <div class="custom-dialog-wrapper">
         <div class="custom-dialog">
           <div class="custom-dialog-header">
-            <h3>鎵规鍥炲簱</h3>
+            <h3>鎵樼洏鍥炲簱</h3>
             <el-button type="text" @click="closeBatchReturnDialog" class="close-button">脳</el-button>
           </div>
           <div class="custom-dialog-body">
@@ -269,8 +350,8 @@
               <el-form-item label="璁㈠崟缂栧彿">
                 <el-input v-model="batchReturnForm.orderNo" disabled></el-input>
               </el-form-item>
-              <el-form-item label="鎵规缂栧彿">
-                <el-input v-model="batchReturnForm.batchNo" disabled></el-input>
+              <el-form-item label="鎵樼洏缂栧彿">
+                <el-input v-model="batchReturnForm.palletCode" disabled></el-input>
               </el-form-item>
               <el-form-item label="鏈嫞閫夋暟閲�">
                 <el-input v-model="batchReturnForm.unpickedQuantity" disabled></el-input>
@@ -335,36 +416,12 @@
   name: 'BatchOutboundPicking',
   components: {printView},
   data() {
-    // 楠岃瘉瑙勫垯瀹氫箟...
-    const validateBatchQuantity = (rule, value, callback) => {
-      if (value === null || value === undefined || value === '') {
-        callback(new Error('璇疯緭鍏ュ垎閰嶆暟閲�'));
-      } else if (value <= 0) {
-        callback(new Error('鍒嗛厤鏁伴噺蹇呴』澶т簬0'));
-      } else {
-        callback();
-      }
-    };
-
-    const validateOrderDetailId = (rule, value, callback) => {
-      if (!value) {
-        callback(new Error('璇烽�夋嫨鐗╂枡鏄庣粏'));
-      } else {
-        callback();
-      }
-    };
-
     return {
       scanData: {
         orderNo: '',
         palletCode: '',
-        barcode: '',
-        batchNo: ''
+        barcode: ''
       },
-      currentBatchNo: '', // 褰撳墠鎵规鍙�
-      batchList: [], // 鎵规鍒楄〃
-      selectedBatchNo: '', // 閫変腑鐨勬壒娆″彿
-      batchSummary: {}, // 鎵规姹囨�讳俊鎭�
       unpickedList: [],
       pickedList: [],
       selectedPickedRows: [],
@@ -376,30 +433,22 @@
       palletStatus: '鏈煡',
       
       // 寮圭獥鐘舵��
-      showBatchAllocateDialog: false,
       showCustomSplitDialog: false,
       showRevertSplitDialog: false,
       showBatchReturnDialog: false,
       showEmptyPalletDialog: false,
+      showSplitChainDialog: false, // 鏂板锛氭媶鍖呴摼淇℃伅寮圭獥
       
       // 鍔犺浇鐘舵��
-      batchAllocateLoading: false,
       splitLoading: false,
       revertSplitLoading: false,
       batchReturnLoading: false,
       emptypalletOutLoading: false,
+      splitChainLoading: false, // 鏂板锛氭媶鍖呴摼鍔犺浇鐘舵��
       
       // 琛ㄥ崟鏁版嵁
-      batchAllocateForm: {
-        orderNo: '',
-        orderDetailId: '',
-        batchQuantity: 0
-      },
-      allocatableDetails: [], // 鍙垎閰嶇殑璁㈠崟鏄庣粏
-      
       splitForm: {
         orderNo: '',
-        batchNo: '',
         palletCode: '',
         originalBarcode: '',
         materielCode: '',
@@ -413,7 +462,7 @@
       
       batchReturnForm: {
         orderNo: '',
-        batchNo: '',
+        palletCode: '',
         unpickedCount: 0,
         unpickedQuantity: 0
       },
@@ -423,25 +472,128 @@
         palletCode: ''
       },
       
+      // 鏂板锛氭媶鍖呴摼鐩稿叧鏁版嵁
+      splitChainInfo: {
+        originalBarcode: '',
+        totalSplitTimes: 0,
+        splitChain: []
+      },
+      
       // 楠岃瘉瑙勫垯
-      batchAllocateFormRules: {
-        orderDetailId: [
-          { required: true, validator: validateOrderDetailId, trigger: 'change' }
+      splitFormRules: {
+        originalBarcode: [
+          { required: true, message: '璇疯緭鍏ュ師鏉$爜', trigger: 'blur' }
         ],
-        batchQuantity: [
-          { required: true, validator: validateBatchQuantity, trigger: 'blur' }
+        splitQuantity: [
+          { required: true, message: '璇疯緭鍏ユ媶鍖呮暟閲�', trigger: 'blur' },
+          { type: 'number', min: 0.01, message: '鎷嗗寘鏁伴噺蹇呴』澶т簬0', trigger: 'blur' }
         ]
       },
       
-      // 鍏朵粬楠岃瘉瑙勫垯...
+      revertSplitFormRules: {
+        newBarcode: [
+          { required: true, message: '璇疯緭鍏ユ柊鏉$爜', trigger: 'blur' }
+        ]
+      },
+      
+      emptypalletOutFormRules: {
+        palletCode: [
+          { required: true, message: '璇疯緭鍏ユ墭鐩樼爜', trigger: 'blur' }
+        ]
+      },
+       // 寮圭獥鐘舵�� - 鏀逛负浣跨敤瀵硅薄绠$悊锛岄伩鍏嶅悓鏃舵墦寮�澶氫釜寮圭獥
+      dialogs: {
+        customSplit: false,
+        revertSplit: false,
+        splitChain: false,
+        batchReturn: false,
+        emptyPallet: false
+      },
+      
+      // 鍔犺浇鐘舵��
+      loading: {
+        split: false,
+        revertSplit: false,
+        batchReturn: false,
+        emptyPallet: false,
+        splitChain: false
+      },
+      
+      // 褰撳墠娲诲姩鐨勫脊绐楃被鍨�
+      activeDialog: null,
       isProcessing: false
+    }
+  },
+  computed: {
+     // 璁$畻灞炴�ф槧灏勫埌dialogs瀵硅薄
+    showCustomSplitDialog: {
+      get() { return this.dialogs.customSplit; },
+      set(val) { 
+        this.dialogs.customSplit = val;
+        this.activeDialog = val ? 'customSplit' : null;
+      }
+    },
+    showRevertSplitDialog: {
+      get() { return this.dialogs.revertSplit; },
+      set(val) { 
+        this.dialogs.revertSplit = val;
+        this.activeDialog = val ? 'revertSplit' : null;
+      }
+    },
+    showSplitChainDialog: {
+      get() { return this.dialogs.splitChain; },
+      set(val) { 
+        this.dialogs.splitChain = val;
+        this.activeDialog = val ? 'splitChain' : null;
+      }
+    },
+    showBatchReturnDialog: {
+      get() { return this.dialogs.batchReturn; },
+      set(val) { 
+        this.dialogs.batchReturn = val;
+        this.activeDialog = val ? 'batchReturn' : null;
+      }
+    },
+    showEmptyPalletDialog: {
+      get() { return this.dialogs.emptyPallet; },
+      set(val) { 
+        this.dialogs.emptyPallet = val;
+        this.activeDialog = val ? 'emptyPallet' : null;
+      },
+    },
+     // 鍔犺浇鐘舵�佹槧灏�
+    splitLoading: {
+      get() { return this.loading.split; },
+      set(val) { this.loading.split = val; }
+    },
+    revertSplitLoading: {
+      get() { return this.loading.revertSplit; },
+      set(val) { this.loading.revertSplit = val; }
+    },
+    batchReturnLoading: {
+      get() { return this.loading.batchReturn; },
+      set(val) { this.loading.batchReturn = val; }
+    },
+    emptypalletOutLoading: {
+      get() { return this.loading.emptyPallet; },
+      set(val) { this.loading.emptyPallet = val; }
+    },
+    splitChainLoading: {
+      get() { return this.loading.splitChain; },
+      set(val) { this.loading.splitChain = val; }
+    },
+    // 鏄惁鍙互鍙栨秷鏁翠釜鎷嗗寘閾�
+    canCancelWholeChain() {
+      return this.splitChainInfo.splitChain && 
+             this.splitChainInfo.splitChain.some(item => !item.isReverted);
     }
   },
   mounted() {
     if (this.$route.query.orderNo) {
       this.scanData.orderNo = this.$route.query.orderNo;
-      this.batchAllocateForm.orderNo = this.$route.query.orderNo;
-      this.loadBatchList();
+      this.splitForm.orderNo = this.$route.query.orderNo;
+      this.batchReturnForm.orderNo = this.$route.query.orderNo;
+      this.emptypalletOutForm.orderNo = this.$route.query.orderNo;
     }
     this.$nextTick(() => {
       this.$refs.palletInput.focus();
@@ -450,150 +602,6 @@
   methods: {
     goBack(){
       this.$router.back()
-    },
-
-    // 鎵规鐩稿叧鏂规硶
-    async loadBatchList() {
-      try {
-        const res = await http.post('/api/BatchOutbound/order-batch-list', {
-          orderNo: this.scanData.orderNo
-        });
-        if (res.status) {
-          this.batchList = res.data || [];
-          if (this.batchList.length > 0) {
-            this.selectedBatchNo = this.batchList[0].batchNo;
-            this.currentBatchNo = this.selectedBatchNo;
-            this.scanData.batchNo = this.selectedBatchNo;
-            this.loadBatchData();
-          }
-        }
-      } catch (error) {
-        this.$message.error('鍔犺浇鎵规鍒楄〃澶辫触');
-      }
-    },
-
-    async refreshBatchList() {
-      await this.loadBatchList();
-      this.$message.success('鎵规鍒楄〃宸插埛鏂�');
-    },
-
-    onBatchChange(batchNo) {
-      this.currentBatchNo = batchNo;
-      this.scanData.batchNo = batchNo;
-      this.loadBatchData();
-    },
-
-    async loadBatchData() {
-      if (!this.currentBatchNo) return;
-      
-      await this.loadBatchSummary();
-      await this.loadUnpickedList();
-      await this.loadPickedList();
-    },
-
-    async loadBatchSummary() {
-      try {
-        const res = await http.post('/api/BatchOutbound/batch-summary', {
-          orderNo: this.scanData.orderNo,
-          batchNo: this.currentBatchNo
-        });
-        if (res.status) {
-          this.batchSummary = res.data || {};
-        }
-      } catch (error) {
-        this.$message.error('鍔犺浇鎵规姹囨�诲け璐�');
-      }
-    },
-
-    async loadUnpickedList() {
-      try {
-        const res = await http.post('/api/BatchOutbound/batch-unpicked-list', {
-          orderNo: this.scanData.orderNo,
-          batchNo: this.currentBatchNo
-        });
-        this.unpickedList = res.data || [];
-        this.summary.unpickedCount = this.unpickedList.length;
-        this.summary.unpickedQuantity = this.unpickedList.reduce((sum, item) => sum + (item.remainQuantity || 0), 0);
-      } catch (error) {
-        this.$message.error('鍔犺浇鏈嫞閫夊垪琛ㄥけ璐�');
-      }
-    },
-
-    async loadPickedList() {
-      try {
-        const res = await http.post('/api/BatchOutbound/batch-picked-list', {
-          orderNo: this.scanData.orderNo,
-          batchNo: this.currentBatchNo
-        });
-        this.pickedList = res.data || [];
-        this.summary.pickedCount = this.pickedList.length;
-      } catch (error) {
-        this.$message.error('鍔犺浇宸叉嫞閫夊垪琛ㄥけ璐�');
-      }
-    },
-
-    getBatchStatusType(status) {
-      const statusMap = {
-        0: 'info', // 鍒嗛厤涓�
-        1: 'warning', // 鎵ц涓�
-        2: 'success', // 宸插畬鎴�
-        3: 'danger' // 宸插洖搴�
-      };
-      return statusMap[status] || 'info';
-    },
-
-    // 鍒嗘壒鍒嗛厤鐩稿叧鏂规硶
-    async openBatchAllocateDialog() {
-      this.showBatchAllocateDialog = true;
-      await this.loadAllocatableDetails();
-      this.batchAllocateForm.orderDetailId = '';
-      this.batchAllocateForm.batchQuantity = 0;
-    },
-
-    async loadAllocatableDetails() {
-      try {
-        const res = await http.post('/api/BatchOutbound/allocatable-order-details', {
-          orderNo: this.scanData.orderNo
-        });
-        if (res.status) {
-          this.allocatableDetails = res.data || [];
-        }
-      } catch (error) {
-        this.$message.error('鍔犺浇鍙垎閰嶆槑缁嗗け璐�');
-      }
-    },
-
-    getAvailableQuantity() {
-      const detail = this.allocatableDetails.find(d => d.id === this.batchAllocateForm.orderDetailId);
-      return detail ? detail.availableQuantity : 0;
-    },
-
-    async handleBatchAllocate() {
-      if (this.$refs.batchAllocateFormRef) {
-        this.$refs.batchAllocateFormRef.validate(async (valid) => {
-          if (valid) {
-            this.batchAllocateLoading = true;
-            try {
-              const res = await http.post('/api/BatchOutbound/batch-allocate-stock', this.batchAllocateForm);
-              if (res.status) {
-                this.$message.success('鍒嗘壒鍒嗛厤鎴愬姛');
-                this.showBatchAllocateDialog = false;
-                await this.loadBatchList(); // 鍒锋柊鎵规鍒楄〃
-              } else {
-                this.$message.error(res.message || '鍒嗘壒鍒嗛厤澶辫触');
-              }
-            } catch (error) {
-              this.$message.error('鍒嗘壒鍒嗛厤澶辫触');
-            } finally {
-              this.batchAllocateLoading = false;
-            }
-          }
-        });
-      }
-    },
-
-    closeBatchAllocateDialog() {
-      this.showBatchAllocateDialog = false;
     },
 
     // 鍒嗘嫞鐩稿叧鏂规硶
@@ -606,21 +614,20 @@
         return;
       }
 
-      if (!this.currentBatchNo) {
-        this.$message.warning('璇峰厛閫夋嫨鎵规');
-        return;
-      }
-
       this.isProcessing = true;
       
       try {
-        const res = await http.post('/api/BatchOutbound/confirm-picking', this.scanData);
+        const res = await http.post('/api/OutboundBatchPicking/confirm-picking', {
+          orderNo: this.scanData.orderNo,
+          palletCode: this.scanData.palletCode,
+          barcode: this.scanData.barcode
+        });
         if (res.status) {
           this.$message.success('鎷i�夌‘璁ゆ垚鍔�');
           this.scanData.barcode = '';
-          await this.loadBatchData();
-          if(res.data && res.data.splitResults && res.data.splitResults.length>0){
-            this.$refs.childs.open(res.data.splitResults);
+          await this.loadPalletData();
+          if(res.data && res.data && res.data.length>0){
+            this.$refs.childs.open(res.data);
           }
           this.$nextTick(() => {
             this.$refs.barcodeInput.focus();
@@ -643,15 +650,23 @@
         this.$message.warning('璇峰厛鎵弿鎵樼洏鐮�');
         return;
       }
-      if (!this.currentBatchNo) {
-        this.$message.warning('璇峰厛閫夋嫨鎵规');
-        return;
-      }
-      this.showCustomSplitDialog = true;
-      this.resetSplitForm();
-      this.splitForm.orderNo = this.scanData.orderNo;
-      this.splitForm.batchNo = this.currentBatchNo;
-      this.splitForm.palletCode = this.scanData.palletCode;
+         // 鍏抽棴鍏朵粬鎵�鏈夊脊绐�
+      this.closeAllDialogs();
+        // 寤惰繜鎵撳紑鏂板脊绐楋紝纭繚鍏朵粬寮圭獥瀹屽叏鍏抽棴
+      this.$nextTick(() => {
+        this.showCustomSplitDialog = true;
+        this.resetSplitForm();
+        this.splitForm.orderNo = this.scanData.orderNo;
+        this.splitForm.palletCode = this.scanData.palletCode;
+        
+        // 纭繚杈撳叆妗嗚幏寰楃劍鐐�
+        this.$nextTick(() => {
+          const inputs = document.querySelectorAll('.custom-dialog input');
+          if (inputs.length > 0) {
+            inputs[0].focus();
+          }
+        });
+      });
     },
 
     async onSplitBarcodeScan() {
@@ -659,13 +674,16 @@
       this.splitForm.originalBarcode = this.splitForm.originalBarcode.replace(/\n/g, '').trim();
 
       try {
-        const res = await http.post('/api/BatchOutbound/split-package-info', {
+        const res = await http.post('/api/OutboundBatchPicking/split-package-info', {
           orderNo: this.splitForm.orderNo,
-          batchNo: this.splitForm.batchNo,
+          palletCode: this.splitForm.palletCode,
           barcode: this.splitForm.originalBarcode
         });
 
         if (res.status) {
+            if(res.data && res.data.length>0){           
+            this.$refs.childs.open(res.data); 
+          }
           this.splitForm.materielCode = res.data.materielCode;
           this.splitForm.maxQuantity = res.data.remainQuantity;
           this.splitForm.splitQuantity = Math.min(1, this.splitForm.maxQuantity);
@@ -679,145 +697,440 @@
 
     async handleSplitPackage() {
       if (this.$refs.splitFormRef) {
-        this.$refs.splitFormRef.validate(async (valid) => {
-          if (valid) {
-            this.splitLoading = true;
-            try {
-              const res = await http.post('/api/BatchOutbound/manual-split-package', this.splitForm);
-              if (res.status) {
-                this.$message.success('鎷嗗寘鎴愬姛');
-                this.showCustomSplitDialog = false;
-                await this.loadBatchData();
-              } else {
-                this.$message.error(res.message || '鎷嗗寘澶辫触');
-              }
-            } catch (error) {
-              this.$message.error('鎷嗗寘澶辫触');
-            } finally {
-              this.splitLoading = false;
-            }
+        const valid = await this.$refs.splitFormRef.validate();
+        if (!valid) return;
+        
+        this.splitLoading = true;
+        try {
+          const res = await http.post('/api/OutboundBatchPicking/split-package', {
+            orderNo: this.splitForm.orderNo,
+            palletCode: this.splitForm.palletCode,
+            originalBarcode: this.splitForm.originalBarcode,
+            splitQuantity: this.splitForm.splitQuantity
+          });
+          if (res.status) {
+            this.$message.success('鎷嗗寘鎴愬姛');
+            this.showCustomSplitDialog = false;
+            await this.loadPalletData();
+          } else {
+            this.$message.error(res.message || '鎷嗗寘澶辫触');
           }
-        });
+        } catch (error) {
+          this.$message.error('鎷嗗寘澶辫触: ' + (error.message || '缃戠粶閿欒'));
+        } finally {
+          this.splitLoading = false;
+        }
       }
     },
-
+// 鍦ㄦ媶鍖呭脊绐椾腑鏌ョ湅鎷嗗寘閾�
+async viewSplitChainFromSplit(barcode) {
+  if (!barcode) {
+    this.$message.warning('璇峰厛杈撳叆鏉$爜');
+    return;
+  }
+  
+  // 鍏堝叧闂媶鍖呭脊绐�
+  this.closeCustomSplitDialog();
+  
+  await this.$nextTick();
+  
+  // 鐒跺悗鎵撳紑鎷嗗寘閾句俊鎭脊绐�
+  await this.viewSplitChain(barcode);
+},
     // 鎾ら攢鎷嗗寘
     async onRevertSplitBarcodeScan() {
-      if (!this.revertSplitForm.newBarcode) return;
+        if (!this.revertSplitForm.newBarcode) return;
       this.revertSplitForm.newBarcode = this.revertSplitForm.newBarcode.replace(/\n/g, '').trim();
     },
 
     async handleRevertSplit() {
-      if (this.$refs.revertSplitFormRef) {
-        this.$refs.revertSplitFormRef.validate(async (valid) => {
-          if (valid) {
-            this.revertSplitLoading = true;
-            try {
-              const res = await http.post('/api/BatchOutbound/cancel-split-package', {
-                orderNo: this.scanData.orderNo,
-                batchNo: this.currentBatchNo,
-                newBarcode: this.revertSplitForm.newBarcode
-              });
-              if (res.status) {
-                this.$message.success('鎾ら攢鎷嗗寘鎴愬姛');
-                this.showRevertSplitDialog = false;
-                await this.loadBatchData();
-              } else {
-                this.$message.error(res.message || '鎾ら攢鎷嗗寘澶辫触');
-              }
-            } catch (error) {
-              this.$message.error('鎾ら攢鎷嗗寘澶辫触');
-            } finally {
-              this.revertSplitLoading = false;
-            }
+       if (this.$refs.revertSplitFormRef) {
+        const valid = await this.$refs.revertSplitFormRef.validate();
+        if (!valid) return;
+        
+        this.revertSplitLoading = true;
+        try {
+          const res = await http.post('/api/OutboundBatchPicking/cancel-split', {
+            orderNo: this.scanData.orderNo,
+            palletCode: this.scanData.palletCode,
+            newBarcode: this.revertSplitForm.newBarcode
+          });
+          if (res.status) {
+            this.$message.success('鎾ら攢鎷嗗寘鎴愬姛');
+            this.showRevertSplitDialog = false;
+            await this.loadPalletData();
+          } else {
+            this.$message.error(res.message || '鎾ら攢鎷嗗寘澶辫触');
           }
-        });
+        } catch (error) {
+          this.$message.error('鎾ら攢鎷嗗寘澶辫触: ' + (error.message || '缃戠粶閿欒'));
+        } finally {
+          this.revertSplitLoading = false;
+        }
       }
     },
-
-    // 鍥炲簱鐩稿叧鏂规硶
-    openBatchReturnDialog() {
-      if (!this.currentBatchNo) {
-        this.$message.warning('璇峰厛閫夋嫨鎵规');
+// 鏌ユ壘瀹屾暣鎷嗗寘閾撅紙浠庢牴鏉$爜寮�濮嬶級
+async findRootChain(currentBarcode) {
+  this.splitChainLoading = true;
+  try {
+    const res = await http.post('/api/OutboundBatchPicking/find-root-split-chain', {
+      orderNo: this.scanData.orderNo,
+      barcode: currentBarcode
+    });
+    
+    if (res.status) {
+      this.splitChainInfo = res.data;
+      this.$message.success('宸插姞杞藉畬鏁存媶鍖呴摼');
+    } else {
+      this.$message.error(res.message || '鏌ユ壘瀹屾暣鎷嗗寘閾惧け璐�');
+    }
+  } catch (error) {
+    this.$message.error('鏌ユ壘瀹屾暣鎷嗗寘閾惧け璐�');
+  } finally {
+    this.splitChainLoading = false;
+  }
+},
+    // 鎷嗗寘閾剧浉鍏虫柟娉�
+   // 鏌ョ湅鎷嗗寘閾句俊鎭�
+async viewSplitChain(barcode) {
+   if (!barcode) {
+        this.$message.warning('璇峰厛杈撳叆鏉$爜');
         return;
       }
-      this.showBatchReturnDialog = true;
-      this.batchReturnForm.orderNo = this.scanData.orderNo;
-      this.batchReturnForm.batchNo = this.currentBatchNo;
-      this.batchReturnForm.unpickedCount = this.summary.unpickedCount;
-      this.batchReturnForm.unpickedQuantity = this.summary.unpickedQuantity;
+      
+      this.splitChainLoading = true;
+      try {
+        const res = await http.post('/api/OutboundBatchPicking/split-package-chain-info', {
+          orderNo: this.scanData.orderNo,
+          barcode: barcode
+        });
+        
+        if (res.status) {
+          this.splitChainInfo = res.data;
+          
+          // 鍏抽棴鍏朵粬寮圭獥鍚庡啀鎵撳紑鎷嗗寘閾惧脊绐�
+          this.closeAllDialogs();
+          
+          await this.$nextTick(() => {
+            this.showSplitChainDialog = true;
+            
+            // 鏄剧ず鎻愮ず淇℃伅
+            let chainType = "褰撳墠鏉$爜鐨勬媶鍖呴摼";
+            if (this.splitChainInfo.chainType === 'root') {
+              chainType = "瀹屾暣鎷嗗寘閾撅紙浠庡師濮嬫潯鐮佸紑濮嬶級";
+            } else if (this.splitChainInfo.chainType === 'branch') {
+              chainType = "鍒嗘敮鎷嗗寘閾�";
+            }
+            
+            this.$message.info(`宸插姞杞�${chainType}锛屽叡${this.splitChainInfo.totalSplitTimes}娆℃媶鍖卄);
+          });
+        } else {
+          this.$message.error(res.message || '鑾峰彇鎷嗗寘閾句俊鎭け璐�');
+        }
+      } catch (error) {
+        this.$message.error('鑾峰彇鎷嗗寘閾句俊鎭け璐�: ' + (error.message || '缃戠粶閿欒'));
+      } finally {
+        this.splitChainLoading = false;
+      }
+},
+
+    // 鍏抽棴鎷嗗寘閾句俊鎭脊绐�
+    closeSplitChainDialog() {
+      this.showSplitChainDialog = false;
+      
+    },
+    // 鍦ㄦ挙閿�鎷嗗寘寮圭獥涓煡鐪嬫媶鍖呴摼
+async viewSplitChainFromRevert(barcode) {
+  if (!barcode) {
+    this.$message.warning('璇峰厛杈撳叆鏉$爜');
+    return;
+  }
+  
+  // 鍏堝叧闂挙閿�鎷嗗寘寮圭獥
+  this.closeRevertSplitDialog();
+  
+  await this.$nextTick();
+  
+  // 鐒跺悗鎵撳紑鎷嗗寘閾句俊鎭脊绐�
+  await this.viewSplitChain(barcode);
+},
+// 蹇�熼噸鏂版墦寮�鎷嗗寘閾惧脊绐�
+async quickReopenSplitChainDialog(barcode) {
+  if (!barcode) return;
+  
+  this.showSplitChainDialog = true;
+  this.splitChainLoading = true;
+  
+  try {
+    const res = await http.post('/api/OutboundBatchPicking/split-package-chain-info', {
+      orderNo: this.scanData.orderNo,
+      barcode: barcode
+    });
+    
+    if (res.status) {
+      this.splitChainInfo = res.data;
+    }
+  } catch (error) {
+    console.error('閲嶆柊鍔犺浇鎷嗗寘閾句俊鎭け璐�:', error);
+  } finally {
+    this.splitChainLoading = false;
+  }
+},
+    // 鍙栨秷鍗曚釜鎷嗗寘璁板綍
+async cancelSingleSplit(newBarcode) {
+   try {
+        await ElMessageBox.confirm(
+          `纭畾瑕佸彇娑堟潯鐮� ${newBarcode} 鐨勬媶鍖呮搷浣滃悧锛焋, 
+          '鍙栨秷鍗曚釜鎷嗗寘', 
+          {
+            confirmButtonText: '纭畾鍙栨秷',
+            cancelButtonText: '鍐嶆兂鎯�',
+            type: 'warning',
+            customClass: 'message-box-top'
+          }
+        );
+        
+        this.revertSplitLoading = true;
+        
+        const res = await http.post('/api/OutboundBatchPicking/cancel-split', {
+          orderNo: this.scanData.orderNo,
+          palletCode: this.scanData.palletCode,
+          newBarcode: newBarcode
+        });
+        
+        if (res.status) {
+          this.$message.success('鍙栨秷鎷嗗寘鎴愬姛');
+          await this.loadPalletData();
+          
+          // 閲嶆柊鍔犺浇鎷嗗寘閾句俊鎭�
+          if (this.splitChainInfo.originalBarcode) {
+            await this.viewSplitChain(this.splitChainInfo.originalBarcode);
+          }
+        } else {
+          this.$message.error(res.message || '鍙栨秷鎷嗗寘澶辫触');
+        }
+      } catch (error) {
+        if (error !== 'cancel') {
+          this.$message.error('鍙栨秷鎷嗗寘澶辫触: ' + error.message);
+        }
+      } finally {
+        this.revertSplitLoading = false;
+      }
+},
+
+// 鍙栨秷鏁翠釜鎷嗗寘閾�  
+async cancelWholeSplitChain() {
+  if (!this.canCancelWholeChain) return;
+      
+      try {
+        await ElMessageBox.confirm(
+          `纭畾瑕佸彇娑堟暣涓媶鍖呴摼鍚楋紵\n杩欏皢鍙栨秷浠庢潯鐮� ${this.splitChainInfo.originalBarcode} 寮�濮嬬殑鎵�鏈夋媶鍖呮搷浣溿�俙, 
+          '鍙栨秷鎷嗗寘閾剧‘璁�', 
+          {
+            confirmButtonText: '纭畾鍙栨秷',
+            cancelButtonText: '鍐嶆兂鎯�',
+            type: 'warning',
+            center: true,
+            closeOnClickModal: false,
+            customClass: 'message-box-top'
+          }
+        );
+        
+        this.revertSplitLoading = true;
+        
+        const res = await http.post('/api/OutboundBatchPicking/cancel-split-chain', {
+          orderNo: this.scanData.orderNo,
+          palletCode: this.scanData.palletCode,
+          startBarcode: this.splitChainInfo.originalBarcode
+        });
+        
+        if (res.status) {
+          this.$message.success('鍙栨秷鎷嗗寘閾炬垚鍔�');
+          this.closeSplitChainDialog();
+          await this.loadPalletData();
+        } else {
+          this.$message.error(res.message || '鍙栨秷鎷嗗寘閾惧け璐�');
+        }
+      } catch (error) {
+        if (error !== 'cancel') {
+          this.$message.error('鍙栨秷鎷嗗寘閾惧け璐�: ' + error.message);
+        }
+      } finally {
+        this.revertSplitLoading = false;
+      }
+},
+
+    // 妫�鏌ユ潯鐮佹槸鍚﹀凡琚垎鎷�
+    hasPicked(barcode) {
+      return this.pickedList.some(item => item.currentBarcode === barcode);
+    },
+
+    // 鏍煎紡鍖栨棩鏈熸椂闂�
+    formatDateTime(dateTime) {
+      if (!dateTime) return '';
+      const date = new Date(dateTime);
+      return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}:${date.getSeconds().toString().padStart(2, '0')}`;
+    },
+ closeAllDialogs() {
+      this.showCustomSplitDialog = false;
+      this.showRevertSplitDialog = false;
+      this.showSplitChainDialog = false;
+      this.showBatchReturnDialog = false;
+      this.showEmptyPalletDialog = false;
+      this.activeDialog = null;
+    },
+    // 鍥炲簱鐩稿叧鏂规硶
+    openBatchReturnDialog() {
+     if (!this.scanData.palletCode) {
+        this.$message.warning('璇峰厛鎵弿鎵樼洏鐮�');
+        return;
+      }
+      
+      // 鍏抽棴鍏朵粬寮圭獥
+      this.closeAllDialogs();
+      
+      this.$nextTick(() => {
+        this.showBatchReturnDialog = true;
+        this.batchReturnForm.orderNo = this.scanData.orderNo;
+        this.batchReturnForm.palletCode = this.scanData.palletCode;
+        this.batchReturnForm.unpickedCount = this.summary.unpickedCount;
+        this.batchReturnForm.unpickedQuantity = this.summary.unpickedQuantity;
+      });
     },
 
     async handleBatchReturnConfirm() {
       this.batchReturnLoading = true;
       try {
-        const res = await http.post('/api/BatchOutbound/batch-return-stock', {
+        const res = await http.post('/api/OutboundBatchPicking/return-stock', {
           orderNo: this.scanData.orderNo,
-          batchNo: this.currentBatchNo
+          palletCode: this.scanData.palletCode
         });
         if (res.status) {
-          this.$message.success('鎵规鍥炲簱鎴愬姛');
+          this.$message.success('鍥炲簱鎴愬姛');
           this.showBatchReturnDialog = false;
-          await this.loadBatchData();
+          await this.loadPalletData();
         } else {
-          this.$message.error(res.message || '鎵规鍥炲簱澶辫触');
+          this.$message.error(res.message || '鍥炲簱澶辫触');
         }
       } catch (error) {
-        this.$message.error('鎵规鍥炲簱澶辫触');
+        this.$message.error('鍥炲簱澶辫触: ' + (error.message || '缃戠粶閿欒'));
       } finally {
         this.batchReturnLoading = false;
       }
     },
 
     // 鍙栫┖绠辨柟娉�
+    handleEmptyPallet() {
+      // 鍏抽棴鍏朵粬寮圭獥
+      this.closeAllDialogs();
+      
+      this.$nextTick(() => {
+        this.showEmptyPalletDialog = true;
+        this.emptypalletOutForm.orderNo = this.scanData.orderNo;
+        this.emptypalletOutForm.palletCode = '';
+      });
+    },
+
     async handleEmptyPalletConfirm() {
       this.emptypalletOutLoading = true;
       try {
-        const res = await http.post('/api/BatchOutbound/remove-empty-pallet', this.emptypalletOutForm);
+        const res = await http.post('/api/OutboundBatchPicking/remove-empty-pallet', {
+          orderNo: this.emptypalletOutForm.orderNo,
+          palletCode: this.emptypalletOutForm.palletCode
+        });
         if (res.status) {
           this.$message.success('鍙栬蛋绌虹鎴愬姛');
           this.showEmptyPalletDialog = false;
-          await this.loadBatchData();
+          await this.loadPalletData();
         } else {
           this.$message.error(res.message || '鍙栬蛋绌虹澶辫触');
         }
       } catch (error) {
-        this.$message.error('鍙栬蛋绌虹澶辫触');
+        this.$message.error('鍙栬蛋绌虹澶辫触: ' + (error.message || '缃戠粶閿欒'));
       } finally {
         this.emptypalletOutLoading = false;
       }
     },
 
-    // 鍏朵粬鍘熸湁鏂规硶...
+    // 鏁版嵁鍔犺浇鏂规硶
+    async loadPalletData() {
+       if (!this.scanData.orderNo || !this.scanData.palletCode) return;
+      
+      try {
+        await Promise.all([
+          this.loadUnpickedList(),
+          this.loadPickedList(),
+          this.loadPalletStatus()
+        ]);
+      } catch (error) {
+        console.error('鍔犺浇鎵樼洏鏁版嵁澶辫触:', error);
+      }
+    },
+
+    async loadUnpickedList() {
+       try {
+        const res = await http.post('/api/OutboundBatchPicking/pallet-locks', {
+          orderNo: this.scanData.orderNo,
+          palletCode: this.scanData.palletCode
+        });
+        if (res.status) {
+          this.unpickedList = (res.data || []).filter(item => item.canPick === true);
+          this.summary.unpickedCount = this.unpickedList.length;
+          this.summary.unpickedQuantity = this.unpickedList.reduce((sum, item) => sum + (item.remainQuantity || 0), 0);
+        }
+      } catch (error) {
+        console.error('鍔犺浇鏈嫞閫夊垪琛ㄥけ璐�:', error);
+        this.$message.error('鍔犺浇鏈嫞閫夊垪琛ㄥけ璐�');
+      }
+    },
+
+    async loadPickedList() {
+      try {
+        const res = await http.post('/api/OutboundBatchPicking/pallet-picked-list', {
+          orderNo: this.scanData.orderNo,
+          palletCode: this.scanData.palletCode
+        });
+        if (res.status) {
+          this.pickedList = res.data.map(item => ({
+            ...item,
+            currentBarcode: item.barcode
+          }));
+          this.summary.pickedCount = this.pickedList.length;
+        }
+      } catch (error) {
+        console.error('鍔犺浇宸叉嫞閫夊垪琛ㄥけ璐�:', error);
+        this.$message.error('鍔犺浇宸叉嫞閫夊垪琛ㄥけ璐�');
+      }
+    },
+
+    async loadPalletStatus() {
+          try {
+        const res = await http.post('/api/OutboundBatchPicking/pallet-status', {
+          orderNo: this.scanData.orderNo,
+          palletCode: this.scanData.palletCode
+        });
+        if (res.status) {
+          this.palletStatus = res.data.statusText || '鏈煡';
+        }
+      } catch (error) {
+        console.error('鍔犺浇鎵樼洏鐘舵�佸け璐�:', error);
+        this.palletStatus = '鏈煡';
+      }
+    },
+
+    // 鎵爜鐩稿叧鏂规硶
     onPalletScan() {
-      this.scanData.palletCode = this.scanData.palletCode.replace(/\n/g, '').trim();
+       this.scanData.palletCode = this.scanData.palletCode.replace(/\n/g, '').trim();
       if (!this.scanData.palletCode) return;
       
-      this.loadActiveBatch();
+      this.loadPalletData();
       this.$nextTick(() => {
         this.$refs.barcodeInput.focus();
       });
     },
 
-    async loadActiveBatch() {
-      try {
-        const res = await http.post('/api/BatchOutbound/active-batch', {
-          orderNo: this.scanData.orderNo,
-          palletCode: this.scanData.palletCode
-        });
-        if (res.status && res.data) {
-          this.currentBatchNo = res.data.batchNo;
-          this.scanData.batchNo = res.data.batchNo;
-          this.selectedBatchNo = res.data.batchNo;
-          await this.loadBatchData();
-        }
-      } catch (error) {
-        console.log('鑾峰彇娲昏穬鎵规澶辫触锛屽彲鑳芥墭鐩樻病鏈夊叧鑱旀壒娆�');
-      }
-    },
-
     onBarcodeScan() {
-      this.scanData.barcode = this.scanData.barcode.replace(/\n/g, '').trim();
+       this.scanData.barcode = this.scanData.barcode.replace(/\n/g, '').trim();
       if (!this.scanData.barcode) return;
       this.confirmPicking();
     },
@@ -845,34 +1158,40 @@
         return;
       }
 
-      this.$confirm(`纭畾瑕佸彇娑堥�変腑鐨� ${this.selectedPickedRows.length} 椤瑰悧锛焋, '鎻愮ず', {
-        confirmButtonText: '纭畾',
-        cancelButtonText: '鍙栨秷',
-        type: 'warning'
-      }).then(async () => {
-        try {
-          for (const row of this.selectedPickedRows) {
-            try {
-              const res = await http.post('/api/BatchOutbound/cancel-picking', {
-                orderNo: this.scanData.orderNo,
-                batchNo: this.currentBatchNo,
-                palletCode: this.scanData.palletCode,
-                barcode: row.currentBarcode
-              });
-              if (!res.status) {
-                this.$message.warning(`鍙栨秷鎷i�夊け璐�: ${row.currentBarcode} - ${res.message}`);
-              }
-            } catch (error) {
-              this.$message.warning(`鍙栨秷鎷i�夊け璐�: ${row.currentBarcode} - ${error.message}`);
+      try {
+        await ElMessageBox.confirm(
+          `纭畾瑕佸彇娑堥�変腑鐨� ${this.selectedPickedRows.length} 椤瑰悧锛焋, 
+          '鎻愮ず', 
+          {
+            confirmButtonText: '纭畾',
+            cancelButtonText: '鍙栨秷',
+            type: 'warning',
+            customClass: 'message-box-top'
+          }
+        );
+        
+        for (const row of this.selectedPickedRows) {
+          try {
+            const res = await http.post('/api/OutboundBatchPicking/cancel-picking', {
+              orderNo: this.scanData.orderNo,
+              palletCode: this.scanData.palletCode,
+              barcode: row.currentBarcode
+            });
+            if (!res.status) {
+              this.$message.warning(`鍙栨秷鎷i�夊け璐�: ${row.currentBarcode} - ${res.message}`);
             }
-          }        
-          this.$message.success('鎵归噺鍙栨秷瀹屾垚');
-          await this.loadBatchData();
-          this.selectedPickedRows = [];
-        } catch (error) {
+          } catch (error) {
+            this.$message.warning(`鍙栨秷鎷i�夊け璐�: ${row.currentBarcode} - ${error.message}`);
+          }
+        }        
+        this.$message.success('鎵归噺鍙栨秷瀹屾垚');
+        await this.loadPalletData();
+        this.selectedPickedRows = [];
+      } catch (error) {
+        if (error !== 'cancel') {
           this.$message.error('鎵归噺鍙栨秷鎿嶄綔澶辫触');
         }
-      });
+      }
     },
 
     // 閲嶇疆鏂规硶
@@ -889,8 +1208,13 @@
     },
 
     openRevertSplitDialog() {
-      this.showRevertSplitDialog = true;
-      this.revertSplitForm.newBarcode = '';
+       // 鍏抽棴鍏朵粬寮圭獥
+      this.closeAllDialogs();
+      
+      this.$nextTick(() => {
+        this.showRevertSplitDialog = true;
+        this.revertSplitForm.newBarcode = '';
+      });
     },
 
     closeRevertSplitDialog() {
@@ -902,10 +1226,9 @@
       this.showBatchReturnDialog = false;
     },
 
-    openEmptyPalletDialog() {
-      this.showEmptyPalletDialog = true;
-      this.emptypalletOutForm.orderNo = this.scanData.orderNo;
-      this.emptypalletOutForm.palletCode = '';
+    onEmptyPalletScan() {
+      if (!this.emptypalletOutForm.palletCode) return;
+      this.emptypalletOutForm.palletCode = this.emptypalletOutForm.palletCode.replace(/\n/g, '').trim();
     },
 
     closeEmptyPalletDialog() {
@@ -913,9 +1236,8 @@
       this.emptypalletOutForm.palletCode = '';
     },
 
-    onEmptyPalletScan() {
-      if (!this.emptypalletOutForm.palletCode) return;
-      this.emptypalletOutForm.palletCode = this.emptypalletOutForm.palletCode.replace(/\n/g, '').trim();
+    parentcall() {
+      // 鎵撳嵃鍥炶皟
     }
   }
 })
@@ -924,26 +1246,6 @@
 <style scoped>
 .OutboundPicking-container {
   padding: 20px;
-}
-
-.batch-operations {
-  margin-bottom: 15px;
-}
-
-.batch-actions {
-  display: flex;
-  align-items: center;
-  gap: 10px;
-}
-
-.batch-summary-area {
-  margin-bottom: 15px;
-}
-
-.batch-summary-info {
-  display: flex;
-  gap: 15px;
-  flex-wrap: wrap;
 }
 
 .scanner-form {
@@ -977,6 +1279,23 @@
 }
 
 /* 鑷畾涔夊脊绐楁牱寮� */
+:deep(.el-message-box) {
+  z-index: 9999 !important;
+}
+
+:deep(.el-overlay) {
+  z-index: 9998 !important;
+}
+
+:deep(.el-message) {
+  z-index: 10000 !important;
+}
+
+/* 纭繚纭瀵硅瘽妗嗗湪鏈�鍓嶉潰 */
+:deep(.message-box-top) {
+  z-index: 10001 !important;
+}
+
 .custom-dialog-overlay {
   position: fixed;
   top: 0;
@@ -987,12 +1306,12 @@
   display: flex;
   align-items: center;
   justify-content: center;
-  z-index: 9999;
+  z-index: 2000;
 }
 
 .custom-dialog-wrapper {
   position: relative;
-  z-index: 10000;
+  z-index: 2001;
 }
 
 .custom-dialog {

--
Gitblit v1.9.3