src/views/procurementManagement/procurementLedger/index.vue
@@ -106,7 +106,7 @@
                               prop="specificationModel" />
              <el-table-column label="单位"
                               prop="unit" />
                               <el-table-column label="入库审核状态"
              <el-table-column label="入库审核状态"
                               prop="stockInApprovalStatus"
                               width="120">
                <template #default="scope">
@@ -118,10 +118,12 @@
              </el-table-column>
              <el-table-column label="数量"
                               prop="quantity" />
              <el-table-column label="销售发货数量"
                               prop="shippedQuantity" />
              <el-table-column label="可用数量"
                               prop="availableQuality" />
              <el-table-column label="退货数量"
                               prop="returnQuality" />
                               prop="returnQuantity" />
              <el-table-column label="税率(%)"
                               prop="taxRate" />
              <el-table-column label="含税单价(元)"
@@ -155,6 +157,42 @@
        <el-table-column label="项目名称"
                         prop="projectName"
                         width="320"
                         show-overflow-tooltip />
        <el-table-column label="采购类别"
                         prop="purchaseCategory"
                         width="100"
                         show-overflow-tooltip />
        <el-table-column label="提货方式"
                         prop="pickupMethod"
                         width="100"
                         show-overflow-tooltip />
        <el-table-column label="采购油品"
                         prop="purchaseOilProduct"
                         width="100"
                         show-overflow-tooltip />
        <el-table-column label="物流方式"
                         prop="logisticsMethod"
                         width="100"
                         show-overflow-tooltip />
        <el-table-column label="采购油库"
                         prop="oilDepotName"
                         width="150"
                         show-overflow-tooltip />
        <el-table-column label="客户名称"
                         prop="customerName"
                         width="150"
                         show-overflow-tooltip />
        <el-table-column label="最佳到站日期"
                         prop="bestArrivalDate"
                         width="120"
                         show-overflow-tooltip />
        <el-table-column label="采购数量(吨)"
                         prop="purchaseQuantity"
                         width="120"
                         align="center" />
        <el-table-column label="采购申请订单状态"
                         prop="purchaseOrderStatus"
                         width="140"
                         show-overflow-tooltip />
        <el-table-column label="审批状态"
                         prop="approvalStatus"
@@ -191,6 +229,11 @@
                         width="200"
                         show-overflow-tooltip
                         :formatter="formattedNumber" />
        <el-table-column label="实际合同金额(元)"
                         prop="netContractAmount"
                         width="200"
                         show-overflow-tooltip
                         :formatter="(_, __, cellValue) => formatMoney(cellValue)" />
        <el-table-column label="录入人"
                         prop="recorderName"
                         width="120"
@@ -211,7 +254,7 @@
            <el-button link
                       type="primary"
                       @click="openForm('edit', scope.row)"
                       :disabled="scope.row.stockInStatus === '完全入库'">编辑
                       :disabled="scope.row.approvalStatus === 3">编辑
            </el-button>
            <el-button link
                       type="primary"
@@ -290,17 +333,10 @@
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="付款方式">
              <el-input v-model="form.paymentMethod"
                        placeholder="请输入"
                        clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="签订日期:"
                          prop="executionDate">
            <el-form-item label="最佳到站日期:"
                          prop="bestArrivalDate">
              <el-date-picker style="width: 100%"
                              v-model="form.executionDate"
                              v-model="form.bestArrivalDate"
                              value-format="YYYY-MM-DD"
                              format="YYYY-MM-DD"
                              type="date"
@@ -308,9 +344,16 @@
                              clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="付款方式">
              <el-input v-model="form.paymentMethod"
                        placeholder="请输入"
                        clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
          <el-col :span="8">
            <el-form-item label="录入人:"
                          prop="recorderId">
              <el-select v-model="form.recorderId"
@@ -324,7 +367,19 @@
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
          <el-col :span="8">
            <el-form-item label="签订日期:"
                          prop="executionDate">
              <el-date-picker style="width: 100%"
                              v-model="form.executionDate"
                              value-format="YYYY-MM-DD"
                              format="YYYY-MM-DD"
                              type="date"
                              placeholder="请选择"
                              clearable />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="录入日期:"
                          prop="entryDate">
              <el-date-picker style="width: 100%"
