<template>
  <div>
    <div class="pda-container">
      <!-- 头部栏 -->
      <div class="header-bar">
        <div class="header-left" @click="handleBack">
          <i class="el-icon-arrow-left"></i>
          <span>人工分拣组盘</span>
        </div>
        <div class="header-right" @click="$router.push({ path: '/' })">
          首页
        </div>
      </div>
      <div class="table-body" style="max-height: 500px; overflow-y: auto;">
      <div class="main-content form-section">
        <!-- 第一行：栈板扫描 -->
        <div class="input-group">
          <label class="input-label">栈板编码</label>
          <div style="display: flex; gap: 8px;">
            <el-input
              v-model="palletCode"
              placeholder="请扫描栈板编码"
              class="form-input"
              style="flex: 0.75;"
              clearable
              @keyup.enter.native="handlePalletScan"
              inputmode="none"
              autocomplete="off"
              autocorrect="off"
              spellcheck="false"
              ref="palletInput"
            />
            <button class="action-btn secondary" style="flex: 0.25; margin: 0;" @click="handleFinishSorting" :disabled="finishSortingLoading || detailList.length === 0">
              {{ finishSortingLoading ? '处理中...' : '结束分拣' }}
            </button>
<!--            <button-->
<!--              class="action-btn secondary"-->
<!--              style="flex: 0.25; margin: 0;"-->
<!--              @click="handleCallPallet"-->
<!--            >-->
<!--              Call栈板-->
<!--            </button>-->
          </div>
        </div>

        <!-- 第二行：栈板类型和自动分拣 (扫描栈板后显示) -->
        <div v-if="palletScanned" class="input-group">
          <div style="display: flex; gap: 8px; align-items: end;">
            <div style="flex: 0.65;">
              <label class="input-label">栈板类型</label>
              <el-select
                v-model="currentPalletType"
                placeholder="请选择栈板类型"
                style="width: 100%;"
                :disabled="palletTypeDisabled"
                @change="handlePalletTypeChange"
              >
                <el-option
                  v-for="type in palletTypeOptions"
                  :key="type.palletType"
                  :label="`${type.palletType} - ${type.typeDesc}`"
                  :value="type.palletType"
                />
              </el-select>
            </div>
            <div style="flex: 0.35;">
              <label class="input-label">自动分拣</label>
              <el-select
                v-model="currentAutoSort"
                placeholder="请选择"
                style="width: 100%;"
                :disabled="autoSortDisabled"
                @change="handleAutoSortChange"
              >
                <el-option label="是" value="Y"></el-option>
                <el-option label="否" value="N"></el-option>
              </el-select>
            </div>
          </div>
        </div>

        <!-- 第2.5行：是否强制整托出库 (扫描栈板后显示) - rqrq -->
        <div v-if="palletScanned" class="input-group">
          <el-checkbox
            v-model="forceFullPalletOut"
            :disabled="palletTypeDisabled"
            @change="handleForceFullPalletOutChange"
            style="width: 100%;">
            是否强制整托出库
          </el-checkbox>
        </div>

        <!-- 第三行：当前栈板站点显示 (扫描栈板后显示) - rqrq -->
        <div v-if="palletScanned" class="input-group">
          <label class="input-label">当前站点</label>
          <div style="display: flex; gap: 8px;">
            <el-input
              v-model="currentPalletStation"
              placeholder="栈板当前站点"
              class="form-input"
              readonly
              style="flex: 0.75;">
            </el-input>
            <button
              class="action-btn secondary"
              style="flex: 0.25; margin: 0; white-space: nowrap;"
              @click="refreshTable"
            >
              刷新
            </button>
          </div>
        </div>

        <!-- 第四行：扫进/扫出选择 (扫描栈板后显示) -->
        <div v-if="palletScanned" class="input-group">
          <div style="display: flex; gap: 8px; align-items: center;">
            <div style="flex: 0.75;">
              <el-radio-group v-model="operationType" style="display: flex;">
                <el-radio label="in" style="margin-right: 0px; white-space: nowrap;">扫进</el-radio>
                <el-radio label="out" style="white-space: nowrap;">扫回</el-radio>
              </el-radio-group>
            </div>
            <button
              class="action-btn secondary"
              style="flex: 0.25; margin: 0; white-space: nowrap;"
              :disabled="currentPalletType === ''"
              @click="showScanModal"
            >
              扫描条码
            </button>
          </div>
        </div>
      </div>

      <!-- 栈板明细表格 (扫描栈板后显示) -->
      <div v-if="palletScanned" class="rma-list">
        <div class="list-title-row" style="display: flex; gap: 8px; align-items: center; padding: 0;">
          <div class="list-title" style="flex: 0.75; margin: 0;">
            <button class="action-btn primary" style="flex: 0.25; margin: 0;" @click="showDetailModal" :disabled="completeAssemblyLoading">
              {{ '浏览明细' }}
            </button>
            <laber style="margin-left: 5px;">条码数:{{detailList.length}}</laber>
          </div>
          <button class="action-btn primary" style="flex: 0.25; margin: 0;" @click="handleCompleteAssembly" :disabled="completeAssemblyLoading">
            {{ completeAssemblyLoading ? '处理中...' : '提交分拣' }}
          </button>
        </div>
        <div class="detail-table">
          <div class="table-header">
            <div class="col-position">位置</div>
            <div class="col-layer">层数</div>
            <div class="col-serial">标签号</div>
          </div>
          <div
            v-for="(detail, index) in detailList"
            :key="index"
            class="table-row"
            @click="handleRowDblClick(detail, index)"
          >
            <div class="col-position">{{ detail.position }}</div>
            <div class="col-layer">{{ detail.layer }}</div>
            <div class="col-serial">{{ detail.serialNo }}</div>
          </div>
          <!-- 暂无数据提示 -->
          <div v-if="detailList.length === 0" class="table-row empty-row">
            <div class="empty-hint">暂无栈板明细数据</div>
          </div>
        </div>
      </div>
      </div>
    </div>
    <el-dialog
      :title="'已扫描数量:'+detailList.length"
      :visible.sync="detailModalVisible"
      width="90%"
      :close-on-click-modal="false"
      :show-close="false"
      :modal="true"
      :modal-append-to-body="true"
      :append-to-body="true"
    >
      <div class="table-body" style="max-height: 240px; overflow-y: auto;">
      <div class="detail-table">
        <div class="table-header">
          <div class="col-position">位置</div>
          <div class="col-layer">层数</div>
          <div class="col-serial">标签号</div>
        </div>
        <div
          v-for="(detail, index) in detailList"
          :key="index"
          class="table-row"
          @click="handleRowDblClick(detail, index)"
        >
          <div class="col-position">{{ detail.position }}</div>
          <div class="col-layer">{{ detail.layer }}</div>
          <div class="col-serial">{{ detail.serialNo }}</div>
        </div>
        <!-- 暂无数据提示 -->
        <div v-if="detailList.length === 0" class="table-row empty-row">
          <div class="empty-hint">暂无栈板明细数据</div>
        </div>
      </div>
      </div>
      <div slot="footer" class="dialog-footer">
        <button class="action-btn secondary" style="margin-left: 10px;" @click="detailModalVisible=false">取消</button>
      </div>
    </el-dialog>
    <!-- 扫码模态框 - rqrq -->
    <el-dialog
      title="扫描标签"
      :visible.sync="scanModalVisible"
      width="90%"
      :close-on-click-modal="false"
      :show-close="false"
      :modal="true"
      :modal-append-to-body="true"
      :append-to-body="true"
    >
      <div class="scan-modal-content">
        <!-- 扫进时显示层数选择和位置网格 - rqrq -->
        <div v-if="operationType === 'in'" class="modal-form">
          <!-- 层数选择（混装托盘不显示） - rqrq -->
          <div v-if="!currentMixedMode && scanLayerOptions.length > 0" class="input-group">
            <label class="input-label">层数（当前选择：第{{ scanLayer }}层）</label>
            <div class="layer-grid">
              <div
                v-for="layer in scanLayerOptions"
                :key="layer"
                class="layer-item"
                :class="{
                  'layer-selected': scanLayer === layer
                }"
                @click="handleLayerClick(layer)"
              >
                {{ layer }}
              </div>
            </div>
          </div>

          <!-- 位置网格选择器 - rqrq -->
          <div class="input-group">
            <label class="input-label">
              位置{{ currentSelectedPosition ? `（当前选择：${currentSelectedPosition}）` : '' }}
              <span v-if="positionGridLoading" style="color: #909399; font-size: 12px;">（加载中...）</span>
            </label>
            <div class="position-grid" :class="[
              {'position-grid-loading': positionGridLoading},
              getPositionGridClass
            ]">
              <div
                v-for="(item, index) in displayPositionGrid"
                :key="index"
                class="position-item"
                :class="{
                  'position-disabled': positionGridLoading || !availablePositions.includes(item.position),
                  'position-selected': currentSelectedPosition === item.position,
                  'position-loading': positionGridLoading,
                  'position-placeholder': item.isPlaceholder
                }"
                @click="handlePositionClick(item.position)"
              >
                <template v-if="!item.isPlaceholder">{{ item.position }}({{ item.count }})</template>
              </div>
            </div>
          </div>
        </div>

        <!-- 标签扫描 - rqrq -->
        <div class="input-group">
          <label class="input-label">标签二维码</label>
          <el-input
            v-model="scanCode"
            placeholder="请扫描标签二维码"
            class="form-input"
            clearable
            :disabled="operationType === 'in' && !currentSelectedPosition"
            @keyup.enter.native="handleLabelScan"
            inputmode="none"
            autocomplete="off"
            autocorrect="off"
            spellcheck="false"
            ref="scanInput"
          />
        </div>
      </div>

      <div slot="footer" class="dialog-footer">
        <button class="action-btn secondary" style="margin-left: 10px;" @click="closeScanModal">取消</button>
      </div>
    </el-dialog>

    <!-- 修改位置模态框 -->
    <el-dialog
      title="修改标签位置"
      :visible.sync="editPositionModalVisible"
      width="90%"
      :close-on-click-modal="false"
      :show-close="false"
      :modal="true"
      :modal-append-to-body="true"
      :append-to-body="true"
    >
      <div class="edit-modal-content">
        <!-- 标签号（只读） -->
        <div class="input-group">
          <label class="input-label">标签号</label>
          <el-input
            v-model="editSerialNo"
            placeholder="标签号"
            class="form-input"
            readonly
          />
        </div>

        <!-- 位置选择 -->
        <div class="input-group">
          <label class="input-label">位置</label>
          <el-select
            v-model="editPosition"
            placeholder="请选择位置"
            style="width: 100%;"
            @change="handleEditPositionChange"
          >
            <el-option
              v-for="position in positionOptions"
              :key="position"
              :label="position"
              :value="position"
            />
          </el-select>
        </div>

        <!-- 层数选择 -->
        <div class="input-group">
          <label class="input-label">层数</label>
          <el-select
            v-model="editLayer"
            placeholder="请选择层数"
            style="width: 100%;"
          >
            <el-option
              v-for="layer in editLayerOptions"
              :key="layer"
              :label="`第${layer}层`"
              :value="layer"
            />
          </el-select>
        </div>
      </div>

      <div slot="footer" class="dialog-footer">
        <button class="action-btn primary" @click="confirmEditPosition" :disabled="editPositionLoading">
          {{ editPositionLoading ? '处理中...' : '确定' }}
        </button>
        <button class="action-btn secondary" style="margin-left: 10px;" @click="closeEditPositionModal" :disabled="editPositionLoading">取消</button>
      </div>
    </el-dialog>

    <!-- Call栈板模态框 -->
    <el-dialog
      title="调用空托盘"
      :visible.sync="callPalletModalVisible"
      width="90%"
      :close-on-click-modal="false"
      :show-close="false"
      :modal="true"
      :modal-append-to-body="true"
      :append-to-body="true"
    >
      <div class="call-modal-content">
        <!-- 起始站点选择 -->
        <div class="input-group">
          <label class="input-label">起始站点</label>
          <el-select
            v-model="selectedCallStartStation"
            placeholder="请选择起始站点"
            style="width: 100%;"
            @change="handleCallStartStationChange"
          >
            <el-option
              v-for="station in callStartStationOptions"
              :key="station.stationCode"
              :label="`${station.stationCode} - ${station.stationName}`"
              :value="station.stationCode"
            />
          </el-select>
        </div>

        <!-- 目标站点输入 -->
        <div class="input-group">
          <label class="input-label">目标站点</label>
          <el-input
            ref="callTargetStationInput"
            v-model="selectedCallTargetStation"
            placeholder="请扫描或输入目标站点"
            clearable
            style="width: 100%;"
          />
        </div>
      </div>

      <div slot="footer" class="dialog-footer">
        <button class="action-btn primary" @click="confirmCallPallet" :disabled="callPalletLoading">
          {{ callPalletLoading ? '调用中...' : '确定' }}
        </button>
        <button class="action-btn secondary" style="margin-left: 10px;" @click="closeCallPalletModal" :disabled="callPalletLoading">取消</button>
      </div>
    </el-dialog>

  </div>
