c0101796 by lxs

数据定价计算方式更新

1 parent 54773648
......@@ -848,36 +848,63 @@ const reporting = (formInfo) => {
const calculatePrice = (pData) => {
let modelFormula = modelData.value.modelFormula;
// 1. 移除所有干扰的引号(确保是数学表达式)
modelFormula = modelFormula.replace(/["']/g, "");
modelFormula = modelFormula.replace(/["']/g, "").trim();
// 1. 提取变量名(中文、英文、数字、下划线)
// 2. 定义允许的数学运算符和函数
const allowedOperators = /[+\-*/%^() .\d]/;
const mathFunctions = ['sin', 'cos', 'tan', 'log', 'sqrt', 'abs', 'pow'];
// 3. 提取变量名
const variableRegex = /[\u4e00-\u9fa5a-zA-Z_][\u4e00-\u9fa5a-zA-Z0-9_]*/g;
const variableNames = modelFormula.match(variableRegex) || [];
// 2. 去重
const uniqueVariables = [...new Set(variableNames)];
// 3. 构建变量映射 { 销售额: 2000, 成本: 500.5, ... }
// 4. 构建变量映射
const variables = {};
uniqueVariables.forEach(name => {
const dim = pData.find(d => d.dimensionalityName === name);
variables[name] = dim ? parseFloat(dim.sNum) : 0; // 找不到则默认为 0
// 过滤数学函数
if (!mathFunctions.includes(name)) {
const dim = pData.find(d => d.dimensionalityName === name);
variables[name] = dim ? parseFloat(dim.sNum) || 0 : 0;
}
});
// 4. 替换变量为数值(不加引号,确保是数字运算
// 5. 替换变量为数值(考虑边界情况
let expression = modelFormula;
uniqueVariables.forEach(name => {
Object.keys(variables).forEach(name => {
expression = expression.replace(new RegExp(name, 'g'), variables[name]);
});
// 5. 安全计算(推荐 math.js,或 new Function)
// 7. 表达式安全检查
// 7.1 检查是否只包含允许的字符
const sanitizedExpr = expression.replace(allowedOperators, '');
if (sanitizedExpr.length > 0) {
console.error('公式包含非法字符:', sanitizedExpr);
return NaN;
}
// 8. 执行计算
try {
//如果用 eval,确保表达式格式正确
const resultNum = eval(expression);
// 8.1 转换运算符
expression = expression
.replace(/\s+/g, '') // 去除空格
.replace(/\^/g, '**') // 转换幂运算
.replace(/÷/g, '/') // 转换除法符号
.replace(/×/g, '*') // 转换乘法符号
.replace(/(\d+)\(/g, '$1*(') // 处理隐式乘法
.replace(/\)\(/g, ')*('); // 处理括号间乘法
dataTransactionPrice.value = (Math.round(parseFloat(resultNum) * 100) / 100).toFixed(2);
// 8.2 安全计算
const result = new Function('return ' + expression)();
const roundedResult = Math.round(parseFloat(result) * 100) / 100;
dataTransactionPrice.value = roundedResult.toFixed(2);
return roundedResult;
} catch (error) {
console.error('公式计算错误:', error);
console.error('公式计算错误:', {
error,
originalFormula: modelFormula,
processedFormula: expression
});
return NaN;
}
};
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!