src/views/salesManagement/deliveryLedger/index.vue
@@ -2,7 +2,17 @@
  <div class="app-container">
    <div class="search_form">
      <el-form :model="searchForm" :inline="true">
        <el-form-item label="销售订单号:">
        <el-form-item label="发货单号:">
          <el-input
            v-model="searchForm.shippingNo"
            placeholder="请输入"
            clearable
            prefix-icon="Search"
            style="width: 200px"
            @change="handleQuery"
          />
        </el-form-item>
        <el-form-item label="销售合同号:">
          <el-input
            v-model="searchForm.salesContractNo"
            placeholder="请输入"
@@ -15,16 +25,6 @@
        <el-form-item label="车牌号:">
          <el-input
            v-model="searchForm.shippingCarNumber"
            placeholder="请输入"
            clearable
            prefix-icon="Search"
            style="width: 200px"
            @change="handleQuery"
          />
        </el-form-item>
        <el-form-item label="快递单号:">
          <el-input
            v-model="searchForm.expressNumber"
            placeholder="请输入"
            clearable
            prefix-icon="Search"
@@ -50,17 +50,27 @@
        border
        v-loading="tableLoading"
        @selection-change="handleSelectionChange"
        :row-key="(row) => row.id"
        :row-key="(row) => `${row.source || 'shipping'}-${row.stockOutRecordId ?? row.id}`"
        style="width: 100%"
        height="calc(100vh - 21.5em)"
      >
        <el-table-column align="center" type="selection" width="55" />
        <el-table-column align="center" label="序号" type="index" width="60" />
        <el-table-column
          label="销售订单"
          prop="salesContractNo"
          show-overflow-tooltip
          align="center"
          type="selection"
          :selectable="isRowSelectable"
          width="55"
        />
        <el-table-column align="center" label="序号" type="index" width="60" />
        <el-table-column label="来源" prop="source" align="center" width="100">
          <template #default="scope">
            <el-tag
              :type="isOilOutRow(scope.row) ? 'success' : 'info'"
              size="small"
            >
              {{ isOilOutRow(scope.row) ? "油品出库" : "发货单" }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column
          label="发货订单号"
          prop="shippingNo"
@@ -72,6 +82,16 @@
          show-overflow-tooltip
        />
        <el-table-column
          label="客户对接人"
          prop="contactPerson"
          show-overflow-tooltip
        />
        <el-table-column
          label="对接人电话"
          prop="contactPhone"
          show-overflow-tooltip
        />
        <el-table-column
          label="产品名称"
          prop="productName"
          show-overflow-tooltip
@@ -79,6 +99,27 @@
        <el-table-column
          label="规格型号"
          prop="specificationModel"
          show-overflow-tooltip
        />
        <el-table-column label="批号" show-overflow-tooltip>
          <!-- 油品出库行的批号是 outBatchNo(batch_no),发货单行没有该字段 -->
          <template #default="scope">
            {{
              isOilOutRow(scope.row)
                ? scope.row.outBatchNo || "--"
                : scope.row.batchNo || "--"
            }}
          </template>
        </el-table-column>
        <el-table-column
          label="出库类别"
          prop="outCategory"
          show-overflow-tooltip
        />
        <el-table-column label="储罐号" prop="tankNo" show-overflow-tooltip />
        <el-table-column
          label="油库"
          prop="oilDepotName"
          show-overflow-tooltip
        />
        <el-table-column
@@ -97,13 +138,8 @@
          show-overflow-tooltip
        />
        <el-table-column
          label="快递公司"
          prop="expressCompany"
          show-overflow-tooltip
        />
        <el-table-column
          label="快递单号"
          prop="expressNumber"
          label="司机姓名"
          prop="driverName"
          show-overflow-tooltip
        />
        <el-table-column
@@ -173,21 +209,6 @@
      >
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="发货类型:" prop="type">
              <el-select
                v-model="form.type"
                placeholder="请选择发货类型"
                style="width: 100%"
                @change="handleShippingTypeChange"
              >
                <el-option label="货车" value="货车" />
                <el-option label="快递" value="快递" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="发货日期:" prop="shippingDate">
              <el-date-picker
                style="width: 100%"
@@ -202,31 +223,11 @@
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="24" v-if="form.type === '货车'">
          <el-col :span="24">
            <el-form-item label="发货车牌号:" prop="shippingCarNumber">
              <el-input
                v-model="form.shippingCarNumber"
                placeholder="请输入发货车牌号"
                clearable
              />
            </el-form-item>
          </el-col>
          <el-col :span="24" v-else>
            <el-form-item label="快递公司:" prop="expressCompany">
              <el-input
                v-model="form.expressCompany"
                placeholder="请输入快递公司"
                clearable
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30" v-if="form.type === '快递'">
          <el-col :span="24">
            <el-form-item label="快递单号:" prop="expressNumber">
              <el-input
                v-model="form.expressNumber"
                placeholder="请输入快递单号"
                clearable
              />
            </el-form-item>
@@ -257,14 +258,17 @@
    >
      <div v-if="detailRow" class="detail-wrapper">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="销售订单">{{
            detailRow.salesContractNo || "--"
          }}</el-descriptions-item>
          <el-descriptions-item label="发货订单号">{{
            detailRow.shippingNo || "--"
          }}</el-descriptions-item>
          <el-descriptions-item label="客户名称">{{
            detailRow.customerName || "--"
          }}</el-descriptions-item>
          <el-descriptions-item label="客户对接人">{{
            detailRow.contactPerson || "--"
          }}</el-descriptions-item>
          <el-descriptions-item label="对接人电话">{{
            detailRow.contactPhone || "--"
          }}</el-descriptions-item>
          <el-descriptions-item label="产品名称">{{
            detailRow.productName || "--"
@@ -272,8 +276,14 @@
          <el-descriptions-item label="规格型号">{{
            detailRow.specificationModel || "--"
          }}</el-descriptions-item>
          <el-descriptions-item label="发货类型">{{
            detailRow.type || "--"
          <el-descriptions-item label="出库类别">{{
            detailRow.outCategory || "--"
          }}</el-descriptions-item>
          <el-descriptions-item label="储罐号">{{
            detailRow.tankNo || "--"
          }}</el-descriptions-item>
          <el-descriptions-item label="油库">{{
            detailRow.oilDepotName || "--"
          }}</el-descriptions-item>
          <el-descriptions-item label="发货日期">{{
            detailRow.shippingDate || "--"
@@ -284,11 +294,8 @@
          <el-descriptions-item label="发货车牌号">{{
            detailRow.shippingCarNumber || "--"
          }}</el-descriptions-item>
          <el-descriptions-item label="快递公司">{{
            detailRow.expressCompany || "--"
          }}</el-descriptions-item>
          <el-descriptions-item label="快递单号" :span="2">{{
            detailRow.expressNumber || "--"
          <el-descriptions-item label="司机姓名">{{
            detailRow.driverName || "--"
          }}</el-descriptions-item>
          <el-descriptions-item label="出库单号" :span="2">{{
            detailRow.outboundBatches || "--"
@@ -321,7 +328,7 @@
          />
          <el-table-column
            label="发货数量"
            prop="deliveryQuantity"
            prop="totalQuantity"
            min-width="120"
            align="center"
          />
@@ -356,7 +363,6 @@
const tableData = ref([]);
const selectedRows = ref([]);
const tableLoading = ref(false);
const salesOrderOptions = ref([]);
const page = reactive({
  current: 1,
  size: 100,
@@ -373,46 +379,27 @@
const dialogFormVisible = ref(false);
const data = reactive({
  searchForm: {
    salesContractNo: "", // 销售订单号
    shippingNo: "", // 发货单号(两类来源都匹配)
    salesContractNo: "", // 销售合同号(只匹配发货单行)
    shippingCarNumber: "", // 车牌号
    expressNumber: "", // 快递单号
  },
  form: {
    id: null,
    salesContractNo: "",
    customerName: "",
    specificationModel: "",
    productName: "",
    type: "货车", // 货车, 快递
    shippingDate: "",
    shippingCarNumber: "",
    expressCompany: "",
    expressNumber: "", // 快递单号
  },
  rules: {
    salesContractNo: [
      { required: true, message: "请选择销售订单", trigger: "change" },
    ],
    customerName: [
      { required: true, message: "请输入客户名称", trigger: "blur" },
    ],
    type: [{ required: true, message: "请选择发货类型", trigger: "change" }],
    shippingDate: [
      { required: true, message: "请选择发货时间", trigger: "change" },
    ],
    shippingCarNumber: [
      {
        validator: (_, value, callback) =>
          validateShippingCarNumber(value, callback),
        trigger: "blur",
      },
    ],
    expressCompany: [
      {
        validator: (_, value, callback) =>
          validateExpressCompany(value, callback),
        trigger: "blur",
      },
      { required: true, message: "请输入发货车牌号", trigger: "blur" },
    ],
  },
});
@@ -444,19 +431,14 @@
    });
};
// 销售订单变化时自动填充客户名称
const handleSalesOrderChange = (value) => {
  const selectedOrder = salesOrderOptions.value.find(
    (item) => item.salesContractNo === value
  );
  if (selectedOrder) {
    form.value.customerName = selectedOrder.customerName;
  }
};
// 油品出库行来自 stock_out_record,id 与 shipping_info 会撞号,
// 发货/删除/详情等接口背后都是 shipping_info,不能用于这类行
const isOilOutRow = (row) => row?.source === "oilOut";
const isRowSelectable = (row) => !isOilOutRow(row);
// 表格选择数据
const handleSelectionChange = (selection) => {
  selectedRows.value = selection;
  selectedRows.value = selection.filter((item) => !isOilOutRow(item));
};
// 打开弹框
@@ -472,13 +454,9 @@
  if (type === "edit" && row) {
    form.value = {
      id: row.id ?? null,
      salesContractNo: row.salesContractNo ?? "",
      customerName: row.customerName ?? "",
      type: row.type || "货车",
      shippingDate: row.shippingDate || getCurrentDate(),
      shippingCarNumber: row.shippingCarNumber ?? "",
      expressCompany: row.expressCompany ?? "",
      expressNumber: row.expressNumber ?? "",
    };
    deliveryFileList.value = row.storageBlobVOs || [];
  }
@@ -491,7 +469,8 @@
  detailRow.value = row || null;
  detailProductList.value = [];
  detailDialogVisible.value = true;
  if (!row?.id) return;
  // 油品出库行不走发货单详情接口(id 会撞号),直接用列表行数据展示
  if (!row?.id || isOilOutRow(row)) return;
  try {
    const res = await getDeliveryDetail(row.id);
    const detailData = res?.data;
@@ -554,7 +533,9 @@
    productName: item.productName ?? row.productName ?? "--",
    specificationModel:
      item.specificationModel ?? item.model ?? row.specificationModel ?? "--",
    deliveryQuantity:
    totalQuantity:
      item.totalQuantity ??
      row.totalQuantity ??
      item.deliveryQuantity ??
      item.quantity ??
      item.shippingQuantity ??
@@ -582,14 +563,8 @@
    if (valid) {
      const payload = {
        id: form.value.id,
        type: form.value.type,
        shippingDate: form.value.shippingDate,
        shippingCarNumber:
          form.value.type === "货车" ? form.value.shippingCarNumber : "",
        expressCompany:
          form.value.type === "快递" ? form.value.expressCompany : "",
        expressNumber:
          form.value.type === "快递" ? form.value.expressNumber : "",
        shippingCarNumber: form.value.shippingCarNumber,
        storageBlobDTOs: deliveryFileList.value || [],
      };
      deductStock(payload).then((res) => {
@@ -680,20 +655,6 @@
    });
};
// 发货类型校验:货车时要求车牌,快递时要求快递公司
const validateShippingCarNumber = (value, callback) => {
  if (form.value.type === "货车") {
    if (!value) return callback(new Error("请输入发货车牌号"));
  }
  callback();
};
const validateExpressCompany = (value, callback) => {
  if (form.value.type === "快递") {
    if (!value) return callback(new Error("请输入快递公司"));
  }
  callback();
};
// 发货图片上传前校检
function handleDeliveryBeforeUpload(file) {
  // 校检文件类型
@@ -764,16 +725,6 @@
    }
  }
}
// 发货类型切换时清空对应字段
const handleShippingTypeChange = (val) => {
  if (val === "货车") {
    form.value.expressCompany = "";
    form.value.expressNumber = "";
  } else {
    form.value.shippingCarNumber = "";
  }
};
// 获取审核状态文本
const getApprovalStatusText = (status) => {