<template>
  <div class="packing-detail-tab">
    <!-- 批量编辑按钮 -->
    <div class="batch-edit-toolbar" v-if="showActions">
      <el-button type="primary" size="small" icon="el-icon-edit" @click="openBatchEditDialog">
        批量编辑
      </el-button>
    </div>

    <el-table
      :data="dataListBoxes"
      :height="height"
      border
      v-loading="dataListLoading"
      style="width: 100%;"
      :expand-row-keys="expandedBoxRows"
      :row-key="getBoxRowKey"
      @expand-change="handleBoxExpand"
      show-summary
      :summary-method="getSummaries">
      <el-table-column type="expand">
        <template slot-scope="props">
          <!-- 加载状态 -->
          <div v-if="props.row.loading" class="expand-loading">
            <i class="el-icon-loading"></i>
            <span>正在加载明细数据...</span>
          </div>

          <!-- 明细内容区域 -->
          <div v-else class="expand-detail-container">
            <!-- 明细表格 -->
            <el-table
              v-if="props.row.palletDetails && props.row.palletDetails.length > 0"
              :data="props.row.palletDetails"
              :max-height="300"
              size="mini"
              stripe
              class="expand-detail-table">
              <el-table-column
                v-for="(item,index) in columnList3" :key="index"
                :sortable="item.columnSortable"
                :prop="item.columnProp"
                :header-align="item.headerAlign"
                :show-overflow-tooltip="item.showOverflowTooltip"
                :align="item.align"
                :min-width="item.columnWidth"
                :label="item.columnLabel">
                <template slot-scope="scope">
                  <span v-if="!item.columnHidden">
                    {{ formatDetailValue(scope.row[item.columnProp], item.columnProp) }}
                  </span>
                  <span v-if="item.columnImage">
                    <img :src="scope.row[item.columnProp]" style="width: 100px; height: 80px"/>
                  </span>
                </template>
              </el-table-column>

              <!-- 明细操作列 -->
              <el-table-column
                label="操作"
                width="120"
                align="center"
                fixed="right"
                v-if="showActions">
                <template slot-scope="scope">
                  <a type="text" size="small"  @click="handleEditDetail(scope.row, props.row)">修改</a>
                  <a type="text" size="small"  @click="handleDeleteDetail(scope.row, props.row)">删除</a>
                </template>
              </el-table-column>
            </el-table>

            <!-- 空数据状态 -->
            <div v-else class="expand-empty-state">
              <i class="el-icon-box"></i>
              <p>暂无明细数据</p>
              <span>该栈板下暂时没有装箱明细信息</span>
            </div>
          </div>
        </template>
      </el-table-column>
      <el-table-column
        v-for="(item,index) in columnListBoxes" :key="index"
        :sortable="item.columnSortable"
        :prop="item.columnProp"
        :header-align="item.headerAlign"
        :show-overflow-tooltip="item.showOverflowTooltip"
        :align="item.align"
        :fixed="item.fixed==''?false:item.fixed"
        :min-width="item.columnWidth"
        :label="item.columnLabel">
        <template slot-scope="scope">
          <span v-if="!item.columnHidden"> {{ scope.row[item.columnProp] }}</span>
          <span v-if="item.columnImage"><img :src="scope.row[item.columnProp]"
                                             style="width: 100px; height: 80px"/></span>
        </template>
      </el-table-column>

      <!-- 主表格操作列 -->
      <el-table-column
        label="操作"
        width="120"
        align="center"
        fixed="right"
        v-if="showActions">
        <template slot-scope="scope">
          <a type="text" size="small"  @click="handleEditBox(scope.row)">修改</a>
          <a type="text" size="small"  @click="handleDeleteBox(scope.row)">删除</a>
        </template>
      </el-table-column>
    </el-table>

    <!-- 修改箱信息弹窗 -->
    <el-dialog
      title="修改箱信息"
      :visible.sync="editBoxDialogVisible"
      width="200px"
      :close-on-click-modal="false">
      <el-form :model="editBoxForm" ref="editBoxForm" label-position="top" label-width="100px">
        <el-row :gutter="20">
          <el-col :span="24">
            <el-form-item label="箱数" prop="box_qty">
              <el-input v-model="editBoxForm.box_qty" @input="onBoxQtyChange" :min="1" :precision="0" style="width: 100%"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="毛重" prop="grossWeight">
              <el-input v-model="editBoxForm.grossWeight" @input="onGrossWeightChange" :min="0" :precision="2" style="width: 100%"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="净重" prop="netWeight">
              <el-input v-model="editBoxForm.netWeight" @input="onNetWeightChange" :min="0" :precision="2" style="width: 100%"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="editBoxDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitEditBox" >确定</el-button>
      </div>
    </el-dialog>

    <!-- 修改明细弹窗 -->
    <el-dialog
      title="修改明细信息"
      :visible.sync="editDetailDialogVisible"
      width="400px"
      :close-on-click-modal="false">
      <el-form :model="editDetailForm" ref="editDetailForm" label-position="top" label-width="100px">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="PO" prop="poNo">
              <el-input v-model="editDetailForm.poNo" disabled></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="PN" prop="pn">
              <el-input v-model="editDetailForm.pn" disabled></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="数量" prop="qty">
              <el-input v-model="editDetailForm.qty" style="width: 100%"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="Rolls" prop="rolls">
              <el-input v-model="editDetailForm.rolls" style="width: 100%"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="editDetailDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitEditDetail" >确定</el-button>
      </div>
    </el-dialog>

    <!-- 批量编辑弹窗 -->
    <el-dialog
      title="批量编辑装箱明细"
      :visible.sync="batchEditDialogVisible"
      width="60%"
      top="5vh"
      custom-class="batch-edit-dialog"
      :close-on-click-modal="false"
      @open="loadBatchEditData">
      <div class="batch-edit-container" v-loading="batchEditLoading">
        <!-- 操作提示 -->
        <div class="batch-edit-tips">
          <el-alert
            type="info"
            :closable="false"
            show-icon>
            <template slot="title">
              <span>直接在表格中编辑数据，修改后点击"保存所有修改"按钮提交</span>
              <span v-if="batchEditModifiedCount > 0" class="modified-count">
                （已修改 <b>{{ batchEditModifiedCount }}</b> 处）
              </span>
            </template>
          </el-alert>
        </div>

        <!-- 行合并表格 -->
        <el-table
          :data="batchEditTableData"
          :span-method="batchEditSpanMethod"
          border
          size="small"
          max-height="60vh"
          style="width: 100%"
          :row-class-name="getBatchEditRowClassName"
          :header-cell-style="{background:'#f5f7fa', color:'#606266', fontWeight:'600'}">

          <!-- Box信息列（会合并） -->
          <el-table-column label="序号" prop="item_no" width="60" align="center">
            <template slot-scope="scope">
              <span class="box-info-cell">{{ scope.row.item_no }}</span>
            </template>
          </el-table-column>

          <el-table-column label="箱数" prop="box_qty" width="80" align="center">
            <template slot-scope="scope">
              <el-input
                v-model="scope.row.box_qty"
                size="mini"
                type="number"
                :class="{'modified-input': isBoxFieldModified(scope.row, 'box_qty')}"
                @input="onBatchBoxQtyInput(scope.row)"
                @change="onBatchBoxFieldChange(scope.row, 'box_qty')">
              </el-input>
            </template>
          </el-table-column>

          <el-table-column label="毛重" prop="grossWeight" width="100" align="center">
            <template slot-scope="scope">
              <el-input
                v-model="scope.row.grossWeight"
                size="mini"
                type="number"
                :class="{'modified-input': isBoxFieldModified(scope.row, 'grossWeight')}"
                @input="onBatchGrossWeightInput(scope.row)"
                @change="onBatchBoxFieldChange(scope.row, 'grossWeight')">
              </el-input>
            </template>
          </el-table-column>

          <el-table-column label="净重" prop="netWeight" width="100" align="center">
            <template slot-scope="scope">
              <el-input
                v-model="scope.row.netWeight"
                size="mini"
                type="number"
                :class="{'modified-input': isBoxFieldModified(scope.row, 'netWeight')}"
                @input="onBatchNetWeightInput(scope.row)"
                @change="onBatchBoxFieldChange(scope.row, 'netWeight')">
              </el-input>
            </template>
          </el-table-column>

          <!-- 明细信息列（不合并） -->
          <el-table-column label="PO" prop="poNo" min-width="120" align="left">
            <template slot-scope="scope">
              <span>{{ scope.row.poNo || '-' }}</span>
            </template>
          </el-table-column>

          <el-table-column label="PN" prop="pn" min-width="120" align="left">
            <template slot-scope="scope">
              <span>{{ scope.row.pn || '-' }}</span>
            </template>
          </el-table-column>

          <el-table-column label="数量" prop="qty" width="100" align="center">
            <template slot-scope="scope">
              <el-input
                v-model="scope.row.qty"
                size="mini"
                type="number"
                :class="{'modified-input': isDetailFieldModified(scope.row, 'qty')}"
                @change="onBatchDetailFieldChange(scope.row, 'qty')">
              </el-input>
            </template>
          </el-table-column>

          <el-table-column label="Rolls" prop="rolls" width="80" align="center">
            <template slot-scope="scope">
              <el-input
                v-model="scope.row.rolls"
                size="mini"
                type="number"
                :class="{'modified-input': isDetailFieldModified(scope.row, 'rolls')}"
                @change="onBatchDetailFieldChange(scope.row, 'rolls')">
              </el-input>
            </template>
          </el-table-column>
        </el-table>
      </div>

      <div slot="footer" class="dialog-footer">
        <el-button @click="batchEditDialogVisible = false">取消</el-button>
        <el-button
          type="primary"
          :loading="batchEditSaving"
          :disabled="batchEditModifiedCount === 0"
          @click="saveBatchEdit">
          保存所有修改 ({{ batchEditModifiedCount }})
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { selectBoxList, searchCoDelPalletDataNew, updateBoxInfo, deleteBoxInfo, updateDetailInfo, deleteDetailInfo, batchUpdatePackingInfo } from "@/api/ecss/ecss.js"

