liding
6 天以前 a40681b6c72f58ccebd636e9db3ea3365c1799aa
src/views/procurementManagement/procurementLedger/index.vue
@@ -33,6 +33,18 @@
                      prefix-icon="Search"
                      @change="handleQuery" />
          </el-form-item>
          <el-form-item label="供应商类型:">
            <el-select v-model="searchForm.supplierType"
                       placeholder="请选择"
                       style="width: 220px"
                       clearable
                       @change="handleQuery">
              <el-option label="对公"
                         value="1" />
              <el-option label="对私"
                         value="2" />
            </el-select>
          </el-form-item>
          <el-form-item label="录入日期:">
            <el-date-picker v-model="searchForm.entryDate"
                            value-format="YYYY-MM-DD"
@@ -53,7 +65,9 @@
      <div style="display: flex;justify-content: flex-end;margin-bottom: 20px;">
        <el-button type="primary"
                   @click="openForm('add')">新增台账</el-button>
        <el-button type="primary" plain @click="handleImport">导入</el-button>
        <el-button type="primary"
                   plain
                   @click="handleImport">导入</el-button>
        <el-button @click="handleOut">导出</el-button>
        <el-button type="danger"
                   plain
@@ -90,17 +104,33 @@
                               prop="unit" />
              <el-table-column label="数量"
                               prop="quantity" />
              <el-table-column label="可用数量"
                               prop="availableQuality" />
              <el-table-column label="退货数量"
                               prop="returnQuality" />
              <el-table-column label="税率(%)"
                               prop="taxRate" />
                               prop="taxRate"
                               v-if="props.row.supplierType === 1" />
              <el-table-column label="含税单价(元)"
                               prop="taxInclusiveUnitPrice"
                               :formatter="formattedNumber" />
                               :formatter="formattedNumber"
                               v-if="props.row.supplierType === 1" />
              <el-table-column label="含税总价(元)"
                               prop="taxInclusiveTotalPrice"
                               :formatter="formattedNumber" />
                               :formatter="formattedNumber"
                               v-if="props.row.supplierType === 1" />
              <el-table-column label="不含税总价(元)"
                               prop="taxExclusiveTotalPrice"
                               :formatter="formattedNumber" />
                               :formatter="formattedNumber"
                               v-if="props.row.supplierType === 1" />
              <el-table-column label="单价(对私)"
                               prop="unitPrice"
                               :formatter="formattedNumber"
                               v-if="props.row.supplierType === 2" />
              <el-table-column label="总价(对私)"
                               prop="totalPrice"
                               :formatter="formattedNumber"
                               v-if="props.row.supplierType === 2" />
            </el-table>
          </template>
        </el-table-column>
@@ -114,12 +144,20 @@
                         show-overflow-tooltip />
        <el-table-column label="销售合同号"
                         prop="salesContractNo"
                          width="160"
                         width="160"
                         show-overflow-tooltip />
        <el-table-column label="供应商名称"
                         prop="supplierName"
                          width="160"
                         width="160"
                         show-overflow-tooltip />
        <el-table-column label="供应商类型"
                         prop="supplierType"
                         width="100"
                         show-overflow-tooltip>
          <template #default="scope">
            {{ scope.row.supplierType === 1 ? '对公' : '对私' }}
          </template>
        </el-table-column>
        <el-table-column label="项目名称"
                         prop="projectName"
                         width="320"
@@ -129,9 +167,8 @@
                         width="100"
                         show-overflow-tooltip>
          <template #default="scope">
            <el-tag
              :type="getApprovalStatusType(scope.row.approvalStatus)"
              size="small">
            <el-tag :type="getApprovalStatusType(scope.row.approvalStatus)"
                    size="small">
              {{ approvalStatusText[scope.row.approvalStatus] || '未知状态' }}
            </el-tag>
          </template>
@@ -168,12 +205,10 @@
          <template #default="scope">
            <el-button link
                       type="primary"
                       size="small"
                       @click="openForm('edit', scope.row)"
                       :disabled="scope.row.approvalStatus !== 1 && scope.row.approvalStatus !== 4">编辑</el-button>
            <el-button link
                       type="primary"
                       size="small"
                       @click="downLoadFile(scope.row)">附件</el-button>
          </template>
        </el-table-column>