</template>

<script>
import {
  checkPalletExists,
  getPalletDetails,
  getLayersByPosition,
  savePalletDetail,
  restorePalletDetail,
  getLabelInfo,
  getLayersForEdit,
  updatePalletDetailPosition,
  getPalletInfo,
  getPalletTypeList,
  getPalletTypeAreas,
  updatePalletTypeAndAutoSort,
  getAgvStations,
  getAvailableAgvStations,
  callPalletToStation,
  completePalletAssemblyForFenJian,
  getAvailablePositionsForLayer,
  finishSorting,
  getSortingList
} from '../../../api/automatedWarehouse/palletPacking'

export default {
  data() {
    return {
      site: localStorage.getItem('site'),
      palletCode: '',
      palletScanned: false,
      operationType: 'in', // 'in' 或 'out'
      detailModalVisible:false,
      // 栈板类型和自动分拣
      currentPalletFamily: '',        // 当前栈板大分类（固定不可改）
      currentPalletType: '',          // 当前栈板类型
      currentAutoSort: '',            // 当前是否自动分拣 Y/N
      forceFullPalletOut: false,      // 是否强制整托出库 - rqrq
      palletTypeOptions: [],          // 托盘类型选项列表
      palletTypeDisabled: false,      // 栈板类型下拉框是否禁用（有明细数据时禁用）
      autoSortDisabled: false,        // 自动分拣下拉框是否禁用
      currentWcsAutoSort: '',         // 当前托盘类型的wcsAutoSort值
      currentMaxLayer: 0,             // 当前托盘类型的最大层数，0=无限

      // 筛选条件
      selectedPosition: '',
      selectedLayer: '',
      positionOptions: [],
      layerOptions: [],
      currentPalletStation: '',       // 当前栈板站点 - rqrq

      // 扫码模态框 - rqrq
      scanModalVisible: false,
      scanCode: '',
      scanPosition: '',
      scanLayer: 1,
      scanLayerOptions: [],
      needRefreshOnClose: false, // 标记是否需要在关闭模态框时刷新

      // 位置网格数据 - rqrq
      positionGrid: [],           // 位置网格列表（用于显示4宫格或9宫格）,格式: [{position: '1', count: 2}, ...]
      availablePositions: [],     // 可用位置列表
      currentSelectedPosition: '', // 当前选中的位置
      currentMixedMode: false,    // 是否混装模式
      positionGridLoading: false, // 位置网格加载中

      // 栈板明细
      detailList: [],

      // 分拣原始数据缓存（用于扫回恢复）- rqrq
      // key: serialNo, value: {palletId, position, layer, wcsFlag, partNo, createDate, createBy}
      originalDetailCache: {},

      // Call栈板模态框
      callPalletModalVisible: false,
      callStartStationOptions: [],  // 起始站点选项（statusDb=1，有货）
      callTargetStationOptions: [],  // 目标站点选项（statusDb=0，空闲）
      selectedCallStartStation: '',
      selectedCallTargetStation: '',

      // 修改位置模态框
      editPositionModalVisible: false,
      editSerialNo: '',
      editPosition: '',
      editLayer: '',
      editLayerOptions: [],
      editOriginalPosition: '',
      editOriginalLayer: '',

      // 按钮loading状态（防止重复点击）
      editPositionLoading: false,        // 修改位置按钮
      callPalletLoading: false,          // Call栈板按钮
      completeAssemblyLoading: false,    // 完成组托按钮
      finishSortingLoading: false,       // 结束分拣按钮 - rqrq

      //需要分拣的清单
      sortingList: [],
    };
  },
  computed: {
    // 获取位置网格的CSS类 - rqrq
    getPositionGridClass() {
      const len = this.positionGrid.length;
      if (len === 1) return 'position-grid-1';
      if (len === 2) return 'position-grid-4'; // 2宫格用4宫格布局
      if (len === 4) return 'position-grid-4';
      return 'position-grid-9';
    },
    // 生成显示用的位置网格（处理2宫格斜对角显示）- rqrq
    displayPositionGrid() {
      const len = this.positionGrid.length;
      // 2宫格特殊处理：用4宫格布局，1在左上(索引0)，2在右下(索引3) - rqrq
      if (len === 2) {
        const pos1 = this.positionGrid.find(p => p.position === '1') || { position: '1', count: 0 };
        const pos2 = this.positionGrid.find(p => p.position === '2') || { position: '2', count: 0 };
        return [
          { ...pos1, isPlaceholder: false },           // 左上 - 位置1
          { position: '', count: 0, isPlaceholder: true },  // 右上 - 占位
          { position: '', count: 0, isPlaceholder: true },  // 左下 - 占位
          { ...pos2, isPlaceholder: false }            // 右下 - 位置2
        ];
      }
      // 1宫格、4宫格、9宫格直接返回
      return this.positionGrid.map(p => ({ ...p, isPlaceholder: false }));
    }
  },
  methods: {
    // 返回上一页 - rqrq
    handleBack() {
      // 清空分拣原始数据缓存 - rqrq
      this.originalDetailCache = {};
      console.log('已清空分拣原始数据缓存 - rqrq');
      this.$router.back();
    },

    // 重置页面到初始状态 - rqrq
    resetPage() {
      // 清空栈板信息
      this.palletCode = '';
      this.palletScanned = false;
      this.operationType = 'in';

      // 清空栈板类型和自动分拣
      this.currentPalletFamily = '';
      this.currentPalletType = '';
      this.currentAutoSort = '';
      this.forceFullPalletOut = false; // 清空强制整托出库 - rqrq
      this.palletTypeOptions = [];
      this.palletTypeDisabled = false;
      this.autoSortDisabled = false;
      this.currentWcsAutoSort = '';
      this.currentMaxLayer = 0;

      // 清空筛选条件
      this.selectedPosition = '';
      this.selectedLayer = '';
      this.positionOptions = [];
      this.layerOptions = [];
      this.currentPalletStation = ''; // 清空当前站点 - rqrq

      // 清空栈板明细
      this.detailList = [];

      // 清空分拣原始数据缓存 - rqrq
      this.originalDetailCache = {};
      console.log('已清空分拣原始数据缓存 - rqrq');

      // 清空扫码模态框
      this.scanModalVisible = false;
      this.scanCode = '';
      this.scanPosition = '';
      this.scanLayer = '';
      this.scanLayerOptions = [];
      this.needRefreshOnClose = false;

      // 清空修改位置模态框
      this.editPositionModalVisible = false;
      this.editSerialNo = '';
      this.editPosition = '';
      this.editLayer = '';
      this.editLayerOptions = [];
      this.editOriginalPosition = '';
      this.editOriginalLayer = '';

      // 聚焦到栈板输入框
      this.$nextTick(() => {
        if (this.$refs.palletInput) {
          this.$refs.palletInput.focus();
        }
      });

      console.log('页面已重置到初始状态');
    },

    // 扫描栈板 - rqrq
    handlePalletScan() {
      if (!this.palletCode.trim()) {
        this.$alert('请输入栈板编码', '错误', { confirmButtonText: '确定' });
        return;
      }

      checkPalletExists({
        site: this.site,
        palletId: this.palletCode
      }).then(({ data }) => {
        if (data.code === 0) {
          this.palletCode=data.palletId
          let palletId=data.palletId
          console.log(this.palletCode)
          console.log(palletId)
          this.$nextTick(()=>{
            this.palletScanned = true;
            this.positionOptions = data.positions || [];

            // 扫描新栈板时清空sortingList - rqrq
            this.sortingList = [];
            console.log('扫描新栈板，已清空sortingList - rqrq');

            // 获取栈板详细信息（包括palletType和autoSort）
            this.loadPalletInfo(palletId);
            this.refreshTable();
          })
        } else {
          // 失败：弹出提示框，截取前100字符 - rqrq
          let errorMsg = data.msg || '栈板不存在';
          if (errorMsg.length > 100) {
            errorMsg = errorMsg.substring(0, 100) + '...';
          }
          this.$alert(errorMsg, '错误', {
            confirmButtonText: '确定',
            callback: () => {
              this.palletCode = '';
              this.$nextTick(() => {
                if (this.$refs.palletInput) {
                  this.$refs.palletInput.focus();
                }
              });
            }
          });
        }
      }).catch(error => {
        console.error('验证栈板失败:', error);
        // 网络错误：弹出提示框 - rqrq
        let errorMsg = error.message || '验证栈板失败';
        if (errorMsg.length > 100) {
          errorMsg = errorMsg.substring(0, 100) + '...';
        }
        this.$alert(errorMsg, '错误', {
          confirmButtonText: '确定',
          callback: () => {
            this.palletCode = '';
            this.$nextTick(() => {
              if (this.$refs.palletInput) {
                this.$refs.palletInput.focus();
              }
            });
          }
        });
      });
    },

    // 加载栈板信息
    loadPalletInfo(palletId) {
      getPalletInfo({
        site: this.site,
        palletId: palletId
      }).then(({ data }) => {
        if (data.code === 0) {
          const palletInfo = data.row || {};
          this.currentPalletFamily = palletInfo.palletFamily || '';
          this.currentPalletType = palletInfo.palletType || '';
          this.currentAutoSort = palletInfo.autoSort || 'N';
          this.currentPalletStation = palletInfo.locationCode || ''; // 获取当前站点 - rqrq

          // 分拣界面：校验栈板站点必须是R1/R2/R3/R4 - rqrq
          const allowedStations = ['R1', 'R2', 'R3', 'R4'];
          if (!allowedStations.includes(this.currentPalletStation)) {
            this.$alert(
              `分拣功能只能在R1/R2/R3/R4站点使用，当前栈板站点为：${this.currentPalletStation || '空'}`,
              '站点错误',
              {
                confirmButtonText: '确定',
                callback: () => {
                  this.resetPage();
                  this.$nextTick(() => {
                    if (this.$refs.palletInput) {
                      this.$refs.palletInput.focus();
                    }
                  });
                }
              }
            );
            return;
          }

          // 第一次进页面扫描栈板查询的时候，如果sore_Type=3，那么也要显示勾选 - rqrq
          const soreType = palletInfo.soreType;
          if (soreType === 3) {
            this.forceFullPalletOut = true;
            console.log('soreType=3，自动勾选强制整托出库 - rqrq');
          } else {
            this.forceFullPalletOut = false;
          }

          // 加载托盘类型列表（根据palletFamily过滤）
          this.loadPalletTypeList();
        } else {
          this.$alert(data.msg || '获取栈板信息失败', '错误', { confirmButtonText: '确定' });
        }
      }).catch(error => {
        console.error('获取栈板信息失败:', error);
        this.$alert('获取栈板信息失败', '错误', { confirmButtonText: '确定' });
      });
    },

    // 加载托盘类型列表
    loadPalletTypeList() {
      getPalletTypeList({
        site: this.site,
        palletFamily: this.currentPalletFamily,
        active: 'Y'
      }).then(({ data }) => {
        if (data.code === 0) {
          this.palletTypeOptions = data.rows || [];

          // 设置当前托盘类型的wcsAutoSort值和maxLayer
          const currentType = this.palletTypeOptions.find(t => t.palletType === this.currentPalletType);
          if (currentType) {
            this.currentWcsAutoSort = currentType.wcsAutoSort || 'N';
            this.currentMaxLayer = currentType.maxLayer || 0;
            this.updateAutoSortControl();

            // 加载当前托盘类型的区域列表
            this.loadPalletTypeAreas();
          }
        } else {
          this.palletTypeOptions = [];
        }
      }).catch(error => {
        console.error('获取托盘类型列表失败:', error);
        this.palletTypeOptions = [];
      });
    },

    // 加载托盘类型的区域列表
    loadPalletTypeAreas() {
      getPalletTypeAreas({
        site: this.site,
        palletType: this.currentPalletType
      }).then(({ data }) => {
        if (data.code === 0) {
          // 从pallet_type_area获取position列表
          const areas = data.rows || [];
          this.positionOptions = areas.map(area => area.position);
        } else {
          this.positionOptions = [];
        }
      }).catch(error => {
        console.error('获取托盘区域列表失败:', error);
        this.positionOptions = [];
      });
    },

    // 托盘类型变更事件
    handlePalletTypeChange() {
      // 查找选中的托盘类型
      const selectedType = this.palletTypeOptions.find(t => t.palletType === this.currentPalletType);

      if (selectedType) {
        this.currentWcsAutoSort = selectedType.wcsAutoSort || 'N';
        this.currentMaxLayer = selectedType.maxLayer || 0;

        // 默认值：从托盘类型表取
        this.currentAutoSort = this.currentWcsAutoSort;

        // 如果栈板类型选择了A0103（手工选择后触发），那么自动勾选强制整托出库 - rqrq
        if (this.currentPalletType === 'A0103') {
          this.forceFullPalletOut = true;
          console.log('栈板类型选择了A0103，自动勾选强制整托出库 - rqrq');
        }

        // 更新自动分拣控制
        this.updateAutoSortControl();

        // 重新查询pallet_type_area，更新位置下拉框
        this.loadPalletTypeAreas();

        // 保存到数据库
        this.savePalletTypeAndAutoSort();
      }
    },

    // 更新自动分拣控制逻辑
    updateAutoSortControl() {
      if (this.currentWcsAutoSort === 'N') {
        // 不支持自动分拣，锁定为N，禁用选择
        this.currentAutoSort = 'N';
        this.autoSortDisabled = true;
      } else {
        // 支持自动分拣，可以选择Y或N
        this.autoSortDisabled = false;
      }
    },

    // 是否自动分拣变更事件
    handleAutoSortChange() {
      // 保存到数据库
      this.savePalletTypeAndAutoSort();
    },

    // 是否强制整托出库变更事件 - rqrq
    handleForceFullPalletOutChange() {
      console.log('是否强制整托出库变更 - rqrq，forceFullPalletOut=' + this.forceFullPalletOut);
      // 保存到数据库
      this.savePalletTypeAndAutoSort();
    },

    // 保存栈板类型、自动分拣标志和存储类型 - rqrq
    savePalletTypeAndAutoSort() {
      updatePalletTypeAndAutoSort({
        site: this.site,
        palletId: this.palletCode,
        palletType: this.currentPalletType,
        autoSort: this.currentAutoSort,
        forceFullPalletOut: this.forceFullPalletOut  // 是否强制整托出库 - rqrq
      }).then(({ data }) => {
        if (data.code === 0) {
          this.$message.success('更新成功');
        } else {
          this.$alert(data.msg || '更新失败', '错误', { confirmButtonText: '确定' });
        }
      }).catch(error => {
        console.error('更新失败:', error);
        this.$alert('更新失败', '错误', { confirmButtonText: '确定' });
      });
    },

    // Call栈板 - 调用空托盘
    handleCallPallet() {
      this.callPalletModalVisible = true;
      this.selectedCallStartStation = '';
      this.selectedCallTargetStation = '';

      // 获取起始站点（有货的正式站点）
      getAvailableAgvStations({ statusDb: 1 }).then(({ data }) => {
        if (data && data.code === 0) {
          this.callStartStationOptions = data.stations || [];
          console.log('起始站点列表:', this.callStartStationOptions);
        } else {
          this.$alert(data.msg || '获取起始站点列表失败', '错误', { confirmButtonText: '确定' });
        }
      }).catch(error => {
        console.error('获取起始站点列表失败:', error);
        this.$alert('获取起始站点列表失败', '错误', { confirmButtonText: '确定' });
      });

      // 获取目标站点（空闲的正式站点）
      getAvailableAgvStations({ statusDb: 0 }).then(({ data }) => {
        if (data && data.code === 0) {
          this.callTargetStationOptions = data.stations || [];
        } else {
          this.$alert(data.msg || '获取目标站点列表失败', '错误', { confirmButtonText: '确定' });
        }
      }).catch(error => {
        console.error('获取目标站点列表失败:', error);
        this.$alert('获取目标站点列表失败', '错误', { confirmButtonText: '确定' });
      });
    },

    // 起始站点选择change事件，自动聚焦到目标站点输入框
    handleCallStartStationChange() {
      this.$nextTick(() => {
        if (this.$refs.callTargetStationInput) {
          this.$refs.callTargetStationInput.focus();
        }
      });
    },

    // 位置选择变化
    handlePositionChange() {
      if (this.selectedPosition) {
        getLayersByPosition({
          site: this.site,
          palletId: this.palletCode,
          position: this.selectedPosition
        }).then(({ data }) => {
          if (data.code === 0) {
            this.layerOptions = data.layers || [];
          }
        }).catch(error => {
          console.error('获取层数失败:', error);
        });
      } else {
        this.layerOptions = [];
      }
      this.selectedLayer = '';
    },

    // 刷新表格
    refreshTable() {
      getPalletDetails({
        site: this.site,
        palletId: this.palletCode,
        position: this.selectedPosition,
        layer: this.selectedLayer
      }).then(({ data }) => {
        if (data.code === 0) {
          this.detailList = data.details || [];

          // 如果栈板有明细数据，禁用栈板类型和自动分拣的修改
          const hasDetails = this.detailList.length > 0;
          this.palletTypeDisabled = hasDetails;

          // 如果有明细数据，自动分拣也要禁用；否则根据wcsAutoSort判断
          if (hasDetails) {
            this.autoSortDisabled = true;
          } else {
            this.updateAutoSortControl();
          }
        } else {
          this.detailList = [];
          this.palletTypeDisabled = false;
          this.updateAutoSortControl();
        }
      }).catch(error => {
        console.error('获取栈板明细失败:', error);
        this.detailList = [];
        this.palletTypeDisabled = false;
        this.updateAutoSortControl();
      });
    },

        // 显示扫码模态框 - rqrq
    showScanModal() {
      this.scanModalVisible = true;
      this.scanCode = '';
      this.currentSelectedPosition = '';
      this.needRefreshOnClose = false;

      // 初始化层数和位置网格 - rqrq
      if (this.operationType === 'in') {
        this.scanLayer = 1;
        // 先查询当前栈板已有的最大层数，动态生成层数选项 - rqrq
        this.loadLayerOptions();
      } else {
        // 扫出操作，直接聚焦到输入框 - rqrq
        this.$nextTick(() => {
          if (this.$refs.scanInput) {
            this.$refs.scanInput.focus();
          }
        });
      }
    },
        // 加载层数选项 - rqrq
    loadLayerOptions() {
      console.log('开始加载层数选项 - rqrq，maxLayer=' + this.currentMaxLayer);

      getPalletDetails({
        site: this.site,
        palletId: this.palletCode,
        position: '',
        layer: null
      }).then(({ data }) => {
        if (data && data.code === 0) {
          const details = data.details || [];

          // 获取当前已有的最大层数 - rqrq
          let maxExistingLayer = 0;
          if (details.length > 0) {
            maxExistingLayer = Math.max(...details.map(d => d.layer || 0));
          }

          // 根据maxLayer判断 - rqrq
          if (this.currentMaxLayer === 0) {
            // maxLayer=0：不限高，可选层数为已有最大层+1层 - rqrq
            this.currentMixedMode = false;
            this.scanLayerOptions = Array.from({ length: maxExistingLayer + 1 }, (_, i) => i + 1);
            console.log('不限高模式 - 已有最大层：' + maxExistingLayer + '，可选层数：' + this.scanLayerOptions.length + ' - rqrq');
          } else {
            // maxLayer>0：有限高，可选1~maxLayer层 - rqrq
            this.currentMixedMode = false;
            this.scanLayerOptions = Array.from({ length: this.currentMaxLayer }, (_, i) => i + 1);
            console.log('限高模式 - maxLayer：' + this.currentMaxLayer + ' - rqrq');
          }

          // 加载位置网格 - rqrq
          this.loadAvailablePositions();
        } else {
          this.$alert(data.msg || '获取栈板信息失败', '错误', { confirmButtonText: '确定' });
        }
      }).catch(error => {
        console.error('获取栈板信息失败:', error);
        this.$alert('获取栈板信息失败', '错误', { confirmButtonText: '确定' });
      });
    },

    // 加载可用位置 - rqrq
    loadAvailablePositions() {
      console.log('开始加载位置网格 - rqrq，layer=' + this.scanLayer);

      // 设置加载状态，禁用所有位置 - rqrq
      this.positionGridLoading = true;
      this.availablePositions = []; // 清空可用位置，全部禁用

      // 先获取当前层的所有明细数据，用于统计每个position的数量 - rqrq
      getPalletDetails({
        site: this.site,
        palletId: this.palletCode,
        position: '',
        layer: this.scanLayer
      }).then(({ data: detailData }) => {
        // 统计每个position的数量 - rqrq
        const positionCountMap = {};
        if (detailData && detailData.code === 0) {
          const details = detailData.details || [];
          details.forEach(detail => {
            const pos = detail.position;
            positionCountMap[pos] = (positionCountMap[pos] || 0) + 1;
          });
          console.log('当前层(' + this.scanLayer + ')各位置数量统计 - rqrq:', positionCountMap);
        }

        // 获取位置网格信息 - rqrq
        return getAvailablePositionsForLayer({
          site: this.site,
          palletId: this.palletCode,
          layer: this.scanLayer
        }).then(({ data }) => {
          if (data && data.code === 0) {
            const result = data.data;
            const positions = result.positions || [];
            this.availablePositions = result.availablePositions || [];

            // 将positions转换为包含count的对象数组 - rqrq
            this.positionGrid = positions.map(position => ({
              position: position,
              count: positionCountMap[position] || 0
            }));

            console.log('位置网格加载完成 - 总位置：' + this.positionGrid.length + '，可用：' + this.availablePositions.length + ' - rqrq');
          } else {
            this.$alert(data.msg || '获取位置信息失败', '错误', { confirmButtonText: '确定' });
            // 失败后保持全部禁用 - rqrq
            this.availablePositions = [];
            this.positionGrid = [];
          }
        });
      }).catch(error => {
        console.error('获取位置信息失败:', error);
        this.$alert('获取位置信息失败', '错误', { confirmButtonText: '确定' });
        // 失败后保持全部禁用 - rqrq
        this.availablePositions = [];
        this.positionGrid = [];
      }).finally(() => {
        // 无论成功失败，都要解除加载状态 - rqrq
        this.positionGridLoading = false;
      });
    },

    // 点击层数格子 - rqrq
    handleLayerClick(layer) {
      if (this.scanLayer === layer) {
        return; // 已选中，不重复处理
      }

      console.log('切换层数 - rqrq，从第' + this.scanLayer + '层切换到第' + layer + '层');
      this.scanLayer = layer;
      this.currentSelectedPosition = '';
      this.loadAvailablePositions();
    },

    // 点击位置网格 - rqrq
    handlePositionClick(position) {
      // 加载中或位置不可用时不处理 - rqrq
      if (this.positionGridLoading) {
        this.$message.warning('位置信息加载中，请稍候');
        return;
      }

      if (!this.availablePositions.includes(position)) {
        this.$message.warning('该位置不可用');
        return;
      }

      this.currentSelectedPosition = position;
      this.scanPosition = position;
      console.log('选择位置 - rqrq，position=' + position);

      // 聚焦到扫描输入框 - rqrq
      this.$nextTick(() => {
        if (this.$refs.scanInput) {
          this.$refs.scanInput.focus();
        }
      });
    },

    moveFocusToScanInput(){
      this.$nextTick(() => {
        if (this.$refs.scanInput) {
          this.$refs.scanInput.focus();
        }
      });
    },
    // 关闭扫码模态框
    closeScanModal() {
      this.scanModalVisible = false;
      // 如果有操作成功，则在关闭时刷新外面的列表
      if (this.needRefreshOnClose) {
        this.refreshTable();
        this.needRefreshOnClose = false;
      }
    },



    // 处理标签扫描 - rqrq
    handleLabelScan() {
      if (!this.scanCode.trim()) {
        this.$alert('请输入标签编码', '错误', { confirmButtonText: '确定' });
        return;
      }

      if (this.operationType === 'in') {
        // 扫进操作 - rqrq
        if (!this.scanPosition) {
          this.$alert('请选择位置', '错误', { confirmButtonText: '确定' });
          return;
        }
        if (!this.scanLayer) {
          this.$alert('请选择层数', '错误', { confirmButtonText: '确定' });
          return;
        }

        // 扫进操作新增：校验标签是否在分拣明细中 - rqrq
        if (this.sortingList.length === 0) {
          // 如果sortingList为空，先获取分拣明细 - rqrq
          console.log('sortingList为空，开始获取分拣明细 - rqrq');

          getSortingList({
            site: this.site,
            palletId: this.palletCode
          }).then(({ data }) => {
            if (data && data.code === 0) {
              this.sortingList = data.rfidList || [];
              console.log('分拣明细获取成功 - rqrq，共' + this.sortingList.length + '条');

              // 获取成功后，继续校验标签 - rqrq
              this.validateAndScanIn();
            } else {
              // 获取失败 - rqrq
              this.$alert(data.msg || '获取分拣明细失败', '错误', {
                confirmButtonText: '确定',
                callback: () => {
                  this.scanCode = '';
                  this.$nextTick(() => {
                    if (this.$refs.scanInput) {
                      this.$refs.scanInput.focus();
                    }
                  });
                }
              });
            }
          }).catch(error => {
            console.error('获取分拣明细失败:', error);
            this.$alert(error.message || '获取分拣明细失败', '错误', {
              confirmButtonText: '确定',
              callback: () => {
                this.scanCode = '';
                this.$nextTick(() => {
                  if (this.$refs.scanInput) {
                    this.$refs.scanInput.focus();
                  }
                });
              }
            });
          });
          return;
        }

        // sortingList有数据，直接校验 - rqrq
        this.validateAndScanIn();

      } else {
        // 扫回操作（不需要校验分拣明细）- rqrq
        this.handleScanOut();
      }
    },

    // 校验标签并执行扫进操作 - rqrq
    validateAndScanIn() {
      // 校验sortingList是否为空 - rqrq
      if (this.sortingList.length === 0) {
        this.$alert('当前不存在分拣任务', '提示', {
          confirmButtonText: '确定',
          callback: () => {
            this.scanCode = '';
            this.$nextTick(() => {
              if (this.$refs.scanInput) {
                this.$refs.scanInput.focus();
              }
            });
          }
        });
        return;
      }

      // 校验标签是否在sortingList中 - rqrq
      if (!this.sortingList.includes(this.scanCode)) {
        this.$alert('该物料不在分拣明细中', '错误', {
          confirmButtonText: '确定',
          callback: () => {
            this.scanCode = '';
            this.$nextTick(() => {
              if (this.$refs.scanInput) {
                this.$refs.scanInput.focus();
              }
            });
          }
        });
        return;
      }

      console.log('标签校验通过，开始扫进 - rqrq');

      // 校验通过，执行原有的扫进逻辑 - rqrq
      // 先查询这个标签的原始数据（扫进之前的数据）- rqrq
      getLabelInfo({
        site: this.site,
        serialNo: this.scanCode
      }).then(({ data: queryData }) => {
        let originalDetail = null;
        if (queryData && queryData.code === 0 && queryData.row) {
          originalDetail = queryData.row;
        }

        // 执行扫进操作 - rqrq
        savePalletDetail({
          site: this.site,
          palletId: this.palletCode,
          position: this.scanPosition,
          layer: this.scanLayer,
          serialNo: this.scanCode,
          sortFlag:1,//是分拣
        }).then(({ data }) => {
          if (data.code === 0) {
            // 扫进成功后，缓存原始数据 - rqrq
            if (originalDetail) {
              this.originalDetailCache[this.scanCode] = {
                palletId: originalDetail.palletId || '',
                position: originalDetail.position || '',
                layer: originalDetail.layer || 1,
                wcsFlag: originalDetail.wcsFlag !== undefined ? originalDetail.wcsFlag : 1,
                partNo: originalDetail.partNo || '',
                createDate: originalDetail.createDate || new Date().toISOString(),
                createBy: originalDetail.createBy || ''
              };
              console.log('扫进成功，已缓存原始数据 - rqrq，serialNo=' + this.scanCode +
                          '，原栈板=' + originalDetail.palletId);
            }

            this.$message.success('扫进成功');
            this.needRefreshOnClose = true;
            this.scanCode = '';

            // 重新加载层数选项（可能新增了层数） - rqrq
            this.loadLayerOptions();

            // 保持当前位置选中，聚焦到输入框 - rqrq
            this.$refs.scanInput.focus();
          } else {
              // 扫进失败：弹出提示框，截取前100字符 - rqrq
              let errorMsg = data.msg || '扫进失败';
              if (errorMsg.length > 100) {
                errorMsg = errorMsg.substring(0, 100) + '...';
              }
              this.$alert(errorMsg, '错误', {
                confirmButtonText: '确定',
                callback: () => {
                  this.scanCode = '';
                  this.$nextTick(() => {
                    if (this.$refs.scanInput) {
                      this.$refs.scanInput.focus();
                    }
                  });
                }
              });
            }
          }).catch(error => {
            console.error('扫进失败:', error);
            // 网络错误：弹出提示框 - rqrq
            let errorMsg = error.message || '扫进失败';
            if (errorMsg.length > 100) {
              errorMsg = errorMsg.substring(0, 100) + '...';
            }
            this.$alert(errorMsg, '错误', {
              confirmButtonText: '确定',
              callback: () => {
                this.scanCode = '';
                this.$nextTick(() => {
                  if (this.$refs.scanInput) {
                    this.$refs.scanInput.focus();
                  }
                });
              }
            });
          });

      }).catch(error => {
        console.error('查询标签信息失败:', error);
        // 查询失败不影响扫进操作，只是无法缓存原始数据 - rqrq
        console.log('无法查询标签原始信息，将不缓存 - rqrq');
      });
    },

    // 扫回操作 - rqrq
    handleScanOut() {
      // 扫回操作（恢复到原栈板）- rqrq
      // 检查是否有缓存的原始数据 - rqrq
      const originalData = this.originalDetailCache[this.scanCode];
      if (!originalData) {
        this.$alert('未找到该标签的原始数据，无法扫回', '错误', { confirmButtonText: '确定' });
        this.scanCode = '';
        this.$nextTick(() => {
          if (this.$refs.scanInput) {
            this.$refs.scanInput.focus();
          }
        });
        return;
      }

      // 调用恢复接口 - rqrq
      restorePalletDetail({
        site: this.site,
        serialNo: this.scanCode,
        originalPalletId: originalData.palletId,
        originalPosition: originalData.position,
        originalLayer: originalData.layer,
        partNo: originalData.partNo,
        createDate: originalData.createDate,
        createBy: originalData.createBy,
        wcsFlag: originalData.wcsFlag
      }).then(({ data }) => {
        if (data.code === 0) {
          // 恢复成功后，删除缓存 - rqrq
          delete this.originalDetailCache[this.scanCode];
          console.log('扫回成功，已删除缓存 - rqrq，serialNo=' + this.scanCode);

          this.$message.success('扫回成功');
          this.needRefreshOnClose = true;
          this.scanCode = '';
          this.$nextTick(() => {
            if (this.$refs.scanInput) {
              this.$refs.scanInput.focus();
            }
          });
        } else {
          // 扫回失败：弹出提示框，截取前100字符 - rqrq
          let errorMsg = data.msg || '扫回失败';
          if (errorMsg.length > 100) {
            errorMsg = errorMsg.substring(0, 100) + '...';
          }
          this.$alert(errorMsg, '错误', {
            confirmButtonText: '确定',
            callback: () => {
              this.scanCode = '';
              this.$nextTick(() => {
                if (this.$refs.scanInput) {
                  this.$refs.scanInput.focus();
                }
              });
            }
          });
        }
      }).catch(error => {
        console.error('扫回失败:', error);
        // 网络错误：弹出提示框 - rqrq
        let errorMsg = error.message || '扫回失败';
        if (errorMsg.length > 100) {
          errorMsg = errorMsg.substring(0, 100) + '...';
        }
        this.$alert(errorMsg, '错误', {
          confirmButtonText: '确定',
          callback: () => {
            this.scanCode = '';
            this.$nextTick(() => {
              if (this.$refs.scanInput) {
                this.$refs.scanInput.focus();
              }
            });
          }
        });
      });
    },

    // 双击行事件 - 修改位置
    handleRowDblClick(detail, index) {

      this.editSerialNo = detail.serialNo;
      this.editPosition = detail.position;
      this.editLayer = detail.layer;
      this.editOriginalPosition = detail.position;
      this.editOriginalLayer = detail.layer;

      // 获取当前位置的层数选项（排除自己）
      this.handleEditPositionChange();

      this.editPositionModalVisible = true;
    },

    // 编辑位置选择变化
    handleEditPositionChange() {
      if (this.editPosition) {
        // maxLayer=0表示混装托盘，只能选第1层
        if (this.currentMaxLayer === 0) {
          this.editLayerOptions = [1];
          this.editLayer = 1; // 自动选中第1层
          return;
        }

        // maxLayer>0，根据已有层数和maxLayer计算可选层数
        getLayersForEdit({
          site: this.site,
          palletId: this.palletCode,
          position: this.editPosition,
          excludeSerialNo: this.editSerialNo
        }).then(({ data }) => {
          if (data.code === 0) {
            let layerOptions = data.layers || [];

            // 根据maxLayer限制层数选项
            if (this.currentMaxLayer > 0) {
              // 过滤掉超过maxLayer的层数
              layerOptions = layerOptions.filter(layer => layer <= this.currentMaxLayer);
            }

            this.editLayerOptions = layerOptions;
            // 如果当前选择的层数不在新的选项中，清空选择
            // if (!this.editLayerOptions.includes(this.editLayer)) {
            //   this.editLayer = '';
            // }
          }
        }).catch(error => {
          console.error('获取层数失败:', error);
          this.editLayerOptions = [];
        });
      } else {
        this.editLayerOptions = [];
        this.editLayer = '';
      }
    },

    // 确定修改位置
    confirmEditPosition() {
      if (!this.editPosition) {
        this.$alert('请选择位置', '错误', { confirmButtonText: '确定' });
        return;
      }
      if (!this.editLayer) {
        this.$alert('请选择层数', '错误', { confirmButtonText: '确定' });
        return;
      }

      // 检查是否有变化
      if (this.editPosition === this.editOriginalPosition && this.editLayer === this.editOriginalLayer) {
        this.$message.warning('位置没有变化');
        return;
      }

      // 设置loading状态，防止重复点击
      this.editPositionLoading = true;

      updatePalletDetailPosition({
        site: this.site,
        palletId: this.palletCode,
        serialNo: this.editSerialNo,
        newPosition: this.editPosition,
        newLayer: this.editLayer
      }).then(({ data }) => {
        if (data.code === 0) {
          this.$message.success('位置修改成功');
          this.closeEditPositionModal();
          this.refreshTable();
        } else {
          this.$alert(data.msg || '位置修改失败', '错误', { confirmButtonText: '确定' });
        }
      }).catch(error => {
        console.error('位置修改失败:', error);
        this.$alert('位置修改失败', '错误', { confirmButtonText: '确定' });
      }).finally(() => {
        // 无论成功或失败，都要恢复按钮状态
        this.editPositionLoading = false;
      });
    },

    // 关闭修改位置模态框
    closeEditPositionModal() {
      this.editPositionModalVisible = false;
      this.editSerialNo = '';
      this.editPosition = '';
      this.editLayer = '';
      this.editLayerOptions = [];
      this.editOriginalPosition = '';
      this.editOriginalLayer = '';
    },

    // 完成组托按钮点击事件
    handleCompleteAssembly() {
      if (!this.palletCode) {
        this.$alert('请先扫描栈板', '错误', { confirmButtonText: '确定' });
        return;
      }

      // 检查是否有栈板明细
      if (!this.detailList || this.detailList.length === 0) {
        this.$alert('栈板明细为空，请先扫进物料', '错误', { confirmButtonText: '确定' });
        return;
      }

      // 确认操作
      this.$confirm('确认完成组托并推送数据到WCS系统吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.doCompleteAssembly();
      }).catch(() => {
        // 用户取消
      });
    },

    // 执行完成组托
    doCompleteAssembly() {
      // 设置loading状态，防止重复点击
      this.completeAssemblyLoading = true;

      completePalletAssemblyForFenJian({
        site: this.site,
        palletId: this.palletCode
      }).then(({ data }) => {
        if (data.code === 0) {
          this.$message.success('数据已推送到WCS系统');
          // 清空sortingList，表示本次分拣结束 - rqrq
          this.sortingList = [];
          console.log('提交分拣成功，已清空sortingList - rqrq');
          // 清空页面数据，初始化页面
          // this.resetPage();
        } else {
          // 失败时弹出提示框 - rqrq
          this.$alert(data.msg || '本次分拣失败', '错误', {
            confirmButtonText: '确定',
            callback: () => {
              // 点击确定后提示框消失，不做其他操作 - rqrq
            }
          });
        }
      }).catch(error => {
        console.error('本次分拣失败:', error);
        // 网络错误也弹出提示框 - rqrq
        this.$alert(error.message || '本次分拣失败', '错误', {
          confirmButtonText: '确定',
          callback: () => {
            // 点击确定后提示框消失，不做其他操作 - rqrq
          }
        });
      }).finally(() => {
        // 无论成功或失败，都要恢复按钮状态
        this.completeAssemblyLoading = false;
      });
    },

    // 确认Call栈板
    confirmCallPallet() {
      if (!this.selectedCallStartStation) {
        this.$alert('请选择起始站点', '错误', { confirmButtonText: '确定' });
        return;
      }
      if (!this.selectedCallTargetStation) {
        this.$alert('请选择目标站点', '错误', { confirmButtonText: '确定' });
        return;
      }

      // 前端验证：两个站点不能一样
      if (this.selectedCallStartStation === this.selectedCallTargetStation) {
        this.$alert('起始站点和目标站点不能相同', '错误', { confirmButtonText: '确定' });
        return;
      }

      // 设置loading状态，防止重复点击
      this.callPalletLoading = true;

      callPalletToStation({
        site: this.site,
        startStation: this.selectedCallStartStation,
        targetStation: this.selectedCallTargetStation
      }).then(({ data }) => {
        if (data.code === 0) {
          this.$message.success('空托盘调用任务创建成功');
          this.closeCallPalletModal();
        } else {
          this.$alert(data.msg || '调用空托盘失败', '错误', { confirmButtonText: '确定' });
        }
      }).catch(error => {
        console.error('调用空托盘失败:', error);
        this.$alert('异常:'+error, '错误', { confirmButtonText: '确定' });
      }).finally(() => {
        // 无论成功或失败，都要恢复按钮状态
        this.callPalletLoading = false;
      });
    },

    // 关闭Call栈板模态框
    closeCallPalletModal() {
      this.callPalletModalVisible = false;
      this.selectedCallStartStation = '';
      this.selectedCallTargetStation = '';
      this.callStartStationOptions = [];
      this.callTargetStationOptions = [];
    },
    showDetailModal(){
      this.detailModalVisible=true;
    },

    // 结束分拣按钮点击事件 - rqrq
    handleFinishSorting() {
      if (!this.palletCode) {
        this.$alert('请先扫描栈板', '错误', { confirmButtonText: '确定' });
        return;
      }

      // 检查是否有栈板明细
      // if (!this.detailList || this.detailList.length === 0) {
      //   this.$alert('栈板明细为空，无法结束分拣', '错误', { confirmButtonText: '确定' });
      //   return;
      // }

      // 确认操作 - rqrq
      this.$confirm('确认结束分拣并将栈板送至缓存区（Z104）吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.doFinishSorting();
      }).catch(() => {
        // 用户取消
      });
    },

    // 执行结束分拣 - rqrq
    doFinishSorting() {
      // 设置loading状态，防止重复点击 - rqrq
      this.finishSortingLoading = true;

      finishSorting({
        site: this.site,
        palletId: this.palletCode
      }).then(({ data }) => {
        if (data.code === 0) {
          this.$message.success('结束分拣成功，已创建送货任务');
          // 清空页面数据，初始化页面 - rqrq
          this.resetPage();
        } else {
          this.$alert(data.msg || '结束分拣失败', '错误', { confirmButtonText: '确定' });
        }
      }).catch(error => {
        console.error('结束分拣失败:', error);
        this.$alert('结束分拣失败', '错误', { confirmButtonText: '确定' });
      }).finally(() => {
        // 无论成功或失败，都要恢复按钮状态 - rqrq
        this.finishSortingLoading = false;
      });
    },
  },
  mounted() {
    this.$nextTick(() => {
      if (this.$refs.palletInput) {
        this.$refs.palletInput.focus();
      }
    });
  }
};
</script>

