diff --git a/klp-ui/src/assets/images/contractLogo.png b/klp-ui/src/assets/images/contractLogo.png new file mode 100644 index 00000000..7e438a76 Binary files /dev/null and b/klp-ui/src/assets/images/contractLogo.png differ diff --git a/klp-ui/src/utils/productContent.js b/klp-ui/src/utils/productContent.js index 16f3ab3f..2ecbe87a 100644 --- a/klp-ui/src/utils/productContent.js +++ b/klp-ui/src/utils/productContent.js @@ -89,6 +89,122 @@ export function calculateProductTaxTotal(product) { return quantity * taxPrice; } +/** + * 计算无税单价 = 含税单价 / 税率除数 + * @param {Object} product - 产品对象 + * @returns {number} 无税单价 + */ +export function calculateProductNoTaxPrice(product) { + if (!product) return 0; + const taxPrice = parseFloat(product.taxPrice) || 0; + const taxDivisor = parseFloat(product.taxDivisor) || 1.13; + return taxPrice / taxDivisor; +} + +/** + * 计算无税总额 = 数量 * 无税单价 + * @param {Object} product - 产品对象 + * @returns {number} 无税总额 + */ +export function calculateProductNoTaxTotal(product) { + if (!product) return 0; + const quantity = parseFloat(product.quantity) || 0; + const noTaxPrice = parseFloat(product.noTaxPrice) || 0; + return quantity * noTaxPrice; +} + +/** + * 计算税额 = 含税总额 - 无税总额 + * @param {Object} product - 产品对象 + * @returns {number} 税额 + */ +export function calculateProductTaxAmount(product) { + if (!product) return 0; + const taxTotal = parseFloat(product.taxTotal) || 0; + const noTaxTotal = parseFloat(product.noTaxTotal) || 0; + return taxTotal - noTaxTotal; +} + +/** + * 根据变更字段重新计算产品所有金额字段 + * @param {Object} product - 产品对象 + * @param {string} changedField - 变更的字段名 + * @returns {Object} 更新后的产品对象 + */ +export function calculateProductFields(product, changedField = 'quantity') { + if (!product) return product; + + const quantity = parseFloat(product.quantity) || 0; + let taxPrice = parseFloat(product.taxPrice) || 0; + let taxDivisor = parseFloat(product.taxDivisor) || 1.13; + let noTaxPrice, noTaxTotal, taxTotal, taxAmount; + + switch (changedField) { + case 'quantity': + case 'taxPrice': + taxTotal = quantity * taxPrice; + noTaxPrice = taxPrice / taxDivisor; + noTaxTotal = quantity * noTaxPrice; + taxAmount = taxTotal - noTaxTotal; + break; + case 'taxDivisor': + noTaxPrice = taxPrice / taxDivisor; + taxTotal = quantity * taxPrice; + noTaxTotal = quantity * noTaxPrice; + taxAmount = taxTotal - noTaxTotal; + break; + case 'noTaxPrice': + noTaxPrice = parseFloat(product.noTaxPrice) || 0; + taxPrice = noTaxPrice * taxDivisor; + taxTotal = quantity * taxPrice; + noTaxTotal = quantity * noTaxPrice; + taxAmount = taxTotal - noTaxTotal; + break; + case 'noTaxTotal': + noTaxTotal = parseFloat(product.noTaxTotal) || 0; + noTaxPrice = quantity > 0 ? noTaxTotal / quantity : 0; + taxPrice = noTaxPrice * taxDivisor; + taxTotal = quantity * taxPrice; + taxAmount = taxTotal - noTaxTotal; + break; + case 'taxTotal': + taxTotal = parseFloat(product.taxTotal) || 0; + taxPrice = quantity > 0 ? taxTotal / quantity : 0; + noTaxPrice = taxPrice / taxDivisor; + noTaxTotal = quantity * noTaxPrice; + taxAmount = taxTotal - noTaxTotal; + break; + case 'taxAmount': + taxAmount = parseFloat(product.taxAmount) || 0; + taxTotal = quantity * taxPrice; + noTaxTotal = taxTotal - taxAmount; + noTaxPrice = quantity > 0 ? noTaxTotal / quantity : 0; + taxPrice = quantity > 0 ? noTaxPrice * taxDivisor : 0; + taxTotal = quantity * taxPrice; + noTaxTotal = quantity * noTaxPrice; + taxAmount = taxTotal - noTaxTotal; + break; + default: + taxTotal = quantity * taxPrice; + noTaxPrice = taxPrice / taxDivisor; + noTaxTotal = quantity * noTaxPrice; + taxAmount = taxTotal - noTaxTotal; + } + + const round2 = (v) => Math.round(v * 100) / 100; + + return { + ...product, + quantity, + taxPrice: round2(taxPrice), + noTaxPrice: round2(noTaxPrice), + taxTotal: round2(taxTotal), + noTaxTotal: round2(noTaxTotal), + taxAmount: round2(taxAmount), + taxDivisor + }; +} + /** * 重新计算所有产品的含税总额和总计 * @param {Object} content - 产品内容对象 @@ -99,10 +215,9 @@ export function recalculateTotals(content) { return { ...DEFAULT_PRODUCT_CONTENT }; } - const products = (content.products || []).map(product => ({ - ...product, - taxTotal: calculateProductTaxTotal(product) - })); + const products = (content.products || []).map(product => + calculateProductFields(product, 'quantity') + ); const totalQuantity = calculateTotalQuantity(products); const totalTaxTotal = calculateTotalTaxTotal(products); @@ -124,15 +239,16 @@ export function recalculateTotals(content) { export function convertOrderItemToProduct(orderItem) { if (!orderItem) return {}; - return { + const product = { spec: orderItem.finishedProductSpec || '', material: orderItem.material || '', quantity: parseFloat(orderItem.weight) || 0, taxPrice: parseFloat(orderItem.contractPrice) || 0, - noTaxPrice: parseFloat(orderItem.itemAmount) || 0, - taxTotal: (parseFloat(orderItem.contractPrice) || 0) * (parseFloat(orderItem.weight) || 0), + taxDivisor: parseFloat(orderItem.taxDivisor) || 1.13, remark: orderItem.remark || '' }; + + return calculateProductFields(product, 'quantity'); } /** @@ -304,6 +420,10 @@ export default { calculateTotalQuantity, calculateTotalTaxTotal, calculateProductTaxTotal, + calculateProductNoTaxPrice, + calculateProductNoTaxTotal, + calculateProductTaxAmount, + calculateProductFields, recalculateTotals, convertOrderItemToProduct, convertOrderItemsToContent, diff --git a/klp-ui/src/views/crm/contract/components/ContractList.vue b/klp-ui/src/views/crm/contract/components/ContractList.vue index 84360c58..aba7786d 100644 --- a/klp-ui/src/views/crm/contract/components/ContractList.vue +++ b/klp-ui/src/views/crm/contract/components/ContractList.vue @@ -133,13 +133,40 @@ + + + +
+ +
+
产品表列配置
+ 全选 +
+ {{ col.label }} +
+ +
勾选的列将显示在导出的产品表中
+
+ +
+ +
+
+ + 取 消 + 确认导出 + +