@@ -186,12 +221,12 @@
                  @pagination="paginationChange" />
    </div>
    <FormDialog v-model="dialogFormVisible"
               :title="operationType === 'add' ? '新增采购台账页面' : '编辑采购台账页面'"
               :width="'70%'"
               :operation-type="operationType"
               @close="closeDia"
               @confirm="submitForm"
               @cancel="closeDia">
                :title="operationType === 'add' ? '新增采购台账页面' : '编辑采购台账页面'"
                :width="'70%'"
                :operation-type="operationType"
                @close="closeDia"
                @confirm="submitForm"
                @cancel="closeDia">
      <el-form :model="form"
               label-width="140px"
               label-position="top"
@@ -229,11 +264,12 @@
              <el-select v-model="form.supplierId"
                         placeholder="请选择"
                         filterable
                         clearable>
                         clearable
                         @change="handleSupplierChange">
                <el-option v-for="item in supplierList"
                           :key="item.id"
                           :label="item.supplierName"
                                        :value="item.id" >{{item.supplierName + '---' + item.supplierType}}</el-option>
                           :value="item.id">{{item.supplierName + '---' + (item.supplierType === 1 ? item.taxpayerIdentificationNum || '无' : '对私')}}</el-option>
              </el-select>
            </el-form-item>
          </el-col>
@@ -301,38 +337,33 @@
              <template #label>
                <div style="display: flex; align-items: center; justify-content: space-between; width: 100%;">
                  <span>审批人选择:</span>
                  <el-button type="primary" size="small" @click="addApproverNode" icon="Plus">新增节点</el-button>
                  <el-button type="primary"
                             size="small"
                             @click="addApproverNode"
                             icon="Plus">新增节点</el-button>
                </div>
              </template>
              <div class="approver-nodes-container">
                <div
                  v-for="(node, index) in approverNodes"
                  :key="node.id"
                  class="approver-node-item"
                >
                <div v-for="(node, index) in approverNodes"
                     :key="node.id"
                     class="approver-node-item">
                  <div class="approver-node-header">
                    <span class="approver-node-label">审批节点 {{ index + 1 }}</span>
                    <el-button
                      v-if="approverNodes.length > 1"
                      type="danger"
                      size="small"
                      text
                      @click="removeApproverNode(index)"
                      icon="Delete"
                    >删除</el-button>
                    <el-button v-if="approverNodes.length > 1"
                               type="danger"
                               size="small"
                               text
                               @click="removeApproverNode(index)"
                               icon="Delete">删除</el-button>
                  </div>
                  <el-select
                    v-model="node.userId"
                    placeholder="请选择审批人"
                    filterable
                    style="width: 100%;"
                  >
                    <el-option
                      v-for="user in userList"
                      :key="user.userId"
                      :label="user.nickName"
                      :value="user.userId"
                    />
                  <el-select v-model="node.userId"
                             placeholder="请选择审批人"
                             filterable
                             style="width: 100%;">
                    <el-option v-for="user in userList"
                               :key="user.userId"
                               :label="user.nickName"
                               :value="user.userId" />
                  </el-select>
                </div>
              </div>
@@ -343,6 +374,7 @@
          <el-form-item label="产品信息:"
                        prop="entryDate">
            <el-button type="primary"
                       v-if="currentSupplierType"
                       @click="openProductForm('add')">添加</el-button>
            <el-button plain
                       type="danger"
@@ -370,11 +402,10 @@
                         :value="item.templateName">
                <div style="display: flex; justify-content: space-between; align-items: center;">
                  <span>{{ item.templateName }}</span>
                  <el-icon
                    v-if="item.id"
                    class="delete-icon"
                    @click.stop="handleDeleteTemplate(item)"
                    style="cursor: pointer; color: #f56c6c; font-size: 14px; margin-left: 8px;">
                  <el-icon v-if="item.id"
                           class="delete-icon"
                           @click.stop="handleDeleteTemplate(item)"
                           style="cursor: pointer; color: #f56c6c; font-size: 14px; margin-left: 8px;">
                    <Delete />
                  </el-icon>
                </div>
@@ -417,19 +448,33 @@
                           show-overflow-tooltip />
          <el-table-column label="税率(%)"
                           prop="taxRate"
                           width="80" />
                           width="80"
                           v-if="currentSupplierType === 1" />
          <el-table-column label="含税单价(元)"
                           prop="taxInclusiveUnitPrice"
                           :formatter="formattedNumber"
                           width="150" />
                           width="150"
                           v-if="currentSupplierType === 1" />
          <el-table-column label="含税总价(元)"
                           prop="taxInclusiveTotalPrice"
                           :formatter="formattedNumber"
                           width="150" />
                           width="150"
                           v-if="currentSupplierType === 1" />
          <el-table-column label="不含税总价(元)"
                           prop="taxExclusiveTotalPrice"
                           :formatter="formattedNumber"
                           width="150" />
                           width="150"
                           v-if="currentSupplierType === 1" />
          <el-table-column label="单价(对私)"
                           prop="unitPrice"
                           :formatter="formattedNumber"
                           width="150"
                           v-if="currentSupplierType === 2" />
          <el-table-column label="总价(对私)"
                           prop="totalPrice"
                           :formatter="formattedNumber"
                           width="150"
                           v-if="currentSupplierType === 2" />
          <el-table-column label="是否质检"
                           prop="isChecked"
                           width="150">