<style scoped>
/* 表格样式 */
.detail-table {
  background: white;
  border-radius: 6px;
  overflow: hidden;
  border: 1px solid #e0e0e0;
}

.table-header,
.table-row {
  display: flex;
  align-items: center;
  padding: 8px;
  border-bottom: 1px solid #e0e0e0;
}

.table-header {
  background: #f5f5f5;
  font-weight: bold;
  font-size: 14px;
}

.table-row {
  font-size: 13px;
}

.table-row:last-child {
  border-bottom: none;
}

.col-position {
  flex: 1;
  text-align: center;
}

.col-layer {
  flex: 1;
  text-align: center;
}

.col-serial {
  flex: 4;
  text-align: center;
  word-break: break-all;
}

/* 空数据提示 */
.empty-hint {
  text-align: center;
  color: #999;
  padding: 20px;
  background: white;
  border-radius: 6px;
  margin-top: 16px;
}

/* 模态框样式 */
.scan-modal-content {
  padding: 10px 0;
}

.modal-form {
  margin-bottom: 16px;
}

.dialog-footer {
  text-align: center;
}

/* 修复模态框层级问题 */
::v-deep .el-dialog__wrapper {
  z-index: 2000 !important;
}

::v-deep .el-overlay {
  z-index: 2000 !important;
}