@@ -334,6 +389,126 @@
                              type="date"
                              placeholder="请选择"
                              clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <div class="form-section-title">采购入库提交</div>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="申请提交时间:"
                          prop="applicationSubmitTime">
              <el-date-picker style="width: 100%"
                              v-model="form.applicationSubmitTime"
                              value-format="YYYY-MM-DD HH:mm:ss"
                              format="YYYY-MM-DD HH:mm:ss"
                              type="datetime"
                              placeholder="请选择"
                              clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="采购类别:"
                          prop="purchaseCategory">
              <el-radio-group v-model="form.purchaseCategory"
                              @change="purchaseCategoryChange">
                <el-radio value="客存">客存</el-radio>
                <el-radio value="代储">代储</el-radio>
                <el-radio value="采购入库">采购入库</el-radio>
                <el-radio value="采购直销">采购直销</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="物流方式:"
                          prop="logisticsMethod">
              <el-select v-model="form.logisticsMethod"
                         placeholder="请选择"
                         clearable
                         style="width: 100%">
                <el-option label="厂家配送"
                           value="厂家配送" />
                <el-option label="委外物流"
                           value="委外物流" />
                <el-option label="客户自提"
                           value="客户自提" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="提货方式:"
                          prop="pickupMethod">
              <el-radio-group v-model="form.pickupMethod">
                <el-radio value="暂不提货">暂不提货</el-radio>
                <el-radio value="提货">提货</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="采购油库:"
                          prop="oilDepotId">
              <el-select v-model="form.oilDepotId"
                         placeholder="请选择"
                         clearable
                         popper-class="oil-depot-select-popper"
                         style="width: 100%">
                <el-option v-for="item in oilDepotList"
                           :key="item.id"
                           :label="item.depotName"
                           :value="item.id">
                  <div class="oil-depot-option">
                    <div class="oil-depot-option-title">{{ item.depotName }}</div>
                    <div class="oil-depot-option-line">负责人:{{ item.chargePerson }}</div>
                    <div class="oil-depot-option-line">联系电话:{{ item.phone }}</div>
                    <div class="oil-depot-option-line">所属公司:{{ item.company }}</div>
                    <div class="oil-depot-option-line">启用日期:{{ item.enableDate }}</div>
                  </div>
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="客户名称:"
                          prop="customerName">
              <el-input v-model="form.customerName"
                        placeholder="仅采购类别为代储/采购直销时可填写"
                        clearable
                        :disabled="!['代储', '采购直销'].includes(form.purchaseCategory)" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="采购数量(吨):"
                          prop="purchaseQuantity">
              <el-input-number v-model="form.purchaseQuantity"
                               :precision="0"
                               :step="1"
                               :min="0"
                               placeholder="请输入"
                               style="width: 100%" />
            </el-form-item>
          </el-col>
        </el-row>
        <div class="form-section-title">系统信息</div>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="采购申请订单状态:"
                          prop="purchaseOrderStatus">
              <el-select v-model="form.purchaseOrderStatus"
                         placeholder="请选择"
                         clearable
                         style="width: 100%">
                <el-option label="已申请,未装车"
                           value="已申请,未装车" />
                <el-option label="以出厂,未入库"
                           value="以出厂,未入库" />
                <el-option label="已入库"
                           value="已入库" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
