feat(product): 实现产品目录单价自动计算与分配功能

新增 `calculateAndDistributeCataloguePrice` 方法,用于在添加或删除产品时,
根据业务规则自动计算并更新指定产品的目录单价。同时排除固定产品价格影响,
确保价格计算的准确性。支持多种产品编码的差异化计算逻辑,并在价格变更时重新计算单价、总价等关联字段。
dev_1.0.0
chenhao 2025-09-22 14:13:18 +08:00
parent 672ff91437
commit 92218dac59
1 changed files with 214 additions and 1 deletions

View File

@ -106,9 +106,12 @@
</style>
<!-- JS 函数引用或内联 -->
<script th:inline="javascript"> /*<![CDATA[*/
let canUpdateFlag=[[${canUpdate}]]
const updatePriceProductList=['8813A3YA','8813A3YB','8813A7U4','8813A7U2']
const quantityStep = ['3130A4TE']
const FOLD_ON_FOLD = 0.988;
// 需要排除的固定产品常量
const EXCLUDED_PRODUCTS = ['3130A4NA', '3130A4N9', '3130A4N5', '0504A14F', '0202A1NU', '0504A14G', '0202A1NT', '0504A1JX', '0202A1NS'];
const productType=[{
name:'softwareProjectProductInfoList',
type:'1',
@ -144,6 +147,8 @@
$.modal.close(index);
$(that).parent().parent().remove();
updateIndices();
// 删除产品后重新计算和分配目录单价
calculateAndDistributeCataloguePrice();
});
}
function updateIndices() {
@ -288,16 +293,19 @@
$('#productTable tbody').append(generatedTr(0,data,length))
// initSearchProduct('1')
initPrice()
// 添加产品后重新计算和分配目录单价
calculateAndDistributeCataloguePrice()
}
function addProduct2(data) {
let length = $('#productTable2 tbody').find('tr').length
$('#productTable2 tbody').append(generatedTr(1,data,length))
initPrice()
// 添加产品后重新计算和分配目录单价
calculateAndDistributeCataloguePrice()
}
function generatedTr(index,data,length){
debugger
let flag=true
let productTypeParam=productType[index]
let queryParam=productTypeParam.type
@ -367,6 +375,180 @@
$('#productTable3 tbody').append(generatedTr(2,data,length))
initPrice()
// 添加产品后重新计算和分配目录单价
calculateAndDistributeCataloguePrice()
}
/**
* 计算所有产品的目录总价之和并分配到updatePriceProductList产品的目录单价
*/
function calculateAndDistributeCataloguePrice() {
if (!canUpdateFlag){
return;
}
// 1. 获取需要更新价格的产品行
let updatePriceRows = getUpdatePriceProductRows();
console.log(`需要更新价格产品行${updatePriceRows.length}`)
if (updatePriceRows.length === 0) {
return;
}
// 3. 根据产品编码分配目录单价
updatePriceRows.each(function () {
let $row = $(this);
let productCode = $row.find('.productBomCode').val();
let newCataloguePrice = calculateCataloguePriceByProductCode(productCode, updatePriceRows.length);
// 更新目录单价
$row.find('.cataloguePrice').val(newCataloguePrice);
$row.find('.catalogue-price-format').val(formatAmountNumber(newCataloguePrice));
// 触发价格重新计算
recalculateRowPrices($row);
});
}
/**
* 计算排除固定产品后的目录总价之和包括productTable和productTable2
* @returns {number} 排除固定产品后的目录总价之和
*/
function calculateTotalCataloguePriceExcludingFixed() {
let total = 0;
// 计算软件产品表格productTable
$('#productTable tbody tr').each(function () {
let productCode = $(this).find('.productBomCode').val();
// 排除固定产品
if (!EXCLUDED_PRODUCTS.includes(productCode)) {
let catalogueAllPrice = parseFloat($(this).find('.catalogueAllPrice').val()) || 0;
total += catalogueAllPrice;
}
});
// 计算终端产品表格productTable2
$('#productTable2 tbody tr').each(function () {
let productCode = $(this).find('.productBomCode').val();
// 排除固定产品
if (!EXCLUDED_PRODUCTS.includes(productCode)) {
let catalogueAllPrice = parseFloat($(this).find('.catalogueAllPrice').val()) || 0;
total += catalogueAllPrice;
}
});
return total;
}
/**
* 获取需要更新价格的产品行包括productTable和productTable2
* @returns {jQuery} 匹配的产品行集合
*/
function getUpdatePriceProductRows() {
let rows = $();
// 从软件产品表格productTable中获取
$('#productTable3 tbody tr').each(function () {
let productCode = $(this).find('.productBomCode').val();
if (updatePriceProductList.includes(productCode)) {
rows = rows.add($(this));
}
});
return rows;
}
/**
* 根据产品编码计算该产品的目录单价
* @param {string} productCode 产品编码
* @param {number} totalCataloguePrice 总的目录价格
* @param {number} updateProductCount 需要更新的产品数量
* @returns {number} 计算后的目录单价
*/
function calculateCataloguePriceByProductCode(productCode, updateProductCount) {
// 不同产品编码的计算规则不一样,需要根据具体业务逻辑实现
console.log(`产品编码为${productCode}`)
switch (productCode) {
case '8813A3YA':
return calculatePriceFor8813A3YA(updateProductCount);
case '8813A3YB':
return calculatePriceFor8813A3YB(updateProductCount);
case '8813A7U4':
return calculatePriceFor8813A7U4(updateProductCount);
case '8813A7U2':
return calculatePriceFor8813A7U2(updateProductCount);
default:
// 默认平均分配
return 1;
}
}
/**
* 计算产品 8813A3YA 的目录单价
* @param {number} totalCataloguePrice 总目录价格
* @param {number} updateProductCount 需要更新的产品数量
* @returns {number} 计算后的目录单价
*/
function calculatePriceFor8813A3YA(updateProductCount) {
// 计算规则:其它产品目录总价 * 5.33%,需要排除固定产品
let excludedTotalPrice = calculateTotalCataloguePriceExcludingFixed();
return (excludedTotalPrice * 0.0533).toFixed(2);
}
/**
* 计算产品 8813A3YB 的目录单价
* @param {number} totalCataloguePrice 总目录价格
* @param {number} updateProductCount 需要更新的产品数量
* @returns {number} 计算后的目录单价
*/
function calculatePriceFor8813A3YB(updateProductCount) {
// 计算规则:其它产品目录总价 * 5.33% * 3 * 0.8,需要排除固定产品
let excludedTotalPrice = calculateTotalCataloguePriceExcludingFixed();
return (excludedTotalPrice * 0.0533 * 3 * 0.8).toFixed(2);
}
/**
* 计算产品 8813A7U4 的目录单价
* @param {number} totalCataloguePrice 总目录价格
* @param {number} updateProductCount 需要更新的产品数量
* @returns {number} 计算后的目录单价
*/
function calculatePriceFor8813A7U4(updateProductCount) {
// 计算规则:目录总价 * 1.5%,需要排除固定产品
let excludedTotalPrice = calculateTotalCataloguePriceExcludingFixed();
return (excludedTotalPrice * 0.015).toFixed(2);
}
/**
* 计算产品 8813A7U2 的目录单价
* @param {number} totalCataloguePrice 总目录价格
* @param {number} updateProductCount 需要更新的产品数量
* @returns {number} 计算后的目录单价
*/
function calculatePriceFor8813A7U2(updateProductCount) {
// 计算规则:目录总价 * 1.5% * 3 * 0.8,需要排除固定产品
let excludedTotalPrice = calculateTotalCataloguePriceExcludingFixed();
return (excludedTotalPrice * 0.015 * 3 * 0.8).toFixed(2);
}
/**
* 重新计算某一行的价格相关数据
* @param {jQuery} $row 产品行的jQuery对象
*/
function recalculateRowPrices($row) {
let cataloguePrice = parseFloat($row.find('.cataloguePrice').val()) || 0;
let discount = parseFloat($row.find('.discount').val()) || 1;
let quantity = parseFloat($row.find('.quantity').val()) || 0;
// 重新计算单价
let price = (cataloguePrice * discount).toFixed(2);
$row.find('.price').val(price);
$row.find('.price-formmat').val(formatAmountNumber(price));
// 重新计算总价
let allPrice = (price * quantity).toFixed(2);
$row.find('.allPrice').val(allPrice);
$row.find('.allPrice-formmat').val(formatAmountNumber(allPrice));
// 重新计算目录总价
let catalogueAllPrice = (cataloguePrice * quantity).toFixed(2);
$row.find('.catalogueAllPrice').val(catalogueAllPrice);
$row.find('.catalogueAllPrice-formmat').val(formatAmountNumber(catalogueAllPrice));
}
function getData(that,name){
let currentTd = $(that).closest('td'); // 获取当前 td 元素
@ -511,6 +693,37 @@
if (!quantityStepFlag && quantityElement.val()) {
quantityElement.val(parseInt(quantityElement.val()))
}
let $row = $(ele).parent().parent();
let cataloguePrice = parseFloat($row.find('.cataloguePrice').val()) || 0;
let discount = parseFloat($row.find('.discount').val()) || parseFloat($row.find('.guidanceDiscount').val()) || 1;
let quantity = parseFloat($row.find('.quantity').val()) || 0;
// Calculate unit price (单价)
let price = (cataloguePrice * discount).toFixed(2);
$row.find('.price').val(price);
$row.find('.price-formmat').val(formatAmountNumber(price));
// Calculate total price (总价) if quantity exists
if (quantity > 0) {
let allPrice = (price * quantity).toFixed(2);
$row.find('.allPrice').val(allPrice);
$row.find('.allPrice-formmat').val(formatAmountNumber(allPrice));
}
// Calculate catalogue total price (目录总价) if quantity exists
if (quantity > 0) {
let catalogueAllPrice = (cataloguePrice * quantity).toFixed(2);
$row.find('.catalogueAllPrice').val(catalogueAllPrice);
$row.find('.catalogueAllPrice-formmat').val(formatAmountNumber(catalogueAllPrice));
}
// Update discount format display
let discountFormat = (discount * 100).toFixed(2);
$row.find('.discount').val(discount);
$row.find('.discount-format').val(discountFormat);
if (updatePriceProductList.includes(rows[0].productCode)){
calculateAndDistributeCataloguePrice()
}
$.modal.close(index);
}