/* 修复单选框样式 */
::v-deep .el-radio {
  margin-right: 8px !important;
}

::v-deep .el-radio__label {
  font-size: 14px;
}

/* 标题行样式 */
.list-title-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.list-title-row .list-title {
  margin: 0;
  flex: 1;
}

/* 空数据行样式 */
.empty-row {
  justify-content: center;
  align-items: center;
  padding: 20px;
  border-bottom: none;
}

.empty-row .empty-hint {
  text-align: center;
  color: #999;
  width: 100%;
}

/* 按钮禁用状态样式 */
.action-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  background-color: #ccc !important;
  border-color: #ccc !important;
}

/* 层数网格样式 - rqrq */
.layer-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}

.layer-item {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 50px;
  height: 45px;
  padding: 0 12px;
  background-color: #fff;
  border: 2px solid #dcdfe6;
  border-radius: 6px;
  font-size: 15px;
  font-weight: bold;
  cursor: pointer;
  transition: all 0.3s;
  user-select: none;
}

.layer-item:hover {
  border-color: #409eff;
  background-color: #ecf5ff;
}

.layer-item.layer-selected {
  border-color: #409eff;
  background-color: #409eff;
  color: #fff;
}

/* 位置网格样式 - rqrq */
.position-grid {
  display: grid;
  gap: 10px;
  margin-top: 8px;
  position: relative;
}

