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 }}
+
+
+
勾选的列将显示在导出的产品表中
+
+
+
+
+
+
+
+ 取 消
+ 确认导出
+
+