src/views/procurementManagement/procurementLedger/index.vue
@@ -19,13 +19,6 @@
                      clearable
                      :prefix-icon="Search" />
          </el-form-item>
          <el-form-item label="销售合同号:">
            <el-input v-model="searchForm.salesContractNo"
                      placeholder="请输入"
                      clearable
                      prefix-icon="Search"
                      @change="handleQuery" />
          </el-form-item>
          <el-form-item label="项目名称:">
            <el-input v-model="searchForm.projectName"
                      placeholder="请输入"
@@ -106,22 +99,12 @@
                               prop="specificationModel" />
              <el-table-column label="单位"
                               prop="unit" />
                               <el-table-column label="入库审核状态"
                               prop="stockInApprovalStatus"
                               width="120">
                <template #default="scope">
                  <el-tag :type="getStockInApprovalStatusType(scope.row.stockInApprovalStatus)"
                          size="small">
                    {{ scope.row.stockInApprovalStatus || '--' }}
                  </el-tag>
                </template>
              </el-table-column>
              <el-table-column label="数量"
                               prop="quantity" />
              <el-table-column label="可用数量"
                               prop="availableQuality" />
              <el-table-column label="退货数量"
                               prop="returnQuality" />
                               prop="returnQuantity" />
              <el-table-column label="税率(%)"
                               prop="taxRate" />
              <el-table-column label="含税单价(元)"
@@ -144,10 +127,6 @@
                         prop="purchaseContractNumber"
                         width="160"
                         show-overflow-tooltip />
        <el-table-column label="销售合同号"
                         prop="salesContractNo"
                         width="160"
                         show-overflow-tooltip />
        <el-table-column label="供应商名称"
                         prop="supplierName"
                         width="160"
