# 动态逻辑

本系统支持使用 Groovy (opens new window) 语言进行客制化开发, Groovy 语 言是 Java 语言的一个超集,其支持 Java 语言的语法,但增加了更多动态特性,更加适用 于进行领域建模和运行时增强。

提示

如果团队对 Groovy 语言不熟悉,也可以完全使用 Java 语言的语法进行开发,Groovy 与 Java 语言的兼容性非常好。

# 目标读者

本文档的目标读者为:本系统的开发和实施人员

# 动态逻辑定义的结构

动态逻辑可以通过菜单 开发定制 -> 动态逻辑 -> 动态逻辑 进行维护,其包含的相 关属性如下图所示:

Create Dynamic Logic

针对相关字段,详述如下

# 动态逻辑引擎概述

系统提供了一个动态逻辑引擎,用于在系统中执行动态逻辑,动态逻辑可以是一段 Groovy 代码、JVM 字节码,也可以是一个外部的操作系统命令等。

动态逻辑引擎 描述
GROOVY_CODE 用于执行 Groovy 代码(兼容纯 Java 语法)
JVM_BYTECODE 用于执行预编译的 JVM 字节码
OS_COMMAND 用于执行操作系统命令
RENDER_LINK GROOVY_CODE 的别名,返回一个链接给调用方
BEAN_EXECUTOR 执行自定义插件提供的 Bean(Plugin Bean Executor)

提示

动态逻辑相关各对象的 name 字段在创建后,即不可修改。

# 动态逻辑开发指南

# 动态逻辑概述

动态逻辑是一种灵活的业务逻辑实现方式:开发者编写 Groovy 代码(或以 JVM 字节码、 OS 命令等形式提供实现),由平台在业务事件的特定时机注入上下文变量并执行,执行结 果按约定返回给调用方。通过动态逻辑,可以实现对象生命周期客制化、表单客制化、动 态权限、动态动作、定时任务等各类业务扩展。

# 定义动态逻辑

在定义动态逻辑时,您需要关注以下几个方面:

  • 逻辑类型 (Logic Type): 决定该逻辑的适用场景(对象 Hook、表单 Hook、动态权 限、动态动作等),不同逻辑类型注入的变量不同,详见各章节文档。
  • 代码 (Code): 逻辑实现代码。代码中通过注入的上下文变量读取业务数据,并按 各逻辑类型约定的结构返回结果。
  • 引擎 (Engine): 默认使用 GROOVY_CODE 引擎执行代码。

# 代码编写与返回结果

动态逻辑的代码为一段 Groovy 脚本,运行时平台注入该逻辑类型对应的上下文变量(如 objectuserContextapplicationlog 等),代码返回的值按逻辑类型约定的 结构处理。例如:

// 对象创建 Hook:返回修改后的属性
def label = "新客户-${object.name}"
[result: [label: label]]
1
2
3

提示

代码中可以使用 log 变量打印执行日志,日志会出现在平台的逻辑执行记录中。

# 实际应用示例

以下是一些具体的业务场景和动态逻辑定义示例:

# 客户信用额度自动调整

业务场景:创建客户时,根据客户的初始信用评级自动设置信用额度。

动态逻辑定义:

  • 逻辑类型:对象生命周期客制化(创建 Hook)
  • 代码:读取 object.creditRating,按评级映射初始信用额度并返回。

# 智能工单分配

业务场景:创建工单时,根据工单类型自动分配默认处理人。

动态逻辑定义:

  • 逻辑类型:对象生命周期客制化(创建 Hook)
  • 代码:根据 object.workOrderType 匹配处理人并返回默认值。

# 表单联动

业务场景:订单创建表单中,选择「订单类型」后自动联动「交货日期」的显隐与必填。

动态逻辑定义:

  • 逻辑类型:表单客制化(Form Hook),配置在 DynamicForm.formHook
  • 触发字段:formHookTriggerFields 设置为 orderType
  • 代码:根据 changedFieldsobject 的值,返回字段属性 Map。详细用法请参考 表单客制化(Form Hook)

以上指南旨在帮助开发者更好地理解和实现动态逻辑,以满足不同业务场景的需求。在实际 应用中,根据具体的业务需求来定制和优化动态逻辑,可以实现业务流程的灵活性和自动化。

# 动态逻辑类型

以下列出了系统中当前支持的客制化逻辑的类型及其使用场景:

  • 库函数:供其他客制化逻辑调用的函数。
  • 动态权限:对象的动态创建权限判断、删除和更新权限判断。
  • 表单客制化(Form Hook):字段间联动、下拉选项、字段的隐藏与显示、默认值等。
  • 对象生命周期客制化:对象创建、修改、删除、被访问前后的客制化逻辑注入。
  • 动态动作:动态动作的启用逻辑和核心逻辑。
  • 定时任务:定时任务的启用逻辑和核心逻辑。
  • 仪表盘:仪表盘和小组件的启用逻辑及核心逻辑。
  • 过滤器:过滤器的启用逻辑和过滤条件配置。
  • 动态服务:动态服务核心逻辑。
  • 动态集成:动态集成启用逻辑和核心逻辑。

以下分别对动态逻辑在不同业务场景下的应用进行了详细说明:

# 自定义函数 0.30.0+

自定义函数是由用户自己定义的一段动态逻辑,它可以被其他动态逻辑直接调用。

# 函数调用示例

我们首先需要定义一个名为 Test functionFunction logic 类型的 DynamicLogic

Define Function

可以看到我们的逻辑是 a + b, 这里的 ab 都是调用时需要传入的参数。

接下来我们可以在任意的 DynamicLogic 中调用该函数,下面以一个 DynamicAction 的 CoreLogic 举例子

Invoke function 1

可以看到左侧出现了我们刚才定义的 Test function1,点击后右侧代码编辑面板即可出现调用该函数的代码2。其中的 params 为 Map 类型的参数列表,具体调用的代码为

import tech.muyan.utils.BeanContainer
import tech.muyan.api.DynamicFunctionService
// 定义一个 Map 类型的参数列表
Map<String, Object> params = new HashMap<>()
params.put("a", 1)
params.put("b", 2)
// 调用我们刚才定义的函数
// 第一个参数为 DynamicLogic 的名称,第二个参数为调用时传入的参数, 类型为 Map
// 静态方法调用,DynamicFunctionService 是平台内部类,故在 idea 中会找不到该类的定义,但在运行时工作正常
tech.muyan.function.DynamicFunctionService.invoke("Test function", params)
// 或者采用 bean 方式调用
BeanContainer.getBean(DynamicFunctionService.class).invoke("TaskAssignmentLogic", params)
1
2
3
4
5
6
7
8
9
10
11
12

在这里我们改成如下内容:

Invoke function 2

可以看到我们传入了 ab 分别为 12,接下来我们测试执行该逻辑(DynamicAction CoreLogic 具体的调用方式请参考 Dynamic Action 一节)可以看到返回结果如下

Invoke function 3

注意

被调用的 Dynamic Logic 的 Logic Type 必须为 Function logic 才能被其他 Dynamic Logic 用以上方式调用,否则系统会报错: ErrorCode: 15001, ErrorMsg: FunctionNotFound

Last Updated: 2026/7/31 15:31:35