<template>
  <div class="app-container sale-out-page">
    <!-- 上：查询 -->
    <el-card shadow="never" class="top-card">
      <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="68px">
        <el-form-item label="单据编号" prop="deliveryNum">
          <el-input v-model="queryParams.deliveryNum" placeholder="请输入单据编号" clearable style="width: 200px" />
        </el-form-item>

        <el-form-item label="日期" prop="dateRange">
          <el-date-picker
            v-model="queryParams.dateRange"
            type="daterange"
            value-format="yyyy-MM-dd"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            style="width: 260px"
            clearable
          />
        </el-form-item>

        <el-form-item label="客户" prop="customerNum">
          <el-select v-model="queryParams.customerNum" placeholder="请选择客户" filterable clearable style="width: 200px">
            <el-option v-for="item in customerOptions" :key="item.customerNum" :value="item.customerNum" :label="item.customerName" />
          </el-select>
        </el-form-item>

        <el-form-item label="业务员" prop="employeeNum">
          <el-select v-model="queryParams.employeeNum" placeholder="请选择业务员" filterable clearable style="width: 200px">
            <el-option v-for="item in salespersonOptions" :key="item.employeeNum" :value="item.employeeNum" :label="item.employeeName" />
          </el-select>
        </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="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDeleteAll">批量删除</el-button>
        </el-col>
      </el-row>
    </el-card>

    <br />

    <!-- 下：列表 -->
    <el-card shadow="never" class="bottom-card">
      <el-table border stripe v-loading="loading" ref="multipleTable" :data="list" @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column label="单据日期" align="center" prop="documentDate" min-width="110" />
        <el-table-column label="单据编号" align="center" prop="deliveryNum" min-width="150" />
        <el-table-column label="客户编号" align="center" prop="customerNum" min-width="120" />
        <el-table-column label="客户名称" align="center" prop="customerName" min-width="140" />
        <el-table-column label="业务员" align="center" prop="employeeName" min-width="120" />
        <el-table-column label="备注" align="center" prop="remark" min-width="160" />
        <el-table-column label="总计金额" align="center" prop="totalAmount" min-width="110" />
        <el-table-column label="操作" align="center" fixed="right" width="200">
          <template slot-scope="scope">
            <el-button type="text" size="mini" icon="el-icon-document" @click="handleDetail(scope.row)">查看详情</el-button>
            <el-button type="text" size="mini" icon="el-icon-edit" @click="handleEdit(scope.row)">编辑</el-button>
            <el-button type="text" size="mini" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

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

    <!-- 新增/编辑/查看详情：全屏弹框 -->
    <el-dialog :title="dialogTitle" :visible.sync="dialogOpen" fullscreen append-to-body class="sale-out-dialog">
      <!-- 查看详情：除表格外，其余字段用带边框 descriptions（总计金额放备注后面） -->
      <div v-if="dialogMode === 'view'" class="dialog-detail-body">
        <el-card shadow="never" class="dialog-detail-card">
          <el-descriptions :column="3" border size="small" class="detail-desc">
            <el-descriptions-item label="单据日期">{{ emptyDisplay(form.documentDate) }}</el-descriptions-item>
            <el-descriptions-item label="单据编号">{{ emptyDisplay(form.deliveryNum) }}</el-descriptions-item>
            <el-descriptions-item label="客户">{{ emptyDisplay(form.customerName) }}</el-descriptions-item>
            <el-descriptions-item label="业务员">{{ emptyDisplay(form.employeeName) }}</el-descriptions-item>
            <el-descriptions-item label="备注">{{ emptyDisplay(form.remark) }}</el-descriptions-item>
            <el-descriptions-item label="总计金额">{{ emptyDisplay(form.totalAmount) }}</el-descriptions-item>
          </el-descriptions>

          <div class="dialog-table-card dialog-table-card--detail">
            <el-table :data="detailList" border stripe height="100%" class="dialog-table">
              <el-table-column label="货品编号" align="center" prop="goodsNum" min-width="120" show-overflow-tooltip />
              <el-table-column label="货品名称" align="center" prop="goodsName" min-width="130" show-overflow-tooltip />
              <el-table-column label="规格" align="center" prop="goodsSpec" min-width="100" show-overflow-tooltip />
              <el-table-column label="仓库" align="center" prop="warehouseName" min-width="100" show-overflow-tooltip />
              <el-table-column label="批次" align="center" prop="batchNum" min-width="100" show-overflow-tooltip />
              <el-table-column label="基本计量数量" align="center" prop="baseNum" min-width="120" />
              <el-table-column label="销售重量" align="center" prop="salesWeight" min-width="110" />
              <el-table-column label="基本计量单位" align="center" prop="baseUnit" min-width="110" />
              <el-table-column label="辅助计量数量" align="center" prop="assNum" min-width="110" />
              <el-table-column label="辅助计量单位" align="center" prop="assUnit" min-width="110" />
              <el-table-column label="单价" align="center" prop="unitPrice" min-width="100" />
              <el-table-column label="金额" align="center" prop="amount" min-width="110" />
              <el-table-column label="货品备注" align="center" prop="goodsRemark" min-width="140" show-overflow-tooltip />
            </el-table>
          </div>
        </el-card>
      </div>

      <!-- 新增/编辑：表单 + 可编辑表格 + 总计 -->
      <div v-else class="dialog-body">
        <!-- 上：表头 -->
        <el-card shadow="never" class="dialog-head-card">
          <el-form ref="dialogForm" :model="form" label-width="90px" size="small">
            <el-row :gutter="12">
              <el-col :span="6">
                <el-form-item label="单据日期" prop="documentDate">
                  <el-date-picker v-model="form.documentDate" type="date" value-format="yyyy-MM-dd" placeholder="单据日期" style="width: 100%" />
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="单据编号" prop="deliveryNum">
                  <el-input v-model="form.deliveryNum" placeholder="请输入单据编号" clearable />
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="客户" prop="customerNum">
                  <el-select v-model="form.customerNum" placeholder="请选择客户" filterable clearable style="width: 100%" @change="onDialogCustomerChange">
                    <el-option v-for="item in customerOptions" :key="item.customerNum" :value="item.customerNum" :label="item.customerName" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="业务员" prop="employeeNum">
                  <el-select v-model="form.employeeNum" placeholder="请选择业务员" filterable clearable style="width: 100%">
                    <el-option v-for="item in salespersonOptions" :key="item.employeeNum" :value="item.employeeNum" :label="item.employeeName" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="备注" prop="remark">
                  <el-input v-model="form.remark" placeholder="请输入备注" clearable />
                </el-form-item>
              </el-col>
            </el-row>
          </el-form>
        </el-card>

        <!-- 中：明细工具栏 + 可编辑表格（与销售订单一致：添加/删除行） -->
        <div class="dialog-detail-toolbar">
          <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAddDetailRow">添加明细</el-button>
        </div>
        <el-card shadow="never" class="dialog-table-card">
          <el-table :data="detailList" border stripe height="100%" class="dialog-table">
            <el-table-column label="货品编号" align="center" prop="goodsNum" min-width="140">
              <template slot-scope="{ row, $index }">
                <el-input v-model="row.goodsNum" size="mini" placeholder="货品编号" clearable>
                  <template slot="append">
                    <el-tooltip :content="dialogMaterialQueryTooltip" placement="top">
                      <span class="dialog-material-query-append">
                        <el-button
                          type="primary"
                          icon="el-icon-search"
                          circle
                          size="mini"
                          :disabled="!canQueryDialogMaterial"
                          @click="openDialogMaterialQuery($index)"
                        />
                      </span>
                    </el-tooltip>
                  </template>
                </el-input>
              </template>
            </el-table-column>
            <el-table-column label="货品名称" align="center" prop="goodsName" min-width="130">
              <template slot-scope="{ row }">
                <el-input v-model="row.goodsName" size="mini" placeholder="货品名称" clearable />
              </template>
            </el-table-column>
            <el-table-column label="规格" align="center" prop="goodsSpec" min-width="100">
              <template slot-scope="{ row }">
                <el-input v-model="row.goodsSpec" size="mini" placeholder="规格" clearable />
              </template>
            </el-table-column>
            <el-table-column label="仓库" align="center" prop="warehouseName" min-width="150">
              <template slot-scope="{ row }">
                <el-input v-model="row.warehouseName" size="mini" placeholder="仓库" clearable />
              </template>
            </el-table-column>
            <el-table-column label="批次" align="center" prop="batchNum" min-width="170">
              <template slot-scope="{ row, $index }">
                <el-input v-model="row.batchNum" size="mini" placeholder="批次" clearable>
                  <template slot="append">
                    <el-tooltip content="批次查询" placement="top">
                      <el-button
                        type="primary"
                        icon="el-icon-search"
                        circle
                        size="mini"
                        @click="openBatchQueryDialog($index)"
                      />
                    </el-tooltip>
                  </template>
                </el-input>
              </template>
            </el-table-column>
            <el-table-column label="基本计量数量" align="center" prop="baseNum" min-width="120">
              <template slot-scope="{ row, $index }">
                <decimal-input
                  v-model="row.baseNum"
                  size="mini"
                  :precision="2"
                  :min="0"
                  placeholder="数量"
                  @change="() => recalcLineAmount($index)"
                />
              </template>
            </el-table-column>
            <el-table-column label="销售重量" align="center" prop="salesWeight" min-width="110">
              <template slot-scope="{ row }">
                <decimal-input v-model="row.salesWeight" size="mini"  :precision="2" :min="0" placeholder="销售重量" />
              </template>
            </el-table-column>
            <el-table-column label="基本计量单位" align="center" prop="baseUnit" min-width="110">
              <template slot-scope="{ row }">
                <el-input v-model="row.baseUnit" size="mini" placeholder="单位" clearable />
              </template>
            </el-table-column>
            <el-table-column label="辅助计量数量" align="center" prop="assNum" min-width="120">
              <template slot-scope="{ row, $index }">
                <decimal-input
                  v-model="row.assNum"
                  size="mini"
                  :precision="2"
                  :min="0"
                  placeholder="数量"
                  @change="() => syncDetailBaseNumFromAssist(row, $index)"
                />
              </template>
            </el-table-column>
            <el-table-column label="辅助计量单位" align="center" prop="assUnit" min-width="110">
              <template slot-scope="{ row }">
                <el-input v-model="row.assUnit" size="mini" placeholder="单位" clearable />
              </template>
            </el-table-column>
            <el-table-column label="单价" align="center" prop="unitPrice" min-width="100">
              <template slot-scope="{ row, $index }">
                <decimal-input v-model="row.unitPrice" size="mini"  :precision="2" :min="0" placeholder="单价" @change="() => recalcLineAmount($index)" />
              </template>
            </el-table-column>
            <el-table-column label="金额" align="center" prop="amount" min-width="110">
              <template slot-scope="{ row }">
                <el-input :value="row.amount != null && row.amount !== '' ? row.amount : ''" size="mini" readonly placeholder="自动计算" />
              </template>
            </el-table-column>
            <el-table-column label="货品备注" align="center" prop="goodsRemark" min-width="140">
              <template slot-scope="{ row }">
                <el-input v-model="row.goodsRemark" size="mini" placeholder="货品备注" clearable />
              </template>
            </el-table-column>
            <el-table-column label="操作" align="center" width="70" fixed="right">
              <template slot-scope="{ $index }">
                <el-button
                  type="text"
                  icon="el-icon-delete"
                  :disabled="detailList.length <= 1"
                  @click="handleRemoveDetailRow($index)"
                />
              </template>
            </el-table-column>
          </el-table>
        </el-card>

        <!-- 下：总计 -->
        <el-card shadow="never" class="dialog-foot-card">
          <el-row :gutter="12">
            <el-col :span="6">
              <div class="total-amount-field">
                <span class="total-amount-label">总计金额</span>
                <decimal-input v-model="form.totalAmount" size="mini" :precision="2" :min="0" placeholder="总计金额" disabled />
              </div>
            </el-col>
          </el-row>
        </el-card>
      </div>

      <div slot="footer" class="dialog-footer">
        <template v-if="dialogMode === 'view'">
          <el-button type="primary" @click="dialogOpen = false">关 闭</el-button>
        </template>
        <template v-else>
          <el-button @click="dialogOpen = false">取 消</el-button>
          <el-button type="primary" @click="submitForm">确 定</el-button>
        </template>
      </div>
    </el-dialog>

    <!-- 出库明细货品速查（单选）；选后拉价：与销售订单共用 getGoodsPriceInfo -->
    <query-material
      ref="queryMaterial"
      :isMultiple="false"
      :excludeGoodsNums="dialogMaterialExcludeGoodsNums"
      @selectList="handleDialogMaterialSelect"
    />

    <!-- 批次查询（与生产计划 plan 一致：mock 列表，按货品编号过滤，单选；后续可换接口） -->
    <el-dialog
      title="批次查询"
      :visible.sync="batchQueryDialogOpen"
      width="1100px"
      append-to-body
      class="batch-query-dialog"
      @close="onBatchQueryDialogClose"
    >
      <div class="batch-query-tip" v-if="batchQueryGoodsNum">
        当前货品编号：<strong>{{ batchQueryGoodsNum }}</strong>
      </div>
      <el-table
        ref="batchQueryTable"
        :data="batchQueryTableData"
        border
        stripe
        highlight-current-row
        height="400"
        style="width: 100%;"
        @row-click="handleBatchQueryRowClick"
      >
        <el-table-column label="物料编码" prop="goodsNum" align="center" min-width="120" />
        <el-table-column label="物料名称" prop="goodsName" align="center" min-width="140" show-overflow-tooltip />
        <el-table-column label="批次" prop="batch" align="center" min-width="120" />
        <el-table-column label="剩余数量" prop="remainQty" align="center" min-width="100" />
        <el-table-column label="单位" prop="unit" align="center" width="80" />
        <el-table-column label="供应商采购单号" prop="supplierPoNo" align="center" min-width="160" show-overflow-tooltip />
      </el-table>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="handleBatchQueryConfirm">确 定</el-button>
        <el-button @click="batchQueryDialogOpen = false">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { formatDateYMS } from "@/utils";
