import { trimZeros, roundHalfUp } from "./formatNumber.js";
|
|
/**
|
* 通用的表格合计方法
|
* @param {Object} param - 包含表格列配置和数据源的对象
|
* @param {Array<string>} summaryProps - 需要汇总的字段名数组
|
* @param {Object} specialFormat - 特殊格式化规则:字段名 -> 格式化选项(如是否去掉小数)
|
* 支持 { noDecimal: true } 取整显示
|
* { trimZeros: true, decimalPlaces: 6 } 最多保留 6 位小数并去掉末尾多余的 0
|
* { roundEach: 2 } 每行先按 2 位小数四舍五入再求和,
|
* 用于金额列:保证合计与列内展示值相加完全一致
|
* { formatter: fn } 自定义格式化函数,优先级最高
|
* { decimalPlaces: 2 } 固定保留 2 位小数(默认)
|
* @returns {Array} 合计行数据
|
*/
|
const summarizeTable = (param, summaryProps, specialFormat = {}) => {
|
const { columns, data } = param;
|
const sums = [];
|
columns.forEach((column, index) => {
|
if (index === 0) {
|
sums[index] = "合计";
|
return;
|
}
|
const prop = column.property;
|
if (summaryProps.includes(prop)) {
|
const rule = specialFormat[prop];
|
const values = data.map((item) => {
|
const val = Number(item[prop]);
|
// NaN 保持 NaN,便于下面判断「整列都不是数字」
|
if (Number.isNaN(val)) return NaN;
|
return rule && rule.roundEach != null
|
? roundHalfUp(val, rule.roundEach)
|
: val;
|
});
|
// 只对有效数字进行求和
|
if (!values.every(isNaN)) {
|
const sum = values.reduce(
|
(acc, val) => (!isNaN(val) ? acc + val : acc),
|
0
|
);
|
if (specialFormat[prop] && specialFormat[prop].noDecimal) {
|
// 如果指定了不需要保留小数,则直接转换为整数
|
sums[index] = Math.round(sum).toString();
|
} else if (
|
specialFormat[prop] &&
|
typeof specialFormat[prop].formatter === "function"
|
) {
|
// 自定义格式化函数优先
|
sums[index] = specialFormat[prop].formatter(sum);
|
} else if (specialFormat[prop] && specialFormat[prop].trimZeros) {
|
// 指定了去掉末尾多余的 0(最多保留 decimalPlaces 位,默认 6 位)
|
sums[index] = trimZeros(sum, specialFormat[prop].decimalPlaces ?? 6);
|
} else {
|
// 默认保留两位小数
|
sums[index] = parseFloat(sum).toFixed(
|
specialFormat[prop]?.decimalPlaces ?? 2
|
);
|
}
|
} else {
|
sums[index] = "";
|
}
|
} else {
|
sums[index] = "";
|
}
|
});
|
return sums;
|
};
|
// 不含税总价计算,decimals 为保留小数位数(销售/采购相关页面传 6)
|
const calculateTaxExclusiveTotalPrice = (
|
taxInclusiveTotalPrice,
|
taxRate,
|
decimals = 2
|
) => {
|
const taxRateDecimal = taxRate / 100;
|
return (taxInclusiveTotalPrice / (1 + taxRateDecimal)).toFixed(decimals);
|
};
|
// 含税总价计算,decimals 为保留小数位数(销售/采购相关页面传 6)
|
const calculateTaxIncludeTotalPrice = (
|
taxInclusiveUnitPrice,
|
quantity,
|
decimals = 2
|
) => {
|
return (taxInclusiveUnitPrice * quantity).toFixed(decimals);
|
};
|
// 导出函数供其他文件使用
|
export {
|
summarizeTable,
|
calculateTaxExclusiveTotalPrice,
|
calculateTaxIncludeTotalPrice,
|
};
|