export default {
  name: "PackingDetailTab",
  props: {
    currentRow: {
      type: Object,
      default: () => ({})
    },
    height: {
      type: Number,
      default: 200
    },
    showActions: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      dataListBoxes: [], // 箱数据列表
      expandedBoxRows: [], // 展开的行
      dataListLoading: false,

      // 修改箱信息弹窗相关
      editBoxDialogVisible: false,
      editBoxForm: {
        item_no: '',
        box_qty: 1,
        grossWeight: 0,
        netWeight: 0
      },
      editBoxSubmitting: false,
      currentEditBox: null,

      // 修改明细弹窗相关
      editDetailDialogVisible: false,
      editDetailForm: {
        itemNo: '',
        poNo: '',
        pn: '',
        qty: 1,
        rolls: 0
      },
      editDetailSubmitting: false,
      currentEditDetail: null,
      currentEditBoxForDetail: null,

      // 批量编辑弹窗相关
      batchEditDialogVisible: false,
      batchEditLoading: false,
      batchEditSaving: false,
      batchEditTableData: [], // 扁平化的表格数据
      batchEditOriginalData: {}, // 原始数据快照（用于对比是否修改）
      batchEditModifiedBoxes: {}, // 修改过的Box记录
      batchEditModifiedDetails: {}, // 修改过的明细记录
      batchEditSpanInfo: [], // 行合并信息

      // 装箱明细列定义
      columnList3: [
        {
          userId: this.$store.state.user.name,
          functionId: 801002,
          serialNumber: '801002Table3ItemNo',
          tableId: "801002Table3",
          tableName: "装箱明细",
          columnProp: "itemNo",
          headerAlign: "center",
          align: "right",
          columnLabel: "序号",
          columnHidden: false,
          columnImage: false,
          columnSortable: false,
          sortLv: 0,
          status: true,
          fixed: '',
          columnWidth: 40
        },
        {
          userId: this.$store.state.user.name,
          functionId: 801002,
          serialNumber: '801002Table3PoNo',
          tableId: "801002Table3",
          tableName: "装箱明细",
          columnProp: "poNo",
          headerAlign: "center",
          align: "left",
          columnLabel: "PO",
          columnHidden: false,
          columnImage: false,
          columnSortable: false,
          sortLv: 0,
          status: true,
          fixed: '',
          columnWidth: 100
        },
        {
          userId: this.$store.state.user.name,
          functionId: 801002,
          serialNumber: '801002Table3PN',
          tableId: "801002Table3",
          tableName: "装箱明细",
          columnProp: "pn",
          headerAlign: "center",
          align: "left",
          columnLabel: "PN",
          columnHidden: false,
          columnImage: false,
          columnSortable: false,
          sortLv: 0,
          status: true,
          fixed: '',
          columnWidth: 100
        },
        {
          userId: this.$store.state.user.name,
          functionId: 801002,
          serialNumber: '801002Table3Qty',
          tableId: "801002Table3",
          tableName: "装箱明细",
          columnProp: "qty",
          headerAlign: "center",
          align: "right",
          columnLabel: "数量",
          columnHidden: false,
          columnImage: false,
          columnSortable: false,
          sortLv: 0,
          status: true,
          fixed: '',
          columnWidth: 50
        },
        {
          userId: this.$store.state.user.name,
          functionId: 801002,
          serialNumber: '801002Table3Rolls',
          tableId: "801002Table3",
          tableName: "装箱明细",
          columnProp: "rolls",
          headerAlign: "center",
          align: "right",
          columnLabel: "Rolls",
          columnHidden: false,
          columnImage: false,
          columnSortable: false,
          sortLv: 0,
          status: true,
          fixed: '',
          columnWidth: 50
        },
      ],
      // 箱数据列定义
      columnListBoxes: [
        {
          userId: this.$store.state.user.name,
          functionId: 801002,
          serialNumber: '801002Table3ItemNo',
          tableId: "801002Table3",
          tableName: "装箱明细",
          columnProp: "item_no",
          headerAlign: "center",
          align: "right",
          columnLabel: "序号",
          columnHidden: false,
          columnImage: false,
          columnSortable: false,
          sortLv: 0,
          status: true,
          fixed: '',
          columnWidth: 40
        },
        {
          userId: this.$store.state.user.name,
          functionId: 801002,
          serialNumber: '801002Table3BoxQty',
          tableId: "801002Table3",
          tableName: "装箱明细",
          columnProp: "box_qty",
          headerAlign: "center",
          align: "right",
          columnLabel: "箱数",
          columnHidden: false,
          columnImage: false,
          columnSortable: false,
          sortLv: 0,
          status: true,
          fixed: '',
          columnWidth: 50
        },
        {
          userId: this.$store.state.user.name,
          functionId: 801002,
          serialNumber: '801002TableGrossWeight',
          tableId: "801002Table3",
          tableName: "装箱明细",
          columnProp: "grossWeight",
          headerAlign: "center",
          align: "right",
          columnLabel: "毛重",
          columnHidden: false,
          columnImage: false,
          columnSortable: false,
          sortLv: 0,
          status: true,
          fixed: '',
          columnWidth: 50
        },
        {
          userId: this.$store.state.user.name,
          functionId: 801002,
          serialNumber: '801002TableNetWeight',
          tableId: "801002Table3",
          tableName: "装箱明细",
          columnProp: "netWeight",
          headerAlign: "center",
          align: "right",
          columnLabel: "净重",
          columnHidden: false,
          columnImage: false,
          columnSortable: false,
          sortLv: 0,
          status: true,
          fixed: '',
          columnWidth: 50
        },
      ]
    }
  },
  computed: {
    // 批量编辑修改数量
    batchEditModifiedCount() {
      return Object.keys(this.batchEditModifiedBoxes).length +
             Object.keys(this.batchEditModifiedDetails).length;
    }
  },
  watch: {
    currentRow: {
      handler(newVal) {
        if (newVal && newVal.site) {
          this.loadBoxList();
        }
      },
      deep: true,
      immediate: true
    }
  },
  methods: {
    // 装箱明细相关方法
    loadBoxList() {
      if (!this.currentRow || !this.currentRow.site) {
        this.dataListBoxes = [];
        return;
      }

      // 清理之前的展开状态
      this.expandedBoxRows = [];
      this.dataListLoading = true;

      // 获取ecss_CoDelBoxList数据
      selectBoxList(this.currentRow).then(({data}) => {
        if (data && data.code == 0) {
          this.dataListBoxes = data.rows.map(row => ({
            ...row,
            palletDetails: [], // 初始化明细数据为空
            loading: false, // 初始化加载状态
            hadDetails: false // 初始化是否有明细标记
          }))
        } else {
          this.dataListBoxes = [];
        }
      }).catch(error => {
        console.error('加载箱数据失败:', error);
        this.dataListBoxes = [];
      }).finally(() => {
        this.dataListLoading = false;
      });
    },

    // 获取行的唯一标识
    getBoxRowKey(row) {
      // 使用多个字段组合确保唯一性
      return `${row.item_no || ''}_${row.palletRemark || ''}_${row.box_qty || ''}`;
    },

    // 处理行展开事件
    handleBoxExpand(row, expandedRows) {
      // 判断当前操作是展开还是收起
      const isExpanding = expandedRows.includes(row);

      if (isExpanding) {
        // 如果是展开操作，则展开所有行
        this.expandAll();
      } else {
        // 如果是收起操作，则收起所有行
        this.collapseAll();
      }
    },

    // 加载栈板明细数据
    loadPalletDetails(boxRow) {
      if (boxRow.palletDetails && boxRow.palletDetails.length > 0) {
        // 如果已经加载过，直接返回
        return;
      }

      // 设置加载状态
      this.$set(boxRow, 'loading', true);

      // 构造查询参数
      let detailParams = {
        site: this.currentRow.site,
        buNo: this.currentRow.buNo,
        delNo: this.currentRow.delNo,
        seqNo: boxRow.item_no,
        palletRemark: boxRow.palletRemark
      };

      // 调用API获取明细数据
      searchCoDelPalletDataNew(detailParams).then(({data}) => {
        if (data && data.code == 0) {
          // 将明细数据赋值给当前行
          this.$set(boxRow, 'palletDetails', data.rows);

          // 如果明细为空，且之前有明细数据，说明明细被删除了，需要检查box是否也应该被删除
          if (data.rows.length === 0 && boxRow.hadDetails) {
            // 延迟刷新列表，让后端有时间处理删除逻辑
            setTimeout(() => {
              this.loadBoxList();
            }, 500);
          }

          // 标记是否有过明细数据
          this.$set(boxRow, 'hadDetails', data.rows.length > 0);
        } else {
          this.$set(boxRow, 'palletDetails', []);
          this.$set(boxRow, 'hadDetails', false);
        }
      }).catch(error => {
        console.error('加载栈板明细数据失败:', error);
        this.$set(boxRow, 'palletDetails', []);
        this.$set(boxRow, 'hadDetails', false);
      }).finally(() => {
        // 清除加载状态
        this.$set(boxRow, 'loading', false);
      });
    },

    // 格式化明细值显示
    formatDetailValue(value, columnProp) {
      if (value === null || value === undefined || value === '') {
        return '-';
      }

      // 数字类型格式化
      if (columnProp === 'qty' || columnProp === 'rolls') {
        return parseInt(value).toLocaleString();
      }

      return value;
    },

    // 展开所有行
    expandAll() {
      // 获取所有行的key
      this.expandedBoxRows = this.dataListBoxes.map(row => this.getBoxRowKey(row));

      // 为每个行加载明细数据
      this.dataListBoxes.forEach(row => {
        this.loadPalletDetails(row);
      });
    },

    // 收起所有行
    collapseAll() {
      this.expandedBoxRows = [];
    },

    // 刷新数据的公共方法
    refresh() {
      this.loadBoxList();
    },

    /*
     * 删除逻辑说明：
     * 1. 删除明细时：
     *    - 先删除明细数据
     *    - 检查该明细所属的box是否还有其他明细
     *    - 如果没有明细了，自动删除对应的box
     *
     * 2. 删除box时：
     *    - 先检查是否有明细数据
     *    - 如果有明细，提示用户并同时删除所有明细和box
     *    - 如果没有明细，直接删除box
     */

    // 处理修改箱信息
    handleEditBox(boxRow) {
      this.currentEditBox = boxRow;
      this.editBoxForm.item_no = boxRow.item_no;
      this.editBoxForm.box_qty = boxRow.box_qty;
      this.editBoxForm.grossWeight = boxRow.grossWeight;
      this.editBoxForm.netWeight = boxRow.netWeight;
      this.editBoxDialogVisible = true;
    },

    // 处理删除箱信息
    handleDeleteBox(boxRow) {
      // 直接删除box及其所有明细，无需校验
      this.deleteBoxWithDetails(boxRow);
    },

    // 删除箱信息（包含明细）
    deleteBoxWithDetails(boxRow) {
      this.$confirm(`确定要删除序号为 ${boxRow.item_no} 的箱信息吗？删除后无法恢复！`, '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 构造删除参数
        const deleteParams = {
          site: this.currentRow.site,
          buNo: this.currentRow.buNo,
          delNo: this.currentRow.delNo,
          item_no: boxRow.item_no,
          palletRemark: boxRow.palletRemark
        };
        deleteBoxInfo(deleteParams).then(({data}) => {
          if (data && data.code === 0) {
            this.loadBoxList()
            this.$message({
              message: '操作成功',
              type: 'success',
              duration: 1500,
              onClose: () => {}
            })
          } else {
            this.$alert(data.msg, '错误', {
              confirmButtonText: '确定'
            })
          }
        })
      });
    },

    // 处理修改明细
    handleEditDetail(detailRow, boxRow) {
      this.currentEditDetail = detailRow;
      this.currentEditBoxForDetail = boxRow;
      this.editDetailForm.itemNo = detailRow.itemNo;
      this.editDetailForm.poNo = detailRow.poNo;
      this.editDetailForm.pn = detailRow.pn;
      this.editDetailForm.qty = detailRow.qty;
      this.editDetailForm.rolls = detailRow.rolls;
      this.editDetailDialogVisible = true;
    },

    /**
     * 箱数改变时自动计算净重
     * 保持毛重不变，重新计算净重
     * 计算公式：净重 = 毛重 - box_qty/2
     */
    onBoxQtyChange(value) {
      // 防止循环触发，使用标志位
      if (this._isCalculating) {
        return;
      }

      this._isCalculating = true;

      try {
        const boxQty = parseFloat(value) || 0;
        const grossWeight = parseFloat(this.editBoxForm.grossWeight) || 0;

        // 计算净重：净重 = 毛重 - box_qty/2
        const netWeight = grossWeight - (boxQty / 2);

        // 保留2位小数
        this.editBoxForm.netWeight = netWeight.toFixed(2);
      } finally {
        this._isCalculating = false;
      }
    },

    /**
     * 毛重改变时自动计算净重
     * 计算公式：净重 = 毛重 - box_qty/2
     */
    onGrossWeightChange(value) {
      // 防止循环触发，使用标志位
      if (this._isCalculating) {
        return;
      }

      this._isCalculating = true;

      try {
        const grossWeight = parseFloat(value) || 0;
        const boxQty = parseFloat(this.editBoxForm.box_qty) || 0;

        // 计算净重：净重 = 毛重 - box_qty/2
        const netWeight = grossWeight - (boxQty / 2);

        // 保留2位小数
        this.editBoxForm.netWeight = netWeight.toFixed(2);
      } finally {
        this._isCalculating = false;
      }
    },

    /**
     * 净重改变时自动计算毛重
     * 反向计算公式：毛重 = 净重 + box_qty/2
     */
    onNetWeightChange(value) {
      // 防止循环触发，使用标志位
      if (this._isCalculating) {
        return;
      }

      this._isCalculating = true;

      try {
        const netWeight = parseFloat(value) || 0;
        const boxQty = parseFloat(this.editBoxForm.box_qty) || 0;

        // 反向计算毛重：毛重 = 净重 + box_qty/2
        const grossWeight = netWeight + (boxQty / 2);

        // 保留2位小数
        this.editBoxForm.grossWeight = grossWeight.toFixed(2);
      } finally {
        this._isCalculating = false;
      }
    },

    // 提交修改箱信息
    submitEditBox() {
      this.$refs.editBoxForm.validate(valid => {
        if (valid) {
          this.editBoxSubmitting = true;

          // 构造更新参数
          const updateParams = {
            site: this.currentRow.site,
            buNo: this.currentRow.buNo,
            delNo: this.currentRow.delNo,
            item_no: this.currentEditBox.item_no,
            palletRemark: this.currentEditBox.palletRemark,
            box_qty: this.editBoxForm.box_qty,
            grossWeight: this.editBoxForm.grossWeight,
            netWeight: this.editBoxForm.netWeight,
            updateBy: this.$store.state.user.name
          };

          updateBoxInfo(updateParams).then(({ data }) => {
            if (data && data.code === 0) {
              this.editBoxDialogVisible = false;
              this.loadBoxList()
              this.$message({
                message: '操作成功',
                type: 'success',
                duration: 1500,
                onClose: () => {}
              })
            } else {
              this.$alert(data.msg, '错误', {
                confirmButtonText: '确定'
              })
            }
          });
        }
      });
    },

    // 提交修改明细
    submitEditDetail() {
      this.$refs.editDetailForm.validate(valid => {
        if (valid) {
          this.editDetailSubmitting = true;

          // 构造更新参数
          const updateParams = {
            site: this.currentRow.site,
            buNo: this.currentRow.buNo,
            delNo: this.currentRow.delNo,
            seqNo: this.currentEditDetail.seqNo,
            itemNo: this.currentEditDetail.itemNo,
            notifyDetailItemNo: this.currentEditDetail.notifyDetailItemNo,
            poNo: this.editDetailForm.poNo,
            pn: this.editDetailForm.pn,
            qty: this.editDetailForm.qty,
            oldQty: this.currentEditDetail.qty,
            rolls: this.editDetailForm.rolls,
            updateBy: this.$store.state.user.name
          };

          updateDetailInfo(updateParams).then(({ data }) => {
            if (data && data.code === 0) {
              this.editDetailDialogVisible = false;
              this.loadBoxList()
              this.$message({
                message: '操作成功',
                type: 'success',
                duration: 1500,
                onClose: () => {}
              })
            } else {
              this.$alert(data.msg, '错误', {
                confirmButtonText: '确定'
              })
            }
          });
        }
      });
    },

    // 删除明细
    handleDeleteDetail(detailRow, boxRow) {
      this.$confirm(`确定要删除这个明细信息吗？删除后无法恢复！`, '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 构造删除参数
        const deleteParams = {
          site: this.currentRow.site,
          buNo: this.currentRow.buNo,
          delNo: this.currentRow.delNo,
          seqNo: detailRow.seqNo,
          itemNo: detailRow.itemNo,
          notifyDetailItemNo: detailRow.notifyDetailItemNo,
          partNo: detailRow.part_no,
          qty: detailRow.qty
        };
        deleteDetailInfo(deleteParams).then(({data}) => {
          if (data && data.code === 0) {
            this.loadBoxList()
            this.$message({
              message: '操作成功',
              type: 'success',
              duration: 1500,
              onClose: () => {}
            })
          } else {
            this.$alert(data.msg, '错误', {
              confirmButtonText: '确定'
            })
          }
        })
      });
    },

    // 计算合计行数据
    getSummaries(param) {
      const { columns, data } = param;
      const sums = [];

      columns.forEach((column, index) => {
        if (index === 0) {
          // 第一列（展开列）显示"合计"
          sums[index] = '合计';
          return;
        }

        const values = data.map(item => Number(item[column.property]));

        // 根据列属性计算合计
        if (column.property === 'box_qty') {
          // 箱数合计
          const sum = values.reduce((prev, curr) => {
            const value = Number(curr);
            if (!isNaN(value)) {
              return prev + value;
            } else {
              return prev;
            }
          }, 0);
          sums[index] = sum;
        } else if (column.property === 'grossWeight') {
          // 毛重合计
          const sum = values.reduce((prev, curr) => {
            const value = Number(curr);
            if (!isNaN(value)) {
              return prev + value;
            } else {
              return prev;
            }
          }, 0);
          sums[index] = sum.toFixed(3);
        } else if (column.property === 'netWeight') {
          // 净重合计
          const sum = values.reduce((prev, curr) => {
            const value = Number(curr);
            if (!isNaN(value)) {
              return prev + value;
            } else {
              return prev;
            }
          }, 0);
          sums[index] = sum.toFixed(3);
        } else if (column.property === 'item_no') {
          // 序号列显示空
          sums[index] = '';
        } else {
          // 其他列显示空
          sums[index] = '';
        }
      });

      return sums;
    },

    // ========== 批量编辑相关方法 ==========

    /**
     * 打开批量编辑弹窗
     */
    openBatchEditDialog() {
      this.batchEditDialogVisible = true;
    },

    /**
     * 加载批量编辑数据
     * 将Box和明细数据扁平化为一个表格数据
     */
    async loadBatchEditData() {
      this.batchEditLoading = true;
      this.batchEditTableData = [];
      this.batchEditOriginalData = {};
      this.batchEditModifiedBoxes = {};
      this.batchEditModifiedDetails = {};
      this.batchEditSpanInfo = [];

      try {
        // 先获取Box列表
        const boxResponse = await selectBoxList(this.currentRow);
        if (!boxResponse.data || boxResponse.data.code !== 0) {
          this.$message.error('加载箱数据失败');
          return;
        }

        const boxes = boxResponse.data.rows || [];
        const tableData = [];
        const spanInfo = [];

        // 遍历每个Box，获取其明细
        for (const box of boxes) {
          const detailParams = {
            site: this.currentRow.site,
            buNo: this.currentRow.buNo,
            delNo: this.currentRow.delNo,
            seqNo: box.item_no,
            palletRemark: box.palletRemark
          };

          const detailResponse = await searchCoDelPalletDataNew(detailParams);
          const details = (detailResponse.data && detailResponse.data.code === 0)
            ? detailResponse.data.rows || []
            : [];

          // 记录该Box的起始行索引和跨行数
          const startIndex = tableData.length;
          const rowCount = details.length > 0 ? details.length : 1;
          spanInfo.push({ startIndex, rowCount, boxKey: this.getBoxRowKey(box) });

          if (details.length > 0) {
            // 有明细时，为每个明细创建一行
            details.forEach((detail, idx) => {
              const rowData = {
                // Box信息
                _boxKey: this.getBoxRowKey(box),
                _isFirstRowOfBox: idx === 0,
                _rowSpan: idx === 0 ? details.length : 0,
                item_no: box.item_no,
                palletRemark: box.palletRemark,
                box_qty: box.box_qty,
                grossWeight: box.grossWeight,
                netWeight: box.netWeight,
                // 明细信息
                _detailKey: `${detail.seqNo}_${detail.itemNo}_${detail.notifyDetailItemNo}`,
                _hasDetail: true,
                seqNo: detail.seqNo,
                itemNo: detail.itemNo,
                notifyDetailItemNo: detail.notifyDetailItemNo,
                poNo: detail.poNo,
                pn: detail.pn,
                qty: detail.qty,
                rolls: detail.rolls
              };
              tableData.push(rowData);

              // 保存原始数据
              this.batchEditOriginalData[rowData._detailKey] = {
                qty: detail.qty,
                rolls: detail.rolls
              };
            });

            // 保存Box原始数据
            this.batchEditOriginalData[this.getBoxRowKey(box)] = {
              box_qty: box.box_qty,
              grossWeight: box.grossWeight,
              netWeight: box.netWeight
            };
          } else {
            // 没有明细时，创建一行空明细的数据
            const rowData = {
              _boxKey: this.getBoxRowKey(box),
              _isFirstRowOfBox: true,
              _rowSpan: 1,
              item_no: box.item_no,
              palletRemark: box.palletRemark,
              box_qty: box.box_qty,
              grossWeight: box.grossWeight,
              netWeight: box.netWeight,
              _hasDetail: false,
              poNo: '',
              pn: '',
              qty: '',
              rolls: ''
            };
            tableData.push(rowData);

            // 保存Box原始数据
            this.batchEditOriginalData[this.getBoxRowKey(box)] = {
              box_qty: box.box_qty,
              grossWeight: box.grossWeight,
              netWeight: box.netWeight
            };
          }
        }

        this.batchEditTableData = tableData;
        this.batchEditSpanInfo = spanInfo;
      } catch (error) {
        console.error('加载批量编辑数据失败:', error);
        this.$message.error('加载数据失败');
      } finally {
        this.batchEditLoading = false;
      }
    },

    /**
     * 表格行合并方法
     */
    batchEditSpanMethod({ row, column, rowIndex, columnIndex }) {
      // Box信息列（前4列：序号、箱数、毛重、净重）需要合并
      if (columnIndex < 4) {
        if (row._isFirstRowOfBox) {
          return {
            rowspan: row._rowSpan,
            colspan: 1
          };
        } else {
          return {
            rowspan: 0,
            colspan: 0
          };
        }
      }
      return {
        rowspan: 1,
        colspan: 1
      };
    },

    /**
     * 检查Box字段是否被修改
     */
    isBoxFieldModified(row, field) {
      const boxKey = row._boxKey;
      return this.batchEditModifiedBoxes[boxKey] &&
             this.batchEditModifiedBoxes[boxKey][field] !== undefined;
    },

    /**
     * 检查明细字段是否被修改
     */
    isDetailFieldModified(row, field) {
      if (!row._hasDetail) return false;
      const detailKey = row._detailKey;
      return this.batchEditModifiedDetails[detailKey] &&
             this.batchEditModifiedDetails[detailKey][field] !== undefined;
    },

    /**
     * 批量编辑-箱数输入时联动计算净重
     * 计算公式：净重 = 毛重 - box_qty/2
     */
    onBatchBoxQtyInput(row) {
      if (this._isBatchCalculating) return;
      this._isBatchCalculating = true;

      try {
        const boxQty = parseFloat(row.box_qty) || 0;
        const grossWeight = parseFloat(row.grossWeight) || 0;

        // 计算净重：净重 = 毛重 - box_qty/2
        const netWeight = grossWeight - (boxQty / 2);
        row.netWeight = netWeight.toFixed(2);

        // 同步更新所有同Box的行
        const boxKey = row._boxKey;
        this.batchEditTableData.forEach(r => {
          if (r._boxKey === boxKey) {
            r.box_qty = row.box_qty;
            r.netWeight = row.netWeight;
          }
        });

        // 触发净重的变化检测
        this.onBatchBoxFieldChange(row, 'netWeight');
      } finally {
        this._isBatchCalculating = false;
      }
    },

    /**
     * 批量编辑-毛重输入时联动计算净重
     * 计算公式：净重 = 毛重 - box_qty/2
     */
    onBatchGrossWeightInput(row) {
      if (this._isBatchCalculating) return;
      this._isBatchCalculating = true;

      try {
        const grossWeight = parseFloat(row.grossWeight) || 0;
        const boxQty = parseFloat(row.box_qty) || 0;

        // 计算净重：净重 = 毛重 - box_qty/2
        const netWeight = grossWeight - (boxQty / 2);
        row.netWeight = netWeight.toFixed(2);

        // 同步更新所有同Box的行
        const boxKey = row._boxKey;
        this.batchEditTableData.forEach(r => {
          if (r._boxKey === boxKey) {
            r.grossWeight = row.grossWeight;
            r.netWeight = row.netWeight;
          }
        });

        // 触发净重的变化检测
        this.onBatchBoxFieldChange(row, 'netWeight');
      } finally {
        this._isBatchCalculating = false;
      }
    },

    /**
     * 批量编辑-净重输入时联动计算毛重
     * 计算公式：毛重 = 净重 + box_qty/2
     */
    onBatchNetWeightInput(row) {
      if (this._isBatchCalculating) return;
      this._isBatchCalculating = true;

      try {
        const netWeight = parseFloat(row.netWeight) || 0;
        const boxQty = parseFloat(row.box_qty) || 0;

        // 计算毛重：毛重 = 净重 + box_qty/2
        const grossWeight = netWeight + (boxQty / 2);
        row.grossWeight = grossWeight.toFixed(2);

        // 同步更新所有同Box的行
        const boxKey = row._boxKey;
        this.batchEditTableData.forEach(r => {
          if (r._boxKey === boxKey) {
            r.netWeight = row.netWeight;
            r.grossWeight = row.grossWeight;
          }
        });

        // 触发毛重的变化检测
        this.onBatchBoxFieldChange(row, 'grossWeight');
      } finally {
        this._isBatchCalculating = false;
      }
    },

    /**
     * Box字段变化处理
     */
    onBatchBoxFieldChange(row, field) {
      const boxKey = row._boxKey;
      const original = this.batchEditOriginalData[boxKey];

      if (!original) return;

      // 检查是否与原始值不同
      const currentValue = String(row[field]);
      const originalValue = String(original[field]);

      if (currentValue !== originalValue) {
        // 有变化，记录修改
        if (!this.batchEditModifiedBoxes[boxKey]) {
          this.$set(this.batchEditModifiedBoxes, boxKey, {});
        }
        this.$set(this.batchEditModifiedBoxes[boxKey], field, {
          oldValue: original[field],
          newValue: row[field]
        });

        // 同步更新所有同Box的行
        this.batchEditTableData.forEach(r => {
          if (r._boxKey === boxKey) {
            r[field] = row[field];
          }
        });
      } else {
        // 恢复原值，移除修改记录
        if (this.batchEditModifiedBoxes[boxKey]) {
          this.$delete(this.batchEditModifiedBoxes[boxKey], field);
          if (Object.keys(this.batchEditModifiedBoxes[boxKey]).length === 0) {
            this.$delete(this.batchEditModifiedBoxes, boxKey);
          }
        }
      }
    },

    /**
     * 明细字段变化处理
     */
    onBatchDetailFieldChange(row, field) {
      if (!row._hasDetail) return;

      const detailKey = row._detailKey;
      const original = this.batchEditOriginalData[detailKey];

      if (!original) return;

      const currentValue = String(row[field]);
      const originalValue = String(original[field]);

      if (currentValue !== originalValue) {
        // 有变化，记录修改
        if (!this.batchEditModifiedDetails[detailKey]) {
          this.$set(this.batchEditModifiedDetails, detailKey, {
            row: row // 保存行引用，方便后续提交
          });
        }
        this.$set(this.batchEditModifiedDetails[detailKey], field, {
          oldValue: original[field],
          newValue: row[field]
        });
      } else {
        // 恢复原值，移除修改记录
        if (this.batchEditModifiedDetails[detailKey]) {
          this.$delete(this.batchEditModifiedDetails[detailKey], field);
          // 检查是否还有其他字段被修改
          const remainingFields = Object.keys(this.batchEditModifiedDetails[detailKey])
            .filter(k => k !== 'row');
          if (remainingFields.length === 0) {
            this.$delete(this.batchEditModifiedDetails, detailKey);
          }
        }
      }
    },

    /**
     * 获取批量编辑行样式
     */
    getBatchEditRowClassName({ row, rowIndex }) {
      const classes = [];
      // 检查该行是否有Box修改
      if (this.batchEditModifiedBoxes[row._boxKey]) {
        classes.push('box-modified-row');
      }
      // 检查该行是否有明细修改
      if (row._hasDetail && this.batchEditModifiedDetails[row._detailKey]) {
        classes.push('detail-modified-row');
      }
      return classes.join(' ');
    },

    /**
     * 保存批量编辑
     */
    async saveBatchEdit() {
      if (this.batchEditModifiedCount === 0) {
        this.$message.warning('没有需要保存的修改');
        return;
      }

      this.batchEditSaving = true;

      try {
        // 构造Box修改列表
        const boxList = [];
        for (const boxKey of Object.keys(this.batchEditModifiedBoxes)) {
          const row = this.batchEditTableData.find(r => r._boxKey === boxKey);
          if (!row) continue;

          boxList.push({
            item_no: row.item_no,
            palletRemark: row.palletRemark,
            box_qty: row.box_qty,
            grossWeight: row.grossWeight,
            netWeight: row.netWeight
          });
        }

        // 构造明细修改列表
        const detailList = [];
        for (const detailKey of Object.keys(this.batchEditModifiedDetails)) {
          const detailMod = this.batchEditModifiedDetails[detailKey];
          const row = detailMod.row;
          if (!row) continue;

          detailList.push({
            seqNo: row.seqNo,
            itemNo: row.itemNo,
            notifyDetailItemNo: row.notifyDetailItemNo,
            poNo: row.poNo,
            pn: row.pn,
            qty: row.qty,
            rolls: row.rolls
          });
        }

        // 调用批量修改API
        const batchParams = {
          site: this.currentRow.site,
          buNo: this.currentRow.buNo,
          delNo: this.currentRow.delNo,
          updateBy: this.$store.state.user.name,
          boxList: boxList,
          detailList: detailList
        };

        const response = await batchUpdatePackingInfo(batchParams);

        if (response.data && response.data.code === 0) {
          this.$message.success(`成功保存 ${this.batchEditModifiedCount} 处修改`);
          this.batchEditDialogVisible = false;
          this.loadBoxList(); // 刷新主表格
        } else {
          this.$alert(response.data.msg || '保存失败', '错误', {
            confirmButtonText: '确定'
          });
        }
      } catch (error) {
        console.error('批量保存失败:', error);
        this.$message.error('保存失败');
      } finally {
        this.batchEditSaving = false;
      }
    }
  }
}
</script>