import { getStaffList } from "@/api/baseInfo/staff";
import { getSaleOutPage, addSaleOut, editSaleOut, delSaleOut, getSaleOutById } from "@/api/sale/saleOut";
import { getGoodsPriceInfo } from "@/api/sale/saleOrder";
import { getClienteleList } from "@/api/sale/clientele";
import DecimalInput from "@/views/components/DecimalInput.vue";
import QueryMaterial from "@/views/components/queryMaterial.vue";

export default {
  name: "SaleOut",
  components: { DecimalInput, QueryMaterial },
  data() {
    return {
      /** 列表加载状态 */
      loading: false,
      /** 表格数据 */
      list: [],
      /** 总数 */
      total: 0,
      /** 选中 ids */
      ids: [],
      /** 批量删除禁用控制 */
      multiple: true,
      /** 查询参数（必须包含 pageNum/pageSize） */
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        deliveryNum: null,
        documentDateStart: null,
        documentDateEnd: null,
        dateRange: [],
        customerNum: null,
        employeeNum: null,
      },
      /** 客户下拉（当前模拟，后续接接口替换） */
      customerOptions: [],
      /** 业务员下拉（employeeType === '3'） */
      salespersonOptions: [],

      /** 新增/编辑弹框 */
      dialogOpen: false,
      dialogTitle: "新增",
      dialogMode: "add",
      /** 表头表单 */
      form: {
        id: null,
        documentDate: null,
        deliveryNum: null,
        customerNum: null,
        employeeNum: null,
        remark: null,
        totalAmount: "0.00",
      },
      /** 明细行 */
      detailList: [],
      /** 物料速查：当前编辑的明细行下标 */
      currentDetailMaterialRowIndex: null,
      /** 已选货品编号，避免重复选（不含当前行） */
      dialogMaterialExcludeGoodsNums: [],
      /** 批次查询弹框（逻辑同 plan/index.vue） */
      batchQueryDialogOpen: false,
      batchQueryGoodsRowIndex: null,
      batchQueryGoodsNum: "",
      batchQueryTableData: [],
      batchQuerySelectedRow: null,
      /**
       * 批次列表 mock（后续替换为接口）
       * 字段：物料编码、物料名称、批次、剩余数量、单位、供应商采购单号
       */
      mockBatchList: [
        {
          goodsNum: "001001",
          goodsName: "外三元生猪",
          batch: "PC20250301-01",
          remainQty: 120.5,
          unit: "kg",
          supplierPoNo: "CG20250301001",
        },
        {
          goodsNum: "001001",
          goodsName: "外三元生猪",
          batch: "PC20250301-02",
          remainQty: 88,
          unit: "kg",
          supplierPoNo: "CG20250301002",
        },
        {
          goodsNum: "002",
          goodsName: "外三元一级白条",
          batch: "PC20250302-01",
          remainQty: 200,
          unit: "件",
          supplierPoNo: "CG20250302001",
        },
      ],
    };
  },
  created() {
    /** 初始化：日期默认今天到今天 */
    const today = formatDateYMS(new Date().getTime() + 24 * 60 * 60 * 1000);
    this.queryParams.dateRange = [today, today];
    this.queryParams.documentDateStart = today;
    this.queryParams.documentDateEnd = today;
    /** 初始化：下拉数据 */
    this.fetchCustomerOptions();
    this.fetchSalespersonOptions();
    /** 初始化：默认查询 */
    this.getList();
  },
  watch: {
    'queryParams.dateRange': {
      handler(newVal) {
        if(newVal && newVal.length === 2) {
          this.queryParams.documentDateStart = newVal[0];
          this.queryParams.documentDateEnd = newVal[1];
        }
      },
      deep: true,
      immediate: true,
    },
   
  },  
  computed: {
    canQueryDialogMaterial() {
      return this.form.documentDate && this.form.customerNum;
    },
    dialogMaterialQueryTooltip() {
      return this.canQueryDialogMaterial ? "点击查询货品" : "请先选择单据日期和客户";
    },
  },
  methods: {
    /**
     * 详情展示：空值显示「—」
     * @param {*} val 原值
     * @returns {string}
     */
    emptyDisplay(val) {
      if (val === null || val === undefined) return "—";
      const s = String(val).trim();
      return s === "" ? "—" : s;
    },
    /**
     * 详情弹框：业务员展示（优先姓名，否则按编号匹配下拉）
     * @returns {string|null}
     */
    viewSalespersonText() {
      if (this.form.salespersonName) return this.form.salespersonName;
      const no = this.form.salespersonNo;
      if (no == null || no === "") return null;
      const hit = (this.salespersonOptions || []).find((x) => String(x.employeeNum) === String(no));
      return hit ? hit.employeeName : String(no);
    },
    /**
     * 空明细行
     * @returns {Object}
     */
    createEmptyDetailRow() {
      return {
        goodsNum: null,
        goodsName: null,
        goodsSpec: null,
        warehouseNum: null,
        batchNum: null,
        baseNum: null,
        salesWeight: null,
        baseUnit: null,
        assNum: null,
        assUnit: null,
        unitPrice: null,
        amount: null,
        goodsRemark: null,
        /** 基本计量数量 = conversionValue × 辅助计量数量（来自物料速查） */
        conversionValue: null,
      };
    },
    /** 添加一行出库明细（与销售订单「添加明细」一致） */
    handleAddDetailRow() {
      this.detailList.push(this.createEmptyDetailRow());
    },
    /**
     * 删除一行明细，至少保留一行
     * @param {number} index 行下标
     */
    handleRemoveDetailRow(index) {
      if ((this.detailList || []).length <= 1) return;
      this.detailList.splice(index, 1);
      this.recalcTotalAmount();
    },
    /**
     * 客户变化：带出客户名称
     * @param {string} customerNum 客户编号
     */
    onDialogCustomerChange(customerNum) {
      const hit = (this.customerOptions || []).find((x) => String(x.customerNum) === String(customerNum));
      this.form.customerName = hit ? hit.customerName : null;
    },
    /**
     * 打开明细行物料速查
     * @param {number} rowIndex 行下标
     */
    openDialogMaterialQuery(rowIndex) {
      if (!this.canQueryDialogMaterial) {
        this.$message.warning("请先选择单据日期和客户");
        return;
      }
      this.currentDetailMaterialRowIndex = rowIndex;
      this.dialogMaterialExcludeGoodsNums = (this.detailList || [])
        .map((r, i) => {
          if (i === rowIndex || !r) return null;
          const n = r.goodsNum;
          return n != null && String(n).trim() !== "" ? String(n) : null;
        })
        .filter(Boolean);
      if (this.$refs.queryMaterial) this.$refs.queryMaterial.open();
    },
    /**
     * 打开批次查询：按当前行货品编号过滤列表，单选（与 plan/index.vue 一致，数据为 mock）
     * @param {number} rowIndex 明细行下标
     */
    openBatchQueryDialog(rowIndex) {
      const row = this.detailList && this.detailList[rowIndex];
      const goodsNum =
        row && row.goodsNum != null && String(row.goodsNum).trim() !== ""
          ? String(row.goodsNum).trim()
          : "";
      if (!goodsNum) {
        this.$message.warning("请先填写或选择货品编号");
        return;
      }
      this.batchQueryGoodsRowIndex = rowIndex;
      this.batchQueryGoodsNum = goodsNum;
      this.batchQuerySelectedRow = null;
      this.batchQueryTableData = (this.mockBatchList || []).filter(
        (item) => item && String(item.goodsNum || "").trim() === goodsNum
      );
      this.batchQueryDialogOpen = true;
      this.$nextTick(() => {
        if (this.$refs.batchQueryTable) {
          this.$refs.batchQueryTable.setCurrentRow(null);
        }
      });
    },
    /** 批次表行点击：单选高亮 */
    handleBatchQueryRowClick(row) {
      this.batchQuerySelectedRow = row;
      this.$nextTick(() => {
        if (this.$refs.batchQueryTable) {
          this.$refs.batchQueryTable.setCurrentRow(row);
        }
      });
    },
    /**
     * 批次查询确定：回填 batchNum、辅助数量=剩余数量；有换算值则走 sync，否则基本数量=辅助×1（同 plan）
     */
    handleBatchQueryConfirm() {
      const sel = this.batchQuerySelectedRow;
      if (!sel) {
        this.$message.warning("请选择一条批次记录");
        return;
      }
      const idx = this.batchQueryGoodsRowIndex;
      if (idx == null || !this.detailList || !this.detailList[idx]) {
        this.batchQueryDialogOpen = false;
        return;
      }
      const row = this.detailList[idx];
      this.$set(row, "batchNum", sel.batch);
      const assNum = Number(sel.remainQty);
      if (Number.isFinite(assNum)) {
        this.$set(row, "assNum", assNum.toFixed(2));
      } else {
        this.$set(row, "assNum", null);
      }
      const cv = Number(row.conversionValue);
      if (Number.isFinite(cv) && cv > 0) {
        this.syncDetailBaseNumFromAssist(row, idx);
      } else {
        const conv = 1;
        if (Number.isFinite(assNum)) {
          this.$set(row, "baseNum", (assNum * conv).toFixed(2));
        }
        this.recalcLineAmount(idx);
      }
      this.batchQueryDialogOpen = false;
    },
    /** 关闭批次弹框时清理表格状态 */
    onBatchQueryDialogClose() {
      this.batchQuerySelectedRow = null;
      this.batchQueryGoodsRowIndex = null;
      this.batchQueryTableData = [];
    },
    /**
     * 物料确定：写入编号/名称/规格/仓库/单位，再按单据日期+客户+货品查单价（无则 0）
     * @param {Array<Object>} list 选中行
     */
    handleDialogMaterialSelect(list) {
      const selected = list || [];
      if (!selected.length) return;
      const idx = this.currentDetailMaterialRowIndex;
      if (idx == null || idx < 0) return;
      const row = this.detailList[idx];
      if (!row) return;
      const item = selected[0];
      this.$set(row, "goodsNum", item.goodsNum != null ? item.goodsNum : null);
      this.$set(row, "goodsName", item.goodsName != null ? item.goodsName : null);
      this.$set(row, "goodsSpec", item.goodsSpec != null ? item.goodsSpec : null);
      this.$set(row, "warehouseNum", item.warehouseNo != null ? item.warehouseNo : null);
      this.$set(row, "warehouseName", item.warehouseName != null ? item.warehouseName : null);
      this.$set(row, "baseUnit", item.unit != null ? item.unit : null);
      this.$set(
        row,
        "assUnit",
        item.assistantUnit != null ? item.assistantUnit : item.assUnit != null ? item.assUnit : null
      );
      /** 换算值：基本计量数量 = conversionValue × 辅助计量数量 */
      this.$set(
        row,
        "conversionValue",
        item.conversionValue != null && item.conversionValue !== "" ? item.conversionValue : null
      );
      this.syncDetailBaseNumFromAssist(row, idx);
      this.fetchGoodsPriceInfoForDetailRow(idx);
    },
    /**
     * 是否存在有效换算值（基本数量由辅助数量推算，输入禁用）
     * @param {Object} row 明细行
     */
    isDetailBaseNumDerivedFromAssist(row) {
      const cv = Number(row && row.conversionValue);
      return Number.isFinite(cv) && cv > 0;
    },
    /**
     * 按换算同步基本计量数量并重算金额、总计
     * @param {Object} row 明细行
     * @param {number} index 行下标
     */
    syncDetailBaseNumFromAssist(row, index) {
      if (!row) return;
      const cv = Number(row.conversionValue);
      const assRaw = row.assNum;
      const hasAss =
        assRaw !== null &&
        assRaw !== undefined &&
        String(assRaw).trim() !== "" &&
        !Number.isNaN(Number(assRaw));

      if (!Number.isFinite(cv) || cv <= 0) {
        this.recalcLineAmount(index);
        return;
      }
      if (!hasAss) {
        this.$set(row, "baseNum", null);
        this.recalcLineAmount(index);
        return;
      }
      const ass = Number(assRaw);
      if (ass >= 0) {
        this.$set(row, "baseNum", (cv * ass).toFixed(2));
      }
      this.recalcLineAmount(index);
    },
    /**
     * 销售订单侧接口：单据日期、客户编号、货品编号 → 单价
     * @param {number} index 明细行下标
     */
    fetchGoodsPriceInfoForDetailRow(index) {
      const row = this.detailList[index];
      if (!row) return;
      const documentDate = this.form.documentDate;
      const customerNum = this.form.customerNum;
      const goodsNum = row.goodsNum;
      if (!documentDate) {
        this.$message.warning("请先选择单据日期");
        this.$set(row, "unitPrice", "0.00");
        this.recalcLineAmount(index);
        return;
      }
      if (customerNum == null || String(customerNum).trim() === "") {
        this.$message.warning("请先选择客户");
        this.$set(row, "unitPrice", "0.00");
        this.recalcLineAmount(index);
        return;
      }
      if (goodsNum == null || String(goodsNum).trim() === "") {
        this.$set(row, "unitPrice", "0.00");
        this.recalcLineAmount(index);
        return;
      }
      getGoodsPriceInfo({
        documentDate: String(documentDate).trim(),
        customerNum: String(customerNum).trim(),
        goodsNum: String(goodsNum).trim(),
      })
        .then((res) => {
          this.applyGoodsPriceInfoToDetailRow(row, res && res.data);
          /** 接口若带回辅助数量等，有换算值时仍以「辅助×换算」写回基本数量 */
          this.syncDetailBaseNumFromAssist(row, index);
        })
        .catch(() => {
          this.$set(row, "unitPrice", "0.00");
          this.recalcLineAmount(index);
        });
    },
    /**
     * 合并 getGoodsPriceInfo 返回（单价、辅助数量等）；有换算值时不直接覆盖基本数量
     * @param {Object} row 明细行
     * @param {*} data 接口 data
     */
    applyGoodsPriceInfoToDetailRow(row, data) {
      if (data == null) {
        this.$set(row, "unitPrice", "0.00");
        return;
      }
      let d = data;
      if (Array.isArray(d)) {
        d = d[0];
        if (d == null) {
          this.$set(row, "unitPrice", "0.00");
          return;
        }
      }
      if (typeof d !== "object") {
        this.$set(row, "unitPrice", this.pickUnitPriceFromGoodsPriceResponse(data));
        return;
      }
      const price =
        d.unitPrice != null
          ? d.unitPrice
          : d.salePrice != null
            ? d.salePrice
            : d.price != null
              ? d.price
              : null;
      if (price != null && price !== "") {
        const n = Number(price);
        this.$set(row, "unitPrice", Number.isFinite(n) ? n.toFixed(2) : "0.00");
      } else {
        this.$set(row, "unitPrice", "0.00");
      }
      ["goodsSpec", "baseUnit", "assUnit", "assNum"].forEach((k) => {
        if (d[k] != null && d[k] !== "") this.$set(row, k, d[k]);
      });
      if (!this.isDetailBaseNumDerivedFromAssist(row)) {
        if (d.baseNum != null && d.baseNum !== "") this.$set(row, "baseNum", d.baseNum);
      }
    },
    /**
     * 从 getGoodsPriceInfo 返回中解析单价；无有效数字则返回 "0.00"
     * @param {*} data 接口 data
     * @returns {string}
     */
    pickUnitPriceFromGoodsPriceResponse(data) {
      let d = data;
      if (d == null) return "0.00";
      if (Array.isArray(d)) {
        d = d[0];
        if (d == null) return "0.00";
      }
      if (typeof d !== "object") {
        const n = Number(d);
        return Number.isFinite(n) ? n.toFixed(2) : "0.00";
      }
      const raw = d.unitPrice != null ? d.unitPrice : d.salePrice != null ? d.salePrice : d.price;
      if (raw == null || raw === "") return "0.00";
      const n = Number(raw);
      return Number.isFinite(n) ? n.toFixed(2) : "0.00";
    },
    /**
     * 重算行金额（数量 × 单价）并汇总总计
     * @param {number} index 行下标
     */
    recalcLineAmount(index) {
      const row = this.detailList[index];
      if (!row) return;
      const q = Number(row.baseNum);
      const p = Number(row.unitPrice);
      const amt = Number.isFinite(q) && Number.isFinite(p) ? (q * p).toFixed(2) : null;
      this.$set(row, "amount", amt);
      this.recalcTotalAmount();
    },
    /**
     * 汇总总计金额
     */
    recalcTotalAmount() {
      let sum = 0;
      (this.detailList || []).forEach((r) => {
        const v = Number(r && r.amount);
        if (Number.isFinite(v)) sum += v;
      });
      this.form.totalAmount = sum.toFixed(2);
    },
    /**
     * 从列表行解析明细（无则返回模拟行，接接口后替换）
     * @param {Object} row 列表行
     * @returns {Array<Object>}
     */
    resolveDetailFromRow(row) {
      const list = row && row.goods;
      if (Array.isArray(list) && list.length) return list.map((x) => ({ ...x }));
      return [
        {
          goodsNum: "M001",
          goodsName: "示例货品",
          goodsSpec: "标品",
          warehouse: "默认仓",
          batchNo: "B001",
          baseQty: "1",
          salesWeight: "1",
          baseUnit: "kg",
          assistUnit: "箱",
          unitPrice: "10",
          amount: "10.00",
          goodsRemark: null,
        },
      ];
    },
    /**
     * 获取业务员下拉数据（employeeType === '3'）
     */
    fetchSalespersonOptions() {
      getStaffList({}).then((res) => {
        const list = (res && res.data) || [];
        this.salespersonOptions = (list || []).filter((item) => String(item.employeeType) === "3");
      });
    },
    /** 获取客户下拉数据 */
    fetchCustomerOptions() {
      getClienteleList({}).then(res => {
        this.customerOptions = res.data;
      });
    },
    /**
     * 获取列表（预留接口）
     */
    getList() {
      getSaleOutPage(this.queryParams).then(res => {
        this.list = res.data.records;
        this.total = res.data.total;
        this.loading = false;
      });
    },
    /**
     * 表格勾选变化
     * @param {Array} selection 选中行
     */
    handleSelectionChange(selection) {
      this.ids = (selection || []).map((r) => r.id);
      this.multiple = this.ids.length === 0;
    },
    /**
     * 查询按钮
     */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /**
     * 重置按钮
     */
    resetQuery() {
      const today = formatDateYMS(new Date().getTime() + 24 * 60 * 60 * 1000);
      this.queryParams = {
        pageNum: 1,
        pageSize: 10,
        deliveryNum: null,
        dateRange: [today, today],
        customerNum: null,
        employeeNum: null,
        documentDateStart: today,
        documentDateEnd: today,
      };
      this.handleQuery();
    },
    /**
     * 新增（预留）
     */
    handleAdd() {
      const today = formatDateYMS(new Date().getTime() + 24 * 60 * 60 * 1000);
      this.dialogTitle = "新增";
      this.dialogMode = "add";
      this.form = {
        id: null,
        documentDate: today,
        deliveryNum: null,
        customerNum: null,
        employeeNum: null,
        remark: null,
        totalAmount: "0.00",
      };
      this.detailList = [this.createEmptyDetailRow()];
      this.dialogOpen = true;
    },
    /**
     * 批量删除（预留）
     */
    handleDeleteAll() {
      /** TODO：接批量删除接口 */
      if (!this.ids.length) return;
      this.$message.info("批量删除待接入接口");
    },
    /**
     * 查看详情（预留）
     * @param {Object} row 当前行
     */
    handleDetail(row) {
      this.dialogTitle = "查看详情";
      this.dialogMode = "view";
      getSaleOutById({ id: row.id }).then(res => {
        this.form = res.data;
        this.detailList = this.resolveDetailFromRow(res.data);
        this.dialogOpen = true;
      });
    },
    /**
     * 编辑（预留）
     * @param {Object} row 当前行
     */
    handleEdit(row) {
      this.dialogTitle = "编辑";
      this.dialogMode = "edit";
      getSaleOutById({ id: row.id }).then(res => {
        this.form = res.data;
        this.detailList = this.resolveDetailFromRow(res.data);
        /** 编辑载入后按换算关系重算基本数量与金额（与销售订单编辑一致） */
        this.$nextTick(() => {
          (this.detailList || []).forEach((r, i) => this.syncDetailBaseNumFromAssist(r, i));
        });
        this.dialogOpen = true;
      });
    },
    /**
     * 弹框确定（预留）
     */
    submitForm() {
      if (this.dialogMode === "view") return;
      if (this.dialogMode === "add") {
        this.form.goods = this.detailList;
      addSaleOut(this.form).then(res => {
          this.$message.success("保存成功");
          this.dialogOpen = false;
          this.getList();
        });
      } else {
         this.form.goods = this.detailList;
        editSaleOut(this.form).then(res => {
          this.$message.success("保存成功");
          this.dialogOpen = false;
          this.getList();
        });
      }
    },
    /**
     * 删除（单行，预留）
     * @param {Object} row 当前行
     */
    handleDelete(row) {
      this.$confirm("确定要删除这条数据吗？", "提示", { type: "warning" })
        .then(() => {
          delSaleOut({ ids: row.id }).then(res => {
            this.$message.success("删除成功");
            this.getList();
          });
        })
        .catch(() => {});
    },
  },
};
</script>

