heshaofeng
10 天以前 3762d139e17f5c39f968dccad53d88cff85c863d
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/outbound/PickingConfirm.vue
@@ -1,5 +1,5 @@
<template>
  <div class="picking-confirm">
  <div class="OutboundPicking-container">
    <div class="page-header">
      <el-page-header @back="goBack">
        <template #content>
@@ -7,105 +7,346 @@
        </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">确认拣选</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>
          <!-- <el-button type="danger" @click="handleDirectOutbound">直接出库</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="success">已拣选条数: {{summary.pickedCount}}</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>
    
    <div class="content-layout">
      <!-- å·¦ä¾§ï¼šæ‰«ç åŒºåŸŸ -->
      <div class="left-section">
        <div class="scan-section">
          <el-alert
            title="请使用扫码枪扫描托盘码和物料条码,扫码枪带回车功能,扫完物料条码自动确认"
            type="info"
            :closable="false"
            class="scan-alert"
          />
              <el-table-column prop="assignQuantity" 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-column label="操作" width="100">
                <template slot-scope="scope">
                  <el-button
                    size="mini"
                    type="primary"
                    @click="handleSingleReturn(scope.row)">
                    å›žåº“
                  </el-button>
                </template>
              </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">
                å–消拣选
              </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-form :model="scanForm" label-width="100px" class="scan-form">
            <el-form-item label="托盘码" required>
              <el-input
                ref="palletInput"
                v-model="scanForm.palletCode"
                placeholder="请扫描托盘码"
                @keyup.enter="handlePalletScan"
                @blur="loadPalletSummary"
                clearable
              />
            </el-form-item>
            </el-table>
          </el-card>
        </el-col>
      </el-row>
    </div>
            <el-form-item label="物料条码" required>
              <el-input
                ref="materialInput"
                v-model="scanForm.materialBarcode"
                placeholder="请扫描物料条码"
                :disabled="!scanForm.palletCode"
                @keyup.enter="handleMaterialScan"
                clearable
              />
            </el-form-item>
          </el-form>
    <!-- æ‹†åŒ…弹窗 -->
<!-- æ‹†åŒ…弹窗 -->
     <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"
              icon="el-icon-close"
              @click="closeCustomSplitDialog"
              class="close-button">
            </el-button> -->
                  <el-button
              type="text"
              @click="closeCustomSplitDialog"
              class="close-button">
              X
            </el-button>
          <!-- æ‰˜ç›˜æ‹£è´§ç»Ÿè®¡ -->
          <div v-if="palletSummary" class="pallet-summary">
            <el-card header="托盘拣货统计">
              <el-descriptions :column="3" border>
                <el-descriptions-item label="托盘号">
                  {{ scanForm.palletCode }}
                </el-descriptions-item>
                <el-descriptions-item label="未拣货条数">
                  <el-text type="warning">{{ palletSummary.unpickedCount }}</el-text>
                </el-descriptions-item>
                <el-descriptions-item label="未拣货总数">
                  <el-text type="danger">{{ palletSummary.unpickedTotal }}</el-text>
                </el-descriptions-item>
              </el-descriptions>
            </el-card>
          </div>
          <div class="action-buttons">
            <el-button type="primary" @click="handleConfirm" :loading="confirmLoading">
              æ‰‹åŠ¨ç¡®è®¤
            </el-button>
            <el-button @click="handleReset">重置</el-button>
            <el-button @click="$emit('close')">取消</el-button>
          <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">
                <el-input
                  v-model="splitForm.originalBarcode"
                  placeholder="扫描原条码"
                  @keyup.enter.native="onSplitBarcodeScan"
                  @change="onSplitBarcodeScan"
                  clearable>
                </el-input>
              </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 class="right-section">
        <el-card class="outbound-details-card" header="出库详情">
          <vol-table
            ref="outboundTable"
            :table-config="outboundTableConfig"
            :height="300"
          />
        </el-card>
    <!-- æ’¤é”€æ‹†åŒ…弹窗 -->
    <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="originalBarcode">
                <el-input
                  v-model="revertSplitForm.originalBarcode"
                  placeholder="扫描原条码"
                  @keyup.enter.native="onRevertSplitBarcodeScan"
                  @change="onRevertSplitBarcodeScan"
                  clearable>
                </el-input>
              </el-form-item>
            </el-form>
          </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="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="托盘编号" prop="palletCode">
                <el-input
                  v-model="batchReturnForm.palletCode"
                  placeholder="扫描托盘码"
                  @keyup.enter.native="onBatchReturnPalletScan"
                  @change="onBatchReturnPalletScan"
                  clearable>
                </el-input>
              </el-form-item>
              <el-form-item label="未拣选数量">
                <el-input v-model="batchReturnForm.unpickedCount" disabled></el-input>
              </el-form-item>
              <el-form-item label="未拣选条数">
                <el-input v-model="batchReturnForm.unpickedQuantity" 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 class="picked-records">
      <el-card header="已分拣记录">
        <vol-table
          ref="pickedTable"
          :table-config="pickedTableConfig"
          :height="300"
        />
      </el-card>
    <!-- å–走空箱-->
 <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>
  </div>
    <!-- ç›´æŽ¥å‡ºåº“弹窗 -->
    <div v-if="showDirectOutDialog" 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="closeDirectOutDialog"
              class="close-button">
              Ã—
            </el-button>
          </div>
          <div class="custom-dialog-body">
            <el-form
              :model="directOutForm"
              :rules="directOutFormRules"
              ref="directOutFormRef"
              label-width="100px">
              <el-form-item label="订单编号">
                <el-input v-model="directOutForm.orderNo" disabled></el-input>
              </el-form-item>
              <el-form-item label="托盘编号" prop="palletCode">
                <el-input
                  v-model="directOutForm.palletCode"
                  placeholder="扫描托盘码"
                  @keyup.enter.native="onDirectOutPalletScan"
                  @change="onDirectOutPalletScan"
                  clearable>
                </el-input>
              </el-form-item>
            </el-form>
          </div>
          <div class="custom-dialog-footer">
            <el-button @click="closeDirectOutDialog">取消</el-button>
            <el-button type="primary" @click="handleDirectOutConfirm" :loading="directOutLoading">确认出库</el-button>
          </div>
        </div>
      </div>
    </div>
  <print-view ref="childs" @parentcall="parentcall"></print-view>