@@ -446,7 +491,6 @@
            <template #default="scope">
              <el-button link
                         type="primary"
                         size="small"
                         @click="openProductForm('edit', scope.row, scope.$index)">编辑</el-button>
            </template>
          </el-table-column>
@@ -491,28 +535,24 @@
      </el-form>
    </FormDialog>
    <!-- 导入弹窗 -->
    <FormDialog
      v-model="importUpload.open"
      :title="importUpload.title"
      :width="'600px'"
      @close="importUpload.open = false"
      @confirm="submitImportFile"
      @cancel="importUpload.open = false"
    >
      <el-upload
        ref="importUploadRef"
        :limit="1"
        accept=".xlsx,.xls"
        :action="importUpload.url"
        :headers="importUpload.headers"
        :before-upload="importUpload.beforeUpload"
        :on-success="importUpload.onSuccess"
        :on-error="importUpload.onError"
        :on-progress="importUpload.onProgress"
        :on-change="importUpload.onChange"
        :auto-upload="false"
        drag
      >
    <FormDialog v-model="importUpload.open"
                :title="importUpload.title"
                :width="'600px'"
                @close="importUpload.open = false"
                @confirm="submitImportFile"
                @cancel="importUpload.open = false">
      <el-upload ref="importUploadRef"
                 :limit="1"
                 accept=".xlsx,.xls"
                 :action="importUpload.url"
                 :headers="importUpload.headers"
                 :before-upload="importUpload.beforeUpload"
                 :on-success="importUpload.onSuccess"
                 :on-error="importUpload.onError"
                 :on-progress="importUpload.onProgress"
                 :on-change="importUpload.onChange"
                 :auto-upload="false"
                 drag>
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">
          将文件拖到此处,或<em>点击上传</em>
@@ -520,22 +560,24 @@
        <template #tip>
          <div class="el-upload__tip">
            仅支持 xls/xlsx,大小不超过 10MB。
            <el-button link type="primary" @click="downloadTemplate">下载导入模板</el-button>
            <el-button link
                       type="primary"
                       @click="downloadTemplate">下载导入模板</el-button>
          </div>
        </template>
      </el-upload>
    </FormDialog>
    <FormDialog v-model="productFormVisible"
               :title="productOperationType === 'add' ? '新增产品' : '编辑产品'"
               :width="'40%'"
               :operation-type="productOperationType"
               @close="closeProductDia"
               @confirm="submitProduct"
               @cancel="closeProductDia">
                :title="productOperationType === 'add' ? '新增产品' : '编辑产品'"
                :width="'40%'"
                :operation-type="productOperationType"
                @close="closeProductDia"
                @confirm="submitProduct"
                @cancel="closeProductDia">
      <el-form :model="productForm"
               label-width="140px"
               label-position="top"
               :rules="productRules"
               :rules="getProductRules()"
               ref="productFormRef">
        <el-row :gutter="30">
          <el-col :span="24">
@@ -579,7 +621,8 @@
          </el-col>
          <el-col :span="12">
            <el-form-item label="税率(%):"
                          prop="taxRate">
                          prop="taxRate"
                          v-if="currentSupplierType === 1">
              <el-select v-model="productForm.taxRate"
                         placeholder="请选择"
                         clearable
@@ -596,18 +639,6 @@
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="含税单价(元):"
                          prop="taxInclusiveUnitPrice">
              <el-input-number v-model="productForm.taxInclusiveUnitPrice"
                               :precision="2"
                               :step="0.1"
                               :min="0"
                               clearable
                               style="width: 100%"
                               @change="mathNum" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="数量:"
                          prop="quantity">
              <el-input-number :step="0.1"
