zhangwencui
9 天以前 3b0d62ccee6666c8e87470b333a19311e49547d1
三项优化内容
已修改8个文件
2588 ■■■■■ 文件已修改
src/views/basicData/customerFile/index.vue 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/supplierManage/components/HomeTab.vue 280 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/supplierManage/index.vue 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/procurementLedger/index.vue 488 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionCosting/index.vue 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionOrder/index.vue 100 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionReporting/index.vue 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/salesLedger/index.vue 1477 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/customerFile/index.vue
@@ -15,10 +15,10 @@
                   style="width: 240px"
                   clearable
                   @change="handleQuery">
          <el-option label="零售客户"
                     value="零售客户" />
          <el-option label="进销商客户"
                     value="进销商客户" />
          <el-option label="对公"
                     value="1" />
          <el-option label="对私"
                     value="2" />
        </el-select>
        <el-button type="primary"
                   @click="handleQuery"
@@ -125,10 +125,10 @@
              <el-select v-model="form.customerType"
                         placeholder="请选择"
                         clearable>
                <el-option label="零售客户"
                           value="零售客户" />
                <el-option label="进销商客户"
                           value="进销商客户" />
                <el-option label="对公"
                           :value="1" />
                <el-option label="对私"
                           :value="2" />
              </el-select>
            </el-form-item>
          </el-col>
@@ -276,7 +276,8 @@
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitReminderForm">确认</el-button>
          <el-button type="primary"
                     @click="submitReminderForm">确认</el-button>
          <el-button @click="closeReminderDialog">取消</el-button>
        </div>
      </template>
@@ -359,7 +360,8 @@
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitNegotiationForm">确认</el-button>
          <el-button type="primary"
                     @click="submitNegotiationForm">确认</el-button>
          <el-button @click="closeNegotiationDialog">取消</el-button>
        </div>
      </template>
@@ -383,7 +385,7 @@
            <el-col :span="12">
              <div class="info-item">
                <span class="info-label">客户分类:</span>
                <span class="info-value">{{ detailForm.customerType }}</span>
                <span class="info-value">{{ detailForm.customerType==1?"对公":"对私" }}</span>
              </div>
            </el-col>
          </el-row>
@@ -713,6 +715,9 @@
      label: "客户分类",
      prop: "customerType",
      width: 120,
      formatData: params => {
        return params == 1 ? "对公" : "对私";
      },
    },
    {
      label: "客户名称",
@@ -854,20 +859,20 @@
    },
    rules: {
      customerName: [{ required: true, message: "请输入", trigger: "blur" }],
      taxpayerIdentificationNumber: [
        { required: true, message: "请输入", trigger: "blur" },
      ],
      companyAddress: [{ required: true, message: "请输入", trigger: "blur" }],
      companyPhone: [{ required: true, message: "请输入", trigger: "blur" }],
      // taxpayerIdentificationNumber: [
      //   { required: true, message: "请输入", trigger: "blur" },
      // ],
      // companyAddress: [{ required: true, message: "请输入", trigger: "blur" }],
      // companyPhone: [{ required: true, message: "请输入", trigger: "blur" }],
      // contactPerson: [{ required: true, message: "请输入", trigger: "blur" }],
      // contactPhone: [{ required: true, message: "请输入", trigger: "blur" }],
      maintainer: [{ required: false, message: "请选择", trigger: "change" }],
      maintenanceTime: [
        { required: false, message: "请选择", trigger: "change" },
      ],
      basicBankAccount: [{ required: true, message: "请输入", trigger: "blur" }],
      bankAccount: [{ required: true, message: "请输入", trigger: "blur" }],
      bankCode: [{ required: true, message: "请输入", trigger: "blur" }],
      // basicBankAccount: [{ required: true, message: "请输入", trigger: "blur" }],
      // bankAccount: [{ required: true, message: "请输入", trigger: "blur" }],
      // bankCode: [{ required: true, message: "请输入", trigger: "blur" }],
      customerType: [{ required: true, message: "请选择", trigger: "change" }],
    },
  });
src/views/basicData/supplierManage/components/HomeTab.vue
@@ -3,185 +3,172 @@
    <div class="search_form">
      <div>
        <span class="search_title">供应商档案:</span>
        <el-input
            v-model="searchForm.supplierName"
        <el-input v-model="searchForm.supplierName"
            style="width: 240px"
            placeholder="输入供应商名称搜索"
            @change="handleQuery"
            clearable
            :prefix-icon="Search"
        />
        <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
        >搜索</el-button
        >
                  :prefix-icon="Search" />
        <el-button type="primary"
                   @click="handleQuery"
                   style="margin-left: 10px">搜索</el-button>
      </div>
      <div>
        <el-button type="primary" @click="openForm('add')"
        >新增供应商</el-button
        >
        <el-button type="primary"
                   @click="openForm('add')">新增供应商</el-button>
        <el-button @click="handleOut">导出</el-button>
        <el-button type="info" plain icon="Upload" @click="handleImport"
        >导入</el-button
        >
        <el-button type="danger" plain @click="handleDelete">删除</el-button>
        <el-button type="info"
                   plain
                   icon="Upload"
                   @click="handleImport">导入</el-button>
        <el-button type="danger"
                   plain
                   @click="handleDelete">删除</el-button>
      </div>
    </div>
    <div class="table_list">
      <PIMTable
          rowKey="id"
      <PIMTable rowKey="id"
          :column="tableColumn"
          :tableData="tableData"
          :page="page"
          :isSelection="true"
          @selection-change="handleSelectionChange"
          :tableLoading="tableLoading"
          @pagination="pagination"
      ></PIMTable>
                @pagination="pagination"></PIMTable>
    </div>
    <el-dialog
        v-model="dialogFormVisible"
    <el-dialog v-model="dialogFormVisible"
        :title="operationType === 'add' ? '新增供应商信息' : '编辑供应商信息'"
        width="70%"
        @close="closeDia"
    >
      <el-form
          :model="form"
               @close="closeDia">
      <el-form :model="form"
          label-width="140px"
          label-position="top"
          :rules="rules"
          ref="formRef"
      >
               ref="formRef">
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="供应商名称:" prop="supplierName">
              <el-input
                  v-model="form.supplierName"
            <el-form-item label="供应商名称:"
                          prop="supplierName">
              <el-input v-model="form.supplierName"
                  placeholder="请输入"
                  clearable
              />
                        clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item
                label="纳税人识别号:"
                prop="taxpayerIdentificationNum"
            >
              <el-input
                  v-model="form.taxpayerIdentificationNum"
            <el-form-item label="纳税人识别号:"
                          prop="taxpayerIdentificationNum">
              <el-input v-model="form.taxpayerIdentificationNum"
                  placeholder="请输入"
                  clearable
              />
                        clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="公司地址:" prop="companyAddress">
              <el-input
                  v-model="form.companyAddress"
            <el-form-item label="公司地址:"
                          prop="companyAddress">
              <el-input v-model="form.companyAddress"
                  placeholder="请输入"
                  clearable
              />
                        clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="公司电话:" prop="companyPhone">
              <el-input
                  v-model="form.companyPhone"
            <el-form-item label="公司电话:"
                          prop="companyPhone">
              <el-input v-model="form.companyPhone"
                  placeholder="请输入"
                  clearable
              />
                        clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="开户行:" prop="bankAccountName">
              <el-input
                  v-model="form.bankAccountName"
            <el-form-item label="开户行:"
                          prop="bankAccountName">
              <el-input v-model="form.bankAccountName"
                  placeholder="请输入"
                  clearable
              />
                        clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="账号:" prop="bankAccountNum">
              <el-input
                  v-model="form.bankAccountNum"
            <el-form-item label="账号:"
                          prop="bankAccountNum">
              <el-input v-model="form.bankAccountNum"
                  placeholder="请输入"
                  clearable
              />
                        clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="联系人:" prop="contactUserName">
              <el-input
                  v-model="form.contactUserName"
            <el-form-item label="联系人:"
                          prop="contactUserName">
              <el-input v-model="form.contactUserName"
                  placeholder="请输入"
                  clearable
              />
                        clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="联系电话:" prop="contactUserPhone">
              <el-input
                  v-model="form.contactUserPhone"
            <el-form-item label="联系电话:"
                          prop="contactUserPhone">
              <el-input v-model="form.contactUserPhone"
                  placeholder="请输入"
                  clearable
              />
                        clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="维护人:" prop="maintainUserId">
              <el-select
                  v-model="form.maintainUserId"
            <el-form-item label="维护人:"
                          prop="maintainUserId">
              <el-select v-model="form.maintainUserId"
                  placeholder="请选择"
                  clearable
                  disabled
              >
                <el-option
                    v-for="item in userList"
                         disabled>
                <el-option v-for="item in userList"
                    :key="item.nickName"
                    :label="item.nickName"
                    :value="item.userId"
                />
                           :value="item.userId" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="维护时间:" prop="maintainTime">
              <el-date-picker
                  style="width: 100%"
            <el-form-item label="维护时间:"
                          prop="maintainTime">
              <el-date-picker style="width: 100%"
                  v-model="form.maintainTime"
                  value-format="YYYY-MM-DD"
                  format="YYYY-MM-DD"
                  type="date"
                  placeholder="请选择"
                  clearable
              />
                              clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="供应商类型:" prop="supplierType">
              <el-select v-model="form.supplierType" placeholder="请选择" clearable>
                <el-option label="甲" value="甲" />
                <el-option label="乙" value="乙" />
                <el-option label="丙" value="丙" />
                <el-option label="丁" value="丁" />
            <el-form-item label="供应商类型:"
                          prop="supplierType">
              <el-select v-model="form.supplierType"
                         placeholder="请选择"
                         clearable>
                <el-option label="对公"
                           :value="1" />
                <el-option label="对私"
                           :value="2" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="是否白名单:" prop="isWhite">
              <el-select v-model="form.isWhite" placeholder="请选择" clearable>
                <el-option label="是" :value="0" />
                <el-option label="否" :value="1" />
            <el-form-item label="是否白名单:"
                          prop="isWhite">
              <el-select v-model="form.isWhite"
                         placeholder="请选择"
                         clearable>
                <el-option label="是"
                           :value="0" />
                <el-option label="否"
                           :value="1" />
              </el-select>
            </el-form-item>
          </el-col>
@@ -189,21 +176,18 @@
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确认</el-button>
          <el-button type="primary"
                     @click="submitForm">确认</el-button>
          <el-button @click="closeDia">取消</el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 供应商导入对话框 -->
    <el-dialog
        :title="upload.title"
    <el-dialog :title="upload.title"
        v-model="upload.open"
        width="400px"
        append-to-body
    >
      <el-upload
          ref="uploadRef"
               append-to-body>
      <el-upload ref="uploadRef"
          :limit="1"
          accept=".xlsx, .xls"
          :headers="upload.headers"
@@ -213,26 +197,23 @@
          :on-success="handleFileSuccess"
          :on-error="handleFileError"
          :auto-upload="false"
          drag
      >
                 drag>
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
        <template #tip>
          <div class="el-upload__tip text-center">
            <span>仅允许导入xls、xlsx格式文件。</span>
            <el-link
                type="primary"
            <el-link type="primary"
                :underline="false"
                style="font-size: 12px; vertical-align: baseline"
                @click="importTemplate"
            >下载模板</el-link
            >
                     @click="importTemplate">下载模板</el-link>
          </div>
        </template>
      </el-upload>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitFileForm">确 定</el-button>
          <el-button type="primary"
                     @click="submitFileForm">确 定</el-button>
          <el-button @click="upload.open = false">取 消</el-button>
        </div>
      </template>
@@ -269,6 +250,9 @@
    label: "供应商类型",
    prop: "supplierType",
    width: 120,
      formatData: params => {
        return params == 1 ? "对公" : "对私";
      },
  },
  {
    label: "纳税人识别号",
@@ -283,7 +267,7 @@
  {
    label: "联系方式",
    prop: "companyPhone",
    width:150
      width: 150,
  },
  {
    label: "开户行",
@@ -312,19 +296,19 @@
  {
    label: "维护时间",
    prop: "maintainTime",
    width:100
      width: 100,
  },
  {
    dataType: "action",
    label: "操作",
    align: "center",
    fixed: 'right',
      fixed: "right",
    width: 150,
    operation: [
      {
        name: "编辑",
        type: "text",
        clickFun: (row) => {
          clickFun: row => {
          openForm("edit", row);
        },
      },
@@ -332,10 +316,10 @@
        //资质附件
        name: "资质文件",
        type: "text",
        clickFun: (row) => {
          openFilesFormDia(row)
        }
      }
          clickFun: row => {
            openFilesFormDia(row);
          },
        },
    ],
  },
]);
@@ -348,7 +332,7 @@
  size: 100,
  total: 0,
});
const filesDia = ref()
  const filesDia = ref();
