gaoluyang
4 天以前 d16397e58995f4acbd5e8a715ff9186a59258bd7
src/views/salesManagement/salesLedger/index.vue
@@ -6,21 +6,17 @@
          <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.customerContractNo" 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"
            @change="handleQuery" />
        </el-form-item>
        <el-form-item label="项目名称:">
          <el-input v-model="searchForm.projectName" placeholder="请输入" clearable prefix-icon="Search"
            @change="handleQuery" />
        </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-form-item>
        <el-form-item label="产品大类:">
          <el-input v-model="searchForm.productCategory" placeholder="请输入" clearable prefix-icon="Search"
                    @change="handleQuery" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleQuery"> 搜索 </el-button>
@@ -50,6 +46,15 @@
              <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 === 0" type="info">未出库</el-tag>
                  <el-tag v-if="scope.row.approveStatus === 1" type="success">已出库</el-tag>
                  <el-tag v-if="scope.row.approveStatus === 2" type="warning">审核中</el-tag>
                  <el-tag v-if="scope.row.approveStatus === 3" type="success">审核成功</el-tag>
                  <el-tag v-if="scope.row.approveStatus === 4" type="danger">审核失败</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="数量" prop="quantity" />
              <el-table-column label="税率(%)" prop="taxRate" />
              <el-table-column label="含税单价(元)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" />
@@ -60,20 +65,19 @@
        </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="customerContractNo" 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 fixed="right" label="操作" min-width="200" align="center">
        <el-table-column label="发货车牌" prop="shippingCarNumber" width="140" align="center" show-overflow-tooltip />
        <el-table-column label="发货日期" prop="shippingDate" width="140" align="center" show-overflow-tooltip />
        <el-table-column fixed="right" label="操作" min-width="140" align="center">
          <template #default="scope">
            <el-button link type="primary" size="small" :disabled="scope.row.invoiceTotal>0 || scope.row.entryPersonName !== userStore.nickName" @click="openForm('edit', scope.row)">编辑</el-button>
<!--            <el-button link type="primary" size="small" @click="openForm('view', scope.row)">详情</el-button>-->
            <el-button link type="primary" size="small" @click="openForm('edit', scope.row)">编辑</el-button>
            <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">附件</el-button>
            <el-button link type="primary" size="small" @click="openDeliveryForm(scope.row)">发货</el-button>
          </template>
@@ -82,8 +86,14 @@
      <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper"
        :page="page.current" :limit="page.size" @pagination="paginationChange" />
    </div>
    <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '新增销售台账页面' : '编辑销售台账页面'" width="70%"
      @close="closeDia">
    <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 :gutter="30">
          <el-col :span="12">
@@ -93,7 +103,9 @@
          </el-col>
          <el-col :span="12">
            <el-form-item label="业务员:" prop="salesman">
              <el-select v-model="form.salesman" placeholder="请选择" clearable :disabled="operationType === 'view'">
              <el-select v-model="form.salesman"
                                     filterable
                         :reserve-keyword="false" placeholder="请选择" clearable :disabled="operationType === 'view'">
                <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
                  :value="item.nickName" />
              </el-select>
@@ -102,26 +114,14 @@
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="客户合同号:" prop="customerContractNo">
              <el-input v-model="form.customerContractNo" placeholder="请输入" clearable :disabled="operationType === 'view'"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="客户名称:" prop="customerId">
              <el-select v-model="form.customerId" placeholder="请选择" clearable :disabled="operationType === 'view'">
              <el-select v-model="form.customerId" placeholder="请选择" clearable :disabled="operationType === 'view'" filterable>
                <el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.id">
                  {{
                    item.customerName + "——" + item.taxpayerIdentificationNumber
                    item.customerName+'-'+item.customerType
                  }}
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="项目名称:" prop="projectName">
              <el-input v-model="form.projectName" placeholder="请输入" clearable :disabled="operationType === 'view'" />
            </el-form-item>
          </el-col>
               <el-col :span="12">
@@ -134,7 +134,10 @@
        <el-row :gutter="30">
               <el-col :span="12">
                  <el-form-item label="录入人:" prop="entryPerson">
                     <el-select v-model="form.entryPerson" placeholder="请选择" clearable @change="changs" disabled>
                     <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" />
                     </el-select>
                  </el-form-item>