@@ -155,6 +134,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"
@@ -167,17 +182,6 @@
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="入库状态"
                         prop="stockInStatus"
                         width="100"
                         show-overflow-tooltip>
          <template #default="scope">
            <el-tag :type="getStockInStatusType(scope.row.stockInStatus)"
                    size="small">
              {{ scope.row.stockInStatus || '--' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="签订日期"
                         prop="executionDate"
                         width="100"
@@ -186,11 +190,20 @@
                         width="100"
                         prop="paymentMethod"
                         show-overflow-tooltip />
        <el-table-column label="付款类别"
                         width="100"
                         prop="paymentCategory"
                         show-overflow-tooltip />
        <el-table-column label="合同金额(元)"
                         prop="contractAmount"
                         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 +224,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"
@@ -247,21 +260,6 @@
                        clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="销售合同号:"
                          prop="salesLedgerId">
              <el-select v-model="form.salesLedgerId"
                         placeholder="请选择"
                         filterable
                         clearable
                         @change="salesLedgerChange">
                <el-option v-for="item in salesContractList"
                           :key="item.id"
                           :label="item.salesContractNo"
                           :value="item.id" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
@@ -290,17 +288,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 +299,32 @@
                              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-form-item label="付款类别:"
                          prop="paymentCategory">
              <el-select v-model="form.paymentCategory"
                         placeholder="请选择"
                         clearable
                         style="width: 100%">
                <el-option label="授信账期"
                           value="授信账期" />
                <el-option label="先款后货"
                           value="先款后货" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="8">
            <el-form-item label="录入人:"
                          prop="recorderId">
              <el-select v-model="form.recorderId"
@@ -324,7 +338,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 +360,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>
@@ -438,16 +584,6 @@
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="入库审核状态"
                           prop="stockInApprovalStatus"
                           width="120">
            <template #default="scope">
              <el-tag :type="getStockInApprovalStatusType(scope.row.stockInApprovalStatus)"
                      size="small">
                {{ scope.row.stockInApprovalStatus || '--' }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column fixed="right"
                           label="操作"
                           min-width="60"
@@ -455,8 +591,7 @@
            <template #default="scope">
              <el-button link
                         type="primary"
                         @click="openProductForm('edit', scope.row, scope.$index)"
                         :disabled="scope.row.stockInApprovalStatus === '完全入库'">编辑
                         @click="openProductForm('edit', scope.row, scope.$index)">编辑
              </el-button>
            </template>
          </el-table-column>
@@ -706,7 +841,6 @@
    addOrUpdateSalesLedgerProduct,
    delProduct,
    delLedgerFile,
    getProductInfoByContractNo,
  } from "@/api/salesManagement/salesLedger.js";
  import {
    addOrEditPurchase,
@@ -714,7 +848,6 @@
    updatePurchaseTemplate,
    createPurchaseNo,
    delPurchase,
    getSalesNo,
    purchaseListPage,
    productList,
    getPurchaseById,
@@ -722,6 +855,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")
@@ -736,8 +870,8 @@
  const modelOptions = ref([]);
  const userList = ref([]);
  const productOptions = ref([]);
  const salesContractList = ref([]);
  const supplierList = ref([]);
  const oilDepotList = ref([]);
  const tableLoading = ref(false);
  const recordId = ref();
  const fileListDialogVisible = ref(false);
@@ -769,26 +903,6 @@
      2: "warning", // 审批中 - 橙色
      3: "success", // 审批通过 - 绿色
      4: "danger", // 审批失败 - 红色
    };
    return typeMap[status] || "";
  };
  // 获取入库状态标签类型
  const getStockInStatusType = status => {
    const typeMap = {
      "待入库": "info", // 待入库 - 灰色
      "入库中": "warning", // 入库中 - 橙色
      "完全入库": "success", // 完全入库 - 绿色
    };
    return typeMap[status] || "";
  };
  // 获取入库审核状态标签类型
  const getStockInApprovalStatusType = status => {
    const typeMap = {
      "待入库": "info", // 待入库 - 灰色
      "入库中": "warning", // 入库中 - 橙色
      "完全入库": "success", // 完全入库 - 绿色
    };
    return typeMap[status] || "";
  };
@@ -902,7 +1016,6 @@
    searchForm: {
      supplierName: "", // 供应商名称
      purchaseContractNumber: "", // 采购合同编号
      salesContractNo: "", // 销售合同编号
      projectName: "", // 项目名称
      entryDate: null, // 录入日期
      entryDateStart: undefined,
@@ -910,7 +1023,6 @@
    },
    form: {
      purchaseContractNumber: "",
      salesLedgerId: "",
      projectName: "",
      recorderId: "",
      entryDate: "",
@@ -918,12 +1030,23 @@
      supplierName: "",
      supplierId: "",
      paymentMethod: "",
      paymentCategory: "",
      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 +1054,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 +1395,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 => {
@@ -1272,14 +1414,6 @@
  };
  // 打开弹框
  const openForm = async (type, row) => {
    // 编辑时检查入库状态,完全入库时不能编辑
    if (type === "edit" && row) {
      if (row.stockInStatus === '完全入库') {
        proxy.$modal.msgWarning("完全入库状态的记录不能编辑");
        return;
      }
    }
    await getTemplateList();
    await userListNoPage().then(res => {
      userList.value = res.data;
@@ -1293,31 +1427,20 @@
    isTemplateNameDuplicate.value = false;
    try {
      // 并行加载基础数据
      const [salesRes, supplierRes] = await Promise.all([
        getSalesNo(),
      const [supplierRes, oilDepotRes] = await Promise.all([
        getOptions(),
        allOilDepot(),
      ]);
      salesContractList.value = salesRes || [];
      // 供应商过滤出isWhite=0 的数据
      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 +1448,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 +1524,7 @@
  // 提交表单
  const submitForm = () => {
    proxy.$refs["formRef"].validate(valid => {
    proxy.$refs["formRef"].validate(async valid => {
      if (valid) {
        if (productData.value.length > 0) {
          // 新增时,需要从每个产品对象中删除 id 字段
@@ -1417,15 +1543,24 @@
        form.value.storageBlobDTOS = fileList.value;
        form.value.type = 2;
        // 如果salesLedgerId为空,则不传递salesContractNo
        if (!form.value.salesLedgerId) {
          form.value.salesContractNo = "";
        }
        // 新增时不传递id
        const submitData = { ...form.value };
        if (operationType.value === "add") {
          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 => {
@@ -1443,12 +1578,6 @@
  };
  // 打开产品弹框
  const openProductForm = async (type, row, index) => {
    // 编辑时检查产品入库审核状态,完全入库时不能编辑
    if (type === "edit" && row && row.stockInApprovalStatus === '完全入库') {
      proxy.$modal.msgWarning("完全入库状态的产品不能编辑");
      return;
    }
    productOperationType.value = type;
    productOperationIndex.value = index;
    productForm.value = {};
@@ -1627,16 +1756,12 @@
  };
  // 删除产品
  const deleteProduct = () => {
    if (productSelectedRows.value.length === 0) {
      proxy.$modal.msgWarning("请选择数据");
    if (productData.value.length <= 1) {
      proxy.$modal.msgWarning("采购台账至少需要保留一条产品数据");
      return;
    }
    // 检查选中的产品中是否有完全入库的
    const hasFullyStocked = productSelectedRows.value.some(
      row => row.stockInApprovalStatus === '完全入库'
    );
    if (hasFullyStocked) {
      proxy.$modal.msgWarning("选中的产品中包含完全入库的产品,无法删除");
    if (productSelectedRows.value.length === 0) {
      proxy.$modal.msgWarning("请选择数据");
      return;
    }
    if (operationType.value === "add") {
@@ -1837,22 +1962,10 @@
      }
    }
  };
  // 销售合同选择改变方法
  const salesLedgerChange = async row => {
    console.log("row", row);
    var index = salesContractList.value.findIndex(item => item.id == row);
    console.log("index", index);
    if (index > -1) {
      await querygProductInfoByContractNo();
    }
  };
  const querygProductInfoByContractNo = async () => {
    const { code, data } = await getProductInfoByContractNo({
      contractNo: form.value.salesLedgerId,
    });
    if (code == 200) {
      productData.value = data;
  // 采购类别改变:仅代储/采购直销时客户名称可用,切换后清空
  const purchaseCategoryChange = val => {
    if (!["代储", "采购直销"].includes(val)) {
      form.value.customerName = "";
    }
  };
@@ -1925,6 +2038,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 +2067,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 +2148,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>