/* 1宫格：单个居中 - rqrq */
.position-grid.position-grid-1 {
  grid-template-columns: 1fr;
  grid-template-rows: 1fr;
}

/* 4宫格：2行2列，按列排列（1,2 | 3,4）- rqrq */
/* 2宫格也使用此布局，只是1在左上，2在右下 - rqrq */
.position-grid.position-grid-4 {
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(2, 1fr);
  grid-auto-flow: column;
}

/* 9宫格：3行3列，按行排列（1,2,3 | 4,5,6 | 7,8,9） - rqrq */
.position-grid.position-grid-9 {
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  grid-auto-flow: row;
}

/* 2宫格占位格子样式（灰色不可选）- rqrq */
.position-item.position-placeholder {
  background-color: #f0f0f0 !important;
  border: 1px dashed #d0d0d0 !important;
  color: transparent !important;
  cursor: not-allowed !important;
  pointer-events: none !important;
}

/* 加载中的遮罩效果 - rqrq */
.position-grid.position-grid-loading {
  opacity: 0.7;
  pointer-events: none;
}

.position-item {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 60px;
  background-color: #fff;
  border: 2px solid #dcdfe6;
  border-radius: 6px;
  font-size: 16px;
  font-weight: bold;
  cursor: pointer;
  transition: all 0.3s;
  user-select: none;
}

.position-item:hover:not(.position-disabled) {
  border-color: #409eff;
  background-color: #ecf5ff;
}

.position-item.position-selected {
  border-color: #409eff;
  background-color: #409eff;
  color: #fff;
}

.position-item.position-disabled {
  background-color: #f5f7fa;
  color: #c0c4cc;
  cursor: not-allowed;
  opacity: 0.6;
}

/* 加载中的位置项样式 - rqrq */
.position-item.position-loading {
  background: linear-gradient(90deg, #f5f7fa 25%, #e4e7ed 50%, #f5f7fa 75%);
  background-size: 200% 100%;
  animation: loading 1.5s ease-in-out infinite;
}

@keyframes loading {
  0% {
    background-position: 200% 0;
  }
  100% {
    background-position: -200% 0;
  }
}
</style>
