| | |
| | | </template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item label="单价(不含税)" prop="priceExcludingTax"> |
| | | <el-form-item label="单价(含税)" prop="priceIncludingTax"> |
| | | <el-input |
| | | v-model.number="form.priceExcludingTax" |
| | | placeholder="请输入" |
| | | v-model.number="form.priceIncludingTax" |
| | | placeholder="请输入含税单价" |
| | | @blur="handlePriceBlur" |
| | | :disabled="isViewMode" |
| | | > |
| | |
| | | </template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item label="单价(含税)" prop="priceIncludingTax"> |
| | | <el-form-item label="单价(不含税)" prop="priceExcludingTax"> |
| | | <el-input |
| | | v-model.number="form.priceIncludingTax" |
| | | v-model.number="form.priceExcludingTax" |
| | | placeholder="自动计算" |
| | | disabled |
| | | > |
| | |
| | | defineExpose({ |
| | | getDropdownData, |
| | | }); |
| | | // 数值格式化工具函数 |
| | | const toFixed = (num, precision = 2) => { |
| | | if (isNaN(num) || num === null || num === undefined || num === "") { |
| | | return 0; |
| | | } |
| | | return ( |
| | | Math.floor(parseFloat(num) * Math.pow(10, precision)) / |
| | | Math.pow(10, precision) |
| | | ); |
| | | return Number((Math.floor(parseFloat(num) * Math.pow(10, precision)) / Math.pow(10, precision)).toFixed(precision)); |
| | | }; |
| | | // 含税单价计算 |
| | | const unitPriceWithTax = computed(() => { |
| | | const priceExcludingTax = parseFloat(form.value.priceExcludingTax) || 0; |
| | | const taxRate = parseFloat(form.value.taxRate) || 0; |
| | | if (!priceExcludingTax || !taxRate) { |
| | | return 0; |
| | | } |
| | | const result = priceExcludingTax * (1 + taxRate / 100); |
| | | return toFixed(result, 2); |
| | | |
| | | // 安全获取数值 |
| | | const safeNumber = (value) => { |
| | | const num = parseFloat(value); |
| | | return isNaN(num) ? 0 : num; |
| | | }; |
| | | |
| | | // 计算逻辑 - 基于含税单价计算不含税价格 |
| | | const calculatePrices = () => { |
| | | const priceIncludingTax = safeNumber(form.value.priceIncludingTax); // 含税单价 |
| | | const taxRate = safeNumber(form.value.taxRate); // 税率 |
| | | const quantity = safeNumber(form.value.purchaseQuantity); // 采购数量 |
| | | |
| | | // 1. 根据含税单价和税率计算不含税单价 |
| | | // 不含税单价 = 含税单价 / (1 + 税率/100) |
| | | const priceExcludingTax = priceIncludingTax && taxRate |
| | | ? toFixed(priceIncludingTax / (1 + taxRate / 100), 2) |
| | | : 0; |
| | | |
| | | // 2. 计算不含税总价 = 不含税单价 × 数量 |
| | | const totalPriceExcludingTax = priceExcludingTax && quantity |
| | | ? toFixed(priceExcludingTax * quantity, 2) |
| | | : 0; |
| | | |
| | | // 3. 计算含税总价 = 含税单价 × 数量 |
| | | const totalPriceIncludingTax = priceIncludingTax && quantity |
| | | ? toFixed(priceIncludingTax * quantity, 2) |
| | | : 0; |
| | | |
| | | // 更新表单数据 |
| | | form.value.priceExcludingTax = priceExcludingTax; |
| | | form.value.totalPriceExcludingTax = totalPriceExcludingTax; |
| | | form.value.totalPriceIncludingTax = totalPriceIncludingTax; |
| | | }; |
| | | |
| | | // 监听表单对象变化,用于处理编辑模式下的数据加载和实时计算 |
| | | watch( |
| | | () => [form.value.priceIncludingTax, form.value.taxRate, form.value.purchaseQuantity], |
| | | () => { |
| | | // 防抖处理,避免频繁计算 |
| | | nextTick(() => { |
| | | calculatePrices(); |
| | | }); |
| | | |
| | | // 含税总价计算 |
| | | const totalUnitPriceWithTax = computed(() => { |
| | | const priceExcludingTax = parseFloat(form.value.priceExcludingTax) || 0; |
| | | const taxRate = parseFloat(form.value.taxRate) || 0; |
| | | const purchaseQuantity = parseFloat(form.value.purchaseQuantity) || 0; |
| | | |
| | | if (!priceExcludingTax || !taxRate || !purchaseQuantity) { |
| | | return 0; |
| | | } |
| | | |
| | | const unitPriceWithTaxValue = priceExcludingTax * (1 + taxRate / 100); |
| | | const result = unitPriceWithTaxValue * purchaseQuantity; |
| | | return toFixed(result, 2); |
| | | }); |
| | | |
| | | // 不含税总价计算 |
| | | const taxExclusiveTotalPrice = computed(() => { |
| | | const purchaseQuantity = parseFloat(form.value.purchaseQuantity) || 0; |
| | | const priceExcludingTax = parseFloat(form.value.priceExcludingTax) || 0; |
| | | |
| | | if (!purchaseQuantity || !priceExcludingTax) { |
| | | return 0; |
| | | } |
| | | |
| | | const result = purchaseQuantity * priceExcludingTax; |
| | | return toFixed(result, 2); |
| | | }); |
| | | |
| | | // 监听计算值变化,同步到 form 对象中 |
| | | watch(unitPriceWithTax, (newValue) => { |
| | | form.value.priceIncludingTax = newValue; |
| | | }); |
| | | |
| | | watch(totalUnitPriceWithTax, (newValue) => { |
| | | form.value.totalPriceIncludingTax = newValue; |
| | | }); |
| | | |
| | | watch(taxExclusiveTotalPrice, (newValue) => { |
| | | form.value.totalPriceExcludingTax = newValue; |
| | | }); |
| | | }, |
| | | { deep: true } |
| | | ); |
| | | |
| | | const userStore = useUserStore(); |
| | | const userInfo = ref({}); |
| | | const match = () => { |
| | | return userInfo.value.nickName || "未知用户"; |
| | | }; |
| | | // 处理税率输入框失焦,确保精度 |
| | | // 处理税率输入框失焦事件 |
| | | const handleTaxRateBlur = () => { |
| | | if ( |
| | | form.value.taxRate !== null && |
| | | form.value.taxRate !== undefined && |
| | | form.value.taxRate !== "" |
| | | ) { |
| | | if (form.value.taxRate !== null && form.value.taxRate !== undefined && form.value.taxRate !== "") { |
| | | form.value.taxRate = toFixed(parseFloat(form.value.taxRate), 2); |
| | | // watch 会自动触发 calculatePrices,不需要手动调用 |
| | | } |
| | | }; |
| | | |
| | | // 处理不含税单价输入框失焦,确保精度 |
| | | // 处理含税单价输入框失焦事件 |
| | | const handlePriceBlur = () => { |
| | | if ( |
| | | form.value.priceExcludingTax !== null && |
| | | form.value.priceExcludingTax !== undefined && |
| | | form.value.priceExcludingTax !== "" |
| | | ) { |
| | | form.value.priceExcludingTax = toFixed( |
| | | parseFloat(form.value.priceExcludingTax), |
| | | 2 |
| | | ); |
| | | if (form.value.priceIncludingTax !== null && form.value.priceIncludingTax !== undefined && form.value.priceIncludingTax !== "") { |
| | | form.value.priceIncludingTax = toFixed(parseFloat(form.value.priceIncludingTax), 2); |
| | | // watch 会自动触发 calculatePrices,不需要手动调用 |
| | | } |
| | | }; |
| | | |
| | | // 处理采购数量输入框失焦,确保精度 |
| | | // 处理采购数量输入框失焦事件 |
| | | const handleQuantityBlur = () => { |
| | | if ( |
| | | form.value.purchaseQuantity !== null && |
| | | form.value.purchaseQuantity !== undefined && |
| | | form.value.purchaseQuantity !== "" |
| | | ) { |
| | | form.value.purchaseQuantity = toFixed( |
| | | parseFloat(form.value.purchaseQuantity), |
| | | 3 |
| | | ); // 数量保留3位小数 |
| | | if (form.value.purchaseQuantity !== null && form.value.purchaseQuantity !== undefined && form.value.purchaseQuantity !== "") { |
| | | form.value.purchaseQuantity = toFixed(parseFloat(form.value.purchaseQuantity), 3); // 数量保留3位小数 |
| | | // watch 会自动触发 calculatePrices,不需要手动调用 |
| | | } |
| | | }; |
| | | |
| | | onMounted(async () => { |
| | | let res = await userStore.getInfo(); |
| | | userInfo.value = res.user; |
| | | getDropdownData() |
| | | |
| | | await getDropdownData(); |
| | | // 组件加载完成后触发一次计算 |
| | | calculatePrices(); |
| | | }); |
| | | const rules = { |
| | | supplierName: [ |