@@ -617,14 +648,39 @@
                               style="width: 100%"
                               v-model="productForm.quantity"
                               placeholder="请输入"
                               @change="currentSupplierType === 1 ? mathNum() : mathNumPrivate()" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="含税单价(元):"
                          prop="taxInclusiveUnitPrice"
                          v-if="currentSupplierType === 1">
              <el-input-number v-model="productForm.taxInclusiveUnitPrice"
                               :precision="2"
                               :step="0.1"
                               :min="0"
                               clearable
                               style="width: 100%"
                               @change="mathNum" />
            </el-form-item>
            <el-form-item label="单价(对私):"
                          prop="unitPrice"
                          v-else>
              <el-input-number v-model="productForm.unitPrice"
                               :precision="2"
                               :step="0.1"
                               :min="0"
                               clearable
                               style="width: 100%"
                               @change="mathNumPrivate" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="含税总价(元):"
                          prop="taxInclusiveTotalPrice">
                          prop="taxInclusiveTotalPrice"
                          v-if="currentSupplierType === 1">
              <el-input-number v-model="productForm.taxInclusiveTotalPrice"
                               :precision="2"
                               :step="0.1"
@@ -633,10 +689,34 @@
                               style="width: 100%"
                               @change="reverseMathNum('taxInclusiveTotalPrice')" />
            </el-form-item>
            <el-form-item label="总价(对私):"
                          prop="totalPrice"
                          v-else>
              <el-input-number v-model="productForm.totalPrice"
                               :precision="2"
                               :step="0.1"
                               :min="0"
                               clearable
                               style="width: 100%"
                               @change="reverseMathNumPrivate('totalPrice')" />
            </el-form-item>
          </el-col>
          <el-col v-if="currentSupplierType === 2"
                  :span="12">
            <el-form-item label="库存预警数量:"
                          prop="warnNum">
              <el-input-number v-model="productForm.warnNum"
                               :precision="2"
                               :step="0.1"
                               :min="0"
                               clearable
                               style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="不含税总价(元):"
                          prop="taxExclusiveTotalPrice">
                          prop="taxExclusiveTotalPrice"
                          v-if="currentSupplierType === 1">
              <el-input-number v-model="productForm.taxExclusiveTotalPrice"
                               :precision="2"
                               :step="0.1"
@@ -650,7 +730,8 @@
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="发票类型:"
                          prop="invoiceType">
                          prop="invoiceType"
                          v-if="currentSupplierType === 1">
              <el-select v-model="productForm.invoiceType"
                         placeholder="请选择"
                         clearable>
@@ -661,7 +742,8 @@
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
          <el-col v-if="currentSupplierType === 1"
                  :span="12">
            <el-form-item label="库存预警数量:"
                          prop="warnNum">
              <el-input-number v-model="productForm.warnNum"
@@ -688,11 +770,9 @@
        </el-row>
      </el-form>
    </FormDialog>
    <FileListDialog
      ref="fileListRef"
      v-model="fileListDialogVisible"
      title="附件列表"
    />
    <FileListDialog ref="fileListRef"
                    v-model="fileListDialogVisible"
                    title="附件列表" />
  </div>