<style scoped>
.packing-detail-tab {
  width: 100%;
}

/* 展开明细容器样式 */
.expand-detail-container {
  background: #fafafa;
  border-radius: 6px;
  overflow: visible;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

/* 加载状态样式 */
.expand-loading {
  text-align: center;
  padding: 30px;
  color: #666;
  background: #fafafa;
  margin: 8px 16px;
  border-radius: 6px;
}

.expand-loading i {
  font-size: 18px;
  margin-right: 8px;
  color: #409eff;
}

/* 明细表格样式 */
.expand-detail-table {
  margin: 0;
  border: none;
}

/deep/ .expand-detail-table .el-table__body-wrapper {
  overflow-y: auto;
}

/deep/ .expand-detail-table .el-table__header {
  background: #f8f9fa;
}

/deep/ .expand-detail-table .el-table__header th {
  background: #eef7f0;
  color: #333;
  font-weight: 500;
  border-bottom: 2px solid #e9ecef;
}

/deep/ .expand-detail-table .el-table__row:hover > td {
  background-color: #f0f9ff;
}

/deep/ .expand-detail-table .el-table__row.el-table__row--striped {
  background: #fbfcfd;
}

/deep/ .expand-detail-table .el-table__row.el-table__row--striped:hover > td {
  background-color: #f0f9ff;
}

/* 空数据状态样式 */
.expand-empty-state {
  text-align: center;
  padding: 40px 20px;
  color: #999;
}

.expand-empty-state i {
  font-size: 48px;
  color: #ddd;
  margin-bottom: 12px;
  display: block;
}

.expand-empty-state p {
  font-size: 16px;
  margin: 0 0 8px 0;
  color: #666;
}

.expand-empty-state span {
  font-size: 13px;
  color: #999;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .expand-detail-container {
    margin: 8px 8px;
    padding: 6px;
  }
}

