feat: plugin-core, code field eval (#1079)

Reviewed-on: daoyoucloud/tachybase#1079
Co-authored-by: bai.zixv <bai.zixv@foxmail.com>
Co-committed-by: bai.zixv <bai.zixv@foxmail.com>
This commit is contained in:
bai.zixv 2024-05-30 17:02:36 +08:00 committed by sealday
parent b53c265264
commit 53cd459654
2 changed files with 31 additions and 13 deletions

View File

@ -18,7 +18,7 @@ export class ShowFieldCodeInterface extends CollectionFieldInterface {
type = 'object'; type = 'object';
group = 'advanced'; group = 'advanced';
title = 'jsCode(显示)'; title = 'jsCode(显示)';
description = '通过jsCode, 用于定制化显示用户界面内容'; description = `通过jsCode, 用于定制化显示用户界面内容.可使用的变量:scopes:{ form, path, recordData, result, setResult, formatFunc, dayjs}; handlers: { setResult, formatFunc }; modules: { dayjs }`;
sortable = true; sortable = true;
default = { default = {
type: 'virtual', type: 'virtual',

View File

@ -62,23 +62,18 @@ function useAction(props: CodeFieldProps): string | React.ReactNode {
return result.items?.[0]?.children; return result.items?.[0]?.children;
} }
} }
// 动态执行 jsCode 代码
async function dynamicCode({ jsCode, form, path, recordData, result }, { setResult, formatFunc }) { async function dynamicCode({ jsCode, form, path, recordData, result }, { setResult, formatFunc }) {
try { try {
const dayjs = (await import('dayjs')).default; // NOTE: 示例代码, 仿照此例配置即可; 也可放开注释进行调试
const localeSetting = { invalidDate: '-' }; // jsCode = `{
dayjs.updateLocale('en', localeSetting); // const { form, path } = scopes;
// const { setResult } = handlers;
eval(jsCode); // const { dayjs } = modules;
// NOTE: 示例代码, 仿照此例配置即可
// {
// const date_pay = form.getValuesIn(path.replace('.date_fix', '.date_pay')); // const date_pay = form.getValuesIn(path.replace('.date_fix', '.date_pay'));
// const date_receive = form.getValuesIn(path.replace('.date_fix', '.date_receive')); // const date_receive = form.getValuesIn(path.replace('.date_fix', '.date_receive'));
// const date_show = date_pay || date_receive; // const date_show = date_pay || date_receive;
// const formartedDate = dayjs(date_show ?? '-').format('YYYY-MM-DD'); // const formartedDate = dayjs(date_show ?? '-').format('YYYY-MM-DD');
// console.log('%c Line:81 🌰 formartedDate', 'font-size:18px;color:#4fff4B;background:#3f7cff', formartedDate);
// setResult({ // setResult({
// childrenType: 'jsx', // childrenType: 'jsx',
// items: [ // items: [
@ -87,7 +82,21 @@ async function dynamicCode({ jsCode, form, path, recordData, result }, { setResu
// }, // },
// ], // ],
// }); // });
// } // }`;
/** 动态导入开始, 与 jsCode 配置相关的包 */
const dayjs = (await import('dayjs')).default;
const localeSetting = { invalidDate: '-' };
dayjs.updateLocale('en', localeSetting);
/** 动态导入结束 */
evalSimulate(jsCode, {
scopes: { form, path, recordData, result },
handlers: {
setResult,
formatFunc,
},
modules: { dayjs },
});
} catch (error) { } catch (error) {
setResult({ setResult({
childrenType: '', childrenType: '',
@ -101,3 +110,12 @@ async function dynamicCode({ jsCode, form, path, recordData, result }, { setResu
}); });
} }
} }
// 模拟 eval 实现, 相对更安全的实现和更好的性能, 以及限制作用域范围,
function evalSimulate(jsCode, { scopes, handlers, modules }) {
try {
return new Function('$root', `with($root) { ${jsCode}; }`)({ scopes, handlers, modules });
} catch (err) {
console.log('err', err);
}
}