</template>
@@ -710,8 +790,8 @@
  import { Search, Delete } from "@element-plus/icons-vue";
  import { ElMessageBox, ElMessage } from "element-plus";
  import { userListNoPage } from "@/api/system/user.js";
  import FormDialog from '@/components/Dialog/FormDialog.vue';
  import FileListDialog from '@/components/Dialog/FileListDialog.vue';
  import FormDialog from "@/components/Dialog/FormDialog.vue";
  import FileListDialog from "@/components/Dialog/FileListDialog.vue";
  import {
    getSalesLedgerWithProducts,
    addOrUpdateSalesLedgerProduct,
@@ -746,6 +826,7 @@
  const salesContractList = ref([]);
  const supplierList = ref([]);
  const tableLoading = ref(false);
  const currentSupplierType = ref(null); // 跟踪当前选择的供应商类型
  const page = reactive({
    current: 1,
    size: 100,
@@ -764,11 +845,31 @@
  const addApproverNode = () => {
    approverNodes.value.push({ id: nextApproverId++, userId: null });
  };
  const removeApproverNode = (index) => {
  const removeApproverNode = index => {
    approverNodes.value.splice(index, 1);
  };
  // 订单审批状态显示文本
  // 处理供应商选择变化
  const handleSupplierChange = async supplierId => {
    const selectedSupplier = supplierList.value.find(
      item => item.id === supplierId
    );
    if (selectedSupplier) {
      // 只有当当前供应商类型不为 null 且发生变化时,才清空产品表
      // 这样在编辑时加载数据后调用该函数不会清空产品数据
      if (
        currentSupplierType.value !== null &&
        currentSupplierType.value !== selectedSupplier.supplierType
      ) {
        productData.value = [];
      }
      currentSupplierType.value = selectedSupplier.supplierType;
    } else {
      currentSupplierType.value = null;
      productData.value = [];
    }
    await getTemplateList();
  };
  const approvalStatusText = {
    1: "待审核",
    2: "审批中",
@@ -777,12 +878,12 @@
  };
  // 获取审批状态标签类型
  const getApprovalStatusType = (status) => {
  const getApprovalStatusType = status => {
    const typeMap = {
      1: "info",      // 待审核 - 灰色
      2: "warning",   // 审批中 - 橙色
      3: "success",   // 审批通过 - 绿色
      4: "danger",    // 审批失败 - 红色
      1: "info", // 待审核 - 灰色
      2: "warning", // 审批中 - 橙色
      3: "success", // 审批通过 - 绿色
      4: "danger", // 审批失败 - 红色
    };
    return typeMap[status] || "";
  };
@@ -864,7 +965,8 @@
        form.value.paymentMethod = matchedTemplate.paymentMethod;
      }
      // 模板数据中的产品字段是 productList,需要转换为 productData
      productData.value = matchedTemplate.productList || matchedTemplate.productData || [];
      productData.value =
        matchedTemplate.productList || matchedTemplate.productData || [];
    } else {
      // 未匹配到已有模板,视为新模板
      currentTemplateId.value = null;
@@ -900,6 +1002,7 @@
      entryDate: null, // 录入日期
      entryDateStart: undefined,
      entryDateEnd: undefined,
      supplierType: "", // 供应商类型
    },
    form: {
      purchaseContractNumber: "",
@@ -983,6 +1086,43 @@
    },
  });
  const { productForm, productRules } = toRefs(productFormData);
  const getProductRules = () => {
    const baseRules = {
      productId: [{ required: true, message: "请选择", trigger: "change" }],
      productModelId: [{ required: true, message: "请选择", trigger: "change" }],
      unit: [{ required: true, message: "请输入", trigger: "blur" }],
      quantity: [{ required: true, message: "请输入", trigger: "blur" }],
      warnNum: [{ required: true, message: "请选择", trigger: "change" }],
      isChecked: [{ required: true, message: "请选择", trigger: "change" }],
    };
    if (currentSupplierType.value === 1) {
      // 对公供应商需要验证的字段
      return {
        ...baseRules,
        taxInclusiveUnitPrice: [
          { required: true, message: "请输入", trigger: "blur" },
        ],
        taxRate: [{ required: true, message: "请选择", trigger: "change" }],
        taxInclusiveTotalPrice: [
          { required: true, message: "请输入", trigger: "blur" },
        ],
        taxExclusiveTotalPrice: [
          { required: true, message: "请输入", trigger: "blur" },
        ],
        invoiceType: [{ required: true, message: "请选择", trigger: "change" }],
      };
    } else if (currentSupplierType.value === 2) {
      // 对私供应商需要验证的字段
      return {
        ...baseRules,
        unitPrice: [{ required: true, message: "请输入", trigger: "blur" }],
        totalPrice: [{ required: true, message: "请输入", trigger: "blur" }],
      };
    } else {
      return baseRules;
    }
  };
  const upload = reactive({
    // 上传的地址
    url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
@@ -998,7 +1138,7 @@
    url: import.meta.env.VITE_APP_BASE_API + "/purchase/ledger/import",
    headers: { Authorization: "Bearer " + getToken() },
    isUploading: false,
    beforeUpload: (file) => {
    beforeUpload: file => {
      const isExcel = file.name.endsWith(".xlsx") || file.name.endsWith(".xls");
      const isLt10M = file.size / 1024 / 1024 < 10;
      if (!isExcel) {
@@ -1047,7 +1187,11 @@
  // 下载导入模板(如后端路径不同,可在此处调整)
  const downloadTemplate = () => {
    proxy.download("/purchase/ledger/exportTemplate", {}, "采购台账导入模板.xlsx");
    proxy.download(
      "/purchase/ledger/exportTemplate",
      {},
      "采购台账导入模板.xlsx"
    );
  };
  const submitImportFile = () => {
@@ -1112,8 +1256,8 @@
    // 检查是否有产品数据
    if (!productData.value || productData.value.length === 0) {
      ElMessage({
        message: '请先添加产品信息',
        type: 'warning',
        message: "请先添加产品信息",
        type: "warning",
      });
      return;
    }
@@ -1124,7 +1268,7 @@
        .filter(node => node.userId)
        .map(node => node.userId)
        .join(",");
      let params = {
        productData: proxy.HaveJson(productData.value),
        supplierId: form.value.supplierId,
@@ -1134,7 +1278,12 @@
        approveUserIds: approveUserIds,
        templateName: templateName.value.trim(),
      };
      console.log("template params ===>", params, "currentTemplateId:", currentTemplateId.value);
      console.log(
        "template params ===>",
        params,
        "currentTemplateId:",
        currentTemplateId.value
      );
      // 如果 currentTemplateId 有值,说明当前是“编辑已有模板” → 调用更新接口
      // 否则为“新建模板” → 调用新增接口
@@ -1145,7 +1294,10 @@
          ...params,
        });
      } else {
        res = await addPurchaseTemplate(params);
        res = await addPurchaseTemplate({
          ...params,
          templateType: currentSupplierType.value,
        });
      }
      if (res && res.code === 200) {
@@ -1177,22 +1329,34 @@
  };
  // 子表合计方法
  const summarizeChildrenTable = param => {
    return proxy.summarizeTable(
      param,
      [
    // 检查是否有数据,以及数据的供应商类型
    const hasData = param && param.data && param.data.length > 0;
    const supplierType = hasData ? param.data[0].supplierType : null;
    // 根据供应商类型确定要合计的字段
    const fields = [
      "ticketsNum",
      "ticketsAmount",
      "futureTickets",
      "futureTicketsAmount",
    ];
    if (supplierType === 1) {
      // 对公供应商
      fields.unshift(
        "taxInclusiveUnitPrice",
        "taxInclusiveTotalPrice",
        "taxExclusiveTotalPrice",
        "ticketsNum",
        "ticketsAmount",
        "futureTickets",
        "futureTicketsAmount",
      ],
      {
        ticketsNum: { noDecimal: true }, // 不保留小数
        futureTickets: { noDecimal: true }, // 不保留小数
      }
    );
        "taxExclusiveTotalPrice"
      );
    } else if (supplierType === 2) {
      // 对私供应商
      fields.unshift("unitPrice", "totalPrice");
    }
    return proxy.summarizeTable(param, fields, {
      ticketsNum: { noDecimal: true }, // 不保留小数
      futureTickets: { noDecimal: true }, // 不保留小数
    });
  };
  const paginationChange = obj => {
    page.current = obj.page;
@@ -1236,7 +1400,12 @@
        const res = await productList({ salesLedgerId: row.id, type: 2 });
        const index = tableData.value.findIndex(item => item.id === row.id);
        if (index > -1) {
          tableData.value[index].children = res.data || [];
          // 为子表格数据添加供应商类型信息
          const children = (res.data || []).map(item => ({
            ...item,
            supplierType: row.supplierType, // 从父行获取供应商类型
          }));
          tableData.value[index].children = children;
          expandedRowKeys.value.push(row.id);
        }
      } catch (error) {
@@ -1258,11 +1427,17 @@
  };
  // 子表合计方法
  const summarizeProTable = param => {
    return proxy.summarizeTable(param, [
      "taxInclusiveUnitPrice",
      "taxInclusiveTotalPrice",
      "taxExclusiveTotalPrice",
    ]);
    const fields = [];
    if (currentSupplierType.value === 1) {
      fields.push(
        "taxInclusiveUnitPrice",
        "taxInclusiveTotalPrice",
        "taxExclusiveTotalPrice"
      );
    } else if (currentSupplierType.value === 2) {
      fields.push("unitPrice", "totalPrice");
    }
    return proxy.summarizeTable(param, fields);
  };
  // 打开弹框
  const openForm = async (type, row) => {
@@ -1273,8 +1448,8 @@
        return;
      }
    }
    await getTemplateList();
    currentSupplierType.value = null;
    operationType.value = type;
    form.value = {};
    productData.value = [];
@@ -1305,6 +1480,7 @@
      form.value.entryDate = getCurrentDate();
      if (type === "add") {
        await getTemplateList();
        // 新增时生成采购合同号
        try {
          const purchaseNoRes = await createPurchaseNo();
@@ -1328,9 +1504,13 @@
            const approverIds = purchaseRes.approveUserIds.split(",");
            approverNodes.value = approverIds.map((id, index) => ({
              id: index + 1,
              userId: Number(id)
              userId: Number(id),
            }));
            nextApproverId = approverIds.length + 1;
          }
          // 设置当前供应商类型
          if (form.value.supplierId) {
            handleSupplierChange(form.value.supplierId);
          }
        } catch (error) {
          console.error("加载采购台账数据失败:", error);
@@ -1406,8 +1586,10 @@
          proxy.$modal.msgError("请为所有审批节点选择审批人!");
          return;
        }
        const approveUserIds = approverNodes.value.map(node => node.userId).join(",");
        const approveUserIds = approverNodes.value
          .map(node => node.userId)
          .join(",");
        if (productData.value.length > 0) {
          // 新增时,需要从每个产品对象中删除 id 字段
          let processedProductData = productData.value;
@@ -1436,7 +1618,10 @@
        }
        // 新增时不传递id
        const submitData = { ...form.value };
        const submitData = {
          ...form.value,
          purchaseType: currentSupplierType.value,
        };
        if (operationType.value === "add") {
          delete submitData.id;
        }
@@ -1461,20 +1646,39 @@
  const openProductForm = async (type, row, index) => {
    productOperationType.value = type;
    productOperationIndex.value = index;
    productForm.value = {};
    productForm.value = {
      productId: "",
      productCategory: "",
      productModelId: "",
      specificationModel: "",
      unit: "",
      quantity: "",
      // 对公字段
      taxInclusiveUnitPrice: "",
      taxRate: "",
      taxInclusiveTotalPrice: "",
      taxExclusiveTotalPrice: "",
      invoiceType: "",
      // 对私字段
      unitPrice: "",
      totalPrice: "",
      // 公共字段
      warnNum: "",
      isChecked: true,
    };
    proxy.resetForm("productFormRef");
    productFormVisible.value = true;
    // 先获取产品选项,确保数据加载完成
    await getProductOptions();
    // 等待 DOM 更新
    await nextTick();
    if (type === "edit") {
      // 复制行数据
      productForm.value = { ...row };
      // 如果是从模板加载的数据,可能没有 productId 和 productModelId
      // 需要根据 productCategory 和 specificationModel 来查找对应的 ID
      if (!productForm.value.productId && productForm.value.productCategory) {
@@ -1485,25 +1689,34 @@
              return nodes[i].value;
            }
            if (nodes[i].children && nodes[i].children.length > 0) {
              const found = findProductIdByCategory(nodes[i].children, categoryName);
              const found = findProductIdByCategory(
                nodes[i].children,
                categoryName
              );
              if (found) return found;
            }
          }
          return null;
        };
        const productId = findProductIdByCategory(productOptions.value, productForm.value.productCategory);
        const productId = findProductIdByCategory(
          productOptions.value,
          productForm.value.productCategory
        );
        if (productId) {
          productForm.value.productId = productId;
          // 获取型号列表并等待完成
          const modelRes = await modelList({ id: productId });
          modelOptions.value = modelRes;
          // 等待 DOM 更新
          await nextTick();
          // 根据 specificationModel 查找 productModelId
          if (productForm.value.specificationModel && modelOptions.value.length > 0) {
          if (
            productForm.value.specificationModel &&
            modelOptions.value.length > 0
          ) {
            const modelItem = modelOptions.value.find(
              item => item.model === productForm.value.specificationModel
            );
@@ -1517,15 +1730,15 @@
      } else if (productForm.value.productId) {
        // 如果有 productId,正常加载型号列表
        await getModels(productForm.value.productId);
        // 等待 DOM 更新
        await nextTick();
        if (productForm.value.productModelId) {
          getProductModel(productForm.value.productModelId);
        }
      }
      // 最后再等待一次 DOM 更新,确保所有数据都已设置
      await nextTick();
    }
@@ -1609,15 +1822,21 @@
    });
  };
  const submitProductEdit = () => {
    productForm.value.salesLedgerId = currentId.value;
    productForm.value.type = 2;
    addOrUpdateSalesLedgerProduct(productForm.value).then(res => {
      proxy.$modal.msgSuccess("提交成功");
      closeProductDia();
      getPurchaseById({ id: currentId.value, type: 2 }).then(res => {
        productData.value = res.productData;
      });
    });
    // 直接修改本地数据,不再调用接口
    if (productOperationType.value === "add") {
      // 新增产品
      productData.value.push({ ...productForm.value });
    } else if (productOperationType.value === "edit") {
      // 编辑产品
      if (
        productOperationIndex.value !== "" &&
        productOperationIndex.value !== null
      ) {
        productData.value[productOperationIndex.value] = { ...productForm.value };
      }
    }
    proxy.$modal.msgSuccess("操作成功");
    closeProductDia();
  };
  // 删除产品
  const deleteProduct = () => {
@@ -1625,40 +1844,27 @@
      proxy.$modal.msgWarning("请选择数据");
      return;
    }
    if (operationType.value === "add") {
      productSelectedRows.value.forEach(selectedRow => {
        const index = productData.value.findIndex(
          product => product.id === selectedRow.id
        );
        if (index !== -1) {
          productData.value.splice(index, 1);
        }
      });
    } else {
      let ids = [];
      if (productSelectedRows.value.length > 0) {
        ids = productSelectedRows.value.map(item => item.id);
      }
      ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          delProduct(ids).then(res => {
            proxy.$modal.msgSuccess("删除成功");
            closeProductDia();
            getSalesLedgerWithProducts({ id: currentId.value, type: 2 }).then(
              res => {
                productData.value = res.productData;
              }
            );
          });
        })
        .catch(() => {
          proxy.$modal.msg("已取消");
    // 直接从本地数据中删除,不再调用接口
    ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
        productSelectedRows.value.forEach(selectedRow => {
          const index = productData.value.findIndex(
            product => product.id === selectedRow.id
          );
          if (index !== -1) {
            productData.value.splice(index, 1);
          }
        });
    }
        proxy.$modal.msgSuccess("删除成功");
        closeProductDia();
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
  };
  // 关闭产品弹框
  const closeProductDia = () => {
@@ -1683,14 +1889,6 @@
  const handleDelete = () => {
    let ids = [];
    if (selectedRows.value.length > 0) {
      // 检查是否有他人维护的数据
      const unauthorizedData = selectedRows.value.filter(
        item => item.recorderName !== userStore.nickName
      );
      if (unauthorizedData.length > 0) {
        proxy.$modal.msgWarning("不可删除他人维护的数据");
        return;
      }
      ids = selectedRows.value.map(item => item.id);
    } else {
      proxy.$modal.msgWarning("请选择数据");
@@ -1832,6 +2030,27 @@
      }
    }
  };
  // 对私供应商的价格计算
  const mathNumPrivate = () => {
    const { unitPrice, quantity } = productForm.value;
    if (unitPrice && quantity) {
      productForm.value.totalPrice = (unitPrice * quantity).toFixed(2);
    }
  };
  // 对私供应商的反向价格计算
  const reverseMathNumPrivate = type => {
    const { unitPrice, quantity, totalPrice } = productForm.value;
    if (type === "totalPrice") {
      if (quantity) {
        productForm.value.unitPrice = (totalPrice / quantity).toFixed(2);
      } else if (unitPrice) {
        productForm.value.quantity = (totalPrice / unitPrice).toFixed(2);
      }
    }
  };
  // 销售合同选择改变方法
  const salesLedgerChange = async row => {
    console.log("row", row);
@@ -1861,19 +2080,26 @@
  // 获取模板信息
  const getTemplateList = async () => {
    let res = await getPurchaseTemplateList();
    if (res && res.code === 200 && Array.isArray(res.data)) {
      templateList.value = res.data;
    console.log("currentSupplierType.value", currentSupplierType.value);
    if (currentSupplierType.value) {
      let res = await getPurchaseTemplateList({
        templateType: currentSupplierType.value,
      });
      if (res && res.code === 200 && Array.isArray(res.data)) {
        templateList.value = res.data;
      }
    } else {
      templateList.value = [];
    }
  };
  // 删除模板
  const handleDeleteTemplate = async (item) => {
  const handleDeleteTemplate = async item => {
    if (!item.id) {
      proxy.$modal.msgWarning("无法删除该模板");
      return;
    }
    try {
      await ElMessageBox.confirm(
        `确定要删除模板"${item.templateName}"吗?`,
@@ -1884,7 +2110,7 @@
          type: "warning",
        }
      );
      const res = await delPurchaseTemplate([item.id]);
      if (res && res.code === 200) {
        ElMessage({
@@ -1937,7 +2163,7 @@
    display: flex;
    align-items: center;
  }
  // 审批人节点容器样式
  .approver-nodes-container {
    display: flex;
@@ -1948,7 +2174,7 @@
    border-radius: 4px;
    border: 1px solid #e4e7ed;
  }
  .approver-node-item {
    flex: 0 0 calc(33.333% - 12px);
    min-width: 200px;
@@ -1957,38 +2183,38 @@
    border-radius: 4px;
    border: 1px solid #dcdfe6;
    transition: all 0.3s;
    &:hover {
      border-color: #409eff;
      box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
    }
  }
  .approver-node-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 8px;
  }
  .approver-node-label {
    font-size: 13px;
    font-weight: 500;
    color: #606266;
  }
  @media (max-width: 1200px) {
    .approver-node-item {
      flex: 0 0 calc(50% - 8px);
    }
  }
  @media (max-width: 768px) {
    .approver-node-item {
      flex: 0 0 100%;
    }
  }
  // 删除图标样式
  .delete-icon {
    transition: all 0.3s;