From 8639f19c82f6e263654db44286256bb8d028d2c2 Mon Sep 17 00:00:00 2001
From: 647556386 <647556386@qq.com>
Date: 星期日, 30 十一月 2025 10:10:40 +0800
Subject: [PATCH] 1

---
 项目代码/WIDESEA_WMSClient/src/views/outbound/BatchPickingConfirm.vue | 1278 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 1,278 insertions(+), 0 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"
new file mode 100644
index 0000000..4487276
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/BatchPickingConfirm.vue"
@@ -0,0 +1,1278 @@
+<template>
+  <div class="OutboundPicking-container">
+    <div class="page-header">
+      <el-page-header @back="goBack">
+        <template #content>
+          <span class="title">鍑哄簱鎷i�夌‘璁� - {{ this.$route.query.orderNo }}</span>
+        </template>
+      </el-page-header>
+    </div>
+
+    <!-- 鎵爜鍖哄煙 -->
+    <div class="scanner-area">
+      <el-card>
+        <div class="scanner-form">
+          <el-input 
+            ref="palletInput"
+            v-model="scanData.palletCode" 
+            placeholder="鎵弿鎵樼洏鐮�" 
+            @change="onPalletScan"
+            @keyup.enter.native="onPalletScan">
+          </el-input>
+          <el-input 
+            ref="barcodeInput"
+            v-model="scanData.barcode" 
+            placeholder="鎵弿鐗╂枡鏉$爜" 
+            @change="onBarcodeScan"
+            @keyup.enter.native="onBarcodeScan">
+          </el-input>
+          <el-button type="success" @click="confirmPicking">纭鎷i��</el-button>
+          <el-button type="warning" @click="openSplitDialog">鎷嗗寘</el-button>
+          <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="summary-area">
+      <el-card>
+        <div class="summary-info">
+          <el-tag type="warning">鏈嫞閫夋潯鏁�: {{summary.unpickedCount}}</el-tag>
+          <el-tag type="danger">鏈嫞閫夋暟閲�: {{summary.unpickedQuantity}}</el-tag>
+          <el-tag type="info">鎵樼洏鐘舵��: {{palletStatus}}</el-tag>
+        </div>
+      </el-card>
+    </div>
+
+    <!-- 鏁版嵁鍒楄〃 -->
+    <div class="content-area">
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-card header="鏈嫞閫夊垪琛�">
+            <el-table :data="unpickedList" border height="440">
+              <el-table-column prop="materielCode" label="鐗╂枡缂栫爜" width="120"></el-table-column>
+              <el-table-column prop="assignQuantity" label="鍒嗛厤鏁伴噺" width="100"></el-table-column>
+              <el-table-column prop="pickedQty" label="宸叉嫞鏁伴噺" width="100"></el-table-column>
+              <el-table-column prop="remainQuantity" 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>
+        </el-col>
+        
+        <el-col :span="12">
+          <el-card header="宸叉嫞閫夊垪琛�">
+            <div class="table-actions">
+              <el-button 
+                size="mini" 
+                type="danger" 
+                :disabled="selectedPickedRows.length === 0"
+                @click="batchCancelSelected">
+                鍙栨秷鎷i��
+              </el-button>
+              <span class="selection-count">宸查�夋嫨 {{selectedPickedRows.length}} 椤�</span>
+            </div>
+            <el-table 
+              :data="pickedList" 
+              border 
+              height="400"  
+              style="width: 100%"    
+              @selection-change="handlePickedSelectionChange">
+              <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="currentBarcode" label="鏉$爜"></el-table-column>
+            </el-table>
+          </el-card>
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 鎷嗗寘寮圭獥 -->
+    <div v-if="showCustomSplitDialog" 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="closeCustomSplitDialog" class="close-button">X</el-button>
+          </div>
+          <div class="custom-dialog-body">
+            <el-form :model="splitForm" :rules="splitFormRules" ref="splitFormRef" label-width="100px">
+              <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.palletCode" disabled></el-input>
+              </el-form-item>
+              <el-form-item label="鍘熸潯鐮�" prop="originalBarcode">
+                <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>
+              </el-form-item>
+              <el-form-item label="鍓╀綑鏁伴噺">
+                <el-input v-model="splitForm.maxQuantity" disabled></el-input>
+              </el-form-item>
+              <el-form-item label="鎷嗗寘鏁伴噺" prop="splitQuantity">
+                <el-input-number 
+                  v-model="splitForm.splitQuantity" 
+                  :min="1" 
+                  :max="splitForm.maxQuantity"
+                  :precision="2"
+                  :step="1"
+                  style="width: 100%">
+                </el-input-number>
+              </el-form-item>
+            </el-form>
+          </div>
+          <div class="custom-dialog-footer">
+            <el-button @click="closeCustomSplitDialog">鍙栨秷</el-button>
+            <el-button type="primary" @click="handleSplitPackage" :loading="splitLoading">纭鎷嗗寘</el-button>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 鎾ら攢鎷嗗寘寮圭獥 -->
+    <div v-if="showRevertSplitDialog" 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="closeRevertSplitDialog" class="close-button">脳</el-button>
+          </div>
+          <div class="custom-dialog-body">
+            <el-form :model="revertSplitForm" :rules="revertSplitFormRules" ref="revertSplitFormRef" label-width="100px">
+              <el-form-item label="鏂版潯鐮�" prop="newBarcode">
+                <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>
+            <el-button type="primary" @click="handleRevertSplit" :loading="revertSplitLoading">纭鎾ら攢</el-button>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 鎷嗗寘閾句俊鎭脊绐� -->
+<div v-if="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>
+            <el-button type="text" @click="closeBatchReturnDialog" class="close-button">脳</el-button>
+          </div>
+          <div class="custom-dialog-body">
+            <el-form :model="batchReturnForm" :rules="batchReturnFormRules" ref="batchReturnFormRef" label-width="100px">
+              <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.palletCode" disabled></el-input>
+              </el-form-item>
+              <el-form-item label="鏈嫞閫夋暟閲�">
+                <el-input v-model="batchReturnForm.unpickedQuantity" disabled></el-input>
+              </el-form-item>
+              <el-form-item label="鏈嫞閫夋潯鏁�">
+                <el-input v-model="batchReturnForm.unpickedCount" disabled></el-input>
+              </el-form-item>
+            </el-form>
+          </div>
+          <div class="custom-dialog-footer">
+            <el-button @click="closeBatchReturnDialog">鍙栨秷</el-button>
+            <el-button type="primary" @click="handleBatchReturnConfirm" :loading="batchReturnLoading">纭鍥炲簱</el-button>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 鍙栬蛋绌虹寮圭獥 -->
+    <div v-if="showEmptyPalletDialog" 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="closeEmptyPalletDialog" class="close-button">脳</el-button>
+          </div>
+          <div class="custom-dialog-body">
+            <el-form :model="emptypalletOutForm" :rules="emptypalletOutFormRules" ref="emptypalletOutFormRef" label-width="100px">
+              <el-form-item label="璁㈠崟缂栧彿">
+                <el-input v-model="emptypalletOutForm.orderNo" disabled></el-input>
+              </el-form-item>
+              <el-form-item label="鎵樼洏缂栧彿" prop="palletCode">
+                <el-input 
+                  v-model="emptypalletOutForm.palletCode" 
+                  placeholder="鎵弿鎵樼洏鐮�"
+                  @keyup.enter.native="onEmptyPalletScan"
+                  @change="onEmptyPalletScan"
+                  clearable>
+                </el-input>
+              </el-form-item>
+            </el-form>
+          </div>
+          <div class="custom-dialog-footer">
+            <el-button @click="closeEmptyPalletDialog">鍙栨秷</el-button>
+            <el-button type="primary" @click="handleEmptyPalletConfirm" :loading="emptypalletOutLoading">纭鍙栬蛋绌虹</el-button>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <print-view ref="childs" @parentcall="parentcall"></print-view>
+  </div>
+</template>
+
+<script>
+import http from '@/api/http.js'
+import { ref, defineComponent } from "vue";
+import { ElMessage } from 'element-plus' 
+import { useRoute } from 'vue-router'
+import printView from "@/extension/outbound/extend/printView.vue"
+
+export default defineComponent({
+  name: 'BatchOutboundPicking',
+  components: {printView},
+  data() {
+    return {
+      scanData: {
+        orderNo: '',
+        palletCode: '',
+        barcode: ''
+      },
+      unpickedList: [],
+      pickedList: [],
+      selectedPickedRows: [],
+      summary: {
+        unpickedCount: 0,
+        unpickedQuantity: 0,
+        pickedCount: 0
+      },
+      palletStatus: '鏈煡',
+      
+      // 寮圭獥鐘舵��
+      showCustomSplitDialog: false,
+      showRevertSplitDialog: false,
+      showBatchReturnDialog: false,
+      showEmptyPalletDialog: false,
+      showSplitChainDialog: false, // 鏂板锛氭媶鍖呴摼淇℃伅寮圭獥
+      
+      // 鍔犺浇鐘舵��
+      splitLoading: false,
+      revertSplitLoading: false,
+      batchReturnLoading: false,
+      emptypalletOutLoading: false,
+      splitChainLoading: false, // 鏂板锛氭媶鍖呴摼鍔犺浇鐘舵��
+      
+      // 琛ㄥ崟鏁版嵁
+      splitForm: {
+        orderNo: '',
+        palletCode: '',
+        originalBarcode: '',
+        materielCode: '',
+        splitQuantity: 0,
+        maxQuantity: 0
+      },
+      
+      revertSplitForm: {
+        newBarcode: ''
+      },
+      
+      batchReturnForm: {
+        orderNo: '',
+        palletCode: '',
+        unpickedCount: 0,
+        unpickedQuantity: 0
+      },
+      
+      emptypalletOutForm: {
+        orderNo: '',
+        palletCode: ''
+      },
+      
+      // 鏂板锛氭媶鍖呴摼鐩稿叧鏁版嵁
+      splitChainInfo: {
+        originalBarcode: '',
+        totalSplitTimes: 0,
+        splitChain: []
+      },
+      
+      // 楠岃瘉瑙勫垯
+      splitFormRules: {
+        originalBarcode: [
+          { required: true, message: '璇疯緭鍏ュ師鏉$爜', 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' }
+        ]
+      },
+      
+      isProcessing: false
+    }
+  },
+  computed: {
+    // 鏄惁鍙互鍙栨秷鏁翠釜鎷嗗寘閾�
+    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.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();
+    });
+  },
+  methods: {
+    goBack(){
+      this.$router.back()
+    },
+
+    // 鍒嗘嫞鐩稿叧鏂规硶
+    async confirmPicking() {
+      if (this.isProcessing) return;
+      
+      if (!this.scanData.orderNo || !this.scanData.palletCode || !this.scanData.barcode) {
+        this.$message.warning('璇峰厛鎵弿鎵樼洏鐮佸拰鐗╂枡鏉$爜');
+        this.focusBarcodeInput();
+        return;
+      }
+
+      this.isProcessing = true;
+      
+      try {
+        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.loadPalletData();
+          if(res.data && res.data.splitResults && res.data.splitResults.length>0){
+            this.$refs.childs.open(res.data.splitResults);
+          }
+          this.$nextTick(() => {
+            this.$refs.barcodeInput.focus();
+          });
+        } else {
+          this.$message.error(res.message || '鎷i�夌‘璁ゅけ璐�');
+          this.focusBarcodeInput(true);
+        }
+      } catch (error) {
+        this.$message.error('鎷i�夌‘璁ゅけ璐�: ' + (error.message || '缃戠粶閿欒'));
+        this.focusBarcodeInput(true);
+      } finally {
+        this.isProcessing = false;
+      }
+    },
+
+    // 鎷嗗寘鐩稿叧鏂规硶
+    openSplitDialog() {
+      if (!this.scanData.palletCode) {
+        this.$message.warning('璇峰厛鎵弿鎵樼洏鐮�');
+        return;
+      }
+      this.showCustomSplitDialog = true;
+      this.resetSplitForm();
+      this.splitForm.orderNo = this.scanData.orderNo;
+      this.splitForm.palletCode = this.scanData.palletCode;
+    },
+
+    async onSplitBarcodeScan() {
+      if (!this.splitForm.originalBarcode) return;
+      this.splitForm.originalBarcode = this.splitForm.originalBarcode.replace(/\n/g, '').trim();
+
+      try {
+        const res = await http.post('/api/OutboundBatchPicking/split-package-info', {
+          orderNo: this.splitForm.orderNo,
+          palletCode: this.splitForm.palletCode,
+          barcode: this.splitForm.originalBarcode
+        });
+
+        if (res.status) {
+          this.splitForm.materielCode = res.data.materielCode;
+          this.splitForm.maxQuantity = res.data.remainQuantity;
+          this.splitForm.splitQuantity = Math.min(1, this.splitForm.maxQuantity);
+        } else {
+          this.$message.error(res.message || '鑾峰彇鎷嗗寘淇℃伅澶辫触');
+        }
+      } catch (error) {
+        this.$message.error('鑾峰彇鎷嗗寘淇℃伅澶辫触');
+      }
+    },
+
+    async handleSplitPackage() {
+      if (this.$refs.splitFormRef) {
+        this.$refs.splitFormRef.validate(async (valid) => {
+          if (valid) {
+            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('鎷嗗寘澶辫触');
+            } 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;
+      this.revertSplitForm.newBarcode = this.revertSplitForm.newBarcode.replace(/\n/g, '').trim();
+      
+      // 鏂板锛氭壂鎻忓悗鑷姩鏄剧ず鎷嗗寘閾句俊鎭�
+      await this.viewSplitChain(this.revertSplitForm.newBarcode);
+    },
+
+    async handleRevertSplit() {
+      if (this.$refs.revertSplitFormRef) {
+        this.$refs.revertSplitFormRef.validate(async (valid) => {
+          if (valid) {
+            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('鎾ら攢鎷嗗寘澶辫触');
+            } finally {
+              this.revertSplitLoading = false;
+            }
+          }
+        });
+      }
+    },
+// 鏌ユ壘瀹屾暣鎷嗗寘閾撅紙浠庢牴鏉$爜寮�濮嬶級
+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.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;
+      
+      // 鏄剧ず鎻愮ず淇℃伅锛屽憡璇夌敤鎴疯繖鏄粈涔堢被鍨嬬殑鎷嗗寘閾�
+      let chainType = "褰撳墠鏉$爜鐨勬媶鍖呴摼";
+      if (this.splitChainInfo.chainType === 'root') {
+        chainType = "瀹屾暣鎷嗗寘閾撅紙浠庡師濮嬫潯鐮佸紑濮嬶級";
+      } else if (this.splitChainInfo.chainType === 'branch') {
+        chainType = "鍒嗘敮鎷嗗寘閾�";
+      }
+      
+      this.$message.info(`宸插姞杞�${chainType}锛屽叡${this.splitChainInfo.totalSplitTimes}娆℃媶鍖卄);
+      this.showSplitChainDialog = true;
+    } else {
+      this.$message.error(res.message || '鑾峰彇鎷嗗寘閾句俊鎭け璐�');
+    }
+  } catch (error) {
+    this.$message.error('鑾峰彇鎷嗗寘閾句俊鎭け璐�');
+  } 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) {
+  // 鍏堣褰曞綋鍓嶄俊鎭紝鐒跺悗鍏抽棴寮圭獥
+  const originalBarcode = this.splitChainInfo.originalBarcode;
+  this.closeSplitChainDialog();
+  
+  await this.$nextTick();
+  
+  try {
+    await this.$confirm(
+      `纭畾瑕佸彇娑堟潯鐮� ${newBarcode} 鐨勬媶鍖呮搷浣滃悧锛焋, 
+      '鍙栨秷鍗曚釜鎷嗗寘', 
+      {
+        confirmButtonText: '纭畾鍙栨秷',
+        cancelButtonText: '鍐嶆兂鎯�',
+        type: 'warning'
+      }
+    );
+    
+    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();
+      // 閲嶆柊鎵撳紑寮圭獥鏄剧ず鏇存柊鍚庣殑鐘舵��
+      await this.viewSplitChain(originalBarcode);
+    } else {
+      this.$message.error(res.message || '鍙栨秷鎷嗗寘澶辫触');
+      await this.viewSplitChain(originalBarcode);
+    }
+  } catch (error) {
+    if (error === 'cancel') {
+      // 鐢ㄦ埛鍙栨秷鍚庨噸鏂版墦寮�寮圭獥
+      await this.viewSplitChain(originalBarcode);
+    } else {
+      this.$message.error('鍙栨秷鎷嗗寘澶辫触');
+      await this.viewSplitChain(originalBarcode);
+    }
+  } finally {
+    this.revertSplitLoading = false;
+  }
+},
+
+// 鍙栨秷鏁翠釜鎷嗗寘閾�  
+async cancelWholeSplitChain() {
+  // 鍏堣褰曞綋鍓嶆媶鍖呴摼淇℃伅锛岀劧鍚庡叧闂脊绐�
+  const originalBarcode = this.splitChainInfo.originalBarcode;
+  this.closeSplitChainDialog();
+  
+  // 缁欎竴鐐规椂闂磋寮圭獥瀹屽叏鍏抽棴
+  await this.$nextTick();
+  
+  try {
+    // 鐜板湪鏄剧ず纭瀵硅瘽妗嗭紝纭繚瀹冨湪鏈�鍓嶉潰
+    await this.$confirm(
+      `纭畾瑕佸彇娑堟暣涓媶鍖呴摼鍚楋紵\n杩欏皢鍙栨秷浠庢潯鐮� ${originalBarcode} 寮�濮嬬殑鎵�鏈夋媶鍖呮搷浣溿�俙, 
+      '鍙栨秷鎷嗗寘閾剧‘璁�', 
+      {
+        confirmButtonText: '纭畾鍙栨秷',
+        cancelButtonText: '鍐嶆兂鎯�',
+        type: 'warning',
+        center: true,
+        closeOnClickModal: false
+      }
+    );
+    
+    // 鐢ㄦ埛纭鍚庢墽琛屽彇娑堟搷浣�
+    this.revertSplitLoading = true;
+    
+    const res = await http.post('/api/OutboundBatchPicking/cancel-split-chain', {
+      orderNo: this.scanData.orderNo,
+      palletCode: this.scanData.palletCode,
+      startBarcode: originalBarcode
+    });
+    
+    console.log('鍙栨秷鎷嗗寘閾惧搷搴�:', res);
+    
+    if (res.status) {
+      this.$message.success('鍙栨秷鎷嗗寘閾炬垚鍔�');
+      await this.loadPalletData();
+      // 鍙�夛細閲嶆柊鎵撳紑鎷嗗寘閾句俊鎭脊绐楁樉绀烘洿鏂板悗鐨勭姸鎬�
+      // await this.viewSplitChain(originalBarcode);
+    } else {
+      this.$message.error(res.message || '鍙栨秷鎷嗗寘閾惧け璐�');
+      // 澶辫触鍚庨噸鏂版墦寮�寮圭獥
+      await this.viewSplitChain(originalBarcode);
+    }
+  } catch (error) {
+    // 鐢ㄦ埛鍙栨秷鎿嶄綔
+    if (error === 'cancel') {
+      console.log('鐢ㄦ埛鍙栨秷浜嗘媶鍖呴摼鎿嶄綔');
+      // 鐢ㄦ埛鍙栨秷鍚庨噸鏂版墦寮�寮圭獥
+      await this.viewSplitChain(originalBarcode);
+    } else {
+      console.error('鍙栨秷鎷嗗寘閾鹃敊璇�:', error);
+      this.$message.error('鍙栨秷鎷嗗寘閾惧け璐�: ' + error.message);
+      // 鍑洪敊鍚庨噸鏂版墦寮�寮圭獥
+      await this.viewSplitChain(originalBarcode);
+    }
+  } 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')}`;
+    },
+
+    // 鍥炲簱鐩稿叧鏂规硶
+    openBatchReturnDialog() {
+      if (!this.scanData.palletCode) {
+        this.$message.warning('璇峰厛鎵弿鎵樼洏鐮�');
+        return;
+      }
+      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/OutboundBatchPicking/return-stock', {
+          orderNo: this.scanData.orderNo,
+          palletCode: this.scanData.palletCode
+        });
+        if (res.status) {
+          this.$message.success('鍥炲簱鎴愬姛');
+          this.showBatchReturnDialog = false;
+          await this.loadPalletData();
+        } else {
+          this.$message.error(res.message || '鍥炲簱澶辫触');
+        }
+      } catch (error) {
+        this.$message.error('鍥炲簱澶辫触');
+      } finally {
+        this.batchReturnLoading = false;
+      }
+    },
+
+    // 鍙栫┖绠辨柟娉�
+    handleEmptyPallet() {
+      this.showEmptyPalletDialog = true;
+      this.emptypalletOutForm.orderNo = this.scanData.orderNo;
+      this.emptypalletOutForm.palletCode = '';
+    },
+
+    async handleEmptyPalletConfirm() {
+      this.emptypalletOutLoading = true;
+      try {
+        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.loadPalletData();
+        } else {
+          this.$message.error(res.message || '鍙栬蛋绌虹澶辫触');
+        }
+      } catch (error) {
+        this.$message.error('鍙栬蛋绌虹澶辫触');
+      } finally {
+        this.emptypalletOutLoading = false;
+      }
+    },
+
+    // 鏁版嵁鍔犺浇鏂规硶
+    async loadPalletData() {
+      if (!this.scanData.orderNo || !this.scanData.palletCode) return;
+      
+      await this.loadUnpickedList();
+      await this.loadPickedList();
+      await this.loadPalletStatus();
+    },
+
+    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 || [];
+          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/OutboundBatchPicking/pallet-picked-list', {
+          orderNo: this.scanData.orderNo,
+          palletCode: this.scanData.palletCode
+        });
+        if (res.status) {
+          this.pickedList = res.data || [];
+          this.summary.pickedCount = this.pickedList.length;
+        }
+      } catch (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) {
+        this.palletStatus = '鏈煡';
+      }
+    },
+
+    // 鎵爜鐩稿叧鏂规硶
+    onPalletScan() {
+      this.scanData.palletCode = this.scanData.palletCode.replace(/\n/g, '').trim();
+      if (!this.scanData.palletCode) return;
+      
+      this.loadPalletData();
+      this.$nextTick(() => {
+        this.$refs.barcodeInput.focus();
+      });
+    },
+
+    onBarcodeScan() {
+      this.scanData.barcode = this.scanData.barcode.replace(/\n/g, '').trim();
+      if (!this.scanData.barcode) return;
+      this.confirmPicking();
+    },
+
+    focusBarcodeInput(selectText = false) {
+      this.$nextTick(() => {
+        const input = this.$refs.barcodeInput;
+        if (input && input.$el && input.$el.querySelector('input')) {
+          const inputEl = input.$el.querySelector('input');
+          inputEl.focus();
+          if (selectText) {
+            inputEl.select();
+          }
+        }
+      });
+    },
+
+    handlePickedSelectionChange(selection) {
+      this.selectedPickedRows = selection;
+    },
+
+    async batchCancelSelected() {
+      if (this.selectedPickedRows.length === 0) {
+        this.$message.warning('璇峰厛閫夋嫨瑕佸彇娑堢殑椤�');
+        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/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}`);
+              }
+            } catch (error) {
+              this.$message.warning(`鍙栨秷鎷i�夊け璐�: ${row.currentBarcode} - ${error.message}`);
+            }
+          }        
+          this.$message.success('鎵归噺鍙栨秷瀹屾垚');
+          await this.loadPalletData();
+          this.selectedPickedRows = [];
+        } catch (error) {
+          this.$message.error('鎵归噺鍙栨秷鎿嶄綔澶辫触');
+        }
+      });
+    },
+
+    // 閲嶇疆鏂规硶
+    resetSplitForm() {
+      this.splitForm.originalBarcode = '';
+      this.splitForm.materielCode = '';
+      this.splitForm.splitQuantity = 0;
+      this.splitForm.maxQuantity = 0;
+    },
+
+    closeCustomSplitDialog() {
+      this.showCustomSplitDialog = false;
+      this.resetSplitForm();
+    },
+
+    openRevertSplitDialog() {
+      this.showRevertSplitDialog = true;
+      this.revertSplitForm.newBarcode = '';
+    },
+
+    closeRevertSplitDialog() {
+      this.showRevertSplitDialog = false;
+      this.revertSplitForm.newBarcode = '';
+    },
+
+    closeBatchReturnDialog() {
+      this.showBatchReturnDialog = false;
+    },
+
+    onEmptyPalletScan() {
+      if (!this.emptypalletOutForm.palletCode) return;
+      this.emptypalletOutForm.palletCode = this.emptypalletOutForm.palletCode.replace(/\n/g, '').trim();
+    },
+
+    closeEmptyPalletDialog() {
+      this.showEmptyPalletDialog = false;
+      this.emptypalletOutForm.palletCode = '';
+    },
+
+    parentcall() {
+      // 鎵撳嵃鍥炶皟
+    }
+  }
+})
+</script>
+
+<style scoped>
+.OutboundPicking-container {
+  padding: 20px;
+}
+
+.scanner-form {
+  display: flex;
+  gap: 10px;
+  align-items: center;
+  flex-wrap: wrap;
+}
+
+.scanner-form .el-input {
+  width: 200px;
+}
+
+.summary-info {
+  display: flex;
+  gap: 20px;
+  flex-wrap: wrap;
+}
+
+.table-actions {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 10px;
+  padding: 0 10px;
+}
+
+.selection-count {
+  font-size: 12px;
+  color: #909399;
+}
+
+/* 鑷畾涔夊脊绐楁牱寮� */
+:deep(.el-message-box) {
+  z-index: 10010 !important;
+}
+
+:deep(.el-overlay) {
+  z-index: 10009 !important;
+}
+
+:deep(.el-message) {
+  z-index: 10011 !important;
+}
+
+.custom-dialog-overlay {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background-color: rgba(0, 0, 0, 0.5);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  z-index: 2000; /* 淇濇寔涓�涓悎鐞嗙殑 z-index */
+}
+
+.custom-dialog-wrapper {
+  position: relative;
+  z-index: 2001;
+}
+
+.custom-dialog {
+  background: white;
+  border-radius: 4px;
+  width: 500px;
+  max-width: 90vw;
+  max-height: 90vh;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  overflow: auto;
+}
+
+.custom-dialog-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 20px 20px 10px;
+  border-bottom: 1px solid #ebeef5;
+}
+
+.custom-dialog-header h3 {
+  margin: 0;
+  color: #303133;
+}
+
+.close-button {
+  font-size: 18px;
+  color: #909399;
+  padding: 0;
+  width: 24px;
+  height: 24px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.close-button:hover {
+  color: #409EFF;
+  background-color: transparent;
+}
+
+.custom-dialog-body {
+  padding: 20px;
+}
+
+.custom-dialog-footer {
+  padding: 10px 20px 20px;
+  text-align: right;
+  border-top: 1px solid #ebeef5;
+}
+
+.custom-dialog-footer .el-button {
+  margin-left: 10px;
+}
+
+@media (max-width: 768px) {
+  .custom-dialog {
+    width: 95vw;
+    margin: 10px;
+  }
+  
+  .scanner-form {
+    flex-direction: column;
+    align-items: stretch;
+  }
+  /* 纭繚纭瀵硅瘽妗嗗湪鏈�鍓嶉潰 */
+.el-message-box__wrapper {
+  z-index: 10001 !important;
+}
+
+.el-message {
+  z-index: 10002 !important;
+}
+  .scanner-form .el-input {
+    width: 100%;
+  }
+}
+</style>
\ No newline at end of file

--
Gitblit v1.9.3