| | |
| | | label="产品大类" |
| | | prop="productCategory" |
| | | required |
| | | :rules="productRules.productCategory" |
| | | > |
| | | <up-input |
| | | v-model="product.productCategory" |
| | |
| | | label="规格型号" |
| | | prop="specificationModel" |
| | | required |
| | | :rules="productRules.specificationModel" |
| | | > |
| | | <up-input |
| | | v-model="product.specificationModel" |
| | |
| | | label="单位" |
| | | prop="unit" |
| | | required |
| | | :rules="productRules.unit" |
| | | > |
| | | <up-input |
| | | v-model="product.unit" |
| | |
| | | label="税率(%)" |
| | | prop="taxRate" |
| | | required |
| | | :rules="productRules.taxRate" |
| | | > |
| | | <up-input |
| | | v-model="product.taxRate" |
| | |
| | | label="含税单价(元)" |
| | | prop="taxInclusiveUnitPrice" |
| | | required |
| | | :rules="productRules.taxInclusiveUnitPrice" |
| | | > |
| | | <up-input |
| | | v-model="product.taxInclusiveUnitPrice" |
| | |
| | | label="数量" |
| | | prop="quantity" |
| | | required |
| | | :rules="productRules.quantity" |
| | | > |
| | | <up-input |
| | | v-model="product.quantity" |
| | |
| | | label="含税总价(元)" |
| | | prop="taxInclusiveTotalPrice" |
| | | required |
| | | :rules="productRules.taxInclusiveTotalPrice" |
| | | > |
| | | <up-input |
| | | v-model="product.taxInclusiveTotalPrice" |
| | |
| | | label="不含税总价(元)" |
| | | prop="taxExclusiveTotalPrice" |
| | | required |
| | | :rules="productRules.taxExclusiveTotalPrice" |
| | | > |
| | | <up-input |
| | | v-model="product.taxExclusiveTotalPrice" |
| | |
| | | label="发票类型" |
| | | prop="invoiceType" |
| | | required |
| | | :rules="productRules.invoiceType" |
| | | > |
| | | <up-input |
| | | v-model="product.invoiceType" |
| | |
| | | ] |
| | | }; |
| | | |
| | | // 产品信息校验规则 |
| | | const productRules = { |
| | | productCategory: [ |
| | | { required: true, message: '请选择产品大类', trigger: 'change' } |
| | | ], |
| | | specificationModel: [ |
| | | { required: true, message: '请选择规格型号', trigger: 'change' } |
| | | ], |
| | | unit: [ |
| | | { required: true, message: '请输入单位', trigger: 'blur' } |
| | | ], |
| | | taxRate: [ |
| | | { required: true, message: '请选择税率', trigger: 'change' } |
| | | ], |
| | | taxInclusiveUnitPrice: [ |
| | | { required: true, message: '请输入含税单价', trigger: 'blur' }, |
| | | { type: 'number', min: 0, message: '含税单价必须大于0', trigger: 'blur' } |
| | | ], |
| | | quantity: [ |
| | | { required: true, message: '请输入数量', trigger: 'blur' }, |
| | | { type: 'number', min: 0, message: '数量必须大于0', trigger: 'blur' } |
| | | ], |
| | | taxInclusiveTotalPrice: [ |
| | | { required: true, message: '请输入含税总价', trigger: 'blur' }, |
| | | { type: 'number', min: 0, message: '含税总价必须大于0', trigger: 'blur' } |
| | | ], |
| | | taxExclusiveTotalPrice: [ |
| | | { required: true, message: '请输入不含税总价', trigger: 'blur' }, |
| | | { type: 'number', min: 0, message: '不含税总价必须大于0', trigger: 'blur' } |
| | | ], |
| | | invoiceType: [ |
| | | { required: true, message: '请选择发票类型', trigger: 'change' } |
| | | ] |
| | | }; |
| | | |
| | | |
| | | const addProduct = () => { |
| | | if (productData.value === null) { |
| | |
| | | productData.value[idx].taxInclusiveUnitPrice = value.toFixed(2); |
| | | } |
| | | } |
| | | if (!productData.value[currentProductIndex.value].taxRate) { |
| | | if (!productData.value[idx].taxRate) { |
| | | uni.showToast({ |
| | | title: '请先选择税率', |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | const quantity = parseFloat(productData.value[currentProductIndex.value].quantity); |
| | | const unitPrice = parseFloat(productData.value[currentProductIndex.value].taxInclusiveUnitPrice); |
| | | const quantity = parseFloat(productData.value[idx].quantity); |
| | | const unitPrice = parseFloat(productData.value[idx].taxInclusiveUnitPrice); |
| | | |
| | | if (!quantity || quantity <= 0 || !unitPrice) { |
| | | return; |
| | | } |
| | | // 计算含税总价 |
| | | productData.value[currentProductIndex.value].taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2); |
| | | productData.value[idx].taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2); |
| | | |
| | | // 如果有税率,计算不含税总价 |
| | | if (productData.value[currentProductIndex.value].taxRate) { |
| | | productData.value[currentProductIndex.value].taxExclusiveTotalPrice = |
| | | if (productData.value[idx].taxRate) { |
| | | productData.value[idx].taxExclusiveTotalPrice = |
| | | calculateTaxExclusiveTotalPrice( |
| | | productData.value[currentProductIndex.value].taxInclusiveTotalPrice, |
| | | productData.value[currentProductIndex.value].taxRate |
| | | productData.value[idx].taxInclusiveTotalPrice, |
| | | productData.value[idx].taxRate |
| | | ); |
| | | } |
| | | }; |
| | |
| | | productData.value[idx].quantity = value.toFixed(2); |
| | | } |
| | | } |
| | | if (!productData.value[currentProductIndex.value].taxRate) { |
| | | if (!productData.value[idx].taxRate) { |
| | | uni.showToast({ |
| | | title: '请先选择税率', |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | const quantity = parseFloat(productData.value[currentProductIndex.value].quantity); |
| | | const unitPrice = parseFloat(productData.value[currentProductIndex.value].taxInclusiveUnitPrice); |
| | | const quantity = parseFloat(productData.value[idx].quantity); |
| | | const unitPrice = parseFloat(productData.value[idx].taxInclusiveUnitPrice); |
| | | |
| | | if (!quantity || quantity <= 0 || !unitPrice) { |
| | | return; |
| | | } |
| | | // 计算含税总价 |
| | | productData.value[currentProductIndex.value].taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2); |
| | | productData.value[idx].taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2); |
| | | // 如果有税率,计算不含税总价 |
| | | if (productData.value[currentProductIndex.value].taxRate) { |
| | | productData.value[currentProductIndex.value].taxExclusiveTotalPrice = |
| | | if (productData.value[idx].taxRate) { |
| | | productData.value[idx].taxExclusiveTotalPrice = |
| | | calculateTaxExclusiveTotalPrice( |
| | | productData.value[currentProductIndex.value].taxInclusiveTotalPrice, |
| | | productData.value[currentProductIndex.value].taxRate |
| | | productData.value[idx].taxInclusiveTotalPrice, |
| | | productData.value[idx].taxRate |
| | | ); |
| | | } |
| | | }; |
| | |
| | | productData.value[idx].taxInclusiveTotalPrice = value.toFixed(2); |
| | | } |
| | | } |
| | | const totalPrice = parseFloat(productData.value[currentProductIndex.value].taxInclusiveTotalPrice); |
| | | const quantity = parseFloat(productData.value[currentProductIndex.value].quantity); |
| | | const totalPrice = parseFloat(productData.value[idx].taxInclusiveTotalPrice); |
| | | const quantity = parseFloat(productData.value[idx].quantity); |
| | | |
| | | if (!totalPrice || !quantity || quantity <= 0) { |
| | | return; |
| | | } |
| | | // 计算含税单价 = 含税总价 / 数量 |
| | | productData.value[currentProductIndex.value].taxInclusiveUnitPrice = (totalPrice / quantity).toFixed(2); |
| | | productData.value[idx].taxInclusiveUnitPrice = (totalPrice / quantity).toFixed(2); |
| | | // 如果有税率,计算不含税总价 |
| | | if (productData.value[currentProductIndex.value].taxRate) { |
| | | productData.value[currentProductIndex.value].taxExclusiveTotalPrice = |
| | | if (productData.value[idx].taxRate) { |
| | | productData.value[idx].taxExclusiveTotalPrice = |
| | | calculateTaxExclusiveTotalPrice( |
| | | totalPrice, |
| | | productData.value[currentProductIndex.value].taxRate |
| | | productData.value[idx].taxRate |
| | | ); |
| | | } |
| | | }; |
| | |
| | | productData.value[idx].taxExclusiveTotalPrice = value.toFixed(2); |
| | | } |
| | | } |
| | | if (!productData.value[currentProductIndex.value].taxRate) { |
| | | if (!productData.value[idx].taxRate) { |
| | | uni.showToast({ |
| | | title: '请先选择税率', |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | const exclusiveTotalPrice = parseFloat(productData.value[currentProductIndex.value].taxExclusiveTotalPrice); |
| | | const quantity = parseFloat(productData.value[currentProductIndex.value].quantity); |
| | | const taxRate = parseFloat(productData.value[currentProductIndex.value].taxRate); |
| | | const exclusiveTotalPrice = parseFloat(productData.value[idx].taxExclusiveTotalPrice); |
| | | const quantity = parseFloat(productData.value[idx].quantity); |
| | | const taxRate = parseFloat(productData.value[idx].taxRate); |
| | | if (!exclusiveTotalPrice || !quantity || quantity <= 0 || !taxRate) { |
| | | return; |
| | | } |
| | | // 先计算含税总价 = 不含税总价 / (1 - 税率/100) |
| | | const taxRateDecimal = taxRate / 100; |
| | | const inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal); |
| | | productData.value[currentProductIndex.value].taxInclusiveTotalPrice = inclusiveTotalPrice.toFixed(2); |
| | | productData.value[idx].taxInclusiveTotalPrice = inclusiveTotalPrice.toFixed(2); |
| | | // 计算含税单价 = 含税总价 / 数量 |
| | | productData.value[currentProductIndex.value].taxInclusiveUnitPrice = (inclusiveTotalPrice / quantity).toFixed(2); |
| | | productData.value[idx].taxInclusiveUnitPrice = (inclusiveTotalPrice / quantity).toFixed(2); |
| | | }; |
| | | const goBack = () => { |
| | | // 清理本地存储的数据 |
| | |
| | | |
| | | // 检查每个产品是否填写完整 |
| | | for (let i = 0; i < productData.value.length; i++) { |
| | | const errors = validateProduct(productData.value[i], i); |
| | | if (errors.length > 0) { |
| | | const product = productData.value[i]; |
| | | // 优化数字字段验证,处理可能的字符串格式数值 |
| | | const taxInclusiveUnitPrice = parseFloat(product.taxInclusiveUnitPrice); |
| | | const quantity = parseFloat(product.quantity); |
| | | const taxInclusiveTotalPrice = parseFloat(product.taxInclusiveTotalPrice); |
| | | const taxExclusiveTotalPrice = parseFloat(product.taxExclusiveTotalPrice); |
| | | |
| | | if (!product.productCategory) { |
| | | uni.showToast({ |
| | | title: errors[0], |
| | | title: `产品${i + 1}:请选择产品大类`, |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | if (!product.specificationModel) { |
| | | uni.showToast({ |
| | | title: `产品${i + 1}:请选择规格型号`, |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | if (!product.unit) { |
| | | uni.showToast({ |
| | | title: `产品${i + 1}:请输入单位`, |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | if (!product.taxRate) { |
| | | uni.showToast({ |
| | | title: `产品${i + 1}:请选择税率`, |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | if (isNaN(taxInclusiveUnitPrice) || taxInclusiveUnitPrice <= 0) { |
| | | uni.showToast({ |
| | | title: `产品${i + 1}:请输入有效的含税单价`, |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | if (isNaN(quantity) || quantity <= 0) { |
| | | uni.showToast({ |
| | | title: `产品${i + 1}:请输入有效的数量`, |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | if (isNaN(taxInclusiveTotalPrice) || taxInclusiveTotalPrice <= 0) { |
| | | uni.showToast({ |
| | | title: `产品${i + 1}:请输入有效的含税总价`, |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | if (isNaN(taxExclusiveTotalPrice) || taxExclusiveTotalPrice <= 0) { |
| | | uni.showToast({ |
| | | title: `产品${i + 1}:请输入有效的不含税总价`, |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | if (!product.invoiceType) { |
| | | uni.showToast({ |
| | | title: `产品${i + 1}:请选择发票类型`, |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | |
| | | productOptions.value = convertIdToValue(res); |
| | | }); |
| | | }; |
| | | // 单个产品表单验证函数 |
| | | const validateProduct = (product, index) => { |
| | | const errors = []; |
| | | |
| | | if (!product.productCategory) { |
| | | errors.push(`产品${index + 1}:请选择产品大类`); |
| | | } |
| | | if (!product.specificationModel) { |
| | | errors.push(`产品${index + 1}:请选择规格型号`); |
| | | } |
| | | if (!product.unit) { |
| | | errors.push(`产品${index + 1}:请输入单位`); |
| | | } |
| | | if (!product.taxRate) { |
| | | errors.push(`产品${index + 1}:请选择税率`); |
| | | } |
| | | if (!product.taxInclusiveUnitPrice || parseFloat(product.taxInclusiveUnitPrice) <= 0) { |
| | | errors.push(`产品${index + 1}:请输入有效的含税单价`); |
| | | } |
| | | if (!product.quantity || parseFloat(product.quantity) <= 0) { |
| | | errors.push(`产品${index + 1}:请输入有效的数量`); |
| | | } |
| | | if (!product.taxInclusiveTotalPrice || parseFloat(product.taxInclusiveTotalPrice) <= 0) { |
| | | errors.push(`产品${index + 1}:请输入有效的含税总价`); |
| | | } |
| | | if (!product.taxExclusiveTotalPrice || parseFloat(product.taxExclusiveTotalPrice) <= 0) { |
| | | errors.push(`产品${index + 1}:请输入有效的不含税总价`); |
| | | } |
| | | if (!product.invoiceType) { |
| | | errors.push(`产品${index + 1}:请选择发票类型`); |
| | | } |
| | | |
| | | return errors; |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | // 获取页面参数 |