<style scoped lang="scss">
.sale-out-page {
  display: flex;
  flex-direction: column;
}

/** 物料搜索按钮 disabled 时仍能让 tooltip 收到悬停 */
.dialog-material-query-append {
  display: inline-block;
  vertical-align: middle;
  line-height: 1;
}

.dialog-body {
  height: calc(100vh - 140px);
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/** 出库明细「添加明细」工具栏（与销售订单一致） */
.dialog-detail-toolbar {
  flex-shrink: 0;
}

.dialog-detail-body {
  height: calc(100vh - 140px);
  display: flex;
  flex-direction: column;
}

.dialog-detail-card {
  flex: 1;
  display: flex;
  flex-direction: column;
}

::v-deep .dialog-detail-card > .el-card__body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.detail-desc {
  flex-shrink: 0;
}

.dialog-table-card--detail {
  flex: 1;
  min-height: 0;
  margin-top: 12px;
}

.dialog-head-card {
  flex-shrink: 0;
}

.dialog-table-card {
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

::v-deep .dialog-table-card > .el-card__body {
  height: 100%;
  min-height: 0;
  overflow: hidden;
}

.dialog-foot-card {
  flex-shrink: 0;
}

.total-amount-field {
  display: flex;
  align-items: center;
  gap: 10px;
}

.total-amount-label {
  font-size: 13px;
  color: #606266;
  white-space: nowrap;
}

.batch-query-tip {
  margin-bottom: 10px;
  font-size: 13px;
  color: #606266;
}

::v-deep .batch-query-dialog .el-table__body tr.current-row > td {
  background-color: #d9ecff !important;
}
</style>