</template>
<script>
import http from '@/api/http.js'
import { ref, defineComponent } from "vue";
import { ElMessage } from "element-plus";
import { useRoute } from 'vue-router'
import { ElMessage } from 'element-plus'
import { useRoute } from 'vue-router'
import printView from "@/extension/outbound/extend/printView.vue"
export default defineComponent({
  name: 'PickingConfirm',
  components: {
  },
  components: {printView},
  props: {
    orderNo: {
      type: String,
@@ -114,264 +355,1091 @@
  },
  emits: ['confirm', 'close'],
  data() {
        // å®šä¹‰æ‹†åŒ…表单验证规则
    const validateOriginalBarcode = (rule, value, callback) => {
      if (!value || value.trim() === '') {
        callback(new Error('请输入原条码'));
      } else {
        callback();
      }
    };
    const validateSplitQuantity = (rule, value, callback) => {
      if (value === null || value === undefined || value === '') {
        callback(new Error('请输入拆包数量'));
      } else if (value <= 0) {
        callback(new Error('拆包数量必须大于0'));
      } else if (this.splitForm.maxQuantity && value > this.splitForm.maxQuantity) {
        callback(new Error('拆包数量不能大于剩余数量'));
      } else {
        callback();
      }
    };
    // å®šä¹‰æ’¤é”€æ‹†åŒ…表单验证规则
    const validateRevertOriginalBarcode = (rule, value, callback) => {
      if (!value || value.trim() === '') {
        callback(new Error('请输入原条码'));
      } else {
        callback();
      }
    };
        // å®šä¹‰æ‰¹é‡å›žåº“表单验证规则
    const validateBatchReturnPalletCode = (rule, value, callback) => {
      if (!value || value.trim() === '') {
        callback(new Error('请输入托盘码'));
      } else {
        callback();
      }
    };
     // å®šä¹‰ç›´æŽ¥å‡ºåº“表单验证规则
    const validateDirectOutPalletCode = (rule, value, callback) => {
      if (!value || value.trim() === '') {
        callback(new Error('请输入托盘码'));
      } else {
        callback();
      }
    };
    return {
      scanForm: {
      scanData: {
        orderNo: '',
        palletCode: '',
        materialBarcode: ''
        barcode: ''
      },
      palletSummary: null,
      confirmLoading: false,
      pickedTableConfig: {
        url: '/api/outbound/getPickingRecords',
        query: { orderNo: this.orderNo },
        columns: [
          { prop: 'TaskNo', label: '任务号', width: 150 },
          { prop: 'Barcode', label: '物料条码', width: 150 },
          { prop: 'MaterielName', label: '物料名称', width: 150 },
          { prop: 'PickQuantity', label: '拣货数量', width: 100 },
          { prop: 'LocationCode', label: '货位', width: 120 },
          { prop: 'CreateTime', label: '拣货时间', width: 180 }
      unpickedList: [],
      pickedList: [],
       selectedUnpickedRows: [], // æœªæ‹£é€‰åˆ—表选中的行
      selectedPickedRows: [], // å·²æ‹£é€‰åˆ—表选中的行
      summary: {
        unpickedCount: 0,
        unpickedQuantity: 0,
        pickedCount: 0
      },
      palletStatus: '未知',
      showSplitDialog: false,
      showRevertSplitDialog: false,
      showCustomSplitDialog: false, // è‡ªå®šä¹‰æ‹†åŒ…弹窗显示状态
      showBatchReturnDialog: false, // æ‰¹é‡å›žåº“弹窗显示状态
      showReturnDialog: false,
      splitLoading: false,
       revertSplitLoading: false,
      batchReturnLoading: false, // æ‰¹é‡å›žåº“加载状态
      splitForm: {
        orderNo: '',
        palletCode: '',
        originalBarcode: '',
        materielCode: '',
        splitQuantity: 0,
        maxQuantity: 0
      },
            // æ‹†åŒ…表单验证规则
      splitFormRules: {
        originalBarcode: [
          { required: true, validator: validateOriginalBarcode, trigger: 'blur' }
        ],
        splitQuantity: [
          { required: true, validator: validateSplitQuantity, trigger: 'blur' }
        ]
      },
      // å‡ºåº“详情表格配置
      outboundTableConfig: {
        url: '/api/outbound/getOutboundDetails',
        query: { orderNo: this.orderNo },
        columns: [
          { prop: 'OrderNo', label: '出库单号', width: 150 },
          { prop: 'MaterialCode', label: '物料编号', width: 120 },
          { prop: 'MaterialBarcode', label: '物料条码', width: 150 },
          { prop: 'BatchNo', label: '批次号', width: 120 },
          { prop: 'AssignQuantity', label: '分配出库量', width: 100 },
          { prop: 'PalletCode', label: '托盘编号', width: 120 },
          { prop: 'Unit', label: '单位', width: 80 }
      revertSplitForm: {
        originalBarcode: ''
      },
          // æ’¤é”€æ‹†åŒ…表单验证规则
      revertSplitFormRules: {
        originalBarcode: [
          { required: true, validator: validateRevertOriginalBarcode, trigger: 'blur' }
        ]
      },
      orderInfo: {orderNo:''}
         // æ‰¹é‡å›žåº“表单
      batchReturnForm: {
        orderNo: '',
        palletCode: '',
        unpickedCount: 0,
        unpickedQuantity: 0
      },
      // æ‰¹é‡å›žåº“表单验证规则
      batchReturnFormRules: {
        palletCode: [
          { required: true, validator: validateBatchReturnPalletCode, trigger: 'blur' }
        ]
      },
       showDirectOutDialog: false, // ç›´æŽ¥å‡ºåº“弹窗显示状态
      directOutLoading: false, // ç›´æŽ¥å‡ºåº“加载状态
      directOutForm: {
        orderNo: '',
        palletCode: ''
      },
      directOutFormRules: {
        palletCode: [
          { required: true, validator: validateDirectOutPalletCode, trigger: 'blur' }
        ]
      },
      showEmptyPalletDialog: false, // å–走空箱弹窗显示状态
      emptypalletOutLoading: false, // å–走空箱加载状态
      emptypalletOutForm: {
        orderNo: '',
        palletCode: ''
      },
      emptypalletOutFormRules: {
        palletCode: [
          { required: true, validator: validateDirectOutPalletCode, trigger: 'blur' }
        ]
      },
      returnForm: {
        orderNo: '',
        palletCode: '',
        barcode: '',
        materielCode: '',
        returnQuantity: 0
      },
      isProcessing: false // é˜²æ­¢é‡å¤æäº¤
    }
  },
  mounted() {
    this.loadOrderInfo();
    // ä»Žè·¯ç”±å‚数获取订单编号
    if (this.$route.query.orderNo) {
      this.scanData.orderNo = this.$route.query.orderNo;
      this.splitForm.orderNo = this.$route.query.orderNo;
      this.returnForm.orderNo = this.$route.query.orderNo;
    }
        // é¡µé¢åŠ è½½åŽè‡ªåŠ¨èšç„¦åˆ°æ‰˜ç›˜ç è¾“å…¥æ¡†
    this.$nextTick(() => {
      if (this.$refs.palletInput) {
        this.$refs.palletInput.focus()
      }
    })
      this.$refs.palletInput.focus();
    });
  },
  methods: {
    loadOrderInfo() {
      const orderId = this.$route.query.orderId
      if (!orderId) return
      try {
        this.http.get(`/api/OutboundOrder/GetById?id=${orderId}`).then(response => {debugger;
          if (response.status) {
            this.orderInfo = response.data
          }
        })
      } catch (error) {
        ElMessage.error('加载出库单信息失败')
      }
    goBack(){
       this.$router.back()
    },
     goBack() {
      this.$router.back()
    },
    async handlePalletScan() {
      if (this.scanForm.palletCode) {
        ElMessage.success(`已扫描托盘: ${this.scanForm.palletCode}`)
        await this.loadPalletSummary()
        this.$nextTick(() => {
          if (this.$refs.materialInput) {
            this.$refs.materialInput.focus()
          }
        })
     openSplitDialog() {
      console.log('打开自定义拆包弹窗');
         if (!this.scanData.palletCode) {
        this.$message.warning('请先扫描托盘码');
        return;
      }
    },
    async handleMaterialScan() {
      if (!this.scanForm.palletCode) {
        ElMessage.warning('请先扫描托盘码')
        this.$refs.palletInput.focus()
        return
      }
      this.showCustomSplitDialog = true;
      // é‡ç½®è¡¨å•
      this.resetSplitForm();
      // è®¾ç½®è®¢å•和托盘信息
      this.splitForm.orderNo = this.scanData.orderNo;
      this.splitForm.palletCode = this.scanData.palletCode;
      if (!this.scanForm.materialBarcode) {
        ElMessage.warning('请扫描物料条码')
        return
      }
      await this.executePickingConfirm()
    },
    async loadPalletSummary() {
      if (!this.scanForm.palletCode) {
        this.palletSummary = null
        return
      }
      try {
        const result = await http.get('/api/outbound/getPalletPickingSummary', {
          params: {
            orderNo: this.orderNo,
            palletCode: this.scanForm.palletCode
          }
        })
        if (result.success) {
          // å¤„理统计信息
          const summary = result.data
          const assigned = summary.find(x => x.Status === '已分配') || { TotalAssignQty: 0, TotalPickedQty: 0 }
          const picked = summary.find(x => x.Status === '已拣选') || { TotalPickedQty: 0 }
          this.palletSummary = {
            unpickedCount: assigned.TotalAssignQty > 0 ? 1 : 0, // ç®€åŒ–计算
            unpickedTotal: assigned.TotalAssignQty - assigned.TotalPickedQty
          }
        }
      } catch (error) {
        console.error('加载托盘统计失败:', error)
      }
    },
    async handleConfirm() {
      if (!this.scanForm.palletCode || !this.scanForm.materialBarcode) {
        ElMessage.warning('请填写完整的扫码信息')
        return
      }
      await this.executePickingConfirm()
    },
    async executePickingConfirm() {
      this.confirmLoading = true
      try {
        // å…ˆæ‰¾åˆ°å¯¹åº”的出库锁定信息
        const lockInfoResult = await this.http.get('/api/outbound/getOutStockLockInfo', {
          params: {
            orderNo: this.orderNo,
            palletCode: this.scanForm.palletCode,
            materialBarcode: this.scanForm.materialBarcode
          }
        })
        if (!lockInfoResult.success || !lockInfoResult.data || lockInfoResult.data.length === 0) {
          ElMessage.error('未找到对应的出库锁定信息')
          return
        }
        const lockInfo = lockInfoResult.data[0]
        const request = {
          outStockLockId: lockInfo.Id,
          taskNo: `TASK_${Date.now()}`,
          palletCode: this.scanForm.palletCode,
          materialBarcode: this.scanForm.materialBarcode,
          locationCode: lockInfo.LocationCode
        }
        const result = await this.http.post('/api/outbound/pickingConfirm', request)
        if (result.success) {
          ElMessage.success('分拣确认成功')
          this.handleReset()
          this.$emit('confirm')
          // åˆ·æ–°è¡¨æ ¼
          if (this.$refs.pickedTable) {
            this.$refs.pickedTable.refresh()
          }
          // åˆ·æ–°å‡ºåº“详情表格
          if (this.$refs.outboundTable) {
            this.$refs.outboundTable.refresh()
          }
          // é‡æ–°åŠ è½½æ‰˜ç›˜ç»Ÿè®¡
          await this.loadPalletSummary()
        } else {
          ElMessage.error(result.ElMessage)
        }
      } catch (error) {
        ElMessage.error('分拣确认失败')
      } finally {
        this.confirmLoading = false
      }
    },
    handleReset() {
      this.scanForm.materialBarcode = ''
        // æ¸…除表单验证
      this.$nextTick(() => {
        if (this.$refs.materialInput) {
          this.$refs.materialInput.focus()
        if (this.$refs.splitFormRef) {
          this.$refs.splitFormRef.clearValidate();
        }
      })
      });
    },
    // å…³é—­è‡ªå®šä¹‰æ‹†åŒ…弹窗
    closeCustomSplitDialog() {
      this.showCustomSplitDialog = false;
      this.resetSplitForm();
         // æ¸…除表单验证
      if (this.$refs.splitFormRef) {
        this.$refs.splitFormRef.clearValidate();
      }
    },
    // æ‰“开撤销拆包弹窗
    openRevertSplitDialog() {
      console.log('打开撤销拆包弹窗');
      this.showRevertSplitDialog = true;
      // é‡ç½®è¡¨å•
      this.resetRevertSplitForm();
      // æ¸…除表单验证
      this.$nextTick(() => {
        if (this.$refs.revertSplitFormRef) {
          this.$refs.revertSplitFormRef.clearValidate();
        }
      });
    },
    // å…³é—­æ’¤é”€æ‹†åŒ…弹窗
    closeRevertSplitDialog() {
      this.showRevertSplitDialog = false;
      this.resetRevertSplitForm();
      // æ¸…除表单验证
      if (this.$refs.revertSplitFormRef) {
        this.$refs.revertSplitFormRef.clearValidate();
      }
    },
     // æ‰“开批量回库弹窗
    openBatchReturnDialog() {
      console.log('打开批量回库弹窗');
      this.showBatchReturnDialog = true;
      // é‡ç½®è¡¨å•
      this.resetBatchReturnForm();
      // è®¾ç½®è®¢å•信息
      this.batchReturnForm.orderNo = this.scanData.orderNo;
      // æ›´æ–°æœªæ‹£é€‰ä¿¡æ¯
      this.batchReturnForm.unpickedCount = this.summary.unpickedCount || 0;
      this.batchReturnForm.unpickedQuantity = this.summary.unpickedQuantity || 0;
      // æ¸…除表单验证
      this.$nextTick(() => {
        if (this.$refs.batchReturnFormRef) {
          this.$refs.batchReturnFormRef.clearValidate();
        }
      });
    },
    // å…³é—­æ‰¹é‡å›žåº“弹窗
    closeBatchReturnDialog() {
      this.showBatchReturnDialog = false;
      this.resetBatchReturnForm();
      // æ¸…除表单验证
      if (this.$refs.batchReturnFormRef) {
        this.$refs.batchReturnFormRef.clearValidate();
      }
    },
    // å›žåº“托盘码扫码
    onBatchReturnPalletScan() {
      if (!this.batchReturnForm.palletCode) return;
      this.batchReturnForm.palletCode = this.batchReturnForm.palletCode.replace(/\n/g, '').trim();
      // æ¸…除验证状态
      if (this.$refs.batchReturnFormRef) {
        this.$refs.batchReturnFormRef.clearValidate(['palletCode']);
      }
    },
    // å›žåº“确认
    async handleBatchReturnConfirm() {
      // è¡¨å•验证
      if (this.$refs.batchReturnFormRef) {
        this.$refs.batchReturnFormRef.validate((valid) => {
          if (valid) {
            this.submitBatchReturn();
          } else {
            this.$message.warning('请扫描托盘码');
            return false;
          }
        });
      } else {
        // å¦‚果没有表单引用,使用原有的验证
        if (!this.batchReturnForm.palletCode) {
          this.$message.warning('请扫描托盘码');
          return;
        }
        this.submitBatchReturn();
      }
    },
    // æäº¤å›žåº“请求
    async submitBatchReturn() {
      this.batchReturnLoading = true;
      try {
        const res = await this.http.post('/api/OutboundPicking/return-to-stock', {
          orderNo: this.batchReturnForm.orderNo,
          palletCode: this.batchReturnForm.palletCode
        });
        if (res.status) {
          this.$message.success(res.message);
          this.showBatchReturnDialog = false;
          this.loadData();
        } else {
          this.$message.error(res.message || '回库失败');
        }
      } catch (error) {
        this.$message.error('回库失败');
      } finally {
        this.batchReturnLoading = false;
      }
    },
    // æ‰“开直接出库弹窗
    openDirectOutDialog() {
      console.log('打开直接出库弹窗');
      this.showDirectOutDialog = true;
      // é‡ç½®è¡¨å•
      this.resetDirectOutForm();
      // è®¾ç½®è®¢å•信息
      this.directOutForm.orderNo = this.scanData.orderNo;
      // æ¸…除表单验证
      this.$nextTick(() => {
        if (this.$refs.directOutFormRef) {
          this.$refs.directOutFormRef.clearValidate();
        }
      });
    },
    // å…³é—­ç›´æŽ¥å‡ºåº“弹窗
    closeDirectOutDialog() {
      this.showDirectOutDialog = false;
      this.resetDirectOutForm();
      // æ¸…除表单验证
      if (this.$refs.directOutFormRef) {
        this.$refs.directOutFormRef.clearValidate();
      }
    },
    // ç›´æŽ¥å‡ºåº“托盘码扫码
    onDirectOutPalletScan() {
      if (!this.directOutForm.palletCode) return;
      this.directOutForm.palletCode = this.directOutForm.palletCode.replace(/\n/g, '').trim();
      // æ¸…除验证状态
      if (this.$refs.directOutFormRef) {
        this.$refs.directOutFormRef.clearValidate(['palletCode']);
      }
    },
    // ç›´æŽ¥å‡ºåº“确认
    async handleDirectOutConfirm() {
      // è¡¨å•验证
      if (this.$refs.directOutFormRef) {
        this.$refs.directOutFormRef.validate((valid) => {
          if (valid) {
            this.submitDirectOut();
          } else {
            this.$message.warning('请扫描托盘码');
            return false;
          }
        });
      } else {
        // å¦‚果没有表单引用,使用原有的验证
        if (!this.directOutForm.palletCode) {
          this.$message.warning('请扫描托盘码');
          return;
        }
        this.submitDirectOut();
      }
    },
    // æäº¤ç›´æŽ¥å‡ºåº“请求
    async submitDirectOut() {
      this.directOutLoading = true;
      try {
        const res = await this.http.post('/api/OutboundPicking/direct-outbound', {
          orderNo: this.directOutForm.orderNo,
          palletCode: this.directOutForm.palletCode
        });
        debugger;
        if (res.status) {
          this.$message.success('直接出库成功');
          this.showDirectOutDialog = false;
          this.loadData();
        } else {
          this.$message.error(res.message || '直接出库失败');
        }
      } catch (error) {
        this.$message.error('直接出库失败');
      } finally {
        this.directOutLoading = false;
      }
    },
    // é‡ç½®ç›´æŽ¥å‡ºåº“表单
    resetDirectOutForm() {
      this.directOutForm.palletCode = '';
    },
    // ä¿®æ”¹åŽŸæœ‰çš„ç›´æŽ¥å‡ºåº“æŒ‰é’®ç‚¹å‡»äº‹ä»¶
    handleDirectOutbound() {
      this.openDirectOutDialog();
    },
   // æ‰“开取走空箱弹窗
    openEmptyPalletDialog() {
      console.log('打开取走空箱弹窗');
      this.showEmptyPalletDialog = true;
      // é‡ç½®è¡¨å•
      this.resetEmptyPalletForm();
      // è®¾ç½®è®¢å•信息
      this.emptypalletOutForm.orderNo = this.scanData.orderNo;
      // æ¸…除表单验证
      this.$nextTick(() => {
        if (this.$refs.emptyPalletFormRef) {
          this.$refs.emptyPalletFormRef.clearValidate();
        }
      });
    },
    // å…³é—­å–走空箱弹窗
    closeEmptyPalletDialog() {
      this.showEmptyPalletDialog = false;
      this.resetEmptyPalletForm();
      // æ¸…除表单验证
      if (this.$refs.emptyPalletFormRef) {
        this.$refs.emptyPalletFormRef.clearValidate();
      }
    },
    // å–走空箱托盘码扫码
    onEmptyPalletScan() {
      if (!this.emptypalletOutForm.palletCode) return;
      this.emptypalletOutForm.palletCode = this.emptypalletOutForm.palletCode.replace(/\n/g, '').trim();
      // æ¸…除验证状态
      if (this.$refs.emptyPalletFormRef) {
        this.$refs.emptyPalletFormRef.clearValidate(['palletCode']);
      }
    },
    // å–走空箱确认
    async handleEmptyPalletConfirm() {
      // è¡¨å•验证
      if (this.$refs.emptyPalletFormRef) {
        this.$refs.emptyPalletFormRef.validate((valid) => {
          if (valid) {
            this.submitEmptyPallet();
          } else {
            this.$message.warning('请扫描托盘码');
            return false;
          }
        });
      } else {
        // å¦‚果没有表单引用,使用原有的验证
        if (!this.emptypalletOutForm.palletCode) {
          this.$message.warning('请扫描托盘码');
          return;
        }
        this.submitEmptyPallet();
      }
    },
    // æäº¤å–走空箱请求
    async submitEmptyPallet() {
      this.emptypalletOutLoading = true;
      try {
        const res = await this.http.post('/api/OutboundPicking/remove-empty-pallet', {
          orderNo: this.emptypalletOutForm.orderNo,
          palletCode: this.emptypalletOutForm.palletCode
        });
        debugger;
        if (res.status) {
          this.$message.success('取走空箱成功');
          this.showEmptyPalletDialog = false;
          this.loadData();
        } else {
          this.$message.error(res.message || '取走空箱失败');
        }
      } catch (error) {
        this.$message.error('取走空箱失败');
      } finally {
        this.emptypalletOutLoading = false;
      }
    },
    // é‡ç½®å–走空箱表单
    resetEmptyPalletForm() {
      this.emptypalletOutForm.palletCode = '';
    },
    // ä¿®æ”¹åŽŸæœ‰çš„å–èµ°ç©ºç®±æŒ‰é’®ç‚¹å‡»äº‹ä»¶
    handleEmptyPallet() {
      this.openEmptyPalletDialog();
    },
    async loadData() {
      if (!this.scanData.orderNo || !this.scanData.palletCode) {
        return;
      }
      try {
        // åŠ è½½æœªæ‹£é€‰åˆ—è¡¨
        const unpickedRes = await this.http.post('/api/OutboundPicking/unpicked-list', this.scanData);
        this.unpickedList = unpickedRes.data || [];
        // åŠ è½½å·²æ‹£é€‰åˆ—è¡¨
        const pickedRes = await this.http.post('/api/OutboundPicking/picked-list', this.scanData);
        this.pickedList = pickedRes.data || [];
        // åŠ è½½æ±‡æ€»ä¿¡æ¯
        const summaryRes = await this.http.post('/api/OutboundPicking/picking-summary',this.scanData);
        this.summary = summaryRes.data || {};
        // æ›´æ–°æ‰˜ç›˜çŠ¶æ€
        this.updatePalletStatus();
      } catch (error) {
        this.$message.error('加载数据失败');
      }
    },
    updatePalletStatus() {
      if (this.unpickedList.length === 0 && this.pickedList.length > 0) {
        this.palletStatus = '已全部拣选';
      } else if (this.unpickedList.length > 0 && this.pickedList.length === 0) {
        this.palletStatus = '待拣选';
      } else if (this.unpickedList.length > 0 && this.pickedList.length > 0) {
        this.palletStatus = '部分拣选';
      } else {
        this.palletStatus = '无数据';
      }
    },
    // å·²æ‹£é€‰åˆ—表选择变化
    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 {
          let successCount = 0;
          let errorCount = 0;
          for (const row of this.selectedPickedRows) {
            try {
              const res = await this.http.post('/api/OutboundPicking/CancelPicking', {
                orderNo: this.scanData.orderNo,
                palletCode: this.scanData.palletCode,
                barcode: row.currentBarcode
              });
              if (res.status) {
                successCount++;
                 this.$message.success(`成功取消`);
              } else {
                errorCount++;
                 this.$message.warning(`取消拣选失败: ${row.currentBarcode} - ${res.message}`);
              }
            } catch (error) {
              errorCount++;
              this.$message.warning(`取消拣选失败: ${row.currentBarcode} - ${error.message}` );
            }
          }
          this.loadData();
          this.selectedPickedRows = [];
        } catch (error) {
          this.$message.error('批量取消操作失败');
        }
      }).catch(() => {
        this.$message.info('已取消批量操作');
      });
    },
    // æ‰˜ç›˜ç æ‰«ç 
    onPalletScan() {
     // åŽ»é™¤å›žè½¦ç¬¦å’Œå‰åŽç©ºæ ¼
      this.scanData.palletCode = this.scanData.palletCode.replace(/\n/g, '').trim();
      if (!this.scanData.palletCode) return;
      this.splitForm.palletCode = this.scanData.palletCode;
      this.returnForm.palletCode = this.scanData.palletCode;
      // åŠ è½½æ•°æ®
      this.loadData();
      // è‡ªåŠ¨è·³è½¬åˆ°ç‰©æ–™æ¡ç è¾“å…¥æ¡†
      this.$nextTick(() => {
        this.$refs.barcodeInput.focus();
      });
    },
    onBarcodeScan() {
       // åŽ»é™¤å›žè½¦ç¬¦å’Œå‰åŽç©ºæ ¼
      this.scanData.barcode = this.scanData.barcode.replace(/\n/g, '').trim();
      if (!this.scanData.barcode) return;
      // è‡ªåŠ¨ç¡®è®¤æ‹£é€‰
      this.confirmPicking();
    },
    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 this.http.post('/api/OutboundPicking/confirm-picking', this.scanData);
        if (res.status) {
          this.$message.success('拣选确认成功');
          this.scanData.barcode = ''; // æ¸…空物料条码
          this.loadData();
          console.log(res.data.splitResults)
          if(res.data && res.data.splitResults.length>0){
            // è°ƒç”¨å­ç»„件打印方法
            this.$refs.childs.open(res.data.splitResults);
            //this.$refs.childs.printSplitLabel(res.data.splitResults);
          }
          // æˆåŠŸåŽç»§ç»­èšç„¦åˆ°ç‰©æ–™æ¡ç è¾“å…¥æ¡†ï¼Œå‡†å¤‡ä¸‹ä¸€ä¸ªæ‰«ç 
          this.$nextTick(() => {
            this.$refs.barcodeInput.focus();
          });
        } else {
          // æ˜¾ç¤ºåŽç«¯è¿”回的错误信息
          this.$message.error(res.message || '拣选确认失败');
          // å¤±è´¥æ—¶èšç„¦å¹¶é€‰ä¸­ç‰©æ–™æ¡ç è¾“入框内容
          this.focusBarcodeInput(true);
        }
      } catch (error) {
        this.$message.error('拣选确认失败: ' + (error.message || '网络错误'));
        // å¤±è´¥æ—¶èšç„¦å¹¶é€‰ä¸­ç‰©æ–™æ¡ç è¾“入框内容
        this.focusBarcodeInput(true);
      } finally {
        this.isProcessing = false;
      }
    },
    // èšç„¦åˆ°ç‰©æ–™æ¡ç è¾“入框
    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();
          }
        }
      });
    },
    async cancelPicking(row) {
      try {
        const res = await this.http.post('/api/OutboundPicking/CancelPicking', {
          orderNo: this.scanData.orderNo,
          palletCode: this.scanData.palletCode,
          barcode: row.Barcode
        });
        if (res.status) {
          this.$message.success('取消拣选成功');
          this.loadData();
        } else {
          this.$message.error(res.message || '取消拣选失败');
        }
      } catch (error) {
        this.$message.error('取消拣选失败');
      }
    },
   /*  // å›žåº“操作 - å›žåº“整个托盘未拣选的货物
    async handleBatchReturn() {
      if (!this.scanData.orderNo || !this.scanData.palletCode) {
        this.$message.warning('请先扫描托盘码');
        return;
      }
      if (this.unpickedList.length === 0) {
        this.$message.warning('该托盘没有可回库的货物');
        return;
      }
      this.$confirm(`确定要回库整个托盘的未拣选货物吗?共 ${this.unpickedList.length} æ¡è®°å½•`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        try {
          const res = await this.http.post('/api/OutboundPicking/batch-return-to-stock', {
            orderNo: this.scanData.orderNo,
            palletCode: this.scanData.palletCode
          });
          if (res.success) {
            this.$message.success('批量回库成功');
            this.loadData();
          } else {
            this.$message.error(res.message || '批量回库失败');
          }
        } catch (error) {
          this.$message.error('批量回库失败');
        }
      }).catch(() => {
        this.$message.info('已取消批量回库');
      });
    }, */
   /*  // ç›´æŽ¥å‡ºåº“操作
    async handleDirectOutbound() {
      if (!this.scanData.orderNo || !this.scanData.palletCode) {
        this.$message.warning('请先扫描托盘码');
        return;
      }
      this.$confirm('确定要直接出库整个托盘吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        try {
          const res = await this.http.post('/api/OutboundPicking/direct-outbound', {
            orderNo: this.scanData.orderNo,
            palletCode: this.scanData.palletCode
          });
          if (res.success) {
            this.$message.success('直接出库成功');
            this.loadData();
          } else {
            this.$message.error(res.message || '直接出库失败');
          }
        } catch (error) {
          this.$message.error('直接出库失败');
        }
      }).catch(() => {
        this.$message.info('已取消直接出库');
      });
    }, */
    // ç¡®è®¤å›žåº“(通过弹窗)
    async handleReturnConfirm() {
      if (!this.returnForm.barcode) {
        this.$message.warning('请扫描回库条码');
        return;
      }
      try {
        const res = await this.http.post('/api/OutboundPicking/return-to-stock', {
          orderNo: this.returnForm.orderNo,
          palletCode: this.returnForm.palletCode,
          barcode: this.returnForm.barcode
        });
        if (res.status) {
          this.$message.success('回库成功');
          this.showReturnDialog = false;
          this.resetReturnForm();
          this.loadData();
        } else {
          this.$message.error(res.message || '回库失败');
        }
      } catch (error) {
        this.$message.error('回库失败');
      }
    },
    // æ‹†åŒ…扫码
    async onSplitBarcodeScan() {
      if (!this.splitForm.originalBarcode) return;
      // åŽ»é™¤å›žè½¦ç¬¦å’Œå‰åŽç©ºæ ¼
      this.splitForm.originalBarcode = this.splitForm.originalBarcode.replace(/\n/g, '').trim();
      try {
        const res = await this.http.post('/api/OutboundPicking/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);
           // æ¸…除验证状态
          if (this.$refs.splitFormRef) {
            this.$refs.splitFormRef.clearValidate(['originalBarcode']);
          }
        } else {
          this.$message.error(res.message || '获取拆包信息失败');
            // éªŒè¯å¤±è´¥ï¼Œè®¾ç½®é”™è¯¯çŠ¶æ€
          if (this.$refs.splitFormRef) {
            this.$refs.splitFormRef.validateField('originalBarcode');
          }
        }
      } catch (error) {
        this.$message.error('获取拆包信息失败');
         // éªŒè¯å¤±è´¥ï¼Œè®¾ç½®é”™è¯¯çŠ¶æ€
        if (this.$refs.splitFormRef) {
          this.$refs.splitFormRef.validateField('originalBarcode');
        }
      }
    },
    async handleSplitPackage() {
       // è¡¨å•验证
      if (this.$refs.splitFormRef) {
        this.$refs.splitFormRef.validate((valid) => {
          if (valid) {
            this.submitSplitPackage();
          } else {
            this.$message.warning('请填写完整的拆包信息');
            return false;
          }
        });
      } else {
        // å¦‚果没有表单引用,使用原有的验证
        if (!this.splitForm.originalBarcode || this.splitForm.splitQuantity <= 0) {
          this.$message.warning('请填写完整的拆包信息');
          return;
        }
        if (this.splitForm.splitQuantity > this.splitForm.maxQuantity) {
          this.$message.warning('拆包数量不能大于剩余数量');
          return;
        }
        this.submitSplitPackage();
      }
    },
    // æäº¤æ‹†åŒ…请求
    async submitSplitPackage() {
    this.splitLoading = true;
     try {
        const res = await this.http.post('/api/OutboundPicking/split-package', this.splitForm);
        if (res.status) {
          this.$message.success('拆包成功');
          this.showSplitDialog = false;
              this.splitLoading = false;
          this.resetSplitForm();
          this.loadData();
        } else {
               this.splitLoading = false;
          this.$message.error(res.message || '拆包失败');
        }
      } catch (error) {
             this.splitLoading = false;
        this.$message.error('拆包失败');
      }
    },
        // æ’¤é”€æ‹†åŒ…扫码
    onRevertSplitBarcodeScan() {
      if (!this.revertSplitForm.originalBarcode) return;
      this.revertSplitForm.originalBarcode = this.revertSplitForm.originalBarcode.replace(/\n/g, '').trim();
      // æ¸…除验证状态
      if (this.$refs.revertSplitFormRef) {
        this.$refs.revertSplitFormRef.clearValidate(['originalBarcode']);
      }
    },
    async handleRevertSplit() {
      // è¡¨å•验证
      if (this.$refs.revertSplitFormRef) {
        this.$refs.revertSplitFormRef.validate((valid) => {
          if (valid) {
            this.submitRevertSplit();
          } else {
            this.$message.warning('请输入原条码');
            return false;
          }
        });
      } else {
        // å¦‚果没有表单引用,使用原有的验证
        if (!this.revertSplitForm.originalBarcode) {
          this.$message.warning('请输入原条码');
          return;
        }
        this.submitRevertSplit();
      }
    },
    // æäº¤æ’¤é”€æ‹†åŒ…请求
    async submitRevertSplit() {
      this.revertSplitLoading = true;
      try {
        const res = await this.http.post('/api/OutboundPicking/revert-split-package', {
          originalBarcode: this.revertSplitForm.originalBarcode
        });
        if (res.status) {
          this.$message.success('撤销拆包成功');
          this.showRevertSplitDialog = false;
           this.revertSplitLoading = false;
          this.revertSplitForm.originalBarcode = '';
          this.loadData();
        } else {
         this.revertSplitLoading = false;
          this.$message.error(res.message || '撤销拆包失败');
        }
      } catch (error) {
         this.revertSplitLoading = false;
        this.$message.error('撤销拆包失败');
      }
    },
    resetSplitForm() {
      this.splitForm.originalBarcode = '';
      this.splitForm.materielCode = '';
      this.splitForm.splitQuantity = 0;
      this.splitForm.maxQuantity = 0;
    },
    // é‡ç½®æ‰¹é‡å›žåº“表单
    resetBatchReturnForm() {
      this.batchReturnForm.palletCode = '';
      this.batchReturnForm.unpickedCount = 0;
      this.batchReturnForm.unpickedQuantity = 0;
    },
    resetReturnForm() {
      this.returnForm.barcode = '';
      this.returnForm.materielCode = '';
      this.returnForm.returnQuantity = 0;
    }
  }
})
</script>
<style scoped>
.picking-confirm {
.picking-container {
  padding: 20px;
  position: relative; /* ä¸ºå¼¹çª—定位提供上下文 */
}
.scanner-form {
  display: flex;
  flex-direction: column;
  height: 70vh;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
}
.content-layout {
.scanner-form .el-input {
  width: 200px;
}
.summary-info {
  display: flex;
  gap: 16px;
  margin-bottom: 16px;
  flex: 1;
  min-height: 0; /* é‡è¦ï¼šé˜²æ­¢flex子元素溢出 */
  gap: 20px;
  flex-wrap: wrap;
}
.left-section {
  flex: 1;
/* è¡¨æ ¼æ“ä½œåŒºåŸŸæ ·å¼ */
.table-actions {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
  padding: 0 10px;
}
.right-section {
  flex: 1;
.selection-count {
  font-size: 12px;
  color: #909399;
}
/* è¡¨æ ¼æ ·å¼è°ƒæ•´ */
.content-area .el-table {
  margin-top: 0;
}
/* ç¡®ä¿è¡¨æ ¼é«˜åº¦é€‚应 */
.content-area .el-card__body {
  padding: 15px;
}
/* è‡ªå®šä¹‰å¼¹çª—样式 */
.custom-dialog-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 9999;
}
.scan-section {
  flex-shrink: 0;
.custom-dialog-wrapper {
  position: relative;
  z-index: 10000;
}
.scan-alert {
  margin-bottom: 16px;
.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;
}
.scan-form {
  max-width: 500px;
}
.pallet-summary {
  margin: 16px 0;
}
.action-buttons {
  margin-top: 16px;
}
.outbound-details-card {
  height: 100%;
.custom-dialog-header {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  padding: 20px 20px 10px;
  border-bottom: 1px solid #ebeef5;
}
.outbound-details-card :deep(.el-card__body) {
  flex: 1;
.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;
}
.picked-records {
  flex-shrink: 0;
  height: 300px;
.close-button:hover {
  color: #409EFF;
  background-color: transparent;
}
.picked-records :deep(.el-card__body) {
  padding: 0;
.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;
  }
}
</style>