/* 确保主表格容器的滚动行为 */
/deep/ .el-table__expanded-cell {
  padding: 0 !important;
}

/deep/ .el-table__expand-column .cell {
  padding: 0;
}

/* 确保表格滚动条正常显示 */
/deep/ .el-table .el-table__body-wrapper {
  overflow-y: auto;
}

/deep/ .el-table__body-wrapper::-webkit-scrollbar {
  width: 6px;
}

/deep/ .el-table__body-wrapper::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

/deep/ .el-table__body-wrapper::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

/deep/ .el-table__body-wrapper::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

/* 批量编辑工具栏 */
.batch-edit-toolbar {
  margin-bottom: 10px;
  display: flex;
  justify-content: flex-end;
}

/* 批量编辑弹窗样式 */
/deep/ .batch-edit-dialog {
  border-radius: 8px;
}

/deep/ .batch-edit-dialog .el-dialog__header {
  background-color: #f5f7fa;
  border-bottom: 1px solid #e4e7ed;
  padding: 15px 20px;
  border-radius: 8px 8px 0 0;
}

/deep/ .batch-edit-dialog .el-dialog__title {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

/deep/ .batch-edit-dialog .el-dialog__body {
  padding: 15px 20px;
}

/deep/ .batch-edit-dialog .el-dialog__footer {
  border-top: 1px solid #e4e7ed;
  padding: 12px 20px;
}

/* 批量编辑弹窗容器 */
.batch-edit-container {
  min-height: 300px;
}

/* 批量编辑提示 */
.batch-edit-tips {
  margin-bottom: 15px;
}

.batch-edit-tips .modified-count {
  color: #e6a23c;
  margin-left: 10px;
}

.batch-edit-tips .modified-count b {
  color: #f56c6c;
  font-size: 16px;
}

/* 批量编辑表格样式 */
/deep/ .batch-edit-container .el-table {
  border-radius: 4px;
  border: 1px solid #ebeef5;
}

/* 表头样式 - 确保表头可见 */
/deep/ .batch-edit-container .el-table__header-wrapper {
  background-color: #f5f7fa;
}

/deep/ .batch-edit-container .el-table th {
  background-color: #f5f7fa !important;
  color: #606266 !important;
  font-weight: 600;
  font-size: 13px;
  padding: 8px 0;
}

/deep/ .batch-edit-container .el-table th .cell {
  color: #606266 !important;
  font-weight: 600;
}

/* Box信息单元格样式 */
.box-info-cell {
  font-weight: 600;
  color: #409eff;
  font-size: 13px;
}

/* 修改过的输入框样式 */
/deep/ .batch-edit-container .modified-input .el-input__inner {
  background-color: #fff7e6;
  border-color: #e6a23c;
  color: #e6a23c;
}

/* 修改过的行样式 */
/deep/ .batch-edit-container .box-modified-row td:nth-child(-n+4) {
  background-color: #fdf6ec !important;
}

/deep/ .batch-edit-container .detail-modified-row td:nth-child(n+5) {
  background-color: #fff7e6 !important;
}

/* 输入框样式 */
/deep/ .batch-edit-container .el-input--mini .el-input__inner {
  text-align: center;
  padding: 0 8px;
  border-color: #dcdfe6;
}

/deep/ .batch-edit-container .el-input--mini .el-input__inner:focus {
  border-color: #409eff;
}

/* 表格单元格内边距 */
/deep/ .batch-edit-container .el-table td {
  padding: 6px 0;
}

/deep/ .batch-edit-container .el-table .cell {
  padding: 0 8px;
}

/* 数字输入框隐藏上下箭头 */
/deep/ .batch-edit-container input[type="number"]::-webkit-inner-spin-button,
/deep/ .batch-edit-container input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/deep/ .batch-edit-container input[type="number"] {
  -moz-appearance: textfield;
}

/* 合并单元格的垂直居中 */
/deep/ .batch-edit-container .el-table__body td[rowspan] {
  vertical-align: middle;
}

/deep/ .batch-edit-container .el-table__body td[rowspan] .cell {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

/* 文字样式 */
/deep/ .batch-edit-container .el-table .cell span {
  font-size: 13px;
  color: #606266;
}
</style>