@@ -722,6 +897,7 @@
    getPurchaseTemplateList,
    delPurchaseTemplate,
  } from "@/api/procurementManagement/procurementLedger.js";
  import { allOilDepot } from "@/api/basicData/oilDepot.js";
  import useFormData from "@/hooks/useFormData.js";
  const FileList = defineAsyncComponent(() =>
    import("@/components/Dialog/FileList.vue")
@@ -738,6 +914,7 @@
  const productOptions = ref([]);
  const salesContractList = ref([]);
  const supplierList = ref([]);
  const oilDepotList = ref([]);
  const tableLoading = ref(false);
  const recordId = ref();
  const fileListDialogVisible = ref(false);
@@ -776,9 +953,9 @@
  // 获取入库状态标签类型
  const getStockInStatusType = status => {
    const typeMap = {
      "待入库": "info", // 待入库 - 灰色
      "入库中": "warning", // 入库中 - 橙色
      "完全入库": "success", // 完全入库 - 绿色
      待入库: "info", // 待入库 - 灰色
      入库中: "warning", // 入库中 - 橙色
      完全入库: "success", // 完全入库 - 绿色
    };
    return typeMap[status] || "";
  };
@@ -786,9 +963,9 @@
  // 获取入库审核状态标签类型
  const getStockInApprovalStatusType = status => {
    const typeMap = {
      "待入库": "info", // 待入库 - 灰色
      "入库中": "warning", // 入库中 - 橙色
      "完全入库": "success", // 完全入库 - 绿色
      待入库: "info", // 待入库 - 灰色
      入库中: "warning", // 入库中 - 橙色
      完全入库: "success", // 完全入库 - 绿色
    };
    return typeMap[status] || "";
  };
@@ -920,10 +1097,20 @@
      paymentMethod: "",
      executionDate: "",
      isChecked: false,
      purchaseCategory: "",
      purchaseOilProduct: "",
      logisticsMethod: "",
      pickupMethod: "",
      oilDepotId: "",
      customerName: "",
      bestArrivalDate: "",
      purchaseQuantity: "",
      purchaseOrderStatus: "",
      applicationSubmitTime: "",
    },
    rules: {
      purchaseContractNumber: [
        { required: true, message: "请输入", trigger: "blur" },
        { required: false, message: "请输入", trigger: "blur" },
      ],
      projectName: [
        { required: true, message: "请输入项目名称", trigger: "blur" },
@@ -931,6 +1118,18 @@
      supplierId: [{ required: true, message: "请输入", trigger: "blur" }],
      entryDate: [{ required: true, message: "请选择", trigger: "change" }],
      executionDate: [{ required: true, message: "请选择", trigger: "change" }],
      purchaseCategory: [
        { required: true, message: "请选择采购类别", trigger: "change" },
      ],
      purchaseOilProduct: [
        { required: true, message: "请选择采购油品", trigger: "change" },
      ],
      oilDepotId: [
        { required: true, message: "请选择采购油库", trigger: "change" },
      ],
      purchaseQuantity: [
        { required: true, message: "请输入采购数量", trigger: "change" },
      ],
    },
  });
  const { form, rules } = toRefs(data);
