fastlion-amis
Version:
一种MIS页面生成工具
174 lines (173 loc) • 6.67 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.evalJS = exports.setCustomEvalJs = exports.evalExpression = exports.setCustomEvalExpression = exports.filter = exports.tplReg = exports.registerTplEnginer = void 0;
var tslib_1 = require("tslib");
var tpl_builtin_1 = require("./tpl-builtin");
var tpl_lodash_1 = require("./tpl-lodash");
var amis_formula_1 = require("amis-formula");
var bignumber_js_1 = require("bignumber.js");
var enginers = {};
function registerTplEnginer(name, enginer) {
enginers[name] = enginer;
}
exports.registerTplEnginer = registerTplEnginer;
exports.tplReg = /\$\{.+?\}|<%.+?%>/; // 模板字符的匹配表达式 匹配 "ddddd ${aa} ddd"的字符
var tplItemsReg = /\$\{items\|.+?\}/; // 模板字符的匹配表达式 匹配 "ddddd ${items|aa} ddd"的字符
// 暂存的数据缓存 缓存计算过的数据结果 防止重复计算
var curDataCahe = {};
var curDataCaheTimer; // 定时器标识
function filter(tpl, data) {
if (data === void 0) { data = {}; }
var rest = [];
for (var _i = 2; _i < arguments.length; _i++) {
rest[_i - 2] = arguments[_i];
}
// 记录代码块开始时间
if (!tpl || typeof tpl !== 'string') {
return '';
}
// 如果不是模板字符无需进行模板替换
if (!exports.tplReg.test(tpl))
return tpl;
var keys = Object.keys(enginers);
var sum = {};
var sumData;
// 需要用到items的并且有才需要跌迭代压缩一下items 否则没必要
if (tplItemsReg.test(tpl) && data.items) {
if (data.dataSetId && curDataCahe[data.dataSetId]) {
sumData = { items: [curDataCahe[data.dataSetId]] };
}
else {
for (var _a = 0, _b = data === null || data === void 0 ? void 0 : data.items; _a < _b.length; _a++) {
var item = _b[_a];
for (var key in item) {
if (typeof item[key] === 'object')
continue;
if (typeof item[key] === 'number' || !Number.isNaN(+item[key])) {
sum[key] = +sum[key] || 0;
sum[key] = new bignumber_js_1.BigNumber(sum[key]).plus(+item[key] || 0);
}
else if (typeof item[key] === 'string') {
sum[key] += item[key];
}
}
}
curDataCahe[data.dataSetId] = sum;
sumData = { items: [sum] };
// 同一时间段重复的数据只计算一次
if (curDataCaheTimer)
clearTimeout(curDataCaheTimer);
curDataCaheTimer = setTimeout(function () { return curDataCahe = {}; }, 500);
}
}
else {
sumData = data;
}
for (var i = 0, len = keys.length; i < len; i++) {
var enginer = enginers[keys[i]];
if (enginer.test(tpl)) {
return enginer.compile.apply(enginer, (0, tslib_1.__spreadArray)([tpl, sumData], rest, false));
}
else if (enginer.removeEscapeToken) {
tpl = enginer.removeEscapeToken(tpl);
}
}
return tpl;
}
exports.filter = filter;
// 缓存一下提升性能
var EVAL_CACHE = {};
var customEvalExpressionFn;
function setCustomEvalExpression(fn) {
customEvalExpressionFn = fn;
}
exports.setCustomEvalExpression = setCustomEvalExpression;
// 几乎所有的 visibleOn requiredOn 都是通过这个方法判断出来结果,很粗暴也存在风险,建议自己实现。
// 如果想自己实现,请通过 setCustomEvalExpression 来替换。
function evalExpression(expression, data) {
if (typeof customEvalExpressionFn === 'function') {
return customEvalExpressionFn(expression, data);
}
if (!expression || typeof expression !== 'string') {
return false;
}
/* jshint evil:true */
try {
if (typeof expression === 'string' &&
expression.substring(0, 2) === '${' &&
expression[expression.length - 1] === '}') {
// 启用新版本的公式表达式
return evalFormula(expression, data);
}
var debug = false;
var idx = expression.indexOf('debugger');
if (~idx) {
debug = true;
expression = expression.replace(/debugger;?/, '');
}
var fn = void 0;
if (expression in EVAL_CACHE) {
fn = EVAL_CACHE[expression];
}
else {
fn = new Function('data', 'utils', "with(data) {" + (debug ? 'debugger;' : '') + "return !!(" + expression + ");}");
EVAL_CACHE[expression] = fn;
}
data = data || {};
return fn.call(data, data, (0, tpl_builtin_1.getFilters)());
}
catch (e) {
console.warn(expression, e);
return false;
}
}
exports.evalExpression = evalExpression;
var AST_CACHE = {};
function evalFormula(expression, data) {
var ast = AST_CACHE[expression] ||
(0, amis_formula_1.parse)(expression, {
evalMode: false
});
AST_CACHE[expression] = ast;
return (0, amis_formula_1.evaluate)(ast, data, {
defaultFilter: 'raw'
});
}
var customEvalJsFn;
function setCustomEvalJs(fn) {
customEvalJsFn = fn;
}
exports.setCustomEvalJs = setCustomEvalJs;
// 这个主要用在 formula 里面,用来动态的改变某个值。也很粗暴,建议自己实现。
// 如果想自己实现,请通过 setCustomEvalJs 来替换。
function evalJS(js, data) {
if (typeof customEvalJsFn === 'function') {
return customEvalJsFn(js, data);
}
/* jshint evil:true */
try {
if (typeof js === 'string' &&
js.substring(0, 2) === '${' &&
js[js.length - 1] === '}') {
// 启用新版本的公式表达式
return evalFormula(js, data);
}
var fn = new Function('data', 'utils', "with(data) {" + (/^\s*return\b/.test(js) ? '' : 'return ') + js + ";}");
data = data || {};
return fn.call(data, data, (0, tpl_builtin_1.getFilters)());
}
catch (e) {
console.warn(js, e);
return null;
}
}
exports.evalJS = evalJS;
[tpl_builtin_1.register, tpl_lodash_1.register].forEach(function (fn) {
var info = fn();
registerTplEnginer(info.name, {
test: info.test,
compile: info.compile,
removeEscapeToken: info.removeEscapeToken
});
});
//# sourceMappingURL=./utils/tpl.js.map
;