diff --git a/designs/groovy-script/DESiGN.md b/designs/groovy-script/DESiGN.md index 90d6ae44..bfd2c588 100644 --- a/designs/groovy-script/DESiGN.md +++ b/designs/groovy-script/DESiGN.md @@ -1,5 +1,15 @@ # Groovy Script 脚本设计规范 +示例脚本 +``` +// @CUSTOM_SCRIPT +// @SCRIPT_TITLE 这是一个示例脚本 +// @SCRIPT_META {name:"name"} +def run(request){ + return "Hello, ${request.name}!" +} +``` + ## 脚本的实例写法如下 ``` def run(request){ @@ -9,7 +19,7 @@ def run(request){ ## 脚本规范 request对象,根据脚本的不同,起传递的request对象也不同。 -return语句,return语句根据脚本的不同,起返回的对象也不同。 +return语句,return语句根据脚本的不同,对应返回的对象也不同。 ## 开发规范 为了让脚本可以更好的呈现和使用,脚本的配置分为两种模式,一种是可视化配置模式,一种是代码配置模式。 @@ -40,4 +50,16 @@ def run(request){ return "Hello, ${request.name}!" } ``` -上述的脚本在编辑器中就会以“这是一个示例脚本”来展示,而不是以代码的方式来展示。 \ No newline at end of file +上述的脚本在编辑器中就会以“这是一个示例脚本”来展示,而不是以代码的方式来展示。 + + +## 脚本元数据 +在可视化呈现的过程中,界面不仅要能够解析脚本的标题,还需要可以正常的在可视化界面上呈现内容,为此通过@SCRIPT_META来标注界面展示的meta数据格式。 +meta的数据是json格式的数据。 + +``` +// @SCRIPT_META {name:"name"} +def run(request){ + return "Hello, ${request.name}!" +} +``` diff --git a/frontend/packages/flow-pc/flow-pc-design/src/components/script/typings/index.ts b/frontend/packages/flow-pc/flow-pc-design/src/components/script/typings/index.ts index fb11806e..3055b204 100644 --- a/frontend/packages/flow-pc/flow-pc-design/src/components/script/typings/index.ts +++ b/frontend/packages/flow-pc/flow-pc-design/src/components/script/typings/index.ts @@ -4,6 +4,10 @@ export const CUSTOM_SCRIPT = '@CUSTOM_SCRIPT'; /** 脚本标题标记 */ export const SCRIPT_TITLE = '@SCRIPT_TITLE'; + +/** 脚本元数据标记 */ +export const SCRIPT_META = '@SCRIPT_META'; + /** * Groovy脚本类型枚举 */ diff --git a/frontend/packages/flow-pc/flow-pc-design/src/components/script/utils/convertor.ts b/frontend/packages/flow-pc/flow-pc-design/src/components/script/utils/convertor.ts index 8a16dff6..3d00a1b0 100644 --- a/frontend/packages/flow-pc/flow-pc-design/src/components/script/utils/convertor.ts +++ b/frontend/packages/flow-pc/flow-pc-design/src/components/script/utils/convertor.ts @@ -1,4 +1,4 @@ -import {CUSTOM_SCRIPT,SCRIPT_TITLE,GroovyVariableMapping} from "@/components/script/typings"; +import {CUSTOM_SCRIPT, SCRIPT_TITLE, GroovyVariableMapping, SCRIPT_META} from "@/components/script/typings"; import {GroovyFormatter} from "@/components/script/utils/format"; /** @@ -64,6 +64,34 @@ export class GroovyScriptConvertorUtil { } + /** + * 获取脚本中的元数据 + * @param script + */ + public static getScriptMeta(script: string): string { + const titleMatch = script.match(new RegExp(`//\\s*${SCRIPT_META}\\s*(.+)`)); + if (titleMatch) { + return titleMatch[1].trim(); + } + return ''; + } + + + /** + * 更新脚本中的元数据内容,如果不存在则添加 + * @param script + * @param meta + */ + public static updateScriptMeta(script: string, meta: string): string { + const metaComment = `// ${SCRIPT_META} ${meta}`; + if (GroovyScriptConvertorUtil.getScriptTitle(script)) { + return script.replace(new RegExp(`//\\s*${SCRIPT_META}\\s*.+`), metaComment); + } else { + return `${metaComment}\n${script}`; + } + } + + /** * 清除脚本中的注释 * @param script diff --git a/frontend/packages/flow-pc/flow-pc-design/tests/script/utils/convertor-node-title.test.ts b/frontend/packages/flow-pc/flow-pc-design/tests/script/utils/convertor-node-title.test.ts index 1be82f59..bb74a351 100644 --- a/frontend/packages/flow-pc/flow-pc-design/tests/script/utils/convertor-node-title.test.ts +++ b/frontend/packages/flow-pc/flow-pc-design/tests/script/utils/convertor-node-title.test.ts @@ -6,6 +6,7 @@ import { import { NodeTitleVariableAdapter } from "@/components/script/services/variable/node-title"; +import {GroovyScriptConvertorUtil} from "@/components/script/utils/convertor"; describe('NodeTitleGroovyConvertor', () => { @@ -38,6 +39,7 @@ describe('NodeTitleGroovyConvertor', () => { describe('toExpression', () => { it('node title script to expression', () => { const script = ` +// @SCRIPT_TITLE 您有一条待办消息\${当前操作人ID}\${当前操作人ID}\${流程创建人}\${是否管理员} def run(request){ return "您有一条待办消息" + request.getOperatorId() + request.getOperatorId() + request.getCreatorName() + request.getIsFlowManager() } @@ -59,7 +61,8 @@ def run(request){ ` const nodeTitleGroovyConvertor = new NodeTitleGroovyConvertor(script, nodeTitleVariableAdapter.getVariables()); const result = nodeTitleGroovyConvertor.resetExpression('你有一条${当前操作人}的${流程标题}待办消息 【${当前节点}】') - expect(result).toEqual(script); + const title = GroovyScriptConvertorUtil.getScriptTitle(result); + expect(title).toEqual("你有一条${当前操作人}的${流程标题}待办消息 【${当前节点}】"); }); }); }); \ No newline at end of file diff --git a/frontend/packages/flow-pc/flow-pc-design/tests/script/utils/convertor-utils.test.ts b/frontend/packages/flow-pc/flow-pc-design/tests/script/utils/convertor-utils.test.ts index c6d4852d..c3c85196 100644 --- a/frontend/packages/flow-pc/flow-pc-design/tests/script/utils/convertor-utils.test.ts +++ b/frontend/packages/flow-pc/flow-pc-design/tests/script/utils/convertor-utils.test.ts @@ -1,5 +1,5 @@ import {describe, expect, it} from '@rstest/core'; -import {GroovyScriptConvertorUtil} from "@/components/script/services/convertor/utils"; +import {GroovyScriptConvertorUtil} from "@/components/script/utils/convertor"; describe('GroovyScriptUtil', () => { @@ -52,4 +52,34 @@ def run(request){ expect(title).toEqual(`这就是一个实例的标题`); }); }); + + + describe('getScriptMeta', () => { + it('get groovy script meta', () => { + const script = ` +// @SCRIPT_TITLE 这是一个实例的标题 +// @SCRIPT_META {name:"name"} +def run(request){ + return "你有一条" + request.getOperatorName() + "的" + request.getWorkflowTitle() + "待办消息 【" + request.getNodeName() + "】" +}` + const result = GroovyScriptConvertorUtil.getScriptMeta(script) + expect(result).toEqual(`{name:"name"}`); + }); + }); + + + describe('updateScriptMeta', () => { + it('update groovy script meta', () => { + const script = ` +// @SCRIPT_TITLE 这是一个实例的标题 +// @SCRIPT_META {name:"name"} +def run(request){ + return "你有一条" + request.getOperatorName() + "的" + request.getWorkflowTitle() + "待办消息 【" + request.getNodeName() + "】" +}` + const result = GroovyScriptConvertorUtil.updateScriptMeta(script,'{name:"test"}'); + console.log(result); + const title = GroovyScriptConvertorUtil.getScriptMeta(result) + expect(title).toEqual(`{name:"test"}`); + }); + }); }); \ No newline at end of file