张诺
13 小时以前 388e286dc8a5b3b8c4717cc74bf128c807eba6b7
src/views/salesManagement/salesLedger/index.vue
@@ -53,7 +53,7 @@
                <template #default="scope">
               <el-tag v-if="getShippingStatusText(scope.row) === '已发货'"
                                       type="success">已出库</el-tag>
                           <el-tag v-else-if="scope.row.approveStatus === 2"
                           <el-tag v-else-if="scope.row.hasSufficientStock"
                                       type="success">充足</el-tag>
                           <el-tag v-else
                                       type="danger">不足</el-tag>
@@ -87,7 +87,7 @@
                  </div>
                </template>
              </el-table-column>
              <el-table-column label="数量" prop="quantity" />
              <el-table-column label="数量" prop="quantity" :formatter="formattedNumber" />
              <el-table-column label="税率(%)" prop="taxRate" />
              <el-table-column label="含税单价(元)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" />
              <el-table-column label="含税总价(元)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" />
@@ -153,7 +153,7 @@
          </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" placeholder="请选择" clearable :disabled="operationType === 'view'" filterable>
                <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
                  :value="item.nickName" />
              </el-select>
@@ -163,10 +163,10 @@
        <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-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
                  }}
                </el-option>
              </el-select>
@@ -317,7 +317,7 @@
            <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) }}
                  {{ Number(scope.row.totalAmount ?? 0).toFixed(3) }}
               </template>
            </el-table-column>
            <el-table-column fixed="right" label="操作" width="120" align="center">
@@ -352,11 +352,8 @@
            <el-row :gutter="30">
               <el-col :span="24">
                  <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 filterable check-strictly
                                     @change="getModels" :data="productOptions" :render-after-expand="false" style="width: 100%" />
                  </el-form-item>
               </el-col>
            </el-row>
@@ -389,14 +386,14 @@
               <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%"
                                              :precision="2"
                                              :precision="3"
                                              placeholder="请输入" clearable @change="calculateFromUnitPrice" />
                  </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
                                                :precision="2"
                                                :precision="3"
                                                @change="calculateFromQuantity" style="width: 100%" />
                  </el-form-item>
               </el-col>
@@ -507,7 +504,7 @@
                        <div class="info-row">
                           <div>
                              <span class="label">客户名称:</span>
                              <span class="value">{{ item.customerName || '张爱有' }}</span>
                              <span class="value">{{ item.customerName }}</span>
                           </div>
                           <span class="label">单号:</span>
                           <span class="value">{{ item.salesContractNo }}</span>