// 用户信息表单弹框数据
const operationType = ref("");
const dialogFormVisible = ref(false);
@@ -372,18 +356,20 @@
  },
  rules: {
    supplierName: [{ required: true, message: "请输入", trigger: "blur" }],
    taxpayerIdentificationNum: [
      { required: true, message: "请输入", trigger: "blur" },
    ],
    companyAddress: [{ required: true, message: "请输入", trigger: "blur" }],
    companyPhone: [{ required: true, message: "请输入", trigger: "blur" }],
    bankAccountName: [{ required: true, message: "请输入", trigger: "blur" }],
    bankAccountNum: [{ required: true, message: "请输入", trigger: "blur" }],
      // taxpayerIdentificationNum: [
      //   { required: true, message: "请输入", trigger: "blur" },
      // ],
      // companyAddress: [{ required: true, message: "请输入", trigger: "blur" }],
      // companyPhone: [{ required: true, message: "请输入", trigger: "blur" }],
      // bankAccountName: [{ required: true, message: "请输入", trigger: "blur" }],
      // bankAccountNum: [{ required: true, message: "请输入", trigger: "blur" }],
    contactUserName: [{ required: false, message: "请输入", trigger: "blur" }],
    contactUserPhone: [{ required: false, message: "请输入", trigger: "blur" }],
    maintainUserId: [{ required: false, message: "请选择", trigger: "change" }],
    maintainTime: [{ required: false, message: "请选择", trigger: "change" }],
    supplierType: [{ required: true, message: "请选择供应商类型", trigger: "change" }],
      supplierType: [
        { required: true, message: "请选择供应商类型", trigger: "change" },
      ],
  },
});
const { searchForm, form, rules } = toRefs(data);
@@ -394,7 +380,7 @@
  page.current = 1;
  getList();
};
const pagination = (obj) => {
  const pagination = obj => {
  page.current = obj.page;
  page.size = obj.limit;
  getList();
@@ -406,7 +392,7 @@
}
const getList = () => {
  tableLoading.value = true;
  listSupplier({ ...searchForm.value, ...page, isWhite: 0 }).then((res) => {
    listSupplier({ ...searchForm.value, ...page, isWhite: 0 }).then(res => {
    tableLoading.value = false;
    tableData.value = res.data.records;
    page.total = res.data.total;
@@ -433,7 +419,11 @@
}
/** 下载模板 */
function importTemplate() {
  proxy.download("/system/supplier/downloadTemplate", {}, "供应商导入模板.xlsx");
    proxy.download(
      "/system/supplier/downloadTemplate",
      {},
      "供应商导入模板.xlsx"
    );
}
/**文件上传中处理 */
@@ -462,7 +452,7 @@
  proxy.$modal.msgError("文件上传失败");
};
// 表格选择数据
const handleSelectionChange = (selection) => {
  const handleSelectionChange = selection => {
  selectedRows.value = selection;
};
// 打开弹框
@@ -471,11 +461,11 @@
  form.value = {};
  form.value.maintainUserId = userStore.id;
  form.value.maintainTime = getCurrentDate();
  userListNoPage().then((res) => {
    userListNoPage().then(res => {
    userList.value = res.data;
  });
  if (type === "edit") {
    getSupplier(row.id).then((res) => {
      getSupplier(row.id).then(res => {
      form.value = { ...res.data };
    });
  }
@@ -483,7 +473,7 @@
};
// 提交表单
const submitForm = () => {
  proxy.$refs["formRef"].validate((valid) => {
    proxy.$refs["formRef"].validate(valid => {
    if (valid) {
      if (operationType.value === "edit") {
        submitEdit();
@@ -495,7 +485,7 @@
};
// 提交新增
const submitAdd = () => {
  addSupplier(form.value).then((res) => {
    addSupplier(form.value).then(res => {
    proxy.$modal.msgSuccess("提交成功");
    closeDia();
    getList();
@@ -503,7 +493,7 @@
};
// 提交修改
const submitEdit = () => {
  updateSupplier(form.value).then((res) => {
    updateSupplier(form.value).then(res => {
    proxy.$modal.msgSuccess("提交成功");
    closeDia();
    getList();
@@ -522,7 +512,11 @@
    type: "warning",
  })
      .then(() => {
        proxy.download("/system/supplier/export", { isWhite: 0 }, "供应商档案.xlsx");
        proxy.download(
          "/system/supplier/export",
          { isWhite: 0 },
          "供应商档案.xlsx"
        );
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
@@ -533,12 +527,14 @@
  let ids = [];
  if (selectedRows.value.length > 0) {
    // 检查是否有他人维护的数据
    const unauthorizedData = selectedRows.value.filter(item => item.maintainUserName !== userStore.nickName);
      const unauthorizedData = selectedRows.value.filter(
        item => item.maintainUserName !== userStore.nickName
      );
    if (unauthorizedData.length > 0) {
      proxy.$modal.msgWarning("不可删除他人维护的数据");
      return;
    }
    ids = selectedRows.value.map((item) => item.id);
      ids = selectedRows.value.map(item => item.id);
  } else {
    proxy.$modal.msgWarning("请选择数据");
    return;
@@ -551,7 +547,7 @@
      .then(() => {
        tableLoading.value = true;
        delSupplier(ids)
            .then((res) => {
          .then(res => {
              proxy.$modal.msgSuccess("删除成功");
              getList();
            })
@@ -573,10 +569,10 @@
  return `${year}-${month}-${day}`;
}
// 打开附件弹框
const openFilesFormDia = (row) => {
  const openFilesFormDia = row => {
  nextTick(() => {
    filesDia.value?.openDialog(row)
  })
      filesDia.value?.openDialog(row);
    });
};
onMounted(() => {
src/views/basicData/supplierManage/index.vue
@@ -1,11 +1,14 @@
<!-- 在你的主页面中 -->
<template>
  <div class="app-container">
    <el-tabs v-model="activeTab" @tab-change="handleTabChange">
      <el-tab-pane label="正常供应商" name="home">
    <el-tabs v-model="activeTab"
             @tab-change="handleTabChange">
      <el-tab-pane label="正常供应商"
                   name="home">
        <HomeTab ref="homeTab" />
      </el-tab-pane>
      <el-tab-pane label="黑名单" name="blacklist">
      <el-tab-pane label="黑名单"
                   name="blacklist">
        <BlacklistTab ref="blacklistTab" />
      </el-tab-pane>
    </el-tabs>
@@ -13,31 +16,35 @@
</template>
<script>
import HomeTab from './components/HomeTab.vue'
import BlacklistTab from './components/BlacklistTab.vue'
  import HomeTab from "./components/HomeTab.vue";
  import BlacklistTab from "./components/BlacklistTab.vue";
export default {
  name: 'MainPage',
    name: "MainPage",
  components: {
    HomeTab,
    BlacklistTab
      BlacklistTab,
  },
  data() {
    return {
      activeTab: 'home'
    }
        activeTab: "home",
      };
  },
  methods: {
    handleTabChange(tabName) {
      this.activeTab = tabName
        this.activeTab = tabName;
      this.$nextTick(() => {
        if (tabName === 'home') {
          this.$refs.homeTab && this.$refs.homeTab.getList && this.$refs.homeTab.getList()
        } else if (tabName === 'blacklist') {
          this.$refs.blacklistTab && this.$refs.blacklistTab.getList && this.$refs.blacklistTab.getList()
          if (tabName === "home") {
            this.$refs.homeTab &&
              this.$refs.homeTab.getList &&
              this.$refs.homeTab.getList();
          } else if (tabName === "blacklist") {
            this.$refs.blacklistTab &&
              this.$refs.blacklistTab.getList &&
              this.$refs.blacklistTab.getList();
        }
      })
        });
    },
  }
}
    },
  };
</script>
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
@@ -94,18 +108,29 @@
                               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>
@@ -125,6 +150,14 @@
                         prop="supplierName"
                          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"
@@ -134,8 +167,7 @@
                         width="100"
                         show-overflow-tooltip>
          <template #default="scope">
            <el-tag
              :type="getApprovalStatusType(scope.row.approvalStatus)"
            <el-tag :type="getApprovalStatusType(scope.row.approvalStatus)"
              size="small">
              {{ approvalStatusText[scope.row.approvalStatus] || '未知状态' }}
            </el-tag>
@@ -232,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>
@@ -304,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"
                <div v-for="(node, index) in approverNodes"
                  :key="node.id"
                  class="approver-node-item"
                >
                     class="approver-node-item">
                  <div class="approver-node-header">
                    <span class="approver-node-label">审批节点 {{ index + 1 }}</span>
                    <el-button
                      v-if="approverNodes.length > 1"
                    <el-button v-if="approverNodes.length > 1"
                      type="danger"
                      size="small"
                      text
                      @click="removeApproverNode(index)"
                      icon="Delete"
                    >删除</el-button>
                               icon="Delete">删除</el-button>
                  </div>
                  <el-select
                    v-model="node.userId"
                  <el-select v-model="node.userId"
                    placeholder="请选择审批人"
                    filterable
                    style="width: 100%;"
                  >
                    <el-option
                      v-for="user in userList"
                             style="width: 100%;">
                    <el-option v-for="user in userList"
                      :key="user.userId"
                      :label="user.nickName"
                      :value="user.userId"
                    />
                               :value="user.userId" />
                  </el-select>
                </div>
              </div>
@@ -346,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"
@@ -373,8 +402,7 @@
                         :value="item.templateName">
                <div style="display: flex; justify-content: space-between; align-items: center;">
                  <span>{{ item.templateName }}</span>
                  <el-icon
                    v-if="item.id"
                  <el-icon v-if="item.id"
                    class="delete-icon"
                    @click.stop="handleDeleteTemplate(item)"
                    style="cursor: pointer; color: #f56c6c; font-size: 14px; margin-left: 8px;">
@@ -420,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">
@@ -493,16 +535,13 @@
      </el-form>
    </FormDialog>
    <!-- 导入弹窗 -->
    <FormDialog
      v-model="importUpload.open"
    <FormDialog v-model="importUpload.open"
      :title="importUpload.title"
      :width="'600px'"
      @close="importUpload.open = false"
      @confirm="submitImportFile"
      @cancel="importUpload.open = false"
    >
      <el-upload
        ref="importUploadRef"
                @cancel="importUpload.open = false">
      <el-upload ref="importUploadRef"
        :limit="1"
        accept=".xlsx,.xls"
        :action="importUpload.url"
@@ -513,8 +552,7 @@
        :on-progress="importUpload.onProgress"
        :on-change="importUpload.onChange"
        :auto-upload="false"
        drag
      >
                 drag>
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">
          将文件拖到此处,或<em>点击上传</em>
@@ -522,7 +560,9 @@
        <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>
@@ -537,7 +577,7 @@
      <el-form :model="productForm"
               label-width="140px"
               label-position="top"
               :rules="productRules"
               :rules="getProductRules()"
               ref="productFormRef">
        <el-row :gutter="30">
          <el-col :span="24">
@@ -581,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
@@ -598,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"
@@ -619,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"
@@ -635,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"
@@ -652,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>
@@ -663,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"
@@ -690,11 +770,9 @@
        </el-row>
      </el-form>
    </FormDialog>
    <FileListDialog
      ref="fileListRef"
    <FileListDialog ref="fileListRef"
      v-model="fileListDialogVisible"
      title="附件列表"
    />
                    title="附件列表" />
  </div>
</template>
@@ -712,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,
@@ -748,6 +826,7 @@
  const salesContractList = ref([]);
  const supplierList = ref([]);
  const tableLoading = ref(false);
  const currentSupplierType = ref(null); // 跟踪当前选择的供应商类型
  const page = reactive({
    current: 1,
    size: 100,
@@ -766,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: "审批中",
@@ -779,7 +878,7 @@
  };
  // 获取审批状态标签类型
  const getApprovalStatusType = (status) => {
  const getApprovalStatusType = status => {
    const typeMap = {
      1: "info",      // 待审核 - 灰色
      2: "warning",   // 审批中 - 橙色
@@ -866,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;
@@ -902,6 +1002,7 @@
      entryDate: null, // 录入日期
      entryDateStart: undefined,
      entryDateEnd: undefined,
      supplierType: "", // 供应商类型
    },
    form: {
      purchaseContractNumber: "",
@@ -985,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",
@@ -1000,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) {
@@ -1049,7 +1187,11 @@
  // 下载导入模板(如后端路径不同,可在此处调整)
  const downloadTemplate = () => {
    proxy.download("/purchase/ledger/exportTemplate", {}, "采购台账导入模板.xlsx");
    proxy.download(
      "/purchase/ledger/exportTemplate",
      {},
      "采购台账导入模板.xlsx"
    );
  };
  const submitImportFile = () => {
@@ -1114,8 +1256,8 @@
    // 检查是否有产品数据
    if (!productData.value || productData.value.length === 0) {
      ElMessage({
        message: '请先添加产品信息',
        type: 'warning',
        message: "请先添加产品信息",
        type: "warning",
      });
      return;
    }
@@ -1136,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 有值,说明当前是“编辑已有模板” → 调用更新接口
      // 否则为“新建模板” → 调用新增接口
@@ -1147,7 +1294,10 @@
          ...params,
        });
      } else {
        res = await addPurchaseTemplate(params);
        res = await addPurchaseTemplate({
          ...params,
          templateType: currentSupplierType.value,
        });
      }
      if (res && res.code === 200) {
@@ -1179,22 +1329,34 @@
  };
  // 子表合计方法
  const summarizeChildrenTable = param => {
    return proxy.summarizeTable(
      param,
      [
        "taxInclusiveUnitPrice",
        "taxInclusiveTotalPrice",
        "taxExclusiveTotalPrice",
    // 检查是否有数据,以及数据的供应商类型
    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"
      );
    } 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;
@@ -1238,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) {
@@ -1260,11 +1427,17 @@
  };
  // 子表合计方法
  const summarizeProTable = param => {
    return proxy.summarizeTable(param, [
    const fields = [];
    if (currentSupplierType.value === 1) {
      fields.push(
      "taxInclusiveUnitPrice",
      "taxInclusiveTotalPrice",
      "taxExclusiveTotalPrice",
    ]);
        "taxExclusiveTotalPrice"
      );
    } else if (currentSupplierType.value === 2) {
      fields.push("unitPrice", "totalPrice");
    }
    return proxy.summarizeTable(param, fields);
  };
  // 打开弹框
  const openForm = async (type, row) => {
@@ -1275,8 +1448,8 @@
        return;
      }
    }
    currentSupplierType.value = null;
    
    await getTemplateList();
    operationType.value = type;
    form.value = {};
    productData.value = [];
@@ -1307,6 +1480,7 @@
      form.value.entryDate = getCurrentDate();
      if (type === "add") {
        await getTemplateList();
        // 新增时生成采购合同号
        try {
          const purchaseNoRes = await createPurchaseNo();
@@ -1330,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);
@@ -1408,7 +1586,9 @@
          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 字段
@@ -1438,7 +1618,10 @@
        }
        // 新增时不传递id
        const submitData = { ...form.value };
        const submitData = {
          ...form.value,
          purchaseType: currentSupplierType.value,
        };
        if (operationType.value === "add") {
          delete submitData.id;
        }
@@ -1463,7 +1646,26 @@
  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;
    
@@ -1487,14 +1689,20 @@
              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;
          // 获取型号列表并等待完成
@@ -1505,7 +1713,10 @@
          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
            );
@@ -1611,15 +1822,21 @@
    });
  };
  const submitProductEdit = () => {
    productForm.value.salesLedgerId = currentId.value;
    productForm.value.type = 2;
    addOrUpdateSalesLedgerProduct(productForm.value).then(res => {
      proxy.$modal.msgSuccess("提交成功");
    // 直接修改本地数据,不再调用接口
    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();
      getPurchaseById({ id: currentId.value, type: 2 }).then(res => {
        productData.value = res.productData;
      });
    });
  };
  // 删除产品
  const deleteProduct = () => {
@@ -1627,7 +1844,13 @@
      proxy.$modal.msgWarning("请选择数据");
      return;
    }
    if (operationType.value === "add") {
    // 直接从本地数据中删除,不再调用接口
    ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
      productSelectedRows.value.forEach(selectedRow => {
        const index = productData.value.findIndex(
          product => product.id === selectedRow.id
@@ -1636,31 +1859,12 @@
          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();
            getPurchaseById({ id: currentId.value, type: 2 }).then(
              res => {
                productData.value = res.productData;
              }
            );
          });
        })
        .catch(() => {
          proxy.$modal.msg("已取消");
        });
    }
  };
  // 关闭产品弹框
  const closeProductDia = () => {
@@ -1826,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);
@@ -1855,14 +2080,21 @@
  // 获取模板信息
  const getTemplateList = async () => {
    let res = await getPurchaseTemplateList();
    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;
src/views/productionManagement/productionCosting/index.vue
@@ -1,21 +1,29 @@
<template>
    <div class="app-container">
        <el-row :gutter="16" class="content-row">
    <el-row :gutter="16"
            class="content-row">
            <!-- 左侧台账 + 顶部筛选 -->
            <el-col :xs="24" :sm="24" :md="24" :lg="8" :xl="8" class="left-col">
      <el-col :xs="24"
              :sm="24"
              :md="24"
              :lg="8"
              :xl="8"
              class="left-col">
                <div class="left-panel">
                <div class="left-header">
          <el-form :model="searchForm" inline>
            <el-form :model="searchForm"
                     inline>
            <el-form-item prop="dateType">
              <el-radio-group v-model="searchForm.dateType" size="small" @change="handleDateTypeChange">
                <el-radio-group v-model="searchForm.dateType"
                                size="small"
                                @change="handleDateTypeChange">
                <el-radio-button label="day">日</el-radio-button>
                <el-radio-button label="month">月</el-radio-button>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="日期:" prop="dateRange">
              <el-date-picker
                  v-model="searchForm.dateRange"
              <el-form-item label="日期:"
                            prop="dateRange">
                <el-date-picker v-model="searchForm.dateRange"
                  :type="searchForm.dateType === 'day' ? 'date' : 'daterange'"
                  range-separator="至"
                  start-placeholder="开始日期"
@@ -23,41 +31,40 @@
                  format="YYYY-MM-DD"
                  value-format="YYYY-MM-DD"
                  style="width: 200px"
                  @change="handleDateRangeChange"
              />
                                @change="handleDateRangeChange" />
            </el-form-item>
          </el-form>
                </div>
                <PIMTable
                    rowKey="id"
          <PIMTable rowKey="id"
                    :column="leftTableColumn"
                    :tableData="leftTableData"
                    :tableLoading="tableLoading"
          :page="page"
          @row-click="handleLeftRowClick"
          @pagination="pagination"
        ></PIMTable>
                    @pagination="pagination"></PIMTable>
                </div>
            </el-col>
            <!-- 右侧明细 -->
            <el-col :xs="24" :sm="24" :md="24" :lg="16" :xl="16" class="right-col">
      <el-col :xs="24"
              :sm="24"
              :md="24"
              :lg="16"
              :xl="16"
              class="right-col">
                <div class="right-panel">
                    <el-form inline>
                        <el-form-item>
                            <el-button type="primary" @click="handleOut">导出</el-button>
              <el-button type="primary"
                         @click="handleOut">导出</el-button>
                        </el-form-item>
                    </el-form>
                    <PIMTable
                        rowKey="id"
          <PIMTable rowKey="id"
                        :column="tableColumn"
                        :tableData="tableData"
                        :page="page1"
                        :tableLoading="tableLoading1"
                        style="margin-right: 20px;"
                        @pagination="pagination1"
                    ></PIMTable>
                    @pagination="pagination1"></PIMTable>
                </div>
            </el-col>
        </el-row>
@@ -68,7 +75,10 @@
import {onMounted, ref} from "vue";
import { ElMessageBox } from "element-plus";
import dayjs from "dayjs";
import {salesLedgerProductionAccountingListProductionDetails, salesLedgerProductionAccountingList} from "@/api/productionManagement/productionCosting.js";
  import {
    salesLedgerProductionAccountingListProductionDetails,
    salesLedgerProductionAccountingList,
  } from "@/api/productionManagement/productionCosting.js";
const { proxy } = getCurrentInstance();
const tableColumn = ref([
@@ -82,16 +92,16 @@
        prop: "schedulingUserName",
    minWidth: 100,
    },
    {
        label: "合同号",
        prop: "salesContractNo",
    minWidth: 100,
    },
    {
        label: "客户名称",
        prop: "customerName",
    minWidth: 100,
    },
    // {
    //     label: "合同号",
    //     prop: "salesContractNo",
    //   minWidth: 100,
    // },
    // {
    //     label: "客户名称",
    //     prop: "customerName",
    //   minWidth: 100,
    // },
    {
        label: "产品大类",
        prop: "productName",
@@ -140,21 +150,19 @@
        label: "产量",
        prop: "outputNum",
    minWidth: 100,
  },
    {
        label: "工资",
        prop: "wages",
    minWidth: 100,
    },
    {
        label: "合格率",
        prop: "outputRate",
    minWidth: 100,
    formatData: (val) => {
      if (val == null || val === '') return '-'
      return parseFloat(val).toFixed(2)
      formatData: val => {
        if (val == null || val === "") return "-";
        return parseFloat(val).toFixed(2);
    },
    },
]);
@@ -189,19 +197,19 @@
});
const { searchForm } = toRefs(data);
const pagination = (obj) => {
  const pagination = obj => {
    page.current = obj.page;
    page.size = obj.limit;
    getList();
};
const pagination1 = (obj) => {
  const pagination1 = obj => {
  page1.current = obj.page;
  page1.size = obj.limit;
    getList1();
};
const handleDateRangeChange = (value) => {
  const handleDateRangeChange = value => {
    if (value) {
    if (searchForm.value.dateType === "day") {
      searchForm.value.entryDate = value;
@@ -209,46 +217,46 @@
      searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
      searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
    }
    } else {
        searchForm.value.entryDate = undefined;
        searchForm.value.entryDateStart = undefined;
        searchForm.value.entryDateEnd = undefined;
    }
  reloadData()
    reloadData();
};
const getList = () => {
    tableLoading.value = true;
    const params = { ...searchForm.value, ...page };
  salesLedgerProductionAccountingList(params).then((res) => {
    salesLedgerProductionAccountingList(params)
      .then(res => {
        const records = res.data.records || [];
    leftTableData.value = records;
        page.total = res.data.total || 0;
    }).finally(() => {
    tableLoading.value = false;
  })
      .finally(() => {
        tableLoading.value = false;
      });
};
const getList1 = () => {
  tableLoading1.value = true;
  const params = { ...page1, ...searchForm.value };
  salesLedgerProductionAccountingListProductionDetails(params).then((res) => {
    tableData.value = res.data.records || [];;
    salesLedgerProductionAccountingListProductionDetails(params)
      .then(res => {
        tableData.value = res.data.records || [];
    page1.total = res.data.total || 0;
  }).finally(() => {
    tableLoading1.value = false;
  })
      .finally(() => {
        tableLoading1.value = false;
      });
};
// 构建左侧汇总台账(按生产人汇总产量、工资等)
const buildLeftTableData = (records) => {
  const buildLeftTableData = records => {
    const map = {};
    records.forEach((item) => {
    records.forEach(item => {
        const key = item.schedulingUserName || "未知";
        if (!map[key]) {
            map[key] = {
@@ -269,29 +277,34 @@
};
// 左侧日/月切换
const handleDateTypeChange = (value) => {
  const handleDateTypeChange = value => {
    // 这里只作为筛选条件的一部分,直接重新查询列表
  if (value === "day") {
    searchForm.value.entryDate = dayjs().format("YYYY-MM-DD");
    searchForm.value.dateRange = searchForm.value.entryDate
      searchForm.value.dateRange = searchForm.value.entryDate;
  } else {
    searchForm.value.entryDateStart = dayjs().startOf("month").format("YYYY-MM-DD");
      searchForm.value.entryDateStart = dayjs()
        .startOf("month")
        .format("YYYY-MM-DD");
    searchForm.value.entryDateEnd = dayjs().endOf("month").format("YYYY-MM-DD");
    searchForm.value.dateRange = [searchForm.value.entryDateStart, searchForm.value.entryDateEnd]
      searchForm.value.dateRange = [
        searchForm.value.entryDateStart,
        searchForm.value.entryDateEnd,
      ];
  }
  reloadData()
    reloadData();
};
const reloadData = () => {
  page.current = 1;
  page1.current = 1;
  getList();
  tableData.value = []
}
    tableData.value = [];
  };
// 点击左侧行,刷右侧明细(按生产人过滤)
const handleLeftRowClick = (row) => {
  const handleLeftRowClick = row => {
    searchForm.value.schedulingUserName = row.schedulingUserName || "";
    handleQuery();
};
@@ -303,7 +316,6 @@
  getList1();
};
// 导出
const handleOut = () => {
    ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
@@ -312,7 +324,11 @@
        type: "warning",
    })
        .then(() => {
            proxy.download("/salesLedger/productionAccounting/export", {}, "生产核算.xlsx");
        proxy.download(
          "/salesLedger/productionAccounting/export",
          {},
          "生产核算.xlsx"
        );
        })
        .catch(() => {
            proxy.$modal.msg("已取消");
src/views/productionManagement/productionOrder/index.vue
@@ -11,14 +11,14 @@
                    style="width: 160px;"
                    @change="handleQuery" />
        </el-form-item>
        <el-form-item label="合同号:">
        <!-- <el-form-item label="合同号:">
          <el-input v-model="searchForm.salesContractNo"
                    placeholder="请输入"
                    clearable
                    prefix-icon="Search"
                    style="width: 160px;"
                    @change="handleQuery" />
        </el-form-item>
        </el-form-item> -->
        <el-form-item label="产品名称:">
          <el-input v-model="searchForm.productCategory"
                    placeholder="请输入"
@@ -41,8 +41,10 @@
        </el-form-item>
      </el-form>
      <div>
        <el-button type="primary" @click="isShowNewModal = true">新增</el-button>
        <el-button type="danger" @click="handleDelete">删除</el-button>
        <el-button type="primary"
                   @click="isShowNewModal = true">新增</el-button>
        <el-button type="danger"
                   @click="handleDelete">删除</el-button>
        <el-button @click="handleOut">导出</el-button>
      </div>
    </div>
@@ -57,11 +59,9 @@
                @selection-change="handleSelectionChange"
                @pagination="pagination">
        <template #completionStatus="{ row }">
          <el-progress
            :percentage="toProgressPercentage(row?.completionStatus)"
          <el-progress :percentage="toProgressPercentage(row?.completionStatus)"
            :color="progressColor(toProgressPercentage(row?.completionStatus))"
            :status="toProgressPercentage(row?.completionStatus) >= 100 ? 'success' : ''"
          />
                       :status="toProgressPercentage(row?.completionStatus) >= 100 ? 'success' : ''" />
        </template>
      </PIMTable>
    </div>
@@ -90,7 +90,6 @@
        </span>
      </template>
    </el-dialog>
    <new-product-order v-if="isShowNewModal"
                         v-model:visible="isShowNewModal"
                         @completed="handleQuery" />
@@ -106,12 +105,15 @@
    productOrderListPage,
    listProcessRoute,
    bindingRoute,
    listProcessBom, delProductOrder,
    listProcessBom,
    delProductOrder,
  } from "@/api/productionManagement/productionOrder.js";
  import { listMain as getOrderProcessRouteMain } from "@/api/productionManagement/productProcessRoute.js";
  import {fileDel} from "@/api/financialManagement/revenueManagement.js";
  import PIMTable from "@/components/PIMTable/PIMTable.vue";
  const NewProductOrder = defineAsyncComponent(() => import("@/views/productionManagement/productionOrder/New.vue"));
  const NewProductOrder = defineAsyncComponent(() =>
    import("@/views/productionManagement/productionOrder/New.vue")
  );
  const { proxy } = getCurrentInstance();
@@ -122,32 +124,32 @@
    {
      label: "生产订单号",
      prop: "npsNo",
      width: '120px',
      width: "120px",
    },
    {
      label: "销售合同号",
      prop: "salesContractNo",
      width: '150px',
    },
    {
      label: "客户名称",
      prop: "customerName",
      width: '200px',
    },
    // {
    //   label: "销售合同号",
    //   prop: "salesContractNo",
    //   width: "150px",
    // },
    // {
    //   label: "客户名称",
    //   prop: "customerName",
    //   width: "200px",
    // },
    {
      label: "产品名称",
      prop: "productCategory",
      width: '120px',
      width: "120px",
    },
    {
      label: "规格",
      prop: "specificationModel",
      width: '120px',
      width: "120px",
    },
    {
      label: "工艺路线编号",
      prop: "processRouteCode",
      width: '200px',
      width: "200px",
    },
    {
      label: "需求数量",
@@ -176,12 +178,12 @@
      formatData: val => (val ? dayjs(val).format("YYYY-MM-DD") : ""),
      width: 120,
    },
    {
      label: "交付日期",
      prop: "deliveryDate",
      formatData: val => (val ? dayjs(val).format("YYYY-MM-DD") : ""),
      width: 120,
    },
    // {
    //   label: "交付日期",
    //   prop: "deliveryDate",
    //   formatData: val => (val ? dayjs(val).format("YYYY-MM-DD") : ""),
    //   width: 120,
    // },
    {
      dataType: "action",
      label: "操作",
@@ -253,18 +255,18 @@
  // 添加表行类名方法
  const tableRowClassName = ({ row }) => {
    if (!row.deliveryDate) return '';
    if (row.isFh) return '';
    if (!row.deliveryDate) return "";
    if (row.isFh) return "";
    const diff = row.deliveryDaysDiff;
    if (diff === 15) {
      return 'yellow';
      return "yellow";
    } else if (diff === 10) {
      return 'pink';
      return "pink";
    } else if (diff === 2) {
      return 'purple';
      return "purple";
    } else if (diff < 2) {
      return 'red';
      return "red";
    }
  };
@@ -402,14 +404,14 @@
  };
  // 表格选择数据
  const handleSelectionChange = (selection) => {
  const handleSelectionChange = selection => {
    selectedRows.value = selection;
  };
  const handleDelete = () => {
    let ids = [];
    if (selectedRows.value.length > 0) {
      ids = selectedRows.value.map((item) => item.id);
      ids = selectedRows.value.map(item => item.id);
    } else {
      proxy.$modal.msgWarning("请选择数据");
      return;
@@ -418,12 +420,14 @@
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    }).then(() => {
      delProductOrder(ids).then((res) => {
    })
      .then(() => {
        delProductOrder(ids).then(res => {
        proxy.$modal.msgSuccess("删除成功");
        getList();
      });
    }).catch(() => {
      })
      .catch(() => {
      proxy.$modal.msg("已取消");
    });
  };
@@ -436,7 +440,11 @@
      type: "warning",
    })
      .then(() => {
        proxy.download("/productOrder/export", {...searchForm.value}, "生产订单.xlsx");
        proxy.download(
          "/productOrder/export",
          { ...searchForm.value },
          "生产订单.xlsx"
        );
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
@@ -456,11 +464,11 @@
}
::v-deep .yellow {
  background-color: #FAF0DE;
    background-color: #faf0de;
}
::v-deep .pink {
  background-color: #FAE1DE;
    background-color: #fae1de;
}
::v-deep .red {
@@ -468,6 +476,6 @@
}
::v-deep .purple{
  background-color: #F4DEFA;
    background-color: #f4defa;
}
</style>
src/views/productionManagement/productionReporting/index.vue
@@ -99,8 +99,7 @@
                                style="width: 100%" />
              </template>
            </el-table-column>
            <el-table-column label="操作"
                             >
            <el-table-column label="操作">
              <template #default="scope">
                <el-button link
                           type="primary"
@@ -172,11 +171,11 @@
      prop: "workOrderNo",
      width: 120,
    },
    {
      label: "销售合同号",
      prop: "salesContractNo",
      width: 120,
    },
    // {
    //   label: "销售合同号",
    //   prop: "salesContractNo",
    //   width: 120,
    // },
    {
      label: "产品名称",
      prop: "productName",
src/views/salesManagement/salesLedger/index.vue
@@ -1,25 +1,53 @@
<template>
  <div class="app-container">
    <div class="search_form">
      <el-form :model="searchForm" :inline="true">
      <el-form :model="searchForm"
               :inline="true">
        <el-form-item label="客户名称:">
          <el-input v-model="searchForm.customerName" placeholder="请输入" clearable prefix-icon="Search"
          <el-input v-model="searchForm.customerName"
                    placeholder="请输入"
                    clearable
                    prefix-icon="Search"
            @change="handleQuery" />
        </el-form-item>
        <el-form-item label="销售合同号:">
          <el-input v-model="searchForm.salesContractNo" placeholder="请输入" clearable prefix-icon="Search"
          <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="请输入" clearable prefix-icon="Search"
          <el-input v-model="searchForm.projectName"
                    placeholder="请输入"
                    clearable
                    prefix-icon="Search"
            @change="handleQuery" />
        </el-form-item>
        <el-form-item label="客户类型:">
          <el-select v-model="searchForm.customerType"
                     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" format="YYYY-MM-DD" type="daterange"
            placeholder="请选择" clearable @change="changeDaterange" />
          <el-date-picker v-model="searchForm.entryDate"
                          value-format="YYYY-MM-DD"
                          format="YYYY-MM-DD"
                          type="daterange"
                          placeholder="请选择"
                          clearable
                          @change="changeDaterange" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleQuery"> 搜索 </el-button>
          <el-button type="primary"
                     @click="handleQuery"> 搜索 </el-button>
        </el-form-item>
      </el-form>
    </div>
@@ -27,52 +55,92 @@
      <div class="actions">
        <div></div>
        <div>
          <el-button type="primary" @click="openForm('add')">
          <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 @click="handleDelete">删除</el-button>
          <el-button type="primary" plain @click="handlePrint">打印</el-button>
          <el-button type="danger"
                     plain
                     @click="handleDelete">删除</el-button>
          <el-button type="primary"
                     plain
                     @click="handlePrint">打印</el-button>
        </div>
      </div>
      <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
        :expand-row-keys="expandedRowKeys" :row-key="(row) => row.id" :row-class-name="tableRowClassName" show-summary style="width: 100%"
        :summary-method="summarizeMainTable" @expand-change="expandChange" height="calc(100vh - 18.5em)">
        <el-table-column align="center" type="selection" width="55" fixed="left"/>
        <el-table-column type="expand" width="60" fixed="left">
      <el-table :data="tableData"
                border
                v-loading="tableLoading"
                @selection-change="handleSelectionChange"
                :expand-row-keys="expandedRowKeys"
                :row-key="(row) => row.id"
                :row-class-name="tableRowClassName"
                show-summary
                style="width: 100%"
                :summary-method="summarizeMainTable"
                @expand-change="expandChange"
                height="calc(100vh - 18.5em)">
        <el-table-column align="center"
                         type="selection"
                         width="55"
                         fixed="left" />
        <el-table-column type="expand"
                         width="60"
                         fixed="left">
          <template #default="props">
            <el-table :data="props.row.children" border show-summary :summary-method="summarizeChildrenTable">
              <el-table-column align="center" label="序号" type="index"/>
              <el-table-column label="产品大类" prop="productCategory" />
              <el-table-column label="规格型号" prop="specificationModel" />
              <el-table-column label="单位" prop="unit" />
            <el-table :data="props.row.children"
                      border
                      show-summary
                      :summary-method="summarizeChildrenTable">
              <el-table-column align="center"
                               label="序号"
                               type="index" />
              <el-table-column label="产品大类"
                               prop="productCategory" />
              <el-table-column label="规格型号"
                               prop="specificationModel" />
              <el-table-column label="单位"
                               prop="unit" />
                            <el-table-column label="产品状态"
                                                             width="100px"
                                                             align="center">
                <template #default="scope">
                                    <el-tag v-if="scope.row.approveStatus === 1 && (!scope.row.shippingDate || !scope.row.shippingCarNumber)"
                                                    type="success">充足</el-tag>
                                    <el-tag v-else-if="scope.row.approveStatus === 0 && (scope.row.shippingDate || scope.row.shippingCarNumber)"
                                                    type="success">已出库</el-tag>
                                    <el-tag v-else type="danger">不足</el-tag>
                  <el-tag v-else
                          type="danger">不足</el-tag>
                </template>
              </el-table-column>
                            <el-table-column label="发货状态" width="140" align="center">
              <el-table-column label="发货状态"
                               width="140"
                               align="center">
                                <template #default="scope">
                                    <el-tag :type="getShippingStatusType(scope.row)" size="small">
                  <el-tag :type="getShippingStatusType(scope.row)"
                          size="small">
                                        {{ getShippingStatusText(scope.row) }}
                                    </el-tag>
                                </template>
                            </el-table-column>
                            <el-table-column label="快递公司" prop="expressCompany" show-overflow-tooltip />
                            <el-table-column label="快递单号" prop="expressNumber" show-overflow-tooltip />
              <el-table-column label="发货车牌" minWidth="100px" align="center">
              <el-table-column label="快递公司"
                               prop="expressCompany"
                               show-overflow-tooltip />
              <el-table-column label="快递单号"
                               prop="expressNumber"
                               show-overflow-tooltip />
              <el-table-column label="发货车牌"
                               minWidth="100px"
                               align="center">
                <template #default="scope">
                  <div>
                    <el-tag type="success" v-if="scope.row.shippingCarNumber">{{ scope.row.shippingCarNumber }}</el-tag>
                    <el-tag v-else type="info">-</el-tag>
                    <el-tag type="success"
                            v-if="scope.row.shippingCarNumber">{{ scope.row.shippingCarNumber }}</el-tag>
                    <el-tag v-else
                            type="info">-</el-tag>
                  </div>
                </template>
              </el-table-column>
@@ -87,16 +155,43 @@
                  </div>
                </template>
              </el-table-column>
              <el-table-column label="数量" prop="quantity" />
              <el-table-column label="税率(%)" prop="taxRate" />
              <el-table-column label="含税单价(元)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" />
              <el-table-column label="含税总价(元)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" />
              <el-table-column label="不含税总价(元)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" />
              <el-table-column label="数量"
                               prop="quantity" />
              <!-- 对公客户显示的字段 -->
              <template v-if="props.row.customerType =='1'">
                <el-table-column label="税率(%)"
                                 prop="taxRate" />
                <el-table-column label="含税单价(元)"
                                 prop="taxInclusiveUnitPrice"
                                 :formatter="formattedNumber" />
                <el-table-column label="含税总价(元)"
                                 prop="taxInclusiveTotalPrice"
                                 :formatter="formattedNumber" />
                <el-table-column label="不含税总价(元)"
                                 prop="taxExclusiveTotalPrice"
                                 :formatter="formattedNumber" />
              </template>
              <!-- 对私客户显示的字段 -->
              <template v-else-if="props.row.customerType == 2">
                <el-table-column label="单价"
                                 prop="unitPrice"
                                 :formatter="formattedNumber" />
                <el-table-column label="总价"
                                 prop="totalPrice"
                                 :formatter="formattedNumber" />
                <el-table-column label="运费"
                                 prop="freight"
                                 :formatter="formattedNumber" />
                <el-table-column label="含运费单价"
                                 prop="priceWithFreight"
                                 :formatter="formattedNumber" />
              </template>
            <!--操作-->
              <el-table-column Width="60px" label="操作" align="center">
              <el-table-column Width="60px"
                               label="操作"
                               align="center">
                <template #default="scope">
                  <el-button
                    link
                  <el-button link
                    type="primary"
                    :disabled="!canShip(scope.row)"
                    @click="openDeliveryForm(scope.row)">
@@ -107,50 +202,127 @@
            </el-table>
          </template>
        </el-table-column>
        <el-table-column align="center" label="序号" type="index" width="60" />
        <el-table-column label="销售合同号" prop="salesContractNo" width="180" show-overflow-tooltip />
        <el-table-column label="客户名称" prop="customerName" width="300" show-overflow-tooltip />
        <el-table-column label="业务员" prop="salesman" width="100" show-overflow-tooltip />
        <el-table-column label="项目名称" prop="projectName" width="180" show-overflow-tooltip />
        <el-table-column label="付款方式" prop="paymentMethod" show-overflow-tooltip />
        <el-table-column label="合同金额(元)" prop="contractAmount" width="220" show-overflow-tooltip
          :formatter="formattedNumber" />
        <el-table-column label="录入人" prop="entryPersonName" width="100" show-overflow-tooltip />
        <el-table-column label="录入日期" prop="entryDate" width="120" show-overflow-tooltip />
        <el-table-column label="签订日期" prop="executionDate" width="120" show-overflow-tooltip />
        <el-table-column label="交付日期" prop="deliveryDate" width="120" show-overflow-tooltip />
        <el-table-column label="备注" prop="remarks" width="200" show-overflow-tooltip />
        <el-table-column fixed="right" label="操作" width="130" align="center">
        <el-table-column align="center"
                         label="序号"
                         type="index"
                         width="60" />
        <el-table-column label="销售合同号"
                         prop="salesContractNo"
                         width="180"
                         show-overflow-tooltip />
        <el-table-column label="客户名称"
                         prop="customerName"
                         width="300"
                         show-overflow-tooltip />
        <el-table-column label="客户类型"
                         prop="customerType"
                         width="100">
          <template #default="scope">
            <el-button link type="primary" @click="openForm('edit', scope.row)" :disabled="!scope.row.isEdit">编辑</el-button>
            <el-button link type="primary" @click="downLoadFile(scope.row)">附件</el-button>
            {{scope.row.customerType == 1 ? '对公' : '对私'}}
          </template>
        </el-table-column>
        <el-table-column label="业务员"
                         prop="salesman"
                         width="100"
                         show-overflow-tooltip />
        <el-table-column label="项目名称"
                         prop="projectName"
                         width="180"
                         show-overflow-tooltip />
        <el-table-column label="付款方式"
                         prop="paymentMethod"
                         show-overflow-tooltip />
        <el-table-column label="合同金额(元)"
                         prop="contractAmount"
                         width="220"
                         show-overflow-tooltip
                         :formatter="formattedNumber" />
        <el-table-column label="录入人"
                         prop="entryPersonName"
                         width="100"
                         show-overflow-tooltip />
        <el-table-column label="录入日期"
                         prop="entryDate"
                         width="120"
                         show-overflow-tooltip />
        <el-table-column label="签订日期"
                         prop="executionDate"
                         width="120"
                         show-overflow-tooltip />
        <el-table-column label="交付日期"
                         prop="deliveryDate"
                         width="120"
                         show-overflow-tooltip />
        <el-table-column label="备注"
                         prop="remarks"
                         width="200"
                         show-overflow-tooltip />
        <el-table-column fixed="right"
                         label="操作"
                         width="130"
                         align="center">
          <template #default="scope">
            <el-button link
                       type="primary"
                       @click="openForm('edit', scope.row)"
                       :disabled="!scope.row.isEdit">编辑</el-button>
            <el-button link
                       type="primary"
                       @click="downLoadFile(scope.row)">附件</el-button>
          </template>
        </el-table-column>
      </el-table>
      <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper"
        :page="page.current" :limit="page.size" @pagination="paginationChange" />
      <pagination v-show="total > 0"
                  :total="total"
                  layout="total, sizes, prev, pager, next, jumper"
                  :page="page.current"
                  :limit="page.size"
                  @pagination="paginationChange" />
    </div>
    <FormDialog v-model="dialogFormVisible" :title="operationType === 'add' ? '新增销售台账页面' : '编辑销售台账页面'" :width="'70%'"
      :operation-type="operationType" @close="closeDia" @confirm="submitForm" @cancel="closeDia">
      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
    <FormDialog v-model="dialogFormVisible"
                :title="operationType === 'add' ? '新增销售台账页面' : '编辑销售台账页面'"
                :width="'70%'"
                :operation-type="operationType"
                @close="closeDia"
                @confirm="submitForm"
                @cancel="closeDia">
      <el-form :model="form"
               label-width="140px"
               label-position="top"
               :rules="rules"
               ref="formRef">
                <!-- 报价单导入入口:放在表单顶部,选择后反显客户/业务员等 -->
                <el-row v-if="operationType === 'add'" style="margin-bottom: 10px;">
                    <el-col :span="24" style="text-align: right;">
                        <el-button type="primary" plain @click="openQuotationDialog">
        <el-row v-if="operationType === 'add'"
                style="margin-bottom: 10px;">
          <el-col :span="24"
                  style="text-align: right;">
            <el-button type="primary"
                       plain
                       @click="openQuotationDialog">
                            从销售报价导入
                        </el-button>
                    </el-col>
                </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="销售合同号:" prop="salesContractNo">
              <el-input v-model="form.salesContractNo" placeholder="自动生成" clearable disabled />
            <el-form-item label="销售合同号:"
                          prop="salesContractNo">
              <el-input v-model="form.salesContractNo"
                        placeholder="自动生成"
                        clearable
                        disabled />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="业务员:" prop="salesman">
              <el-select v-model="form.salesman" placeholder="请选择" clearable :disabled="operationType === 'view'">
                <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
            <el-form-item label="业务员:"
                          prop="salesman">
              <el-select v-model="form.salesman"
                         placeholder="请选择"
                         clearable
                         :disabled="operationType === 'view'">
                <el-option v-for="item in userList"
                           :key="item.nickName"
                           :label="item.nickName"
                  :value="item.nickName" />
              </el-select>
            </el-form-item>
@@ -158,83 +330,174 @@
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="客户名称:" prop="customerId">
              <el-select v-model="form.customerId" placeholder="请选择" clearable :disabled="operationType === 'view'">
                <el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.id">
                  {{
                    item.customerName + "——" + item.taxpayerIdentificationNumber
                  }}
            <el-form-item label="客户名称:"
                          prop="customerId">
              <el-select v-model="form.customerId"
                         placeholder="请选择"
                         clearable
                         :disabled="operationType === 'view'"
                         @change="handleCustomerChange">
                <el-option v-for="item in customerOption"
                           :key="item.id"
                           :label="item.customerName"
                           :value="item.id">
                  {{ item.customerName + "——" }}
                  {{item.customerType=="1"?item.taxpayerIdentificationNumber || '无':"对私"}}
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
                    <el-col :span="12">
                        <el-form-item label="项目名称:" prop="projectName">
                            <el-input v-model="form.projectName" placeholder="请输入" clearable :disabled="operationType === 'view'" />
            <el-form-item label="项目名称:"
                          prop="projectName">
              <el-input v-model="form.projectName"
                        placeholder="请输入"
                        clearable
                        :disabled="operationType === 'view'" />
                        </el-form-item>
                    </el-col>
        </el-row>
        <el-row :gutter="30">
                    <el-col :span="12">
                        <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 :disabled="operationType === 'view'" />
            <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
                              :disabled="operationType === 'view'" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="付款方式">
                            <el-input v-model="form.paymentMethod" placeholder="请输入" clearable :disabled="operationType === 'view'" />
              <el-input v-model="form.paymentMethod"
                        placeholder="请输入"
                        clearable
                        :disabled="operationType === 'view'" />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="30">
                    <el-col :span="12">
                        <el-form-item label="录入人:" prop="entryPerson">
            <el-form-item label="录入人:"
                          prop="entryPerson">
                            <el-select v-model="form.entryPerson"
                                                 filterable
                                                 default-first-option
                                                 :reserve-keyword="false" placeholder="请选择" clearable @change="changs">
                                <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
                         :reserve-keyword="false"
                         placeholder="请选择"
                         clearable
                         @change="changs">
                <el-option v-for="item in userList"
                           :key="item.userId"
                           :label="item.nickName"
                           :value="item.userId" />
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="录入日期:" prop="entryDate">
                            <el-date-picker style="width: 100%" v-model="form.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
                                                            type="date" placeholder="请选择" clearable />
            <el-form-item label="录入日期:"
                          prop="entryDate">
              <el-date-picker style="width: 100%"
                              v-model="form.entryDate"
                              value-format="YYYY-MM-DD"
                              format="YYYY-MM-DD"
                              type="date"
                              placeholder="请选择"
                              clearable />
                        </el-form-item>
                    </el-col>
                </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="交货日期:" prop="entryDate">
              <el-date-picker style="width: 100%" v-model="form.deliveryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
                              type="date" placeholder="请选择" clearable />
            <el-form-item label="交货日期:"
                          prop="entryDate">
              <el-date-picker style="width: 100%"
                              v-model="form.deliveryDate"
                              value-format="YYYY-MM-DD"
                              format="YYYY-MM-DD"
                              type="date"
                              placeholder="请选择"
                              clearable />
            </el-form-item>
          </el-col>
        </el-row>
                <el-row>
                    <el-form-item label="产品信息:" prop="entryDate">
                        <el-button v-if="operationType !== 'view'" type="primary" @click="openProductForm('add')">添加</el-button>
                        <el-button v-if="operationType !== 'view'" plain type="danger" @click="deleteProduct" >删除</el-button>
        <el-row :gutter="30">
          <el-form-item label="产品信息:"
                        prop="entryDate">
            <el-button v-if="operationType !== 'view' && currentCustomerType"
                       type="primary"
                       @click="openProductForm('add')">添加</el-button>
            <el-button v-if="operationType !== 'view'"
                       plain
                       type="danger"
                       @click="deleteProduct"
                       :disabled="!productData.length">删除</el-button>
                    </el-form-item>
                </el-row>
                <el-table :data="productData" border @selection-change="productSelected" show-summary
        <el-table :data="productData"
                  border
                  @selection-change="productSelected"
                  show-summary
                                    :summary-method="summarizeMainTable">
                    <el-table-column align="center" type="selection" width="55" v-if="operationType !== 'view'"
          <el-table-column align="center"
                           type="selection"
                           width="55"
                           v-if="operationType !== 'view'"
                        :selectable="(row) => !isProductShipped(row)" />
                    <el-table-column align="center" label="序号" type="index" width="60" />
                    <el-table-column label="产品大类" prop="productCategory" />
                    <el-table-column label="规格型号" prop="specificationModel" />
                    <el-table-column label="单位" prop="unit" />
                    <el-table-column label="数量" prop="quantity" />
                    <el-table-column label="税率(%)" prop="taxRate" />
                    <el-table-column label="含税单价(元)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" />
                    <el-table-column label="含税总价(元)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" />
                    <el-table-column label="不含税总价(元)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" />
                    <el-table-column fixed="right" label="操作" min-width="60" align="center" v-if="operationType !== 'view'">
          <el-table-column align="center"
                           label="序号"
                           type="index"
                           width="60" />
          <el-table-column label="产品大类"
                           prop="productCategory" />
          <el-table-column label="规格型号"
                           prop="specificationModel" />
          <el-table-column label="单位"
                           prop="unit" />
          <el-table-column label="数量"
                           prop="quantity" />
          <!-- 对公客户显示的字段 -->
          <template v-if="currentCustomerType == 1">
            <el-table-column label="税率(%)"
                             prop="taxRate" />
            <el-table-column label="含税单价(元)"
                             prop="taxInclusiveUnitPrice"
                             :formatter="formattedNumber" />
            <el-table-column label="含税总价(元)"
                             prop="taxInclusiveTotalPrice"
                             :formatter="formattedNumber" />
            <el-table-column label="不含税总价(元)"
                             prop="taxExclusiveTotalPrice"
                             :formatter="formattedNumber" />
          </template>
          <!-- 对私客户显示的字段 -->
          <template v-else-if="currentCustomerType == 2">
            <el-table-column label="单价"
                             prop="unitPrice"
                             :formatter="formattedNumber" />
            <el-table-column label="总价"
                             prop="totalPrice"
                             :formatter="formattedNumber" />
            <el-table-column label="运费"
                             prop="freight"
                             :formatter="formattedNumber" />
            <el-table-column label="含运费单价"
                             prop="priceWithFreight"
                             :formatter="formattedNumber" />
          </template>
          <el-table-column fixed="right"
                           label="操作"
                           min-width="60"
                           align="center"
                           v-if="operationType !== 'view'">
                        <template #default="scope">
                            <el-button link type="primary" size="small"
              <el-button link
                         type="primary"
                         size="small"
                                :disabled="isProductShipped(scope.row)"
                                @click="openProductForm('edit', scope.row,scope.$index)">编辑</el-button>
                        </template>
@@ -242,19 +505,35 @@
                </el-table>
                <el-row :gutter="30">
                    <el-col :span="24">
                        <el-form-item label="备注:" prop="remarks">
                            <el-input v-model="form.remarks" placeholder="请输入" clearable type="textarea" :rows="2" :disabled="operationType === 'view'" />
            <el-form-item label="备注:"
                          prop="remarks">
              <el-input v-model="form.remarks"
                        placeholder="请输入"
                        clearable
                        type="textarea"
                        :rows="2"
                        :disabled="operationType === 'view'" />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="30">
                    <el-col :span="24">
                        <el-form-item label="附件材料:" prop="salesLedgerFiles">
                            <el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload
                                                 :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError"
                                                 :on-success="handleUploadSuccess" :on-remove="handleRemove">
                                <el-button type="primary" v-if="operationType !== 'view'">上传</el-button>
                                <template #tip v-if="operationType !== 'view'">
            <el-form-item label="附件材料:"
                          prop="salesLedgerFiles">
              <el-upload v-model:file-list="fileList"
                         :action="upload.url"
                         multiple
                         ref="fileUpload"
                         auto-upload
                         :headers="upload.headers"
                         :before-upload="handleBeforeUpload"
                         :on-error="handleUploadError"
                         :on-success="handleUploadSuccess"
                         :on-remove="handleRemove">
                <el-button type="primary"
                           v-if="operationType !== 'view'">上传</el-button>
                <template #tip
                          v-if="operationType !== 'view'">
                                    <div class="el-upload__tip">
                                        文件格式支持
                                        doc,docx,xls,xlsx,ppt,pptx,pdf,txt,xml,jpg,jpeg,png,gif,bmp,rar,zip,7z
@@ -266,167 +545,308 @@
                </el-row>
            </el-form>
        </FormDialog>
        <!-- 从报价单导入(仅审批通过) -->
        <el-dialog
            v-model="quotationDialogVisible"
    <el-dialog v-model="quotationDialogVisible"
            title="选择审批通过的销售报价单"
            width="80%"
            :close-on-click-modal="false"
        >
               :close-on-click-modal="false">
            <div style="margin-bottom: 12px; display:flex; gap: 12px; align-items:center;">
                <el-input
                    v-model="quotationSearchForm.quotationNo"
        <el-input v-model="quotationSearchForm.quotationNo"
                    placeholder="请输入报价单号"
                    clearable
                    style="max-width: 260px;"
                    @change="fetchQuotationList"
                />
                <el-input
                    v-model="quotationSearchForm.customer"
                  @change="fetchQuotationList" />
        <el-input v-model="quotationSearchForm.customer"
                    placeholder="请输入客户名称"
                    clearable
                    style="max-width: 260px;"
                    @change="fetchQuotationList"
                />
                <el-button type="primary" @click="fetchQuotationList">搜索</el-button>
                  @change="fetchQuotationList" />
        <el-button type="primary"
                   @click="fetchQuotationList">搜索</el-button>
                <el-button @click="resetQuotationSearch">重置</el-button>
            </div>
            <el-table
                :data="quotationList"
      <el-table :data="quotationList"
                border
                stripe
                v-loading="quotationLoading"
                height="420px"
            >
                <el-table-column align="center" label="序号" type="index" width="60" />
                <el-table-column prop="quotationNo" label="报价单号" width="180" show-overflow-tooltip />
                <el-table-column prop="customer" label="客户名称" min-width="220" show-overflow-tooltip />
                <el-table-column prop="salesperson" label="业务员" width="120" show-overflow-tooltip />
                <el-table-column prop="quotationDate" label="报价日期" width="140" />
                <el-table-column prop="status" label="审批状态" width="120" align="center" />
                <el-table-column prop="totalAmount" label="报价金额(元)" width="160" align="right">
                height="420px">
        <el-table-column align="center"
                         label="序号"
                         type="index"
                         width="60" />
        <el-table-column prop="quotationNo"
                         label="报价单号"
                         width="180"
                         show-overflow-tooltip />
        <el-table-column prop="customer"
                         label="客户名称"
                         min-width="220"
                         show-overflow-tooltip />
        <el-table-column prop="salesperson"
                         label="业务员"
                         width="120"
                         show-overflow-tooltip />
        <el-table-column prop="quotationDate"
                         label="报价日期"
                         width="140" />
        <el-table-column prop="status"
                         label="审批状态"
                         width="120"
                         align="center" />
        <el-table-column prop="totalAmount"
                         label="报价金额(元)"
                         width="160"
                         align="right">
                    <template #default="scope">
                        {{ Number(scope.row.totalAmount ?? 0).toFixed(2) }}
                    </template>
                </el-table-column>
                <el-table-column fixed="right" label="操作" width="120" align="center">
        <el-table-column fixed="right"
                         label="操作"
                         width="120"
                         align="center">
                    <template #default="scope">
                        <el-button type="primary" link @click="applyQuotation(scope.row)">选择</el-button>
            <el-button type="primary"
                       link
                       @click="applyQuotation(scope.row)">选择</el-button>
                    </template>
                </el-table-column>
            </el-table>
            <pagination
                v-show="quotationPage.total > 0"
      <pagination v-show="quotationPage.total > 0"
                :total="quotationPage.total"
                layout="total, sizes, prev, pager, next, jumper"
                :page="quotationPage.current"
                :limit="quotationPage.size"
                @pagination="quotationPaginationChange"
            />
                  @pagination="quotationPaginationChange" />
            <template #footer>
                <el-button @click="quotationDialogVisible = false">关闭</el-button>
            </template>
        </el-dialog>
        <FormDialog
            v-model="productFormVisible"
    <FormDialog v-model="productFormVisible"
            :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" ref="productFormRef">
      <el-form :model="productForm"
               label-width="140px"
               label-position="top"
               :rules="productRules"
               ref="productFormRef">
                <el-row :gutter="30">
                    <el-col :span="24">
                        <el-form-item label="产品大类:" prop="productCategory">
            <el-form-item label="产品大类:"
                          prop="productCategory">
                            <!-- <el-select v-model="productForm.productCategory" placeholder="请选择" clearable>
                                <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" :value="item.nickName"/>
                            </el-select> -->
                            <el-tree-select v-model="productForm.productCategory" placeholder="请选择" clearable check-strictly
                                                            @change="getModels" :data="productOptions" :render-after-expand="false" style="width: 100%" />
              <el-tree-select v-model="productForm.productCategory"
                              placeholder="请选择"
                              clearable
                              check-strictly
                              @change="getModels"
                              :data="productOptions"
                              :render-after-expand="false"
                              style="width: 100%" />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="30">
                    <el-col :span="24">
                        <el-form-item label="规格型号:" prop="productModelId">
                            <el-select v-model="productForm.productModelId" placeholder="请选择" clearable @change="getProductModel" filterable>
                                <el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" />
            <el-form-item label="规格型号:"
                          prop="productModelId">
              <el-select v-model="productForm.productModelId"
                         placeholder="请选择"
                         clearable
                         @change="getProductModel"
                         filterable>
                <el-option v-for="item in modelOptions"
                           :key="item.id"
                           :label="item.model"
                           :value="item.id" />
                            </el-select>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="30">
                    <el-col :span="12">
                        <el-form-item label="单位:" prop="unit">
                            <el-input v-model="productForm.unit" placeholder="请输入" clearable />
            <el-form-item label="单位:"
                          prop="unit">
              <el-input v-model="productForm.unit"
                        placeholder="请输入"
                        clearable />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="税率(%):" prop="taxRate">
                            <el-select v-model="productForm.taxRate" placeholder="请选择" clearable @change="calculateFromTaxRate">
                                <el-option label="1" value="1" />
                                <el-option label="6" value="6" />
                                <el-option label="13" value="13" />
                            </el-select>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="30">
                    <el-col :span="12">
                        <el-form-item label="含税单价(元):" prop="taxInclusiveUnitPrice">
                            <el-input-number :step="0.01" :min="0" v-model="productForm.taxInclusiveUnitPrice" style="width: 100%"
            <el-form-item label="数量:"
                          prop="quantity">
              <el-input-number :step="0.1"
                               :min="0"
                               v-model="productForm.quantity"
                               placeholder="请输入"
                               clearable
                                                             :precision="2"
                                                             placeholder="请输入" clearable @change="calculateFromUnitPrice" />
                               @change="calculateFromQuantity"
                               style="width: 100%" />
            </el-form-item>
          </el-col>
          <!-- <el-col :span="12">
            <el-form-item label="税率(%):"
                          prop="taxRate">
              <el-select v-model="productForm.taxRate"
                         placeholder="请选择"
                         clearable
                         @change="calculateFromTaxRate">
                <el-option label="1"
                           value="1" />
                <el-option label="6"
                           value="6" />
                <el-option label="13"
                           value="13" />
              </el-select>
            </el-form-item>
          </el-col> -->
        </el-row>
        <el-row :gutter="30">
        </el-row>
        <!-- 对公客户显示的字段 -->
        <template v-if="currentCustomerType == 1">
          <el-row :gutter="30">
            <el-col :span="12">
              <el-form-item label="税率(%):"
                            prop="taxRate">
                <el-select v-model="productForm.taxRate"
                           placeholder="请选择"
                           clearable
                           @change="calculateFromTaxRate">
                  <el-option label="1"
                             value="1" />
                  <el-option label="6"
                             value="6" />
                  <el-option label="13"
                             value="13" />
                </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="数量:" prop="quantity">
                            <el-input-number  :step="0.1" :min="0" v-model="productForm.quantity" placeholder="请输入" clearable
              <el-form-item label="含税单价(元):"
                            prop="taxInclusiveUnitPrice">
                <el-input-number :step="0.01"
                                 :min="0"
                                 v-model="productForm.taxInclusiveUnitPrice"
                                 style="width: 100%"
                                                                :precision="2"
                                                                @change="calculateFromQuantity" style="width: 100%" />
                                 placeholder="请输入"
                                 clearable
                                 @change="calculateFromUnitPrice" />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="30">
                    <el-col :span="12">
                        <el-form-item label="含税总价(元):" prop="taxInclusiveTotalPrice">
                            <el-input v-model="productForm.taxInclusiveTotalPrice" placeholder="请输入" clearable @change="calculateFromTotalPrice" />
              <el-form-item label="含税总价(元):"
                            prop="taxInclusiveTotalPrice">
                <el-input v-model="productForm.taxInclusiveTotalPrice"
                          placeholder="请输入"
                          clearable
                          @change="calculateFromTotalPrice" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="不含税总价(元):" prop="taxExclusiveTotalPrice">
                            <el-input v-model="productForm.taxExclusiveTotalPrice" placeholder="请输入" clearable @change="calculateFromExclusiveTotalPrice" />
              <el-form-item label="不含税总价(元):"
                            prop="taxExclusiveTotalPrice">
                <el-input v-model="productForm.taxExclusiveTotalPrice"
                          placeholder="请输入"
                          clearable
                          @change="calculateFromExclusiveTotalPrice" />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="30">
                    <el-col :span="12">
                        <el-form-item label="发票类型:" prop="invoiceType">
                            <el-select v-model="productForm.invoiceType" placeholder="请选择" clearable>
                                <el-option label="增普票" value="增普票" />
                                <el-option label="增专票" value="增专票" />
              <el-form-item label="发票类型:"
                            prop="invoiceType">
                <el-select v-model="productForm.invoiceType"
                           placeholder="请选择"
                           clearable>
                  <el-option label="增普票"
                             value="增普票" />
                  <el-option label="增专票"
                             value="增专票" />
                            </el-select>
                        </el-form-item>
                    </el-col>
                </el-row>
        </template>
        <!-- 对私客户显示的字段 -->
        <template v-else-if="currentCustomerType == 2">
          <el-row :gutter="30">
            <el-col :span="12">
              <el-form-item label="单价:"
                            prop="unitPrice">
                <el-input-number :step="0.01"
                                 :min="0"
                                 v-model="productForm.unitPrice"
                                 style="width: 100%"
                                 :precision="2"
                                 placeholder="请输入"
                                 clearable
                                 @change="calculatePrivatePrice" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="总价:"
                            prop="totalPrice">
                <el-input-number :step="0.01"
                                 :min="0"
                                 v-model="productForm.totalPrice"
                                 style="width: 100%"
                                 :precision="2"
                                 placeholder="请输入"
                                 clearable />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="30">
            <el-col :span="12">
              <el-form-item label="运费:"
                            prop="freight">
                <el-input-number :step="0.01"
                                 :min="0"
                                 v-model="productForm.freight"
                                 style="width: 100%"
                                 :precision="2"
                                 placeholder="请输入"
                                 clearable
                                 @change="calculatePrivatePrice" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="含运费单价:"
                            prop="priceWithFreight">
                <el-input-number :step="0.01"
                                 :min="0"
                                 v-model="productForm.priceWithFreight"
                                 style="width: 100%"
                                 :precision="2"
                                 placeholder="请输入"
                                 clearable
                                 @change="calculatePrivateTotal" />
              </el-form-item>
            </el-col>
          </el-row>
        </template>
            </el-form>
        </FormDialog>
        <!-- 导入弹窗 -->
        <FormDialog
            v-model="importUpload.open"
    <FormDialog v-model="importUpload.open"
            :title="importUpload.title"
            :width="'600px'"
            @close="importUpload.open = false"
            @confirm="submitImportFile"
            @cancel="importUpload.open = false"
        >
            <el-upload
                ref="importUploadRef"
                @cancel="importUpload.open = false">
      <el-upload ref="importUploadRef"
                :limit="1"
                accept=".xlsx,.xls"
                :action="importUpload.url"
@@ -437,8 +857,7 @@
                :on-progress="importUpload.onProgress"
                :on-change="importUpload.onChange"
                :auto-upload="false"
                drag
            >
                 drag>
                <i class="el-icon-upload"></i>
                <div class="el-upload__text">
                    将文件拖到此处,或<em>点击上传</em>
@@ -446,43 +865,45 @@
                <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>
        <!-- 附件列表弹窗 -->
        <FileListDialog
            ref="fileListRef"
    <FileListDialog ref="fileListRef"
            v-model="fileListDialogVisible"
            title="附件列表"
        />
                    title="附件列表" />
        <!-- 打印预览弹窗 -->
        <el-dialog
            v-model="printPreviewVisible"
    <el-dialog v-model="printPreviewVisible"
            title="打印预览"
            width="90%"
            :close-on-click-modal="false"
            class="print-preview-dialog"
        >
               class="print-preview-dialog">
            <div class="print-preview-container">
                <div class="print-preview-header">
                    <el-button type="primary" @click="executePrint">执行打印</el-button>
          <el-button type="primary"
                     @click="executePrint">执行打印</el-button>
                    <el-button @click="printPreviewVisible = false">关闭预览</el-button>
                </div>
                <div class="print-preview-content">
                    <div v-if="printData.length === 0" style="text-align: center; padding: 50px; color: #999;">
          <div v-if="printData.length === 0"
               style="text-align: center; padding: 50px; color: #999;">
                        暂无打印数据
                    </div>
                    <div v-else style="text-align: center; padding: 10px; color: #666; font-size: 14px; background: #e8f4fd; margin-bottom: 10px;">
          <div v-else
               style="text-align: center; padding: 10px; color: #666; font-size: 14px; background: #e8f4fd; margin-bottom: 10px;">
                        共 {{ printData.length }} 条数据待打印
                    </div>
                    <div v-for="(item, index) in printData" :key="index" class="print-page">
          <div v-for="(item, index) in printData"
               :key="index"
               class="print-page">
                        <div class="delivery-note">
                            <div class="header">
                                <div class="document-title">零售发货单</div>
                            </div>
                            <div class="info-section">
                                <div class="info-row">
                                    <div>
@@ -503,7 +924,6 @@
                                    <span class="value">{{ item.salesContractNo }}</span>
                                </div>
                            </div>
                            <div class="table-section">
                                <table class="product-table">
                                    <thead>
@@ -517,7 +937,8 @@
                                    </tr>
                                    </thead>
                                    <tbody>
                                    <tr v-for="product in item.products" :key="product.id">
                    <tr v-for="product in item.products"
                        :key="product.id">
                                        <td>{{ product.productCategory || '' }}</td>
                                        <td>{{ product.specificationModel || '' }}</td>
                                        <td>{{ product.unit || '' }}</td>
@@ -526,7 +947,8 @@
                                        <td>{{ product.taxInclusiveTotalPrice || '0' }}</td>
                                    </tr>
                                    <tr v-if="!item.products || item.products.length === 0">
                                        <td colspan="6" style="text-align: center; color: #999;">暂无产品数据</td>
                      <td colspan="6"
                          style="text-align: center; color: #999;">暂无产品数据</td>
                                    </tr>
                                    </tbody>
                                    <tfoot>
@@ -541,7 +963,6 @@
                                    </tfoot>
                                </table>
                            </div>
                            <div class="footer-section">
                                <div class="footer-row">
                                    <div class="footer-item">
@@ -574,65 +995,61 @@
            </div>
        </el-dialog>
        <!-- 发货弹框 -->
        <el-dialog
            v-model="deliveryFormVisible"
    <el-dialog v-model="deliveryFormVisible"
            title="发货信息"
        width="40%"
            @close="closeDeliveryDia"
        >
            <el-form :model="deliveryForm" label-width="120px" label-position="top" :rules="deliveryRules" ref="deliveryFormRef">
               @close="closeDeliveryDia">
      <el-form :model="deliveryForm"
               label-width="120px"
               label-position="top"
               :rules="deliveryRules"
               ref="deliveryFormRef">
                <el-row :gutter="30">
                    <el-col :span="24">
                        <el-form-item label="发货类型:" prop="type">
                            <el-select
                                v-model="deliveryForm.type"
            <el-form-item label="发货类型:"
                          prop="type">
              <el-select v-model="deliveryForm.type"
                                placeholder="请选择发货类型"
                                style="width: 100%"
                            >
                                <el-option label="货车" value="货车" />
                                <el-option label="快递" value="快递" />
                         style="width: 100%">
                <el-option label="货车"
                           value="货车" />
                <el-option label="快递"
                           value="快递" />
                            </el-select>
                        </el-form-item>
                    </el-col>
                </el-row>
        <!-- 审批人选择(仿协同审批里的审批人节点选择) -->
        <el-row>
          <el-col :span="24">
            <el-form-item>
              <template #label>
                <span>审批人选择:</span>
                <el-button type="primary" @click="addApproverNode" style="margin-left: 8px;">新增节点</el-button>
                <el-button type="primary"
                           @click="addApproverNode"
                           style="margin-left: 8px;">新增节点</el-button>
              </template>
              <div style="display: flex; align-items: flex-end; flex-wrap: wrap;">
                <div
                  v-for="(node, index) in approverNodes"
                <div v-for="(node, index) in approverNodes"
                  :key="node.id"
                  style="margin-right: 20px; text-align: center; margin-bottom: 10px;"
                >
                     style="margin-right: 20px; text-align: center; margin-bottom: 10px;">
                  <div>
                    <span>审批人</span>
                    →
                  </div>
                  <el-select
                    v-model="node.userId"
                  <el-select v-model="node.userId"
                    placeholder="选择人员"
                    filterable
                    style="width: 140px; margin-bottom: 8px;"
                  >
                    <el-option
                      v-for="user in userList"
                             style="width: 140px; margin-bottom: 8px;">
                    <el-option v-for="user in userList"
                      :key="user.userId"
                      :label="user.nickName"
                      :value="user.userId"
                    />
                               :value="user.userId" />
                  </el-select>
                  <div>
                    <el-button
                      type="danger"
                    <el-button type="danger"
                      @click="removeApproverNode(index)"
                      v-if="approverNodes.length > 1"
                    >删除</el-button>
                               v-if="approverNodes.length > 1">删除</el-button>
                  </div>
                </div>
              </div>
@@ -642,7 +1059,8 @@
            </el-form>
            <template #footer>
                <div class="dialog-footer">
                    <el-button type="primary" @click="submitDelivery">确认发货</el-button>
          <el-button type="primary"
                     @click="submitDelivery">确认发货</el-button>
                    <el-button @click="closeDeliveryDia">取消</el-button>
                </div>
            </template>
@@ -659,8 +1077,8 @@
import { UploadFilled, Download } from "@element-plus/icons-vue";
import useUserStore from "@/store/modules/user";
import { userListNoPage } from "@/api/system/user.js";
import FileListDialog from '@/components/Dialog/FileListDialog.vue';
import FormDialog from '@/components/Dialog/FormDialog.vue';
  import FileListDialog from "@/components/Dialog/FileListDialog.vue";
  import FormDialog from "@/components/Dialog/FormDialog.vue";
import { getQuotationList } from "@/api/salesManagement/salesQuotation.js";
import {
    ledgerListPage,
@@ -671,7 +1089,8 @@
    delLedger,
    addOrUpdateSalesLedgerProduct,
    delProduct,
    delLedgerFile, getProductInventory,
    delLedgerFile,
    getProductInventory,
} from "@/api/salesManagement/salesLedger.js";
import { modelList, productTreeList } from "@/api/basicData/product.js";
import useFormData from "@/hooks/useFormData.js";
@@ -699,6 +1118,7 @@
// 用户信息表单弹框数据
const operationType = ref("");
const dialogFormVisible = ref(false);
  const currentCustomerType = ref(""); // 当前客户类型:对公/对私
const data = reactive({
    searchForm: {
        customerName: "", // 客户名称
@@ -706,6 +1126,7 @@
        entryDate: null, // 录入日期
        entryDateStart: undefined,
        entryDateEnd: undefined,
      customerType: "",
    },
    form: {
        salesContractNo: "",
@@ -739,11 +1160,17 @@
        specificationModel: "",
        unit: "",
        quantity: "",
      // 对公字段
        taxInclusiveUnitPrice: "",
        taxRate: "",
        taxInclusiveTotalPrice: "",
        taxExclusiveTotalPrice: "",
        invoiceType: "",
      // 对私字段
      unitPrice: "",
      totalPrice: "",
      freight: 0,
      priceWithFreight: "",
    },
    productRules: {
        productCategory: [{ required: true, message: "请选择", trigger: "change" }],
@@ -753,6 +1180,7 @@
        ],
        unit: [{ required: true, message: "请输入", trigger: "blur" }],
        quantity: [{ required: true, message: "请输入", trigger: "blur" }],
      // 对公字段验证
        taxInclusiveUnitPrice: [
            { required: true, message: "请输入", trigger: "blur" },
        ],
@@ -764,6 +1192,11 @@
            { required: true, message: "请输入", trigger: "blur" },
        ],
        invoiceType: [{ required: true, message: "请选择", trigger: "change" }],
      // 对私字段验证
      unitPrice: [{ required: true, message: "请输入", trigger: "blur" }],
      totalPrice: [{ required: true, message: "请输入", trigger: "blur" }],
      freight: [{ required: true, message: "请输入", trigger: "blur" }],
      priceWithFreight: [{ required: true, message: "请输入", trigger: "blur" }],
    },
});
const { productForm, productRules } = toRefs(productFormData);
@@ -803,9 +1236,7 @@
    type: "货车", // 货车, 快递
  },
  deliveryRules: {
    type: [
      { required: true, message: "请选择发货类型", trigger: "change" }
    ]
      type: [{ required: true, message: "请选择发货类型", trigger: "change" }],
  },
});
const { deliveryForm, deliveryRules } = toRefs(deliveryFormData);
@@ -816,7 +1247,7 @@
const addApproverNode = () => {
  approverNodes.value.push({ id: nextApproverId++, userId: null });
};
const removeApproverNode = (index) => {
  const removeApproverNode = index => {
  approverNodes.value.splice(index, 1);
};
@@ -828,8 +1259,8 @@
    url: import.meta.env.VITE_APP_BASE_API + "/sales/ledger/import",
    headers: { Authorization: "Bearer " + getToken() },
    isUploading: false,
    beforeUpload: (file) => {
        const isExcel = file.name.endsWith('.xlsx') || file.name.endsWith('.xls');
    beforeUpload: file => {
      const isExcel = file.name.endsWith(".xlsx") || file.name.endsWith(".xls");
        const isLt10M = file.size / 1024 / 1024 < 10;
        if (!isExcel) {
            proxy.$modal.msgError("上传文件只能是 xlsx/xls 格式!");
@@ -842,13 +1273,13 @@
        return true;
    },
    onChange: (file, fileList) => {
        console.log('文件状态改变', file, fileList);
      console.log("文件状态改变", file, fileList);
    },
    onProgress: (event, file, fileList) => {
        console.log('上传中...', event.percent);
      console.log("上传中...", event.percent);
    },
    onSuccess: (response, file, fileList) => {
        console.log('上传成功', response, file, fileList);
      console.log("上传成功", response, file, fileList);
        importUpload.isUploading = false;
        if (response.code === 200) {
            proxy.$modal.msgSuccess("导入成功");
@@ -862,13 +1293,13 @@
        }
    },
    onError: (error, file, fileList) => {
        console.error('上传失败', error, file, fileList);
      console.error("上传失败", error, file, fileList);
        importUpload.isUploading = false;
        proxy.$modal.msgError("导入失败,请重试");
    },
});
const changeDaterange = (value) => {
  const changeDaterange = value => {
    if (value) {
        searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
        searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
@@ -890,7 +1321,7 @@
    expandedRowKeys.value = [];
    getList();
};
const paginationChange = (obj) => {
  const paginationChange = obj => {
    page.current = obj.page;
    page.size = obj.limit;
    getList();
@@ -903,10 +1334,10 @@
    // 移除录入日期的默认值设置,只保留范围日期字段
    delete params.entryDate;
    return ledgerListPage(params)
        .then((res) => {
      .then(res => {
            tableLoading.value = false;
            tableData.value = res.records;
            tableData.value.map((item) => {
        tableData.value.map(item => {
                item.children = [];
            });
            total.value = res.total;
@@ -919,7 +1350,7 @@
// 获取产品大类tree数据
const getProductOptions = () => {
    // 返回 Promise,便于在编辑产品时等待加载完成
    return productTreeList().then((res) => {
    return productTreeList().then(res => {
        productOptions.value = convertIdToValue(res);
        return productOptions.value;
    });
@@ -928,14 +1359,14 @@
    return parseFloat(cellValue).toFixed(2);
};
// 获取tree子数据
const getModels = (value) => {
  const getModels = value => {
    productForm.value.productCategory = findNodeById(productOptions.value, value);
    modelList({ id: value }).then((res) => {
    modelList({ id: value }).then(res => {
        modelOptions.value = res;
    });
};
const getProductModel = (value) => {
    const index = modelOptions.value.findIndex((item) => item.id === value);
  const getProductModel = value => {
    const index = modelOptions.value.findIndex(item => item.id === value);
    if (index !== -1) {
        productForm.value.specificationModel = modelOptions.value[index].model;
        productForm.value.unit = modelOptions.value[index].unit;
@@ -959,7 +1390,7 @@
    return null; // 没有找到节点,返回null
};
function convertIdToValue(data) {
    return data.map((item) => {
    return data.map(item => {
        const { id, children, ...rest } = item;
        const newItem = {
            ...rest,
@@ -986,12 +1417,12 @@
    return null;
}
// 表格选择数据
const handleSelectionChange = (selection) => {
  const handleSelectionChange = selection => {
    // 过滤掉子数据
    selectedRows.value = selection.filter((item) => item.children !== undefined);
    selectedRows.value = selection.filter(item => item.children !== undefined);
    console.log("selection", selectedRows.value);
};
const productSelected = (selectedRows) => {
  const productSelected = selectedRows => {
    productSelectedRows.value = selectedRows;
};
const expandedRowKeys = ref([]);
@@ -1000,10 +1431,15 @@
    if (expandedRows.length > 0) {
        expandedRowKeys.value = [];
        try {
            productList({ salesLedgerId: row.id, type: 1 }).then((res) => {
                const index = tableData.value.findIndex((item) => item.id === row.id);
        productList({ salesLedgerId: row.id, type: 1 }).then(res => {
          const index = tableData.value.findIndex(item => item.id === row.id);
                if (index > -1) {
                    tableData.value[index].children = res.data;
            // 为子表格数据添加客户类型信息
            const childrenData = res.data.map(item => ({
              ...item,
              customerType: row.customerType,
            }));
            tableData.value[index].children = childrenData;
                }
                expandedRowKeys.value.push(row.id);
            });
@@ -1017,22 +1453,22 @@
// 添加表行类名方法
const tableRowClassName = ({ row }) => {
  if (!row.deliveryDate) return '';
  if (row.isFh) return '';
    if (!row.deliveryDate) return "";
    if (row.isFh) return "";
  const diff = row.deliveryDaysDiff;
  if (diff === 15) {
    return 'yellow';
      return "yellow";
  } else if (diff === 10) {
    return 'pink';
      return "pink";
  } else if (diff === 2) {
    return 'purple';
      return "purple";
  } else if (diff < 2) {
    return 'red';
      return "red";
  }
};
// 主表合计方法
const summarizeMainTable = (param) => {
  const summarizeMainTable = param => {
    return proxy.summarizeTable(param, [
        "contractAmount",
        "taxInclusiveTotalPrice",
@@ -1040,23 +1476,48 @@
    ]);
};
// 子表合计方法
const summarizeChildrenTable = (param) => {
  const summarizeChildrenTable = param => {
    return proxy.summarizeTable(param, [
        "taxInclusiveUnitPrice",
        "taxInclusiveTotalPrice",
        "taxExclusiveTotalPrice",
    ]);
};
  // 客户选择变化处理
  const handleCustomerChange = customerId => {
    if (customerId) {
      const customer = customerOption.value.find(item => item.id === customerId);
      if (customer) {
        // 如果客户类型发生变化,清空表格数据
        if (
          currentCustomerType.value &&
          currentCustomerType.value !== customer.customerType
        ) {
          productData.value = [];
        }
        currentCustomerType.value = customer.customerType;
      }
    } else {
      currentCustomerType.value = "";
      productData.value = [];
    }
  };
// 打开弹框
const openForm = async (type, row) => {
    operationType.value = type;
    form.value = {};
    productData.value = [];
    selectedQuotation.value = null;
    currentCustomerType.value = "";
    let userLists = await userListNoPage();
    userList.value = userLists.data;
    customerList().then((res) => {
    customerList().then(res => {
        customerOption.value = res;
      // 如果是编辑模式且有客户ID,设置客户类型
      if (type === "edit" && form.value.customerId) {
        handleCustomerChange(form.value.customerId);
      }
    });
    form.value.entryPerson = userStore.id;
    if (type === "add") {
@@ -1066,11 +1527,17 @@
        form.value.executionDate = getCurrentDate();
    } else {
        currentId.value = row.id;
        getSalesLedgerWithProducts({ id: row.id, type: 1 }).then((res) => {
      getSalesLedgerWithProducts({ id: row.id, type: 1 }).then(res => {
            form.value = { ...res };
            form.value.entryPerson = Number(res.entryPerson);
            productData.value = form.value.productData;
            fileList.value = form.value.salesLedgerFiles;
        productData.value = JSON.parse(
          JSON.stringify(form.value.productData || [])
        );
        fileList.value = form.value.salesLedgerFiles
          ? form.value.salesLedgerFiles
          : [];
        // 设置客户类型
        handleCustomerChange(form.value.customerId);
        });
    }
    // let userAll = await userStore.getInfo()
@@ -1127,14 +1594,14 @@
};
// 报价单弹框分页切换
const quotationPaginationChange = (obj) => {
  const quotationPaginationChange = obj => {
    quotationPage.current = obj.page;
    quotationPage.size = obj.limit;
    fetchQuotationList();
};
// 选中报价单后回填到台账表单
const applyQuotation = (row) => {
  const applyQuotation = row => {
    if (!row) return;
    selectedQuotation.value = row;
    
@@ -1143,9 +1610,13 @@
    
    // 客户名称 -> customerId
    const qCustomerName = String(row.customer || "").trim();
    const customer = (customerOption.value || []).find((c) => {
    const customer = (customerOption.value || []).find(c => {
        const name = String(c.customerName || "").trim();
        return name === qCustomerName || name.includes(qCustomerName) || qCustomerName.includes(name);
      return (
        name === qCustomerName ||
        name.includes(qCustomerName) ||
        qCustomerName.includes(name)
      );
    });
    if (customer?.id) {
        form.value.customerId = customer.id;
@@ -1156,12 +1627,15 @@
    
    // 产品信息映射:报价 products -> 台账 productData
    const products = Array.isArray(row.products) ? row.products : [];
    productData.value = products.map((p) => {
    productData.value = products.map(p => {
        const quantity = Number(p.quantity ?? 0) || 0;
        const unitPrice = Number(p.unitPrice ?? 0) || 0;
        const taxRate = "13"; // 默认 13%,便于直接提交(如需可在产品中自行修改)
        const taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
        const taxExclusiveTotalPrice = proxy.calculateTaxExclusiveTotalPrice(taxInclusiveTotalPrice, taxRate);
      const taxExclusiveTotalPrice = proxy.calculateTaxExclusiveTotalPrice(
        taxInclusiveTotalPrice,
        taxRate
      );
        return {
            // 台账字段
            productCategory: p.product || p.productName || "",
@@ -1212,16 +1686,16 @@
    if (operationType.value === "edit") {
        let ids = [];
        ids.push(file.id);
        delLedgerFile(ids).then((res) => {
      delLedgerFile(ids).then(res => {
            proxy.$modal.msgSuccess("删除成功");
        });
    }
}
// 提交表单
const submitForm = () => {
    proxy.$refs["formRef"].validate((valid) => {
    proxy.$refs["formRef"].validate(valid => {
        if (valid) {
            console.log('productData.value--', productData.value)
        console.log("productData.value--", productData.value);
            if (productData.value !== null && productData.value.length > 0) {
                form.value.productData = proxy.HaveJson(productData.value);
            } else {
@@ -1230,11 +1704,12 @@
            }
            let tempFileIds = [];
            if (fileList.value !== null && fileList.value.length > 0) {
                tempFileIds = fileList.value.map((item) => item.tempId);
          tempFileIds = fileList.value.map(item => item.tempId);
            }
            form.value.tempFileIds = tempFileIds;
            form.value.type = 1;
            addOrUpdateSalesLedger(form.value).then((res) => {
        form.value.salesType = currentCustomerType.value;
        addOrUpdateSalesLedger(form.value).then(res => {
                proxy.$modal.msgSuccess("提交成功");
                closeDia();
                getList();
@@ -1265,16 +1740,20 @@
        productIndex.value = index;
        // 编辑时根据产品大类名称反查 tree 节点 id,并加载规格型号列表
        try {
            const options = productOptions.value && productOptions.value.length > 0
        const options =
          productOptions.value && productOptions.value.length > 0
                ? productOptions.value
                : await getProductOptions();
            const categoryId = findNodeIdByLabel(options, productForm.value.productCategory);
        const categoryId = findNodeIdByLabel(
          options,
          productForm.value.productCategory
        );
            if (categoryId) {
                const models = await modelList({ id: categoryId });
                modelOptions.value = models || [];
                // 根据当前规格型号名称反查并设置 productModelId,便于下拉框显示已选值
                const currentModel = (modelOptions.value || []).find(
                    (m) => m.model === productForm.value.specificationModel
            m => m.model === productForm.value.specificationModel
                );
                if (currentModel) {
                    productForm.value.productModelId = currentModel.id;
@@ -1285,21 +1764,50 @@
            console.error("加载产品规格型号失败", e);
        }
    } else {
        getProductOptions()
      getProductOptions();
    }
    productFormVisible.value = true;
};
// 提交产品表单
const submitProduct = () => {
    proxy.$refs["productFormRef"].validate((valid) => {
    // 动态验证规则
    const dynamicRules = { ...productRules.value };
    // 根据客户类型调整验证规则
    if (currentCustomerType.value == 1) {
      // 对私字段不需要验证
      delete dynamicRules.unitPrice;
      delete dynamicRules.totalPrice;
      delete dynamicRules.freight;
      delete dynamicRules.priceWithFreight;
    } else if (currentCustomerType.value == 2) {
      // 对公字段不需要验证
      delete dynamicRules.taxInclusiveUnitPrice;
      delete dynamicRules.taxRate;
      delete dynamicRules.taxInclusiveTotalPrice;
      delete dynamicRules.taxExclusiveTotalPrice;
      delete dynamicRules.invoiceType;
    }
    proxy.$refs["productFormRef"].validate((valid, fields) => {
        if (valid) {
            if (operationType.value === "edit") {
                submitProductEdit();
          // 编辑模式下直接修改本地表格数据
          if (productOperationType.value === "add") {
            productData.value.push({ ...productForm.value });
          } else {
            productData.value.splice(productIndex.value, 1, {
              ...productForm.value,
            });
          }
          closeProductDia();
            } else {
                if(productOperationType.value === "add"){
                    productData.value.push({ ...productForm.value });
                }else{
                    productData.value[productIndex.value] = { ...productForm.value }
            productData.value.splice(productIndex.value, 1, {
              ...productForm.value,
            });
                }
                closeProductDia();
            }
@@ -1307,13 +1815,31 @@
    });
};
const submitProductEdit = () => {
    productForm.value.salesLedgerId = currentId.value;
    productForm.value.type = 1
    addOrUpdateSalesLedgerProduct(productForm.value).then((res) => {
    // 根据客户类型调整提交的数据
    const productDataToSubmit = { ...productForm.value };
    if (currentCustomerType.value == 1) {
      // 对私字段不需要提交
      delete productDataToSubmit.unitPrice;
      delete productDataToSubmit.totalPrice;
      delete productDataToSubmit.freight;
      delete productDataToSubmit.priceWithFreight;
    } else if (currentCustomerType.value == 2) {
      // 对公字段不需要提交
      delete productDataToSubmit.taxInclusiveUnitPrice;
      delete productDataToSubmit.taxRate;
      delete productDataToSubmit.taxInclusiveTotalPrice;
      delete productDataToSubmit.taxExclusiveTotalPrice;
      delete productDataToSubmit.invoiceType;
    }
    productDataToSubmit.salesLedgerId = currentId.value;
    productDataToSubmit.type = 1;
    addOrUpdateSalesLedgerProduct(productDataToSubmit).then(res => {
        proxy.$modal.msgSuccess("提交成功");
        closeProductDia();
        getSalesLedgerWithProducts({ id: currentId.value, type: 1 }).then((res) => {
            productData.value = res.productData;
      getSalesLedgerWithProducts({ id: currentId.value, type: 1 }).then(res => {
        productData.value = JSON.parse(JSON.stringify(res.productData || []));
        });
    });
};
@@ -1325,46 +1851,23 @@
    }
    
    // 检查是否有已发货或审核通过的产品
    const shippedProducts = productSelectedRows.value.filter(row => isProductShipped(row));
    const shippedProducts = productSelectedRows.value.filter(row =>
      isProductShipped(row)
    );
    if (shippedProducts.length > 0) {
        proxy.$modal.msgWarning("已发货或审核通过的产品不能删除");
        return;
    }
    
    if (operationType.value === "add") {
        productSelectedRows.value.forEach((selectedRow) => {
    // 无论是新增还是编辑模式,都直接修改本地表格数据
    productSelectedRows.value.forEach(selectedRow => {
            const index = productData.value.findIndex(
                (product) => product.id === selectedRow.id
        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: 1 }).then(
                        (res) => {
                            productData.value = res.productData;
                        }
                    );
                });
            })
            .catch(() => {
                proxy.$modal.msg("已取消");
            });
    }
};
// 关闭产品弹框
const closeProductDia = () => {
@@ -1406,7 +1909,7 @@
        });
};
/** 判断单个产品是否已发货(根据shippingStatus判断,已发货或审核通过不可编辑和删除) */
const isProductShipped = (product) => {
  const isProductShipped = product => {
    if (!product) return false;
    const status = String(product.shippingStatus || "").trim();
    // 如果发货状态是"已发货"或"审核通过",则不可编辑和删除
@@ -1414,14 +1917,16 @@
};
/** 判断销售订单下是否存在已发货/发货完成的产品(不可删除) */
const hasShippedProducts = (products) => {
  const hasShippedProducts = products => {
    if (!products || !products.length) return false;
    return products.some((p) => {
    return products.some(p => {
        const status = String(p.shippingStatus || "").trim();
        // 有发货日期或车牌号视为已发货
        if (p.shippingDate || p.shippingCarNumber) return true;
        // 已进行发货、发货完成、已发货 均不可删除
        return status === "已进行发货" || status === "发货完成" || status === "已发货";
      return (
        status === "已进行发货" || status === "发货完成" || status === "已发货"
      );
    });
};
@@ -1431,12 +1936,13 @@
        proxy.$modal.msgWarning("请选择数据");
        return;
    }
    const ids = selectedRows.value.map((item) => item.id);
    const ids = selectedRows.value.map(item => item.id);
    // 检查是否有已进行发货或发货完成的销售订单,若有则不允许删除
    const cannotDeleteNames = [];
    for (const row of selectedRows.value) {
        let products = row.children && row.children.length > 0 ? row.children : null;
      let products =
        row.children && row.children.length > 0 ? row.children : null;
        if (!products) {
            try {
                const res = await productList({ salesLedgerId: row.id, type: 1 });
@@ -1450,7 +1956,9 @@
        }
    }
    if (cannotDeleteNames.length > 0) {
        proxy.$modal.msgWarning("已进行发货或发货完成的销售订单不能删除:" + cannotDeleteNames.join("、"));
      proxy.$modal.msgWarning(
        "已进行发货或发货完成的销售订单不能删除:" + cannotDeleteNames.join("、")
      );
        return;
    }
@@ -1460,7 +1968,7 @@
        type: "warning",
    })
        .then(() => {
            delLedger(ids).then((res) => {
        delLedger(ids).then(res => {
                proxy.$modal.msgSuccess("删除成功");
                getList();
            });
@@ -1487,12 +1995,15 @@
        for (const row of selectedRows.value) {
            try {
                // 调用productList接口查询产品数据
                const productRes = await productList({ salesLedgerId: row.id, type: 1 });
          const productRes = await productList({
            salesLedgerId: row.id,
            type: 1,
          });
                
                // 将产品数据整合到销售台账记录中
                const rowWithProducts = {
                    ...row,
                    products: productRes.data || []
            products: productRes.data || [],
                };
                
                printDataWithProducts.push(rowWithProducts);
@@ -1501,17 +2012,16 @@
                // 即使某个记录的产品数据获取失败,也要包含该记录
                printDataWithProducts.push({
                    ...row,
                    products: []
            products: [],
                });
            }
        }
        
        printData.value = printDataWithProducts;
        console.log('打印数据(包含产品):', printData.value);
      console.log("打印数据(包含产品):", printData.value);
        printPreviewVisible.value = true;
    } catch (error) {
        console.error('获取产品数据失败:', error);
      console.error("获取产品数据失败:", error);
        proxy.$modal.msgError("获取产品数据失败,请重试");
    } finally {
        proxy.$modal.closeLoading();
@@ -1519,11 +2029,11 @@
};
// 执行打印
const executePrint = () => {
    console.log('开始执行打印,数据条数:', printData.value.length);
    console.log('打印数据:', printData.value);
    console.log("开始执行打印,数据条数:", printData.value.length);
    console.log("打印数据:", printData.value);
    
    // 创建一个新的打印窗口
    const printWindow = window.open('', '_blank', 'width=800,height=600');
    const printWindow = window.open("", "_blank", "width=800,height=600");
    
    // 构建打印内容
    let printContent = `
@@ -1674,16 +2184,23 @@
            <div class="info-row">
              <div>
                <span class="label">发货日期:</span>
                <span class="value">${formatDate(item.createTime)}</span>
                                                                                                                                                                                                                                                                                  <span class="value">${formatDate(
                                                                                                                                                                                                                                                                                    item.createTime
                                                                                                                                                                                                                                                                                  )}</span>
              </div>
              <div>
                <span class="label">客户名称:</span>
                <span class="value">${item.customerName}</span>
                                                                                                                                                                                                                                                                                  <span class="value">${
                                                                                                                                                                                                                                                                                    item.customerName
                                                                                                                                                                                                                                                                                  }</span>
              </div>
            </div>
            <div class="info-row">
              <span class="label">单号:</span>
              <span class="value">${item.salesContractNo || ''}</span>
                                                                                                                                                                                                                                                                                <span class="value">${
                                                                                                                                                                                                                                                                                  item.salesContractNo ||
                                                                                                                                                                                                                                                                                  ""
                                                                                                                                                                                                                                                                                }</span>
            </div>
          </div>
@@ -1700,18 +2217,47 @@
                </tr>
              </thead>
              <tbody>
                ${item.products && item.products.length > 0 ?
            item.products.map(product => `
                                                                                                                                                                                                                                                                                  ${
                                                                                                                                                                                                                                                                                    item.products &&
                                                                                                                                                                                                                                                                                    item
                                                                                                                                                                                                                                                                                      .products
                                                                                                                                                                                                                                                                                      .length >
                                                                                                                                                                                                                                                                                      0
                                                                                                                                                                                                                                                                                      ? item.products
                                                                                                                                                                                                                                                                                          .map(
                                                                                                                                                                                                                                                                                            product => `
                    <tr>
                      <td>${product.productCategory || ''}</td>
                      <td>${product.specificationModel || ''}</td>
                      <td>${product.unit || ''}</td>
                      <td>${product.taxInclusiveUnitPrice || '0'}</td>
                      <td>${product.quantity || '0'}</td>
                      <td>${product.taxInclusiveTotalPrice || '0'}</td>
                                                                                                                                                                                                                                                                                        <td>${
                                                                                                                                                                                                                                                                                          product.productCategory ||
                                                                                                                                                                                                                                                                                          ""
                                                                                                                                                                                                                                                                                        }</td>
                                                                                                                                                                                                                                                                                        <td>${
                                                                                                                                                                                                                                                                                          product.specificationModel ||
                                                                                                                                                                                                                                                                                          ""
                                                                                                                                                                                                                                                                                        }</td>
                                                                                                                                                                                                                                                                                        <td>${
                                                                                                                                                                                                                                                                                          product.unit ||
                                                                                                                                                                                                                                                                                          ""
                                                                                                                                                                                                                                                                                        }</td>
                                                                                                                                                                                                                                                                                        <td>${
                                                                                                                                                                                                                                                                                          product.taxInclusiveUnitPrice ||
                                                                                                                                                                                                                                                                                          "0"
                                                                                                                                                                                                                                                                                        }</td>
                                                                                                                                                                                                                                                                                        <td>${
                                                                                                                                                                                                                                                                                          product.quantity ||
                                                                                                                                                                                                                                                                                          "0"
                                                                                                                                                                                                                                                                                        }</td>
                                                                                                                                                                                                                                                                                        <td>${
                                                                                                                                                                                                                                                                                          product.taxInclusiveTotalPrice ||
                                                                                                                                                                                                                                                                                          "0"
                                                                                                                                                                                                                                                                                        }</td>
                    </tr>
                  `).join('') :
            '<tr><td colspan="6" style="text-align: center; color: #999;">暂无产品数据</td></tr>'
                                                                                                                                                                                                                                                                                    `
                                                                                                                                                                                                                                                                                          )
                                                                                                                                                                                                                                                                                          .join(
                                                                                                                                                                                                                                                                                            ""
                                                                                                                                                                                                                                                                                          )
                                                                                                                                                                                                                                                                                      : '<tr><td colspan="6" style="text-align: center; color: #999;">暂无产品数据</td></tr>'
        }
              </tbody>
              <tfoot>
@@ -1720,8 +2266,12 @@
                  <td class="total-value"></td>
                  <td class="total-value"></td>
                  <td class="total-value"></td>
                  <td class="total-value">${getTotalQuantityForPrint(item.products)}</td>
                  <td class="total-value">${getTotalAmountForPrint(item.products)}</td>
                                                                                                                                                                                                                                                                                    <td class="total-value">${getTotalQuantityForPrint(
                                                                                                                                                                                                                                                                                      item.products
                                                                                                                                                                                                                                                                                    )}</td>
                                                                                                                                                                                                                                                                                    <td class="total-value">${getTotalAmountForPrint(
                                                                                                                                                                                                                                                                                      item.products
                                                                                                                                                                                                                                                                                    )}</td>
                </tr>
              </tfoot>
            </table>
@@ -1745,11 +2295,16 @@
            <div class="footer-row">
              <div class="footer-item">
                <span class="label">操作员:</span>
                <span class="value">${userStore.nickName || '撕开前'}</span>
                                                                                                                                                                                                                                                                                  <span class="value">${
                                                                                                                                                                                                                                                                                    userStore.nickName ||
                                                                                                                                                                                                                                                                                    "撕开前"
                                                                                                                                                                                                                                                                                  }</span>
              </div>
              <div class="footer-item">
                <span class="label">打印日期:</span>
                <span class="value">${formatDateTime(new Date())}</span>
                                                                                                                                                                                                                                                                                  <span class="value">${formatDateTime(
                                                                                                                                                                                                                                                                                    new Date()
                                                                                                                                                                                                                                                                                  )}</span>
              </div>
            </div>
          </div>
@@ -1777,7 +2332,7 @@
    };
};
// 格式化日期
const formatDate = (dateString) => {
  const formatDate = dateString => {
    if (!dateString) return getCurrentDate();
    const date = new Date(dateString);
    const year = date.getFullYear();
@@ -1786,7 +2341,7 @@
    return `${year}/${month}/${day}`;
};
// 格式化日期时间
const formatDateTime = (date) => {
  const formatDateTime = date => {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
@@ -1796,8 +2351,8 @@
    return `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`;
};
// 计算产品总数量
const getTotalQuantity = (products) => {
    if (!products || products.length === 0) return '0';
  const getTotalQuantity = products => {
    if (!products || products.length === 0) return "0";
    const total = products.reduce((sum, product) => {
        return sum + (parseFloat(product.quantity) || 0);
    }, 0);
@@ -1805,8 +2360,8 @@
};
// 计算产品总金额
const getTotalAmount = (products) => {
    if (!products || products.length === 0) return '0';
  const getTotalAmount = products => {
    if (!products || products.length === 0) return "0";
    const total = products.reduce((sum, product) => {
        return sum + (parseFloat(product.taxInclusiveTotalPrice) || 0);
    }, 0);
@@ -1814,16 +2369,16 @@
};
// 用于打印的计算函数
const getTotalQuantityForPrint = (products) => {
    if (!products || products.length === 0) return '0';
  const getTotalQuantityForPrint = products => {
    if (!products || products.length === 0) return "0";
    const total = products.reduce((sum, product) => {
        return sum + (parseFloat(product.quantity) || 0);
    }, 0);
    return total.toFixed(2);
};
const getTotalAmountForPrint = (products) => {
    if (!products || products.length === 0) return '0';
  const getTotalAmountForPrint = products => {
    if (!products || products.length === 0) return "0";
    const total = products.reduce((sum, product) => {
        return sum + (parseFloat(product.taxInclusiveTotalPrice) || 0);
    }, 0);
@@ -1890,7 +2445,9 @@
    }
    if (isCalculating.value) return;
    
    const exclusiveTotalPrice = parseFloat(productForm.value.taxExclusiveTotalPrice);
    const exclusiveTotalPrice = parseFloat(
      productForm.value.taxExclusiveTotalPrice
    );
    const quantity = parseFloat(productForm.value.quantity);
    const taxRate = parseFloat(productForm.value.taxRate);
    
@@ -1906,13 +2463,51 @@
    productForm.value.taxInclusiveTotalPrice = inclusiveTotalPrice.toFixed(2);
    
    // 计算含税单价 = 含税总价 / 数量
    productForm.value.taxInclusiveUnitPrice = (inclusiveTotalPrice / quantity).toFixed(2);
    productForm.value.taxInclusiveUnitPrice = (
      inclusiveTotalPrice / quantity
    ).toFixed(2);
    
    isCalculating.value = false;
};
  // 对私客户价格计算:单价和运费变化时计算含运费单价和总价
  const calculatePrivatePrice = () => {
    if (currentCustomerType.value == 2) {
      const unitPrice = parseFloat(productForm.value.unitPrice) || 0;
      const freight = parseFloat(productForm.value.freight) || 0;
      const quantity = parseFloat(productForm.value.quantity) || 0;
      // 计算含运费单价
      productForm.value.priceWithFreight = (unitPrice + freight).toFixed(2);
      // 计算总价
      productForm.value.totalPrice = (
        parseFloat(productForm.value.priceWithFreight) * quantity
      ).toFixed(2);
    }
  };
  // 对私客户价格计算:含运费单价变化时计算总价
  const calculatePrivateTotal = () => {
    if (currentCustomerType.value == 2) {
      const priceWithFreight =
        parseFloat(productForm.value.priceWithFreight) || 0;
      const quantity = parseFloat(productForm.value.quantity) || 0;
      // 计算总价
      productForm.value.totalPrice = (priceWithFreight * quantity).toFixed(2);
    }
  };
// 根据数量变化计算总价
const calculateFromQuantity = () => {
    // 对私客户使用对私计算逻辑
    if (currentCustomerType.value == 2) {
      calculatePrivatePrice();
      return;
    }
    // 对公客户使用原有的计算逻辑
    if (!productForm.value.taxRate) {
        proxy.$modal.msgWarning("请先选择税率");
        return;
@@ -1945,6 +2540,13 @@
// 根据含税单价变化计算总价
const calculateFromUnitPrice = () => {
    // 对私客户使用对私计算逻辑
    if (currentCustomerType.value == 2) {
      calculatePrivatePrice();
      return;
    }
    // 对公客户使用原有的计算逻辑
    if (!productForm.value.taxRate) {
        proxy.$modal.msgWarning("请先选择税率");
        return;
@@ -1977,13 +2579,21 @@
// 根据税率变化计算不含税总价
const calculateFromTaxRate = () => {
    // 对私客户不需要税率计算
    if (currentCustomerType.value == 2) {
      return;
    }
    // 对公客户使用原有的计算逻辑
    if (!productForm.value.taxRate) {
        proxy.$modal.msgWarning("请先选择税率");
        return;
    }
    if (isCalculating.value) return;
    
    const inclusiveTotalPrice = parseFloat(productForm.value.taxInclusiveTotalPrice);
    const inclusiveTotalPrice = parseFloat(
      productForm.value.taxInclusiveTotalPrice
    );
    const taxRate = parseFloat(productForm.value.taxRate);
    
    if (!inclusiveTotalPrice || !taxRate) {
@@ -1994,10 +2604,7 @@
    
    // 计算不含税总价
    productForm.value.taxExclusiveTotalPrice =
        proxy.calculateTaxExclusiveTotalPrice(
            inclusiveTotalPrice,
            taxRate
        );
      proxy.calculateTaxExclusiveTotalPrice(inclusiveTotalPrice, taxRate);
    
    isCalculating.value = false;
};
@@ -2005,62 +2612,62 @@
 * 获取发货状态文本
 * @param row 行数据
 */
const getShippingStatusText = (row) => {
  const getShippingStatusText = row => {
    // 如果已发货(有发货日期或车牌号),显示"已发货"
    if (row.shippingDate || row.shippingCarNumber) {
        return '已发货';
      return "已发货";
    }
    
    // 获取发货状态字段
    const status = row.shippingStatus;
    
    // 如果状态为空或未定义,默认为"待发货"
    if (status === null || status === undefined || status === '') {
        return '待发货';
    if (status === null || status === undefined || status === "") {
      return "待发货";
    }
    
    // 状态是字符串
    const statusStr = String(status).trim();
    const statusTextMap = {
        '待发货': '待发货',
        '待审核': '待审核',
        '审核中': '审核中',
        '审核拒绝': '审核拒绝',
        '审核通过': '审核通过',
        '已发货': '已发货'
      待发货: "待发货",
      待审核: "待审核",
      审核中: "审核中",
      审核拒绝: "审核拒绝",
      审核通过: "审核通过",
      已发货: "已发货",
    };
    return statusTextMap[statusStr] || '待发货';
    return statusTextMap[statusStr] || "待发货";
};
/**
 * 获取发货状态标签类型(颜色)
 * @param row 行数据
 */
const getShippingStatusType = (row) => {
  const getShippingStatusType = row => {
    // 如果已发货(有发货日期或车牌号),显示绿色
    if (row.shippingDate || row.shippingCarNumber) {
        return 'success';
      return "success";
    }
    
    // 获取发货状态字段
    const status = row.shippingStatus;
    
    // 如果状态为空或未定义,默认为灰色(待发货)
    if (status === null || status === undefined || status === '') {
        return 'info';
    if (status === null || status === undefined || status === "") {
      return "info";
    }
    
    // 状态是字符串
    const statusStr = String(status).trim();
    const typeTextMap = {
        '待发货': 'info',
        '待审核': 'info',
        '审核中': 'warning',
        '审核拒绝': 'danger',
        '审核通过': 'success',
        '已发货': 'success'
      待发货: "info",
      待审核: "info",
      审核中: "warning",
      审核拒绝: "danger",
      审核通过: "success",
      已发货: "success",
    };
    return typeTextMap[statusStr] || 'info';
    return typeTextMap[statusStr] || "info";
};
/**
@@ -2068,7 +2675,7 @@
 * 只有在产品状态是充足,发货状态是待发货和审核拒绝的时候才可以发货
 * @param row 行数据
 */
const canShip = (row) => {
  const canShip = row => {
    // 产品状态必须是充足(approveStatus === 1)
    if (row.approveStatus !== 1) {
        return false;
@@ -2083,8 +2690,8 @@
    }
    
    // 发货状态必须是"待发货"或"审核拒绝"
    const statusStr = shippingStatus ? String(shippingStatus).trim() : '';
    return statusStr === '待发货' || statusStr === '审核拒绝';
    const statusStr = shippingStatus ? String(shippingStatus).trim() : "";
    return statusStr === "待发货" || statusStr === "审核拒绝";
};
/**
@@ -2092,21 +2699,23 @@
 *
 * @param row 下载文件的相关信息对象
 */
const fileListRef = ref(null)
const fileListDialogVisible = ref(false)
const downLoadFile = (row) => {
    getSalesLedgerWithProducts({ id: row.id, type: 1 }).then((res) => {
  const fileListRef = ref(null);
  const fileListDialogVisible = ref(false);
  const downLoadFile = row => {
    getSalesLedgerWithProducts({ id: row.id, type: 1 }).then(res => {
        if (fileListRef.value) {
            fileListRef.value.open(res.salesLedgerFiles)
        fileListRef.value.open(res.salesLedgerFiles);
        }
    });
}
  };
// 打开发货弹框
const openDeliveryForm = (row) => {
  const openDeliveryForm = row => {
    // 检查是否可以发货
    if (!canShip(row)) {
        proxy.$modal.msgWarning("只有在产品状态是充足,发货状态是待发货或审核拒绝的时候才可以发货");
      proxy.$modal.msgWarning(
        "只有在产品状态是充足,发货状态是待发货或审核拒绝的时候才可以发货"
      );
        return;
    }
    
@@ -2122,7 +2731,7 @@
// 提交发货表单
const submitDelivery = () => {
  proxy.$refs["deliveryFormRef"].validate((valid) => {
    proxy.$refs["deliveryFormRef"].validate(valid => {
    if (valid) {
      // 审批人必填校验(所有节点都要选人)
      const hasEmptyApprover = approverNodes.value.some(node => !node.userId);
@@ -2130,7 +2739,9 @@
        proxy.$modal.msgError("请为所有审批节点选择审批人!");
        return;
      }
      const approveUserIds = approverNodes.value.map(node => node.userId).join(",");
        const approveUserIds = approverNodes.value
          .map(node => node.userId)
          .join(",");
      // 保存当前展开的行ID,以便发货后重新加载子表格数据
      const currentExpandedKeys = [...expandedRowKeys.value];
      const salesLedgerId = currentDeliveryRow.value.salesLedgerId;
@@ -2139,8 +2750,7 @@
        salesLedgerProductId: currentDeliveryRow.value.id,
        type: deliveryForm.value.type,
                approveUserIds,
      })
        .then(() => {
        }).then(() => {
          proxy.$modal.msgSuccess("发货成功");
          closeDeliveryDia();
          // 刷新主表数据
@@ -2149,12 +2759,16 @@
            if (currentExpandedKeys.length > 0) {
              // 使用 Promise.all 并行加载所有展开行的子表格数据
              const loadPromises = currentExpandedKeys.map(ledgerId => {
                return productList({ salesLedgerId: ledgerId, type: 1 }).then((res) => {
                  const index = tableData.value.findIndex((item) => item.id === ledgerId);
                return productList({ salesLedgerId: ledgerId, type: 1 }).then(
                  res => {
                    const index = tableData.value.findIndex(
                      item => item.id === ledgerId
                    );
                  if (index > -1) {
                    tableData.value[index].children = res.data;
                  }
                });
                  }
                );
              });
              Promise.all(loadPromises).then(() => {
                // 恢复展开状态
@@ -2162,7 +2776,7 @@
              });
            }
          });
        })
        });
    }
  });
};
@@ -2182,7 +2796,7 @@
    getList();
    userListNoPage().then(res => {
        userList.value = res.data;
    })
    });
    getCurrentFactoryName();
});
</script>
@@ -2193,19 +2807,19 @@
}
::v-deep .yellow {
  background-color: #FAF0DE;
    background-color: #faf0de;
}
::v-deep .pink {
  background-color: #FAE1DE;
    background-color: #fae1de;
}
::v-deep .red {
  background-color: #FAE1DE;
    background-color: #fae1de;
}
::v-deep .purple{
  background-color: #F4DEFA;
    background-color: #f4defa;
}
.table_list {
@@ -2312,7 +2926,8 @@
        border-collapse: collapse;
        border: 1px solid #000;
        
        th, td {
      th,
      td {
            border: 1px solid #000;
            padding: 6px;
            text-align: center;