@@ -1260,7 +1459,14 @@
  };
  // 主表合计方法
  const summarizeMainTable = param => {
    return proxy.summarizeTable(param, ["contractAmount"]);
    return proxy.summarizeTable(param, ["contractAmount", "netContractAmount"]);
  };
  const formatMoney = value => {
    if (value === null || value === undefined || value === "") {
      return "--";
    }
    const num = Number(value);
    return Number.isFinite(num) ? num.toFixed(2) : "--";
  };
  // 子表合计方法
  const summarizeProTable = param => {
@@ -1274,7 +1480,7 @@
  const openForm = async (type, row) => {
    // 编辑时检查入库状态,完全入库时不能编辑
    if (type === "edit" && row) {
      if (row.stockInStatus === '完全入库') {
      if (row.stockInStatus === "完全入库") {
        proxy.$modal.msgWarning("完全入库状态的记录不能编辑");
        return;
      }
@@ -1293,9 +1499,10 @@
    isTemplateNameDuplicate.value = false;
    try {
      // 并行加载基础数据
      const [salesRes, supplierRes] = await Promise.all([
      const [salesRes, supplierRes, oilDepotRes] = await Promise.all([
        getSalesNo(),
        getOptions(),
        allOilDepot(),
      ]);
      salesContractList.value = salesRes || [];
@@ -1303,21 +1510,11 @@
      supplierList.value = (supplierRes.data || []).filter(
        item => item.isWhite === 0
      );
      oilDepotList.value = oilDepotRes?.data || [];
      form.value.entryDate = getCurrentDate();
      if (type === "add") {
        // 新增时生成采购合同号
        try {
          const purchaseNoRes = await createPurchaseNo();
          if (purchaseNoRes?.data) {
            form.value.purchaseContractNumber = purchaseNoRes.data;
          }
        } catch (error) {
          console.error("生成采购合同号失败:", error);
          proxy.$modal.msgWarning("生成采购合同号失败");
        }
      } else if (type === "edit" && row?.id) {
      if (type === "edit" && row?.id) {
        // 编辑时加载数据
        currentId.value = row.id;
        try {
@@ -1325,7 +1522,10 @@
          form.value = { ...purchaseRes, stockInStatus: row.stockInStatus };
          fileList.value = purchaseRes.storageBlobVOS || [];
          // 使用 productList 接口获取产品列表,以获取入库审核状态
          const productRes = await productList({ salesLedgerId: row.id, type: 2 });
          const productRes = await productList({
            salesLedgerId: row.id,
            type: 2,
          });
          productData.value = productRes.data || [];
        } catch (error) {
          console.error("加载采购台账数据失败:", error);
@@ -1398,7 +1598,7 @@
  // 提交表单
  const submitForm = () => {
    proxy.$refs["formRef"].validate(valid => {
    proxy.$refs["formRef"].validate(async valid => {
      if (valid) {
        if (productData.value.length > 0) {
          // 新增时,需要从每个产品对象中删除 id 字段
@@ -1428,6 +1628,20 @@
          delete submitData.id;
        }
        // 如果采购合同号为空,则根据录入日期自动生成
        if (!submitData.purchaseContractNumber) {
          try {
            const purchaseNoRes = await createPurchaseNo(submitData.entryDate);
            if (purchaseNoRes?.data) {
              submitData.purchaseContractNumber = purchaseNoRes.data;
            }
          } catch (error) {
            console.error("生成采购合同号失败:", error);
            proxy.$modal.msgWarning("生成采购合同号失败");
            return;
          }
        }
        addOrEditPurchase(submitData).then(res => {
          proxy.$modal.msgSuccess("提交成功");
          closeDia();
@@ -1444,7 +1658,7 @@
  // 打开产品弹框
  const openProductForm = async (type, row, index) => {
    // 编辑时检查产品入库审核状态,完全入库时不能编辑
    if (type === "edit" && row && row.stockInApprovalStatus === '完全入库') {
    if (type === "edit" && row && row.stockInApprovalStatus === "完全入库") {
      proxy.$modal.msgWarning("完全入库状态的产品不能编辑");
      return;
    }
@@ -1627,13 +1841,17 @@
  };
  // 删除产品
  const deleteProduct = () => {
    if (productData.value.length <= 1) {
      proxy.$modal.msgWarning("采购台账至少需要保留一条产品数据");
      return;
    }
    if (productSelectedRows.value.length === 0) {
      proxy.$modal.msgWarning("请选择数据");
      return;
    }
    // 检查选中的产品中是否有完全入库的
    const hasFullyStocked = productSelectedRows.value.some(
      row => row.stockInApprovalStatus === '完全入库'
      row => row.stockInApprovalStatus === "完全入库"
    );
    if (hasFullyStocked) {
      proxy.$modal.msgWarning("选中的产品中包含完全入库的产品,无法删除");
@@ -1837,6 +2055,13 @@
      }
    }
  };
  // 采购类别改变:仅代储/采购直销时客户名称可用,切换后清空
  const purchaseCategoryChange = val => {
    if (!["代储", "采购直销"].includes(val)) {
      form.value.customerName = "";
    }
  };
  // 销售合同选择改变方法
  const salesLedgerChange = async row => {
    console.log("row", row);
@@ -1852,7 +2077,7 @@
      contractNo: form.value.salesLedgerId,
    });
    if (code == 200) {
      productData.value = data;
      productData.value = data || [];
    }
  };
@@ -1925,6 +2150,18 @@
</script>
<style scoped lang="scss">
  // 表单分栏标题:蓝色竖条 + 浅蓝底色,突出分区
  .form-section-title {
    margin: 18px 0 14px;
    padding: 8px 14px;
    font-size: 15px;
    font-weight: 600;
    color: #1d6fd8;
    background: linear-gradient(90deg, rgba(64, 158, 255, 0.14), rgba(64, 158, 255, 0.02));
    border-left: 4px solid #409eff;
    border-radius: 3px;
  }
  .invalid-row {
    opacity: 0.6;
    background-color: #f5f7fa;
@@ -1942,6 +2179,24 @@
  .select-button-group {
    display: flex;
    align-items: center;
  }
  // 采购油库下拉选项:小卡片样式
  .oil-depot-option {
    padding: 8px 10px;
    .oil-depot-option-title {
      font-size: 14px;
      font-weight: 600;
      color: #303133;
      margin-bottom: 4px;
    }
    .oil-depot-option-line {
      font-size: 12px;
      color: #909399;
      line-height: 1.8;
    }
  }
  // 审批人节点容器样式
@@ -2005,3 +2260,25 @@
    }
  }
</style>
<style lang="scss">
  // 下拉面板渲染在 body 下,需全局样式
  .oil-depot-select-popper {
    .el-select-dropdown__item {
      height: auto;
      line-height: normal;
      padding: 4px 0;
    }
    .oil-depot-option {
      border: 1px solid #e4e7ed;
      border-radius: 6px;
      background-color: #fafbfc;
      &:hover {
        border-color: #409eff;
        background-color: #f0f7ff;
      }
    }
  }
</style>