@@ -208,7 +211,7 @@
          <el-button @click="closeDia">取消</el-button>
        </div>
      </template>
    </el-dialog>
    </FormDialog>
    <el-dialog v-model="productFormVisible" :title="productOperationType === 'add' ? '新增产品' : '编辑产品'" width="40%"
      @close="closeProductDia">
      <el-form :model="productForm" label-width="140px" label-position="top" :rules="productRules" ref="productFormRef">
@@ -240,17 +243,19 @@
          </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-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-input-number :step="1" :min="0" v-model="productForm.taxRate" style="width: 100%"
                               placeholder="请输入" clearable @change="calculateFromTaxRate" />
                  </el-form-item>
               </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="含税单价(元):" prop="taxInclusiveUnitPrice">
            <el-form-item label="含税/不含税单价(元):" prop="taxInclusiveUnitPrice">
              <el-input-number :step="0.01" :min="0" v-model="productForm.taxInclusiveUnitPrice" style="width: 100%"
                                              :precision="2"
                                              placeholder="请输入" clearable @change="calculateFromUnitPrice" />
@@ -317,10 +322,10 @@
               <div v-for="(item, index) in printData" :key="index" class="print-page">
                  <div class="delivery-note">
                     <div class="header">
                        <div class="company-name">鼎诚瑞实业有限责任公司</div>
                        <div class="company-name">青海湟水峡农业发展有限公司</div>
                        <div class="document-title">零售发货单</div>
                     </div>
                     <div class="info-section">
                        <div class="info-row">
                           <div>
@@ -328,12 +333,15 @@
                              <span class="value">{{ formatDate(item.createTime) }}</span>
                           </div>
                           <div>
                              <span class="label">客户名称:</span>
                              <span class="value">{{ item.customerName || '张爱有' }}</span>
                              <span class="label">发货车牌号:</span>
                              <span class="value">{{ item.shippingCarNumber }}</span>
                           </div>
                        </div>
                        <div class="info-row">
                           <div>
                              <span class="label">客户名称:</span>
                              <span class="value">{{ item.customerName || '张爱有' }}</span>
                           </div>
                           <span class="label">单号:</span>
                           <span class="value">{{ item.salesContractNo }}</span>
                        </div>