@@ -689,6 +686,7 @@
import useFormData from "@/hooks/useFormData.js";
import dayjs from "dayjs";
import { getCurrentDate } from "@/utils/index.js";
import {listCustomerPrivatePool} from "@/api/basicData/customerFile.js";
const userStore = useUserStore();
const { proxy } = getCurrentInstance();
@@ -769,14 +767,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);
@@ -938,7 +936,7 @@
   });
};
const formattedNumber = (row, column, cellValue) => {
   return parseFloat(cellValue).toFixed(2);
   return parseFloat(cellValue).toFixed(3);
};
// 获取tree子数据
const getModels = (value) => {
@@ -1050,7 +1048,11 @@
      "contractAmount",
      "taxInclusiveTotalPrice",
      "taxExclusiveTotalPrice",
   ]);
   ], {
      contractAmount: { decimalPlaces: 3 },
      taxInclusiveTotalPrice: { decimalPlaces: 3 },
      taxExclusiveTotalPrice: { decimalPlaces: 3 },
   });
};
// 子表合计方法
const summarizeChildrenTable = (param) => {
@@ -1058,18 +1060,43 @@
      "taxInclusiveUnitPrice",
      "taxInclusiveTotalPrice",
      "taxExclusiveTotalPrice",
   ]);
   ], {
      taxInclusiveUnitPrice: { decimalPlaces: 3 },
      taxInclusiveTotalPrice: { decimalPlaces: 3 },
      taxExclusiveTotalPrice: { decimalPlaces: 3 },
   });
};
// 判断是否能编辑
const canEditLedger = (row) => {
   // 如果是维护人,则可以编辑
   return Number(row.entryPerson) === Number(userStore.id);
};
// 判断是否能删除
const canDeleteLedger = (row) => {
   // 如果是维护人,则可以删除
   return Number(row.entryPerson) === Number(userStore.id);
};
// 判断是否是维护人(用于权限校验)
const isMaintainer = (row) => {
   return row.entryPerson === userStore.id;
};
// 打开弹框
const openForm = async (type, row) => {
   if (type === "edit" && row && !canEditLedger(row)) {
      proxy.$modal.msgWarning("当前系统登录人不是维护人,不能编辑数据");
      return;
   }
   operationType.value = type;
   form.value = {};
   productData.value = [];
   selectedQuotation.value = null;
   let userLists = await userListNoPage();
   userList.value = userLists.data;
   customerList().then((res) => {
      customerOption.value = res;
   listCustomerPrivatePool({current: -1,size:-1}).then((res) => {
      customerOption.value = res.data.records;
   });
   form.value.entryPerson = userStore.id;
   if (type === "add") {
@@ -1105,8 +1132,9 @@
   // 先确保客户列表已加载,便于后续回填 customerId
   if (!customerOption.value || customerOption.value.length === 0) {
      try {
         const res = await customerList();
         customerOption.value = res;
         listCustomerPrivatePool({current: -1,size:-1}).then((res) => {
            customerOption.value = res.data.records;
         });
      } catch (e) {
         // ignore,允许用户后续手动选择客户
      }
@@ -1172,9 +1200,9 @@
   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 taxRate = "0"; // 默认 13%,便于直接提交(如需可在产品中自行修改)
      const taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(3);
      const taxExclusiveTotalPrice = proxy.calculateTaxExclusiveTotalPrice(taxInclusiveTotalPrice, taxRate, 3);
      return {
         // 台账字段
         productCategory: p.product || p.productName || "",
@@ -1182,7 +1210,7 @@
         unit: p.unit || "",
         quantity: quantity,
         taxRate: taxRate,
         taxInclusiveUnitPrice: unitPrice.toFixed(2),
         taxInclusiveUnitPrice: unitPrice.toFixed(3),
         taxInclusiveTotalPrice: taxInclusiveTotalPrice,
         taxExclusiveTotalPrice: taxExclusiveTotalPrice,
         invoiceType: "增普票",
@@ -1250,6 +1278,7 @@
         addOrUpdateSalesLedger(form.value).then((res) => {
            proxy.$modal.msgSuccess("提交成功");
            closeDia();
            expandedRowKeys.value = [];
            getList();
         });
      }
@@ -1443,6 +1472,11 @@
const handleDelete = async () => {
   if (selectedRows.value.length === 0) {
      proxy.$modal.msgWarning("请选择数据");
      return;
   }
   const unauthorizedRows = selectedRows.value.filter((row) => !canDeleteLedger(row));
   if (unauthorizedRows.length > 0) {
      proxy.$modal.msgWarning("当前登录用户不是录入人,不能删除该数据");
      return;
   }
   const ids = selectedRows.value.map((item) => item.id);
@@ -1816,7 +1850,7 @@
   const total = products.reduce((sum, product) => {
      return sum + (parseFloat(product.quantity) || 0);
   }, 0);
   return total.toFixed(2);
   return total.toFixed(3);
};
// 计算产品总金额
@@ -1825,7 +1859,7 @@
   const total = products.reduce((sum, product) => {
      return sum + (parseFloat(product.taxInclusiveTotalPrice) || 0);
   }, 0);
   return total.toFixed(2);
   return total.toFixed(3);
};
// 用于打印的计算函数
@@ -1834,7 +1868,7 @@
   const total = products.reduce((sum, product) => {
      return sum + (parseFloat(product.quantity) || 0);
   }, 0);
   return total.toFixed(2);
   return total.toFixed(3);
};
const getTotalAmountForPrint = (products) => {
@@ -1842,7 +1876,7 @@
   const total = products.reduce((sum, product) => {
      return sum + (parseFloat(product.taxInclusiveTotalPrice) || 0);
   }, 0);
   return total.toFixed(2);
   return total.toFixed(3);
};
const mathNum = () => {
@@ -1857,14 +1891,16 @@
   productForm.value.taxInclusiveTotalPrice =
      proxy.calculateTaxIncludeTotalPrice(
         productForm.value.taxInclusiveUnitPrice,
         productForm.value.quantity
         productForm.value.quantity,
         3
      );
   if (productForm.value.taxRate) {
      // 不含税总价计算
      productForm.value.taxExclusiveTotalPrice =
         proxy.calculateTaxExclusiveTotalPrice(
            productForm.value.taxInclusiveTotalPrice,
            productForm.value.taxRate
            productForm.value.taxRate,
            3
         );
   }
};
@@ -1883,14 +1919,15 @@
   isCalculating.value = true;
   
   // 计算含税单价 = 含税总价 / 数量
   productForm.value.taxInclusiveUnitPrice = (totalPrice / quantity).toFixed(2);
   productForm.value.taxInclusiveUnitPrice = (totalPrice / quantity).toFixed(3);
   
   // 如果有税率,计算不含税总价
   if (productForm.value.taxRate) {
      productForm.value.taxExclusiveTotalPrice =
         proxy.calculateTaxExclusiveTotalPrice(
            totalPrice,
            productForm.value.taxRate
            productForm.value.taxRate,
            3
         );
   }
   
@@ -1899,10 +1936,10 @@
// 根据不含税总价计算含税单价和数量
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);
@@ -1918,20 +1955,20 @@
   // 先计算含税总价 = 不含税总价 / (1 - 税率/100)
   const taxRateDecimal = taxRate / 100;
   const inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal);
   productForm.value.taxInclusiveTotalPrice = inclusiveTotalPrice.toFixed(2);
   productForm.value.taxInclusiveTotalPrice = inclusiveTotalPrice.toFixed(3);
   
   // 计算含税单价 = 含税总价 / 数量
   productForm.value.taxInclusiveUnitPrice = (inclusiveTotalPrice / quantity).toFixed(2);
   productForm.value.taxInclusiveUnitPrice = (inclusiveTotalPrice / quantity).toFixed(3);
   
   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);
