<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="计划名称" prop="planName">
        <el-input v-model="queryParams.planName" placeholder="请输入收货计划名称" clearable @keyup.enter.native="handleQuery" />
      </el-form-item>
      <el-form-item label="计划日期" prop="planDate">
        <el-date-picker clearable v-model="queryParams.planDate" type="date" value-format="yyyy-MM-dd"
          placeholder="请选择计划日期">
        </el-date-picker>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single"
          @click="handleUpdate">修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple"
          @click="handleDelete">删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport">导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-row :gutter="20" v-loading="loading">
      <el-col :span="6" v-for="(row, index) in deliveryPlanList" :key="row.planId">
        <el-card shadow="hover" class="delivery-plan-card">
          <div class="card-header">
            <el-checkbox v-model="row.selected" @change="handleCardSelectionChange(row)"></el-checkbox>
            <div class="card-title">{{ row.planName }}</div>
          </div>
          <div class="card-content">
            <div class="content-item">
              <span class="label">计划日期：</span>
              <span>{{ parseTime(row.planDate, '{y}-{m}-{d}') }}</span>
            </div>
            <div class="content-item">
              <span class="label">备注：</span>
              <span>{{ row.remark || '-' }}</span>
            </div>
            <div class="content-item">
              <span class="label">创建人：</span>
              <span>{{ row.createBy }}</span>
            </div>
            <div class="content-item">
              <span class="label">更新时间：</span>
              <span>{{ parseTime(row.updateTime, '{y}-{m}-{d}') }}</span>
            </div>
          </div>
          <div class="card-actions">
            <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(row)">修改</el-button>
            <el-button size="mini" type="text" icon="el-icon-upload2" @click="openImportDialog(row)">导入</el-button>
            <el-button size="mini" type="text" icon="el-icon-notebook-2" @click="openDetailDialog(row)">明细</el-button>
            <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(row)">删除</el-button>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
      @pagination="getList" />

    <!-- 添加或修改收货计划对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="收货计划名称" prop="planName">
          <el-input v-model="form.planName" placeholder="请输入收货计划名称" />
        </el-form-item>
        <el-form-item label="计划日期" prop="planDate">
          <el-date-picker clearable v-model="form.planDate" type="datetime" value-format="yyyy-MM-dd HH:mm:ss"
            placeholder="请选择计划日期">
          </el-date-picker>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 待收货明细管理对话框 -->
    <el-dialog title="待收货明细管理" :visible.sync="detailOpen" width="1400px" append-to-body @close="resetDetail">
      <el-tabs v-model="activeTab" @tab-click="handleTabClick">
        <el-tab-pane label="计划入库" name="plan">
          <el-row :gutter="10" class="mb8">
            <el-col :span="1.5">
              <el-button type="primary" plain icon="el-icon-plus" size="mini"
                @click="openDetailAddDialog">新增</el-button>
            </el-col>
          </el-row>
          <el-table v-loading="detailLoading" :data="detailList" border>
            <el-table-column type="selection" width="55" />
            <el-table-column prop="warehouseArea" label="逻辑库区" width="120" />
            <el-table-column prop="lotNo" label="入场卷号" width="120" />
            <el-table-column prop="supplierLotNo" label="厂家卷号" width="120" />
            <el-table-column prop="productLotNo" label="成品卷号" width="120" />
            <el-table-column prop="productionDate" label="生产/发货日期" width="150">
              <template slot-scope="scope">
                {{ parseTime(scope.row.productionDate, '{y}-{m}-{d}') }}
              </template>
            </el-table-column>
            <el-table-column prop="weight" label="重量(kg)" width="100" />
            <el-table-column prop="goodsName" label="名称" width="120" />
            <el-table-column prop="spec" label="规格" width="120" />
            <el-table-column prop="length" label="长度(mm)" width="100" />
            <el-table-column prop="materialType" label="材质" width="100" />
            <el-table-column prop="manufacturer" label="生产厂家" width="120" />
            <el-table-column prop="surfaceTreatment" label="表面处理" width="100" />
            <el-table-column prop="zincCoating" label="锌层" width="80" />
            <el-table-column prop="teamGroup" label="班组" width="100" />
            <el-table-column prop="temperRolling" label="调制度" width="100" />
            <el-table-column prop="coatingType" label="镀层种类" width="100" />
            <el-table-column prop="goodsType" label="类型" width="100" />
            <el-table-column prop="receiveStatus" label="状态" width="80">
              <template slot-scope="scope">
                <el-tag
                  :type="scope.row.receiveStatus === '0' ? 'info' : scope.row.receiveStatus === '1' ? 'success' : 'danger'">
                  {{ scope.row.receiveStatus === '0' ? '待收货' : scope.row.receiveStatus === '1' ? '已收货' : '异常' }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column label="操作" fixed="right">
              <template slot-scope="scope">
                <el-button size="mini" type="text" @click="openDetailEditDialog(scope.row)">修改</el-button>
                <el-button size="mini" type="text" class="btn-danger"
                  @click="handleDetailDelete(scope.row)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
          <pagination v-show="detailTotal > 0" :total="detailTotal" :page.sync="detailQueryParams.pageNum"
            :limit.sync="detailQueryParams.pageSize" @pagination="getDetailList" />
        </el-tab-pane>
        <el-tab-pane label="实际入库表格" name="actual">
          <el-table v-loading="actualLoading" :data="actualList" border>
            <el-table-column prop="enterCoilNo" label="入场卷号" />
            <el-table-column prop="currentCoilNo" label="成品卷号" />
            <el-table-column prop="itemName" label="名称" width="120" />
            <el-table-column prop="specification" label="规格" width="120" />
            <el-table-column prop="materialType" label="材质" width="100" />
            <el-table-column prop="netWeight" label="重量(kg)" width="100" />
            <el-table-column prop="manufacturer" label="生产厂家" width="120" />
            <el-table-column prop="zincLayer" label="锌层" width="80" />
            <el-table-column prop="warehouseName" label="库区" width="100" />
            <el-table-column prop="qualityStatus" label="质量状态" width="100" />
            <el-table-column prop="createTime" label="入库时间">
              <template slot-scope="scope">
                {{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
        <el-tab-pane label="差异对比" name="diff">
          <div class="diff-config">
            <el-form :model="diffConfig" inline>
              <el-form-item label="重量差异阈值(kg)">
                <el-input-number v-model="diffConfig.weightThreshold" :precision="2" :step="0.1" :min="0" style="width: 120px;" />
              </el-form-item>
              <el-form-item>
                <el-button type="primary" size="mini" @click="calculateDiff">重新计算差异</el-button>
              </el-form-item>
            </el-form>
            <span class="config-tip">重量差异在此阈值内视为相同，超出则标记为不一致</span>
          </div>
          <el-row :gutter="16" class="diff-row">
            <el-col :span="12">
              <div class="diff-section">
                <div class="section-header">
                  <span class="section-icon missing-icon">●</span>
                  <span class="section-title">计划有实际无（少收）</span>
                  <span class="section-count">{{ missingCoils.length }}</span>
                </div>
                <el-table v-loading="diffLoading" height="300" :data="missingCoils" border size="small" class="diff-table">
                  <el-table-column prop="lotNo" label="入场卷号" />
                  <el-table-column prop="goodsName" label="名称" width="100" />
                  <el-table-column prop="spec" label="规格" width="100" />
                  <el-table-column prop="materialType" label="材质" width="80" />
                  <el-table-column prop="weight" label="重量(kg)" width="90" />
                </el-table>
                <div v-if="missingCoils.length === 0" class="empty-tip">暂无少收卷</div>
              </div>
            </el-col>
            <el-col :span="12">
              <div class="diff-section">
                <div class="section-header">
                  <span class="section-icon extra-icon">●</span>
                  <span class="section-title">实际有计划无（多收）</span>
                  <span class="section-count">{{ extraCoils.length }}</span>
                </div>
                <el-table v-loading="diffLoading" height="300" :data="extraCoils" border size="small" class="diff-table">
                  <el-table-column prop="enterCoilNo" label="入场卷号" />
                  <el-table-column prop="itemName" label="名称" width="100" />
                  <el-table-column prop="specification" label="规格" width="100" />
                  <el-table-column prop="materialType" label="材质" width="80" />
                  <el-table-column prop="netWeight" label="重量(kg)" width="90" />
                </el-table>
                <div v-if="extraCoils.length === 0" class="empty-tip">暂无多收卷</div>
              </div>
            </el-col>
          </el-row>
          
          <div class="diff-section">
            <div class="section-header">
              <span class="section-icon diff-icon">●</span>
              <span class="section-title">字段不一致</span>
              <span class="section-count">{{ diffCoils.length }}</span>
            </div>
            <el-table v-loading="diffLoading" height="300" :data="diffCoils" border size="small" class="diff-table">
              <el-table-column prop="lotNo" label="入场卷号" width="120" />
              <el-table-column label="字段差异" min-width="500">
                <template #default="scope">
                  <div class="diff-content">
                    <div v-for="(diff, index) in scope.row.diffs" :key="index" class="diff-item">
                      <span class="field-label">{{ diff.fieldName }}</span>
                      <div class="value-row">
                        <span class="value-label">计划:</span>
                        <span class="plan-value">{{ diff.planValue }}</span>
                      </div>
                      <div class="value-row">
                        <span class="value-label">实际:</span>
                        <span class="actual-value">{{ diff.actualValue }}</span>
                      </div>
                    </div>
                  </div>
                </template>
              </el-table-column>
            </el-table>
            <div v-if="diffCoils.length === 0" class="empty-tip">暂无字段不一致的卷</div>
          </div>
        </el-tab-pane>
      </el-tabs>
    </el-dialog>

    <!-- 添加或修改待收货明细对话框 -->
    <el-dialog :title="detailFormTitle" :visible.sync="detailFormOpen" width="600px" append-to-body
      @close="resetDetailForm">
      <el-form ref="detailForm" :model="detailForm" :rules="detailRules" label-width="100px">
        <el-form-item label="逻辑库区" prop="warehouseArea">
          <el-input v-model="detailForm.warehouseArea" placeholder="请输入逻辑库区" />
        </el-form-item>
        <el-form-item label="入场卷号" prop="lotNo">
          <el-input v-model="detailForm.lotNo" placeholder="请输入入场卷号" />
        </el-form-item>
        <el-form-item label="厂家卷号" prop="supplierLotNo">
          <el-input v-model="detailForm.supplierLotNo" placeholder="请输入厂家卷号" />
        </el-form-item>
        <el-form-item label="成品卷号" prop="productLotNo">
          <el-input v-model="detailForm.productLotNo" placeholder="请输入成品卷号" />
        </el-form-item>
        <el-form-item label="生产/发货日期" prop="productionDate">
          <el-date-picker clearable v-model="detailForm.productionDate" type="date" value-format="yyyy-MM-dd"
            placeholder="请选择生产/发货日期" style="width: 100%;">
          </el-date-picker>
        </el-form-item>
        <el-form-item label="重量(kg)" prop="weight">
          <el-input-number v-model="detailForm.weight" :precision="2" :step="0.01" style="width: 100%;" />
        </el-form-item>
        <el-form-item label="名称" prop="goodsName">
          <el-input v-model="detailForm.goodsName" placeholder="请输入名称" />
        </el-form-item>
        <el-form-item label="规格" prop="spec">
          <el-input v-model="detailForm.spec" placeholder="请输入规格" />
        </el-form-item>
        <el-form-item label="长度(mm)" prop="length">
          <el-input-number v-model="detailForm.length" :precision="2" :step="0.01" style="width: 100%;" />
        </el-form-item>
        <el-form-item label="材质" prop="materialType">
          <el-input v-model="detailForm.materialType" placeholder="请输入材质" />
        </el-form-item>
        <el-form-item label="生产厂家" prop="manufacturer">
          <el-input v-model="detailForm.manufacturer" placeholder="请输入生产厂家" />
        </el-form-item>
        <el-form-item label="表面处理" prop="surfaceTreatment">
          <el-input v-model="detailForm.surfaceTreatment" placeholder="请输入表面处理" />
        </el-form-item>
        <el-form-item label="锌层" prop="zincCoating">
          <el-input v-model="detailForm.zincCoating" placeholder="请输入锌层" />
        </el-form-item>
        <el-form-item label="班组" prop="teamGroup">
          <el-input v-model="detailForm.teamGroup" placeholder="请输入班组" />
        </el-form-item>
        <el-form-item label="调制度" prop="temperRolling">
          <el-input v-model="detailForm.temperRolling" placeholder="请输入调制度" />
        </el-form-item>
        <el-form-item label="镀层种类" prop="coatingType">
          <el-input v-model="detailForm.coatingType" placeholder="请输入镀层种类" />
        </el-form-item>
        <el-form-item label="类型" prop="goodsType">
          <el-input v-model="detailForm.goodsType" placeholder="请输入类型" />
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="detailForm.remark" type="textarea" placeholder="请输入备注" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button :loading="detailButtonLoading" type="primary" @click="submitDetailForm">确 定</el-button>
        <el-button @click="detailFormOpen = false">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 待收货明细导入对话框 -->
    <el-dialog title="待收货明细导入" :visible.sync="importOpen" width="1000px" append-to-body>
      <div class="import-container">
        <div class="file-upload-area" :class="{ disabled: importStatus === 'processing' }">
          <el-upload ref="upload" class="upload-excel" action="" :auto-upload="false" :show-file-list="false"
            :on-change="handleFileChange" accept=".xlsx,.xls"
            :disabled="importStatus === 'processing' || validateLoading || importLoading">
            <el-button type="primary" icon="el-icon-upload2">选择Excel文件</el-button>
          </el-upload>

          <el-button type="success" icon="el-icon-check" @click="handleValidate" v-if="file && importStatus === 'idle'"
            :disabled="!file || validateLoading" :loading="validateLoading">
            校验数据
          </el-button>
          <el-button type="warning" icon="el-icon-circle-check" @click="startImport"
            v-if="file && importStatus === 'idle'"
            :disabled="!file || !isValidated || errorList.length > 0 || importLoading" :loading="importLoading">
            开始导入
          </el-button>
          <el-button type="default" icon="el-icon-refresh" @click="resetImport"
            :disabled="importStatus === 'processing' || validateLoading || importLoading">
            重置
          </el-button>
        </div>

        <div class="template-download">
          <el-link type="primary" icon="el-icon-download" @click="downloadTemplate">下载导入模板</el-link>
          <span class="template-tip">请按照模板格式填写数据</span>
        </div>

        <div v-if="errorList.length > 0" class="error-list">
          <el-alert title="数据校验失败" type="error" :description="`共发现${errorList.length}条错误，请修正后重新导入`" show-icon />
          <el-table :data="errorList" border size="small" max-height="200">
            <el-table-column prop="rowNum" label="行号" width="80" />
            <el-table-column prop="errorMsg" label="错误信息" />
          </el-table>
        </div>

        <div v-if="tableData.length > 0 && importStatus === 'idle'" class="data-preview">
          <el-alert title="数据预览" type="info" :description="`共解析出 ${tableData.length} 条有效数据`" show-icon
            :closable="false" />
          <el-table :data="tableData" border size="small" max-height="300" stripe>
            <el-table-column prop="warehouseArea" label="逻辑库区" width="100" />
            <el-table-column prop="lotNo" label="入场卷号" width="100" />
            <el-table-column prop="supplierLotNo" label="厂家卷号" width="100" />
            <el-table-column prop="productLotNo" label="成品卷号" width="100" />
            <el-table-column prop="productionDate" label="生产/发货日期" width="120" />
            <el-table-column prop="weight" label="重量(kg)" width="100" />
            <el-table-column prop="goodsName" label="名称" width="120" />
            <el-table-column prop="spec" label="规格" width="100" />
            <el-table-column prop="length" label="长度(mm)" width="100" />
            <el-table-column prop="materialType" label="材质" width="100" />
            <el-table-column prop="manufacturer" label="生产厂家" width="120" />
          </el-table>
        </div>

        <div v-if="importStatus === 'processing'" class="import-progress">
          <el-alert title="正在导入数据" type="warning" :description="`当前进度：${progress}%`" show-icon :closable="false" />
          <el-progress :percentage="progress" status="success" />
          <p class="progress-tip">已导入 {{ importedCount }} / {{ totalCount }} 条数据</p>
        </div>

        <div v-if="importStatus === 'finished'" class="import-finished">
          <el-alert title="导入完成" type="success" :description="`共成功导入 ${importedCount} 条数据，总计 ${totalCount} 条`"
            show-icon />
        </div>

        <div v-if="importStatus === 'error'" class="import-error">
          <el-alert title="导入失败" type="error" :description="importErrorMsg" show-icon />
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import * as XLSX from 'xlsx';
import { listDeliveryPlan, getDeliveryPlan, delDeliveryPlan, addDeliveryPlan, updateDeliveryPlan } from "@/api/wms/deliveryPlan";
import { listReceivePlan, getReceivePlan, delReceivePlan, addReceivePlan, updateReceivePlan, checkReceivePlan } from "@/api/wms/receivePlan";
import { listCoilWithIds } from "@/api/wms/coil";
import { listPendingAction } from "@/api/wms/pendingAction";

const TEMPLATE_HEADERS = [
  '逻辑库区', '入场卷号', '厂家卷号', '成品卷号', '生产/发货日期', '重量(kg)',
  '名称', '规格', '长度(mm)', '材质', '生产厂家', '表面处理', '锌层',
  '班组', '调制度', '镀层种类', '类型', '备注'
];

const HEADER_MAP = {
  '逻辑库区': 'warehouseArea',
  '入场卷号': 'lotNo',
  '厂家卷号': 'supplierLotNo',
  '成品卷号': 'productLotNo',
  '生产/发货日期': 'productionDate',
  '重量(kg)': 'weight',
  '名称': 'goodsName',
  '规格': 'spec',
  '长度(mm)': 'length',
  '材质': 'materialType',
  '生产厂家': 'manufacturer',
  '表面处理': 'surfaceTreatment',
  '锌层': 'zincCoating',
  '班组': 'teamGroup',
  '调制度': 'temperRolling',
  '镀层种类': 'coatingType',
  '类型': 'goodsType',
  '备注': 'remark'
};

export default {
  name: "DeliveryPlan",
  data() {
    return {
      buttonLoading: false,
      loading: true,
      ids: [],
      single: true,
      multiple: true,
      showSearch: true,
      total: 0,
      deliveryPlanList: [],
      title: "",
      open: false,
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        planName: undefined,
        planDate: undefined,
        planType: 1
      },
      form: {
        planName: '',
        planDate: '',
      },
      rules: {},

      detailOpen: false,
      detailLoading: false,
      detailList: [],
      detailTotal: 0,
      currentPlanId: null,
      detailQueryParams: {
        pageNum: 1,
        pageSize: 10,
        planId: null
      },
      detailFormOpen: false,
      detailFormTitle: '',
      detailButtonLoading: false,
      detailForm: {},
      detailRules: {
        lotNo: [{ required: true, message: '入场卷号不能为空', trigger: 'blur' }]
      },

      activeTab: 'plan',
      actualLoading: false,
      actualList: [],
      diffLoading: false,
      missingCoils: [],
      extraCoils: [],
      diffCoils: [],
      diffConfig: {
        weightThreshold: 0.5
      },

      importOpen: false,
      file: null,
      rawData: [],
      tableData: [],
      errorList: [],
      isValidated: false,
      progress: 0,
      importedCount: 0,
      totalCount: 0,
      importStatus: 'idle',
      importErrorMsg: '',
      validateLoading: false,
      importLoading: false
    };
  },
  created() {
    this.getList();
  },
  methods: {
    getList() {
      this.loading = true;
      listDeliveryPlan(this.queryParams).then(response => {
        this.deliveryPlanList = response.rows.map(item => ({
          ...item,
          selected: false
        }));
        this.total = response.total;
        this.loading = false;
        this.ids = [];
        this.single = true;
        this.multiple = true;
      });
    },
    cancel() {
      this.open = false;
      this.reset();
    },
    reset() {
      this.form = {
        planId: undefined,
        planName: undefined,
        planDate: undefined,
        planType: 1,
        remark: undefined,
        delFlag: undefined,
        createTime: undefined,
        createBy: undefined,
        updateTime: undefined,
        updateBy: undefined
      };
      this.resetForm("form");
    },
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    handleCardSelectionChange(row) {
      this.ids = this.deliveryPlanList.filter(item => item.selected).map(item => item.planId);
      this.single = this.ids.length !== 1;
      this.multiple = !this.ids.length;
    },
    handleAdd() {
      this.form.planDate = new Date().toLocaleString().substring(0, 19).replace(/\//g, '-').replace('T', ' ');
      this.form.planName = new Date().toLocaleDateString().replace(/\//g, '-') + '收货计划';
      this.form.planType = 1;
      this.open = true;
      this.title = "添加收货计划";
    },
    handleUpdate(row) {
      this.loading = true;
      this.reset();
      const planId = row.planId || this.ids[0];
      getDeliveryPlan(planId).then(response => {
        this.loading = false;
        this.form = response.data;
        this.open = true;
        this.title = "修改收货计划";
      });
    },
    submitForm() {
      this.$refs["form"].validate(valid => {
        if (valid) {
          this.buttonLoading = true;
          if (this.form.planId != null) {
            updateDeliveryPlan(this.form).then(response => {
              this.$modal.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            }).finally(() => {
              this.buttonLoading = false;
            });
          } else {
            addDeliveryPlan(this.form).then(response => {
              this.$modal.msgSuccess("新增成功");
              this.open = false;
              this.getList();
            }).finally(() => {
              this.buttonLoading = false;
            });
          }
        }
      });
    },
    handleDelete(row) {
      const planIds = row.planId || this.ids;
      this.$modal.confirm('是否确认删除收货计划编号为"' + planIds + '"的数据项？').then(() => {
        this.loading = true;
        return delDeliveryPlan(planIds);
      }).then(() => {
        this.loading = false;
        this.getList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => {
      }).finally(() => {
        this.loading = false;
      });
    },
    handleExport() {
      this.download('wms/deliveryPlan/export', {
        ...this.queryParams
      }, `deliveryPlan_${new Date().getTime()}.xlsx`);
    },

    openDetailDialog(row) {
      this.currentPlanId = row.planId;
      this.detailQueryParams.planId = row.planId;
      this.detailOpen = true;
      this.getDetailList();
    },
    resetDetail() {
      this.detailList = [];
      this.currentPlanId = null;
      this.activeTab = 'plan';
      this.actualList = [];
      this.missingCoils = [];
      this.extraCoils = [];
      this.diffCoils = [];
    },
    handleTabClick(tab) {
      if (tab.name === 'actual' && this.actualList.length === 0) {
        this.getActualList();
      } else if (tab.name === 'diff' && (this.missingCoils.length === 0 && this.extraCoils.length === 0 && this.diffCoils.length === 0)) {
        this.calculateDiff();
      }
    },
    getActualList() {
      this.actualLoading = true;
      listPendingAction({
        warehouseId: this.currentPlanId,
        actionType: 401,
        pageSize: 99999,
        pageNum: 1,
      }).then(response => {
        const coilIds = response.rows.map(item => item.coilId).join(',');
        listCoilWithIds({ coilIds }).then(actualRes => {
          this.actualList = actualRes.rows;
          this.actualLoading = false;
        });
      }).catch(() => {
        this.actualLoading = false;
      });
    },
    calculateDiff() {
      this.diffLoading = true;
      Promise.all([
        listReceivePlan({ pageNum: 1, pageSize: 1000, planId: this.currentPlanId }),
        listPendingAction({
          warehouseId: this.currentPlanId,
          actionType: 401,
          pageSize: 99999,
          pageNum: 1,
        }).then(response => {
          const coilIds = response.rows.map(item => item.coilId).join(',');
          return listCoilWithIds({ coilIds }).then(actualRes => {
            this.actualLoading = false;
            return actualRes;
          });
        })
      ]).then(([planRes, actualRes]) => {
        const planList = planRes.rows;
        const actualList = actualRes.rows;

        const planLotNoMap = new Map();
        planList.forEach(item => {
          planLotNoMap.set(item.lotNo, item);
        });

        const actualLotNoMap = new Map();
        actualList.forEach(item => {
          actualLotNoMap.set(item.enterCoilNo, item);
        });

        this.missingCoils = planList.filter(item => !actualLotNoMap.has(item.lotNo));

        this.extraCoils = actualList.filter(item => !planLotNoMap.has(item.enterCoilNo));

        this.diffCoils = [];
        const compareFields = [
          { planField: 'goodsName', actualField: 'itemName', fieldName: '名称' },
          { planField: 'spec', actualField: 'specification', fieldName: '规格' },
          { planField: 'materialType', actualField: 'material', fieldName: '材质' },
          { planField: 'weight', actualField: 'netWeight', fieldName: '重量', isNumber: true },
          { planField: 'manufacturer', actualField: 'manufacturer', fieldName: '生产厂家' },
          { planField: 'zincCoating', actualField: 'zincLayer', fieldName: '锌层' }
        ];

        const diffMap = new Map();
        planList.forEach(planItem => {
          const actualItem = actualLotNoMap.get(planItem.lotNo);
          if (actualItem) {
            const diffs = [];
            compareFields.forEach(field => {
              let planValue = String(planItem[field.planField] || '');
              let actualValue = String(actualItem[field.actualField] || '');
              if (field.isNumber) {
                planValue = Number(planValue);
                actualValue = Number(actualValue);
              }
              let isDiff = false;
              if (field.isNumber) {
                isDiff = Math.abs(planValue - actualValue) > this.diffConfig.weightThreshold;
              } else {
                isDiff = planValue !== actualValue;
              }
              if (isDiff) {
                diffs.push({
                  fieldName: field.fieldName,
                  planValue,
                  actualValue
                });
              }
            });
            if (diffs.length > 0) {
              diffMap.set(planItem.lotNo, {
                lotNo: planItem.lotNo,
                diffs
              });
            }
          }
        });
        this.diffCoils = Array.from(diffMap.values());

        this.diffLoading = false;
      }).catch(() => {
        this.diffLoading = false;
      });
    },
    getDetailList() {
      this.detailLoading = true;
      listReceivePlan(this.detailQueryParams).then(response => {
        this.detailList = response.rows;
        this.detailTotal = response.total;
        this.detailLoading = false;
      });
    },
    openDetailAddDialog() {
      this.detailForm = {
        planId: this.currentPlanId,
        receiveStatus: '0'
      };
      this.detailFormTitle = '新增待收货明细';
      this.detailFormOpen = true;
      this.$nextTick(() => {
        this.$refs.detailForm && this.$refs.detailForm.clearValidate();
      });
    },
    openDetailEditDialog(row) {
      this.detailForm = { ...row };
      this.detailFormTitle = '修改待收货明细';
      this.detailFormOpen = true;
      this.$nextTick(() => {
        this.$refs.detailForm && this.$refs.detailForm.clearValidate();
      });
    },
    resetDetailForm() {
      this.detailForm = {};
    },
    submitDetailForm() {
      this.$refs.detailForm.validate(valid => {
        if (valid) {
          this.detailButtonLoading = true;
          if (this.detailForm.receiveId != null) {
            updateReceivePlan(this.detailForm).then(response => {
              this.$modal.msgSuccess("修改成功");
              this.detailFormOpen = false;
              this.getDetailList();
            }).finally(() => {
              this.detailButtonLoading = false;
            });
          } else {
            addReceivePlan(this.detailForm).then(response => {
              this.$modal.msgSuccess("新增成功");
              this.detailFormOpen = false;
              this.getDetailList();
            }).finally(() => {
              this.detailButtonLoading = false;
            });
          }
        }
      });
    },
    handleDetailDelete(row) {
      this.$modal.confirm('是否确认删除该待收货明细？').then(() => {
        return delReceivePlan(row.receiveId);
      }).then(() => {
        this.getDetailList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => { });
    },

    openImportDialog(row) {
      this.currentPlanId = row.planId;
      this.importOpen = true;
    },
    handleFileChange(file) {
      if (this.validateLoading || this.importLoading || this.importStatus === 'processing') {
        this.$message.warning('当前有操作正在进行中，请完成后再选择新文件');
        return;
      }
      this.file = file.raw;
      this.isValidated = false;
      this.readExcel();
    },
    async readExcel() {
      if (!this.file) return;
      try {
        const fileReader = new FileReader();
        fileReader.readAsArrayBuffer(this.file);
        fileReader.onload = async (e) => {
          try {
            const data = new Uint8Array(e.target.result);
            const workbook = XLSX.read(data, { type: 'array' });
            const sheetName = workbook.SheetNames[0];
            const worksheet = workbook.Sheets[sheetName];
            const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
            this.validateHeaders(jsonData[0]);
            this.rawData = jsonData.slice(1).filter(row => row.length > 0);
            this.formatExcel();
            this.$message.success(`成功解析Excel，共读取到 ${this.rawData.length} 条数据`);
          } catch (error) {
            this.handleError(`解析Excel失败：${error.message}`);
          }
        };
      } catch (error) {
        this.handleError(`读取文件失败：${error.message}`);
      }
    },
    validateHeaders(headers) {
      this.errorList = [];
      if (!headers || headers.length < TEMPLATE_HEADERS.length) {
        this.errorList.push({
          rowNum: 1,
          errorMsg: `表头数量不匹配，要求至少${TEMPLATE_HEADERS.length}列`
        });
        return;
      }
      TEMPLATE_HEADERS.forEach((header, index) => {
        if (headers[index] !== header) {
          this.errorList.push({
            rowNum: 1,
            errorMsg: `第${index + 1}列表头错误，要求："${header}"，实际："${headers[index] || ''}"`
          });
        }
      });
      if (this.errorList.length > 0) {
        this.$message.error('Excel表头格式不符合要求，请检查！');
      }
    },
    async handleValidate() {
      if (this.validateLoading) {
        this.$message.warning('正在校验数据，请稍候...');
        return;
      }
      if (!this.file) {
        this.$message.warning('请先选择Excel文件');
        return;
      }
      this.isValidated = true;
      if (this.rawData.length === 0) {
        this.$message.warning('暂无数据可校验');
        return;
      }
      this.validateLoading = true;
      this.errorList = [];
      try {
        for (let i = 0; i < this.rawData.length; i++) {
          const row = this.rawData[i];
          const rowNum = i + 2;
          const rowObj = this.formatRowData(row, rowNum);
          if (!rowObj.lotNo || rowObj.lotNo.trim() === '') {
            this.errorList.push({ rowNum, errorMsg: '入场卷号不能为空' });
          }
          if (rowObj.weight && isNaN(Number(rowObj.weight))) {
            this.errorList.push({ rowNum, errorMsg: '重量必须是数字' });
          }
          if (rowObj.length && isNaN(Number(rowObj.length))) {
            this.errorList.push({ rowNum, errorMsg: '长度必须是数字' });
          }
        }
        if (this.errorList.length > 0) {
          this.$message.error(`数据校验失败，共发现${this.errorList.length}条错误`);
        } else {
          this.$message.success('数据校验通过，可以开始导入');
        }
      } catch (error) {
        this.handleError(`校验数据时发生错误：${error.message}`);
      } finally {
        this.validateLoading = false;
      }
    },
    formatExcel() {
      this.tableData = [];
      if (this.rawData.length === 0) return;
      this.rawData.forEach((row, index) => {
        const rowNum = index + 2;
        const rowObj = this.formatRowData(row, rowNum);
        this.tableData.push(rowObj);
      });
    },
    formatRowData(row, rowNum) {
      const rowObj = {};
      TEMPLATE_HEADERS.forEach((header, index) => {
        const field = HEADER_MAP[header];
        rowObj[field] = row[index] != null ? row[index].toString().trim() : '';
      });
      rowObj.rowNum = rowNum;
      return rowObj;
    },
    async startImport() {
      if (this.importLoading) {
        this.$message.warning('正在导入数据，请勿重复操作...');
        return;
      }
      if (!this.file || this.tableData.length === 0) {
        this.$message.warning('暂无数据可导入');
        return;
      }
      const confirm = await this.$confirm(
        '确认导入已校验通过的数据？导入过程中请勿刷新页面或关闭浏览器！',
        '导入确认',
        {
          confirmButtonText: '确认导入',
          cancelButtonText: '取消',
          type: 'warning'
        }
      ).catch(() => false);
      if (!confirm) return;
      this.importLoading = true;
      this.importStatus = 'processing';
      this.progress = 0;
      this.importedCount = 0;
      this.totalCount = this.tableData.length;
      this.importErrorMsg = '';
      try {
        await this.batchImport();
        this.importStatus = 'finished';
        this.$message.success(`导入完成！共成功导入${this.importedCount}条数据`);
      } catch (error) {
        this.handleError(`导入失败：${error.message}，已导入${this.importedCount}条数据`);
      } finally {
        this.importLoading = false;
      }
    },
    async batchImport() {
      for (let i = 0; i < this.tableData.length; i++) {
        if (this.importStatus === 'error') break;
        const row = this.tableData[i];
        try {
          await this.importOneRow(row);
          this.importedCount++;
          const currentProgress = Math.round(((i + 1) / this.totalCount) * 100);
          this.progress = currentProgress;
          await new Promise(resolve => setTimeout(resolve, 50));
        } catch (error) {
          throw new Error(`第${row.rowNum}行导入失败：${error.message}`);
        }
      }
    },
    async importOneRow(row) {
      const params = {
        planId: this.currentPlanId,
        warehouseArea: row.warehouseArea,
        lotNo: row.lotNo,
        supplierLotNo: row.supplierLotNo,
        productLotNo: row.productLotNo,
        productionDate: row.productionDate,
        weight: row.weight ? Number(row.weight) : null,
        receiveStatus: '0',
        goodsName: row.goodsName,
        spec: row.spec,
        length: row.length ? Number(row.length) : null,
        materialType: row.materialType,
        manufacturer: row.manufacturer,
        surfaceTreatment: row.surfaceTreatment,
        zincCoating: row.zincCoating,
        teamGroup: row.teamGroup,
        temperRolling: row.temperRolling,
        coatingType: row.coatingType,
        goodsType: row.goodsType,
        remark: row.remark
      };
      const res = await addReceivePlan(params);
      if (res.code !== 200) {
        throw new Error(res.msg || '接口返回异常');
      }
    },
    resetImport() {
      if (this.validateLoading || this.importLoading || this.importStatus === 'processing') {
        this.$message.warning('当前有操作正在进行中，无法重置');
        return;
      }
      if (this.file || this.tableData.length > 0 || this.errorList.length > 0) {
        const confirm = this.$confirm(
          '确认重置所有状态？已选择的文件、解析的数据和校验结果将被清空！',
          '重置确认',
          {
            confirmButtonText: '确认重置',
            cancelButtonText: '取消',
            type: 'info'
          }
        ).catch(() => false);
        if (!confirm) return;
      }
      this.file = null;
      this.rawData = [];
      this.tableData = [];
      this.errorList = [];
      this.isValidated = false;
      this.progress = 0;
      this.importedCount = 0;
      this.totalCount = 0;
      this.importStatus = 'idle';
      this.importErrorMsg = '';
      this.$refs.upload?.clearFiles();
      this.$message.success('已重置所有状态');
    },
    downloadTemplate() {
      const templateData = [
        TEMPLATE_HEADERS,
        ['A库区', 'LOT001', 'SUP001', 'PROD001', '2024-01-01', 1000.50, '钢板', '1.0*1000', 2000, 'Q235', '宝钢', '镀锌', '80', '甲班', '1.5', 'GI', '原材料', '示例备注']
      ];
      const wb = XLSX.utils.book_new();
      const ws = XLSX.utils.aoa_to_sheet(templateData);
      ws['!cols'] = [
        { wch: 12 }, { wch: 12 }, { wch: 12 }, { wch: 12 }, { wch: 15 }, { wch: 12 },
        { wch: 15 }, { wch: 12 }, { wch: 12 }, { wch: 12 }, { wch: 15 }, { wch: 12 },
        { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 12 }, { wch: 10 }, { wch: 15 }
      ];
      XLSX.utils.book_append_sheet(wb, ws, '导入模板');
      XLSX.writeFile(wb, '待收货明细导入模板.xlsx');
    },
    handleError(message) {
      this.$message.error(message);
      this.importStatus = 'error';
      this.importErrorMsg = message;
      this.validateLoading = false;
      this.importLoading = false;
    }
  }
};
</script>

<style scoped>
.delivery-plan-card {
  margin-bottom: 20px;
  height: 100%;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.card-title {
  font-size: 16px;
  font-weight: bold;
  color: #333;
}

.card-content {
  margin-bottom: 20px;
}

.content-item {
  margin-bottom: 10px;
  display: flex;
  align-items: flex-start;
}

.content-item:last-child {
  margin-bottom: 0;
}

.label {
  width: 80px;
  font-weight: 500;
  color: #606266;
  margin-right: 10px;
}

.card-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.btn-danger {
  color: #f56c6c;
}

.import-container {
  padding: 20px;
}

.file-upload-area {
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.file-upload-area.disabled {
  opacity: 0.6;
  pointer-events: none;
}

.template-download {
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.template-tip {
  font-size: 12px;
  color: #909399;
}

.error-list {
  margin-bottom: 20px;
}

.data-preview {
  margin-bottom: 20px;
}

.import-progress {
  margin-bottom: 20px;
  padding: 10px;
  background: #f5f7fa;
  border-radius: 4px;
}

.progress-tip {
  margin: 10px 0 0 0;
  color: #666;
  font-size: 14px;
}

.import-finished,
.import-error {
  margin-bottom: 20px;
}

.diff-config {
  background: #fff;
  border-radius: 8px;
  padding: 12px 16px;
  margin-bottom: 16px;
  border: 1px solid #e4e7ed;
  display: flex;
  align-items: center;
  gap: 16px;
}

.config-tip {
  font-size: 12px;
  color: #909399;
}

.diff-section {
  background: #fafafa;
  border-radius: 8px;
  padding: 16px;
  margin-bottom: 16px;
  border: 1px solid #e4e7ed;
}

.section-header {
  display: flex;
  align-items: center;
  margin-bottom: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid #e4e7ed;
}

.section-icon {
  font-size: 10px;
  margin-right: 8px;
}

.missing-icon {
  color: #f56c6c;
}

.extra-icon {
  color: #67c23a;
}

.diff-icon {
  color: #e6a23c;
}

.section-title {
  font-size: 14px;
  font-weight: 600;
  color: #303133;
}

.section-count {
  margin-left: auto;
  background: #e4e7ed;
  color: #606266;
  font-size: 12px;
  padding: 2px 8px;
  border-radius: 10px;
}

.diff-table {
  background: #fff;
}

.diff-content {
  padding: 8px 0;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

.diff-item {
  padding: 0;
  display: flex;
  gap: 20px;
  background: #f8f9fa;
  border-radius: 4px;
  margin-bottom: 8px;
  border-left: 3px solid #e6a23c;
}

.value-label {
  color: #909399;
  margin-right: 8px;
  width: 36px;
}

.plan-value {
  color: #606266;
  font-family: monospace;
}

.actual-value {
  color: #f56c6c;
  font-family: monospace;
}

.empty-tip {
  text-align: center;
  padding: 20px;
  color: #909399;
  font-size: 14px;
}
</style>