@@ -457,26 +465,31 @@
<script setup>
import { getToken } from "@/utils/auth";
import pagination from "@/components/PIMTable/Pagination.vue";
import {onMounted, ref} from "vue";
import {onMounted, ref, getCurrentInstance} from "vue";
import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js";
import { ElMessageBox } from "element-plus";
import { ElMessageBox, ElMessage } from "element-plus";
import { UploadFilled } from "@element-plus/icons-vue";
import useUserStore from "@/store/modules/user";
import { userListNoPage } from "@/api/system/user.js";
import FileList from "./fileList.vue";
import FileList from '@/views/salesManagement/salesLedger/fileList.vue';
import FormDialog from '@/components/Dialog/FormDialog.vue';
import { getQuotationList } from "@/api/salesManagement/salesQuotation.js";
import {
  ledgerListPage,
  productList,
  customerList,
  addOrUpdateSalesLedger,
  getSalesLedgerWithProducts,
  delLedger,
  addOrUpdateSalesLedgerProduct,
  delProduct,
  delLedgerFile,
   ledgerListPage,
   productList,
   customerList,
   addOrUpdateSalesLedger,
   getSalesLedgerWithProducts,
   delLedger,
   addOrUpdateSalesLedgerProduct,
   delProduct,
   delLedgerFile, getProductInventory,
} from "@/api/salesManagement/salesLedger.js";
import { getQuotationDetail } from "@/api/salesManagement/salesQuotation.js";
import { modelList, productTreeList } from "@/api/basicData/product.js";
import useFormData from "@/hooks/useFormData.js";
import dayjs from "dayjs";
import { getCurrentDate } from "@/utils/index.js";
const userStore = useUserStore();
const { proxy } = getCurrentInstance();
@@ -502,9 +515,8 @@
const data = reactive({
  searchForm: {
    customerName: "", // 客户名称
    customerContractNo: "", // 客户合同编号
    salesContractNo: "", // 销售合同编号
    projectName: "", // 项目名称
    productCategory: "", // 产品大类
    entryDate: null, // 录入日期
    entryDateStart: undefined,
    entryDateEnd: undefined,
@@ -512,9 +524,7 @@
  form: {
    salesContractNo: "",
    salesman: "",
    customerContractNo: "",
    customerId: "",
    projectName: "",
    entryPerson: "",
    entryDate: "",
    maintenanceTime: "",
@@ -524,15 +534,11 @@
  },
  rules: {
    salesman: [{ required: true, message: "请选择", trigger: "change" }],
    customerContractNo: [
      { required: true, message: "请输入", trigger: "blur" },
    ],
    customerId: [{ required: true, message: "请选择", trigger: "change" }],
    projectName: [{ required: true, message: "请输入", trigger: "blur" }],
    entryPerson: [{ required: true, message: "请选择", trigger: "change" }],
    entryDate: [{ required: true, message: "请选择", trigger: "change" }],
    executionDate: [{ required: true, message: "请选择", trigger: "change" }],
  },
    },
});
const { form, rules } = toRefs(data);
const { form: searchForm } = useFormData(data.searchForm);
@@ -563,14 +569,14 @@
    taxInclusiveUnitPrice: [
      { required: true, message: "请输入", trigger: "blur" },
    ],
    taxRate: [{ required: true, message: "请选择", trigger: "change" }],
    // taxRate: [{ required: true, message: "请选择", trigger: "change" }],
    taxInclusiveTotalPrice: [
      { required: true, message: "请输入", trigger: "blur" },
    ],
    taxExclusiveTotalPrice: [
      { required: true, message: "请输入", trigger: "blur" },
    ],
    invoiceType: [{ required: true, message: "请选择", trigger: "change" }],
    // invoiceType: [{ required: true, message: "请选择", trigger: "change" }],
  },
});
const { productForm, productRules } = toRefs(productFormData);
@@ -619,7 +625,11 @@
// 查询列表
/** 搜索按钮操作 */
const handleQuery = () => {
  page.current = 1;
  // 只有在点击搜索按钮时才重置页码到第一页
  // 避免表单字段change事件干扰分页
  if (arguments.length === 0) {
    page.current = 1;
  }
   expandedRowKeys.value = [];
  getList();
};
@@ -646,8 +656,12 @@
};
// 获取产品大类tree数据
const getProductOptions = () => {
  productTreeList().then((res) => {
    productOptions.value = convertIdToValue(res);
  // 返回 Promise,便于在编辑产品时等待加载完成
  return productTreeList().then((res) => {
    // 兼容接口返回 { data: [] } 或直接返回数组
    const list = Array.isArray(res) ? res : (res?.data ?? []);
    productOptions.value = convertIdToValue(list);
    return productOptions.value;
  });
};
const formattedNumber = (row, column, cellValue) => {
@@ -666,6 +680,7 @@
  if (index !== -1) {
    productForm.value.specificationModel = modelOptions.value[index].model;
    productForm.value.unit = modelOptions.value[index].unit;
    fetchQuotationPrice();
  } else {
    productForm.value.specificationModel = null;
    productForm.value.unit = null;
@@ -685,6 +700,29 @@
  }
  return null; // 没有找到节点,返回null
};
// 根据报价接口回填单价
const fetchQuotationPrice = async () => {
  // 需要客户类型、产品名称、规格
  const customer = customerOption.value.find((c) => c.id === form.value.customerId);
  const customerType = customer?.customerType || customer?.type;
  const productName = productForm.value.productCategory;
  const specification = productForm.value.specificationModel;
  try {
    const { data } = await getQuotationDetail({
      type: customerType,
      productName,
      specification,
    });
    const price = data;
    if (price !== null && price !== undefined) {
      productForm.value.taxInclusiveUnitPrice = Number(price);
      mathNum(); // 重新计算总价
    }
  } catch (error) {
    console.error("获取报价单价失败", error);
  }
};
function convertIdToValue(data) {
  return data.map((item) => {
    const { id, children, ...rest } = item;
@@ -698,6 +736,19 @@
    return newItem;
  });
}
// 根据名称反查产品大类 id,便于仅存名称时的反显
function findNodeIdByLabel(nodes, label) {
  if (!label) return null;
  for (let i = 0; i < nodes.length; i++) {
    const node = nodes[i];
    if (node.label === label) return node.value;
    if (node.children && node.children.length > 0) {
      const found = findNodeIdByLabel(node.children, label);
      if (found !== null && found !== undefined) return found;
    }
  }
  return null;
}
// 表格选择数据
const handleSelectionChange = (selection) => {
@@ -755,7 +806,12 @@
    customerOption.value = res;
  });
  form.value.entryPerson = userStore.id;
  if (type !== "add") {
  if (type === "add") {
    // 新增时设置录入日期为当天
    form.value.entryDate = getCurrentDate();
    // 签订日期默认为当天
    form.value.executionDate = getCurrentDate();
  } else {
    currentId.value = row.id;
    getSalesLedgerWithProducts({ id: row.id, type: 1 }).then((res) => {
      form.value = { ...res };
@@ -845,13 +901,40 @@
const productIndex = ref(0);
// 打开产品弹框
const openProductForm = (type, row,index) => {
const openProductForm = async (type, row, index) => {
  productOperationType.value = type;
  productForm.value = {};
  proxy.resetForm("productFormRef");
  // 新增、编辑都需先加载产品树,否则 el-tree-select 无数据
  try {
    await getProductOptions();
  } catch (e) {
    console.error("加载产品树失败", e);
  }
  if (type === "edit") {
    productForm.value = { ...row };
    productIndex.value = index;
    // 编辑时根据产品大类名称反查 tree 节点 id,并加载规格型号列表
    try {
      const options = productOptions.value && productOptions.value.length > 0
        ? productOptions.value
        : await getProductOptions();
      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
        );
        if (currentModel) {
          productForm.value.productModelId = currentModel.id;
        }
      }
    } catch (e) {
      // 加载失败时保持可编辑,不中断弹窗
      console.error("加载产品规格型号失败", e);
    }
  }
  productFormVisible.value = true;
  getProductOptions();
@@ -975,25 +1058,25 @@
      proxy.$modal.msgWarning("请选择要打印的数据");
      return;
   }
   // 显示加载状态
   proxy.$modal.loading("正在获取产品数据,请稍候...");
   try {
      // 为每个选中的销售台账记录查询对应的产品数据
      const printDataWithProducts = [];
      for (const row of selectedRows.value) {
         try {
            // 调用productList接口查询产品数据
            const productRes = await productList({ salesLedgerId: row.id, type: 1 });
            // 将产品数据整合到销售台账记录中
            const rowWithProducts = {
               ...row,
               products: productRes.data || []
            };
            printDataWithProducts.push(rowWithProducts);
         } catch (error) {
            console.error(`获取销售台账 ${row.id} 的产品数据失败:`, error);
@@ -1004,11 +1087,11 @@
            });
         }
      }
      printData.value = printDataWithProducts;
      console.log('打印数据(包含产品):', printData.value);
      printPreviewVisible.value = true;
   } catch (error) {
      console.error('获取产品数据失败:', error);
      proxy.$modal.msgError("获取产品数据失败,请重试");
@@ -1020,10 +1103,10 @@
const executePrint = () => {
   console.log('开始执行打印,数据条数:', printData.value.length);
   console.log('打印数据:', printData.value);
   // 创建一个新的打印窗口
   const printWindow = window.open('', '_blank', 'width=800,height=600');
   // 构建打印内容
   let printContent = `
    <!DOCTYPE html>
@@ -1159,17 +1242,17 @@
    </head>
    <body>
  `;
   // 为每条数据生成打印页面
   printData.value.forEach((item, index) => {
      printContent += `
      <div class="print-page">
        <div class="delivery-note">
          <div class="header">
            <div class="company-name">鼎诚瑞实业有限责任公司</div>
            <div class="company-name">青海湟水峡农业发展有限公司</div>
            <div class="document-title">零售发货单</div>
          </div>
          <div class="info-section">
            <div class="info-row">
              <div>
@@ -1200,7 +1283,7 @@
                </tr>
              </thead>
              <tbody>
                ${item.products && item.products.length > 0 ?
                ${item.products && item.products.length > 0 ?
                  item.products.map(product => `
                    <tr>
                      <td>${product.productCategory || ''}</td>
@@ -1210,7 +1293,7 @@
                      <td>${product.quantity || '0'}</td>
                      <td>${product.taxInclusiveTotalPrice || '0'}</td>
                    </tr>
                  `).join('') :
                  `).join('') :
                  '<tr><td colspan="6" style="text-align: center; color: #999;">暂无产品数据</td></tr>'
                }
              </tbody>
@@ -1257,16 +1340,16 @@
      </div>
    `;
   });
   printContent += `
    </body>
    </html>
  `;
   // 写入内容到新窗口
   printWindow.document.write(printContent);
   printWindow.document.close();
   // 等待内容加载完成后打印
   printWindow.onload = () => {
      setTimeout(() => {
@@ -1295,15 +1378,6 @@
   const seconds = String(date.getSeconds()).padStart(2, "0");
   return `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`;
};
// 获取当前日期并格式化为 YYYY-MM-DD
function getCurrentDate() {
  const today = new Date();
  const year = today.getFullYear();
  const month = String(today.getMonth() + 1).padStart(2, "0"); // 月份从0开始
  const day = String(today.getDate()).padStart(2, "0");
  return `${year}-${month}-${day}`;
}
// 计算产品总数量
const getTotalQuantity = (products) => {
  if (!products || products.length === 0) return '0';
@@ -1366,148 +1440,151 @@
// 根据含税总价计算含税单价和数量
const calculateFromTotalPrice = () => {
  if (isCalculating.value) return;
  const totalPrice = parseFloat(productForm.value.taxInclusiveTotalPrice);
  const quantity = parseFloat(productForm.value.quantity);
  const taxRate = Number(productForm.value.taxRate) || 0;
  if (!totalPrice || !quantity || quantity <= 0) {
    return;
  }
  isCalculating.value = true;
  // 计算含税单价 = 含税总价 / 数量
  productForm.value.taxInclusiveUnitPrice = (totalPrice / quantity).toFixed(2);
  // 如果有税率,计算不含税总价
  if (productForm.value.taxRate) {
    productForm.value.taxExclusiveTotalPrice =
  productForm.value.taxExclusiveTotalPrice =
      proxy.calculateTaxExclusiveTotalPrice(
        totalPrice,
        productForm.value.taxRate
          totalPrice,
          taxRate
      );
  }
  isCalculating.value = false;
};
// 根据不含税总价计算含税单价和数量
const calculateFromExclusiveTotalPrice = () => {
   if (!productForm.value.taxRate) {
      proxy.$modal.msgWarning("请先选择税率");
      return;
   }
   // if (!productForm.value.taxRate) {
   //    proxy.$modal.msgWarning("请先选择税率");
   //    return;
   // }
  if (isCalculating.value) return;
  const exclusiveTotalPrice = parseFloat(productForm.value.taxExclusiveTotalPrice);
  const quantity = parseFloat(productForm.value.quantity);
  const taxRate = parseFloat(productForm.value.taxRate);
  if (!exclusiveTotalPrice || !quantity || quantity <= 0 || !taxRate) {
  const taxRate = Number(productForm.value.taxRate) || 0;
  // if (!exclusiveTotalPrice || !quantity || quantity <= 0 || !taxRate) {
  //   return;
  // }
  if (!exclusiveTotalPrice || !quantity || quantity <= 0) {
    return;
  }
  isCalculating.value = true;
  // 先计算含税总价 = 不含税总价 / (1 - 税率/100)
  const taxRateDecimal = taxRate / 100;
  const inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal);
  productForm.value.taxInclusiveTotalPrice = inclusiveTotalPrice.toFixed(2);
  // 计算含税单价 = 含税总价 / 数量
  productForm.value.taxInclusiveUnitPrice = (inclusiveTotalPrice / quantity).toFixed(2);
  isCalculating.value = false;
};
// 根据数量变化计算总价
const calculateFromQuantity = () => {
   if (!productForm.value.taxRate) {
      proxy.$modal.msgWarning("请先选择税率");
      return;
   }
   // if (!productForm.value.taxRate) {
   //    proxy.$modal.msgWarning("请先选择税率");
   //    return;
   // }
  if (isCalculating.value) return;
  const quantity = parseFloat(productForm.value.quantity);
  const unitPrice = parseFloat(productForm.value.taxInclusiveUnitPrice);
  const taxRate = Number(productForm.value.taxRate) || 0;
  if (!quantity || quantity <= 0 || !unitPrice) {
    return;
  }
  isCalculating.value = true;
  // 计算含税总价
  productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
  // 如果有税率,计算不含税总价
  if (productForm.value.taxRate) {
    productForm.value.taxExclusiveTotalPrice =
  productForm.value.taxExclusiveTotalPrice =
      proxy.calculateTaxExclusiveTotalPrice(
        productForm.value.taxInclusiveTotalPrice,
        productForm.value.taxRate
          productForm.value.taxInclusiveTotalPrice,
          taxRate
      );
  }
  isCalculating.value = false;
};
// 根据含税单价变化计算总价
const calculateFromUnitPrice = () => {
   if (!productForm.value.taxRate) {
      proxy.$modal.msgWarning("请先选择税率");
      return;
   }
   // if (!productForm.value.taxRate) {
   //    proxy.$modal.msgWarning("请先选择税率");
   //    return;
   // }
  if (isCalculating.value) return;
  const quantity = parseFloat(productForm.value.quantity);
  const unitPrice = parseFloat(productForm.value.taxInclusiveUnitPrice);
  const taxRate = Number(productForm.value.taxRate) || 0;
  if (!quantity || quantity <= 0 || !unitPrice) {
    return;
  }
  isCalculating.value = true;
  // 计算含税总价
  productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
  // 如果有税率,计算不含税总价
  if (productForm.value.taxRate) {
    productForm.value.taxExclusiveTotalPrice =
  productForm.value.taxExclusiveTotalPrice =
      proxy.calculateTaxExclusiveTotalPrice(
        productForm.value.taxInclusiveTotalPrice,
        productForm.value.taxRate
          productForm.value.taxInclusiveTotalPrice,
          taxRate
      );
  }
  isCalculating.value = false;
};
// 根据税率变化计算不含税总价
const calculateFromTaxRate = () => {
   if (!productForm.value.taxRate) {
      proxy.$modal.msgWarning("请先选择税率");
      return;
   }
   // if (!productForm.value.taxRate) {
   //    proxy.$modal.msgWarning("请先选择税率");
   //    return;
   // }
  if (isCalculating.value) return;
  const inclusiveTotalPrice = parseFloat(productForm.value.taxInclusiveTotalPrice);
  const taxRate = parseFloat(productForm.value.taxRate);
  if (!inclusiveTotalPrice || !taxRate) {
  const taxRate = Number(productForm.value.taxRate) || 0;
  // if (!inclusiveTotalPrice || !taxRate) {
  //   return;
  // }
  if (!inclusiveTotalPrice) {
    return;
  }
  isCalculating.value = true;
  // 计算不含税总价
  productForm.value.taxExclusiveTotalPrice =
    proxy.calculateTaxExclusiveTotalPrice(
      inclusiveTotalPrice,
      taxRate
    );
  isCalculating.value = false;
};
/**
@@ -1524,12 +1601,18 @@
// 打开发货弹框
const openDeliveryForm = (row) => {
  currentDeliveryRow.value = row;
  deliveryForm.value = {
    shippingDate: getCurrentDate(),
    shippingCarNumber: "",
  };
  deliveryFormVisible.value = true;
  // getProductInventory({ salesLedgerId: row.id, type:1 }).then((res) => {
  //   currentDeliveryRow.value = row;
  //   deliveryForm.value = {
  //     shippingDate: getCurrentDate(),
  //     shippingCarNumber: "",
  //   };
  //   deliveryFormVisible.value = true;
  // }).catch(err => {
  //   ElMessage.error(err.msg);
  // });
   currentDeliveryRow.value = row;
   deliveryFormVisible.value = true;
};
// 提交发货表单
@@ -1592,12 +1675,12 @@
      padding: 15px;
      border-bottom: 1px solid #e4e7ed;
      text-align: center;
      .el-button {
         margin: 0 10px;
      }
   }
   .print-preview-content {
      padding: 20px;
      background-color: #f5f5f5;
@@ -1629,13 +1712,13 @@
.header {
   text-align: center;
   margin-bottom: 8px;
   .company-name {
      font-size: 18px;
      font-weight: bold;
      margin-bottom: 4px;
   }
   .document-title {
      font-size: 16px;
      font-weight: bold;
@@ -1647,16 +1730,16 @@
   display: flex;
   justify-content: space-between;
   align-items: center;
   .info-row {
      line-height: 20px;
      .label {
         font-weight: bold;
         width: 60px;
         font-size: 14px;
      }
      .value {
         margin-right: 20px;
         min-width: 80px;
@@ -1668,12 +1751,12 @@
.table-section {
   margin-bottom: 4px;
   flex: 1;
   .product-table {
      width: 100%;
      border-collapse: collapse;
      border: 1px solid #000;
      th, td {
         border: 1px solid #000;
         padding: 6px;
@@ -1681,16 +1764,16 @@
         font-size: 14px;
         line-height: 1.4;
      }
      th {
         font-weight: bold;
      }
      .total-label {
         text-align: right;
         font-weight: bold;
      }
      .total-value {
         font-weight: bold;
      }
@@ -1703,22 +1786,22 @@
      margin-bottom: 3px;
      line-height: 20px;
      justify-content: space-between;
      .footer-item {
         display: flex;
         margin-right: 20px;
         .label {
            font-weight: bold;
            width: 80px;
            font-size: 14px;
         }
         .value {
            min-width: 80px;
            font-size: 14px;
         }
         &.address-item {
            .address-value {
               min-width: 200px;
@@ -1732,7 +1815,7 @@
   .app-container {
      display: none;
   }
   .print-page {
      box-shadow: none;
      margin: 0;