@@ -1944,26 +1981,29 @@
   isCalculating.value = true;
   
   // 计算含税总价
   productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
   productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(3);
   
   // 如果有税率,计算不含税总价
   if (productForm.value.taxRate) {
      productForm.value.taxExclusiveTotalPrice =
         proxy.calculateTaxExclusiveTotalPrice(
            productForm.value.taxInclusiveTotalPrice,
            productForm.value.taxRate
            productForm.value.taxRate,
            3
         );
   }
   }else{
    productForm.value.taxExclusiveTotalPrice = (unitPrice * quantity).toFixed(3);
  }
   
   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);
@@ -1976,14 +2016,15 @@
   isCalculating.value = true;
   
   // 计算含税总价
   productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
   productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(3);
   
   // 如果有税率,计算不含税总价
   if (productForm.value.taxRate) {
      productForm.value.taxExclusiveTotalPrice =
         proxy.calculateTaxExclusiveTotalPrice(
            productForm.value.taxInclusiveTotalPrice,
            productForm.value.taxRate
            productForm.value.taxRate,
            3
         );
   }
   
@@ -1992,10 +2033,10 @@
// 根据税率变化计算不含税总价
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);
@@ -2011,7 +2052,8 @@
   productForm.value.taxExclusiveTotalPrice =
      proxy.calculateTaxExclusiveTotalPrice(
         inclusiveTotalPrice,
         taxRate
         taxRate,
         3
      );
   
   isCalculating.value = false;
@@ -2084,8 +2126,8 @@
 * @param row 行数据
 */
const canShip = (row) => {
   // 产品状态必须是充足(approveStatus === 1)
   if (row.approveStatus !== 1) {
   // 产品状态必须是充足(基于 hasSufficientStock 判断)
   if (!row || !row.hasSufficientStock) {
      return false;
   }
   
@@ -2235,19 +2277,19 @@
   margin-left: 10px;
}
::v-deep .yellow {
:deep(.yellow) {
  background-color: #FAF0DE;
}
::v-deep .pink {
:deep(.pink) {
  background-color: #FAE1DE;
}
::v-deep .red {
:deep(.red) {
  background-color: #FAE1DE;
}
::v-deep .purple{
:deep(.purple){
  background-color: #F4DEFA;
}