# 开发速查手册

以下是系统开发中常用接口及数据格式说明

# 目标读者

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

# 字段级联

详细信息请参考 客制化字段联动

# 注入变量

变量名称 变量类型 描述
application grails.core.GrailsApplication 当前的 grails 应用上下文
userContext grails.plugin.springsecurity.userdetails.GrailsUser 当前操作的用户信息
domainName java.lang.String 不包含package部分的,当前操作的对象类型
sourceColumn java.lang.String 驱动列,该字段的变化触发了该客制化
destColumn java.lang.String 目标列,客制化的返回结果会作用于该列
sourceColumnValue java.lang.String 驱动列的值
object org.grails.web.json.JSONObject 用户正在编辑的对象当前界面上各个字段的值
log Closure<?> 用于打印执行日志的 log 闭包

# 返回结果

return [
  //指定该字段的显示状态:hide 为隐藏、show 为显示且可编辑、readonly 为只读
  //Specify the display status of the field: hide for hidden, show for editable, and readonly for read-only
  display: hide | show | readonly

  // 指定该字段是否必填, true 表示必填,false 表示非必填
  // Specify whether the field is required: true for required, false for non-required
  required: true | false

  // 指定该字段的值,如果是个多选字段,可以使用 [] 的形式来指定多个值
  // Specify the value of the field, if it is a multi-select field, you can use the [] form to specify multiple values
  value: [] 或者 xxx,

  // 如果该字段是个选择类型的字段,如下的返回值指定其备选项,
  // 每个备选项均包括显示给用户看的 Label 属性和实际保存的 value 属性
  // If the field is a select type field, the following return value specifies its options,
  // each option includes the Label attribute displayed to the user and the value attribute actually saved
  options: [
      {
          "value": "ABSTRACT_DATE",
          "label": "Abstract date"
      },
      {
          "value": "ABSTRACT_DATE_TIME",
          "label": "Abstract date with time"
      }
  ]
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 字段搜索

详细信息请参考 字段快捷搜索逻辑

# 注入变量

变量名称 变量类型 描述
ownerClass java.lang.Class<?> 该字段所属的对象类型
fieldName java.lang.String 在对象中,待搜索字段的字段名称
fieldClass java.lang.Class<?> 待搜索字段的字段类型
keyword java.lang.String 搜索关键字
userContext grails.plugin.springsecurity.userdetails.GrailsUser 当前操作的用户信息
application grails.core.GrailsApplication 当前的 grails 应用上下文
log Closure<?> 用于打印执行日志的 log 闭包

# 返回结果

return [
  // 包含且仅包含一个 key 为 result 的数组
  // Contains and only contains an array with a key of result
  'result': [// result 中是一个数组
    // 数组中每个元素都是一个 domain 对象
    // Each element in the array is a domain object
  ]
]
1
2
3
4
5
6
7

# 字段校验

详细信息请参考 客制化字段校验

# 注入变量

变量名称 变量类型 描述
userContext grails.plugin.springsecurity.userdetails.GrailsUser 当前操作的用户信息
application grails.core.GrailsApplication 当前的 grails 应用上下文
domainName java.lang.String 当前操作的对象类型名称
destColumn java.lang.String 校验的目标列名称
destColumnValue java.lang.Object 目标列的值
create boolean 是否是创建操作,如为 false 表示更新操作
requestData java.lang.Object 前台表单所有字段值的 JSON 序列化
objectId java.lang.Long 校验的对象 id, 对于创建操作,值为 -1
log Closure<?> 用于打印执行日志的 log 闭包

# 返回结果

// result key 对应的 value 即为系统会传递到前台的默认值
// The value corresponding to the result key is the default value passed to the frontend by the system
return [
  valid: true | false,
  message: "校验失败的界面提示信息 Field validation failure information"
]
1
2
3
4
5

# 字段默认值

详细信息请参考 客制化字段默认值

# 注入变量

变量名称 变量类型 描述
objectType tech.muyan.DomainClass 当前操作的对象类型
userContext grails.plugin.springsecurity.userdetails.GrailsUser 当前操作的用户信息
destColumn java.lang.String 设定默认值的目标列
destColumnType java.lang.String 目标列的完整类型名称
application grails.core.GrailsApplication 当前的 grails 应用上下文
log Closure<?> 用于打印执行日志的 log 闭包

# 返回结果

// result key 对应的 value 即为系统会传递到前台的默认值
// The value corresponding to the result key is the default value passed to the frontend by the system
return [result: xxx]
1
2

# 对象创建 Hook

详细信息请参考 对象生命周期客制化

# 注入变量

变量名称 变量类型 描述
object <? extends GormEntity> 对象实例
dynamicFieldValues List<tech.muyan.dynamic.field.DynamicFieldValue> 所有动态字段的值
userContext grails.plugin.springsecurity.userdetails.GrailsUser 当前操作的用户信息
application grails.core.GrailsApplication 当前的 grails 应用上下文
log Closure<?> 用于打印执行日志的 log 闭包
hookType tech.muyan.enums.ObjectHookType 当前执行的 object hook 的类型

# 异常处理

在操作前的客制化逻辑中,可以直接修改操作的对象实例参数实现客制化,对对象实例的修 改会被保存到数据库中。

在操作前和操作后的客制化代码的逻辑执行中,均可使用抛出异常的方式中断系统对该对象 的操作过程,详述如下:

  • tech.muyan.exception.CustomLogicInterruptException 或其子类型的异常被捕获 到,则该对象的操作过程会被中断,该操作不会被保存到数据库中,且该异常的 Message 会 被在前台作为错误显示给用户。

  • tech.muyan.exception.CustomLogicWarningException 或其子类型的异常被捕获到, 则该对象的操作过程不会被中断,但该异常的 Message 会被在前台作为警告显示给用户。

# 对象更新 Hook

详细信息请参考 对象生命周期客制化

# 注入变量

变量名称 变量类型 描述
oldObject <? extends GormEntity> 更新前的对象实例的拷贝
newObject <? extends GormEntity> 包括动态字段的,更新后的对象实例
userContext grails.plugin.springsecurity.userdetails.GrailsUser 当前操作的用户信息
application grails.core.GrailsApplication 当前的 grails 应用上下文
log Closure<?> 用于打印执行日志的 log 闭包
hookType tech.muyan.enums.ObjectHookType 当前执行的 object hook 的类型

# 异常处理

在操作前的客制化逻辑中,可以直接修改操作的对象实例参数实现客制化,对对象实例的修 改会被保存到数据库中。

在操作前和操作后的客制化代码的逻辑执行中,均可使用抛出异常的方式中断系统对该对象 的操作过程,详述如下:

  • tech.muyan.exception.CustomLogicInterruptException 或其子类型的异常被捕获 到,则该对象的操作过程会被中断,该操作不会被保存到数据库中,且该异常的 Message 会 被在前台作为错误显示给用户。

  • tech.muyan.exception.CustomLogicWarningException 或其子类型的异常被捕获到, 则该对象的操作过程不会被中断,但该异常的 Message 会被在前台作为警告显示给用户。

# 对象删除 Hook

详细信息请参考 对象生命周期客制化

# 注入变量

变量名称 变量类型 描述
object <? extends GormEntity> 待删除的对象
userContext grails.plugin.springsecurity.userdetails.GrailsUser 当前操作的用户信息
application grails.core.GrailsApplication 当前的 grails 应用上下文
log Closure<?> 用于打印执行日志的 log 闭包
hookType tech.muyan.enums.ObjectHookType 当前执行的 object hook 的类型

# 异常处理

在操作前的客制化逻辑中,可以直接修改操作的对象实例参数实现客制化,对对象实例的修 改会被保存到数据库中。

在操作前和操作后的客制化代码的逻辑执行中,均可使用抛出异常的方式中断系统对该对象 的操作过程,详述如下:

  • tech.muyan.exception.CustomLogicInterruptException 或其子类型的异常被捕获 到,则该对象的操作过程会被中断,该操作不会被保存到数据库中,且该异常的 Message 会 被在前台作为错误显示给用户。

  • tech.muyan.exception.CustomLogicWarningException 或其子类型的异常被捕获到, 则该对象的操作过程不会被中断,但该异常的 Message 会被在前台作为警告显示给用户。

# 对象接口返回数据

更多信息请参考 对象接口返回数据客制化

# 注入变量

变量名称 变量类型 描述
object <? extends GormEntity> 接口待返回的对象实例
userContext grails.plugin.springsecurity.userdetails.GrailsUser 当前操作的用户信息
application grails.core.GrailsApplication 当前的 grails 应用上下文
page tech.muyan.enums.CustomRenderPageType 调用该 render 方法的页面
log Closure<?> 用于打印执行日志的 log 闭包
ownerClass java.lang.Class<? extends GormEntity> 对于搜索页面, 搜索字段所属对象
fieldName java.lang.String 对于搜索页面, 搜索字段的字段名
fetchType tech.muyan.enums.FetchType 获取数据的类型

fetchType 参数是根据界面的不同业务场景,选择返回的数据的范围,当前可选值说明如下:

说明
ONLY_LABEL_FIELD 只获取 Label 字段和 id
EXCLUDE_ARRAY_COLUMNS 返回除了一对多和多对多的关联对象外的其他字段值
ALL_COLUMNS 返回所有字段值

page 参数的可选值如下:

说明
RELATED_SEARCH 关联对象列表页面带搜索条件
RELATED 关联对象列表页面带
LIST_SEARCH 主列表页面带搜索条件
LIST 主列表页面
FINDER 搜索页面
FINDER_SEARCH 搜索页面带搜索条件
DETAIL 详情或者编辑页面
SHOW_MULTIPLE Show multiple API 的返回值

# 返回结果

// 该客制化代码需要返回的结果为一个 Map, key 为 result, value 中为 [返回字段名: 字段值] 的 Map 的格式返回结果
// The result returned by the custom code needs to be a Map, with a key of result and a value of [return field name: field value] in the format of a Map
[
  result: [
    columnName: columnValue,
    // 对象类型的子字段返回一个只包含 id 的子 map
    objectField: [
      id: objectId
    ],
    // 用于 card list view 进行 HTML 渲染的属性
    "@HTML_CONTENT@": ""
  ]
]
// 或者直接为一个 org.grails.datastore.gorm.GormEntity 对象的实例
// Or directly return an instance of an org.grails.datastore.gorm.GormEntity object
return object
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 对象详情访问 Hook

更多信息请参考 对象详情访问

# 注入变量

变量名称 变量类型 描述
object <? extends GormEntity> 对象实例
renderedObject <? extends GormEntity> 或 Map<String, Object> Render API 返回的对象实例或包含对象数据的 Map 对象
userContext grails.plugin.springsecurity.userdetails.GrailsUser 当前操作的用户信息
application grails.core.GrailsApplication 当前的 grails 应用上下文
fetchType tech.muyan.enums.FetchType 获取数据的类型
log Closure<?> 用于打印执行日志的 log 闭包
hookType tech.muyan.enums.ObjectHookType.ACCESS 当前执行的 object hook 的类型

# 动态创建权限

详细信息请参考 动态创建权限

# 注入变量

变量名称 变量类型 描述
objectType Class<?> 当前操作的对象类型
userContext grails.plugin.springsecurity.userdetails.GrailsUser 当前操作的用户信息
application grails.core.GrailsApplication 当前的 grails 应用上下文
log Closure<?> 用于打印执行日志的 log 闭包

# 返回结果

// 本行代码返回允许用户创建该对象
// Allow user to create this object
return ['create': true] 
1
2

# 动态修改和删除权限

详细信息请参考 动态修改和删除权限

# 注入变量

变量名称 变量类型 描述
objectType Class<?> 当前操作的对象类型
userContext grails.plugin.springsecurity.userdetails.GrailsUser 当前操作的用户信息
objectValue grails.core.GrailsDomainClass 请使用 object 参数 已弃用
object grails.core.GrailsDomainClass 当前操作的对象,类型为当前操作对象的类型
application grails.core.GrailsApplication 当前的 grails 应用上下文
log Closure<?> 用于打印执行日志的 log 闭包

# 返回结果

//返回允许用户更新该对象,但不允许用户删除该对象 
//Allow user to update this object, but not allow user to delete this object
return [
  result: [
    'update': true,
    'delete': false
  ]
] 
1
2
3
4
5
6
7

# 定时任务启用逻辑

更多信息请参考 定时任务启用逻辑

# 注入变量

# 返回结果

// 表示该 action 或 task 或 widget 是否启用
// Indicates whether this action or task or widget is enabled
[result: true | false]
1
2

# 定时任务核心逻辑

更多信息请参考 定时任务核心逻辑

# 注入变量

变量名称 变量类型 描述
triggerDatetime java.time.LocalDateTime 定时任务的触发时间
task tech.muyan.dynamic.task.DynamicTask 触发定时任务实例
application grails.core.GrailsApplication 当前的 grails 应用上下文
log Closure<?> 用于打印执行日志的 log 闭包

# 返回结果

return [
  //执行结果,类型为文本
  //Execution result, type is text
  execResult: 'OK, Result' 
]
1
2
3
4

# 表单字段组显示逻辑

更多信息请参考 字段组显示逻辑客制化

# 注入变量

变量名称 变量类型 描述
application grails.core.GrailsApplication grails 应用上下文
userContext grails.plugin.springsecurity.userdetails.GrailsUser 当前操作的用户信息
objectType tech.muyan.DomainClass 表单关联的 Domain 对象信息
formType tech.muyan.enums.FormType 表单类型,CREATE 或 UPDATE
objectId java.lang.Long 运行的目标 domain 对象 id
object <? extends DefaultGrailsDomainClass> 运行的目标 domain 对象
group tech.muyan.dynamic.form.DynamicFormGroup 当前待判断的字段组对象

# 返回结果

// 表示该字段组在界面上的显示模式,可编辑, 隐藏或者只读
// Represents the display mode of the field group on the interface, editable, hidden, or read-only
return [result: editable | readonly | hide]
1
2

# Dynamic Action 显示逻辑

更多信息请参考 Dynamic Action

# 注入变量

Dynamic Action 的 enable Logic 和 core Logic 的注入变量差别是, enableLogic 注入了 objectId, 而 coreLogic 不会注入该变量

变量名称 变量类型 描述
userContext grails.plugin.springsecurity.userdetails.GrailsUser 当前操作的用户信息
application grails.core.GrailsApplication 当前的 grails 应用上下文
action tech.muyan.dynamic.action.DynamicAction 运行的 action 定义
objectIds List<java.lang.Long> 目标 domain 对象 id 列表
objects List<? extends GormEntity> 目标 domain 对象列表
objectType tech.muyan.DomainClass 目标 domain 对象的类型信息
parameters Map<String, Object> 用户前台输入的 action 运行参数(仅 core Logic 可用)
ownerInfo tech.muyan.importexport.OwnerInfo 当前显示列表的关联主对象
log Closure<?> 用于打印执行日志的 log 闭包

# 返回结果

// 表示该 action 或 task 或 widget 是否启用
// Indicates whether this action or task or widget is enabled
[result: true | false]
1
2

# Dynamic Action 核心逻辑

# 注入变量

Dynamic Action 的 enable Logic 和 core Logic 的注入变量差别是, enableLogic 注入了 objectId, 而 coreLogic 不会注入该变量

变量名称 变量类型 描述
userContext grails.plugin.springsecurity.userdetails.GrailsUser 当前操作的用户信息
application grails.core.GrailsApplication 当前的 grails 应用上下文
action tech.muyan.dynamic.action.DynamicAction 运行的 action 定义
objectIds List<java.lang.Long> 目标 domain 对象 id 列表
objects List<? extends GormEntity> 目标 domain 对象列表
objectType tech.muyan.DomainClass 目标 domain 对象的类型信息
parameters Map<String, Object> 用户前台输入的 action 运行参数(仅 core Logic 可用)
ownerInfo tech.muyan.importexport.OwnerInfo 当前显示列表的关联主对象
log Closure<?> 用于打印执行日志的 log 闭包

# 返回结果

// execResult 为字符类型
// execResult is of string type
// redirect 为字符类型
// redirect is of string type
[
  execResult: "执行的结果/Execution result",
  redirect: "执行后的跳转页面/Page to redirect to after execution",
  //类型为tech.muyan.storage.StorageFieldValue
  //Type is tech.muyan.storage.StorageFieldValue
  download: "执行后返回前端的文件/File returned to the frontend after execution"
]
1
2
3
4
5
6
7
8
9
10

# Dynamic Action 外部命令替换

# 替换变量

占位符 替换目标
${username} 用户的用户名
${roles} 用户的角色列表,逗号分隔
${object} Domain Object 的 JSON 序列化字符串
${parameterName} 前台传入的用户输入参数

# Dynamic Action 返回结果

// execResult 为字符类型
// execResult is of string type
// redirect 为字符类型
// redirect is of string type
[
  execResult: "执行的结果/Execution result",
  redirect: "执行后的跳转页面/Page to redirect to after execution",
  //类型为tech.muyan.storage.StorageFieldValue
  //Type is tech.muyan.storage.StorageFieldValue
  download: "执行后返回前端的文件/File returned to the frontend after execution"
]
1
2
3
4
5
6
7
8
9
10

# Wizard 处理逻辑

关于向导处理逻辑的更多信息请参考 向导定义

# 注入变量

# 返回结果

return [
  // 状态为 warning 或者 error 时,前台显示的警告或者错误信息
  // Warning or error information displayed on the frontend when the status is warning or error
  message: "string",
  //经过逻辑处理之后的表单数据,可以修改之前所有步骤收集的字段值
  //Form data after logic processing, can modify the field values collected in all previous steps
  formValues: [ 
    //如果设置了某个在下一步骤会显示的字段的值,则该值会作为下一步骤表单显示的默认值
    //If the value of a field that will be displayed in the next step is set, 
    //the value will be used as the default value for the form displayed in the next step
    df_<dynamicFieldDefinition1Name>: "xx",
    df_<dynamicFieldDefinition2Name>: 123
  ],
  // 如果需要在下一步骤显示某个字段的下拉选项,可以在此返回,格式如下
  // If you need to display a drop-down option for a field in the next step, 
  // you can return it here, in the format below
  options: [
    {
      fieldName: "xxx",
      options: [
        {
          label: "xxx1",
          value: "xxx1"
        },
        {
          label: "xxx2",
          value: "xxx2"
        },
      ]
    }
  ],
  // 如果需要在下一步骤中渲染某个瞬态字段,可以在此返回,格式如下
  // 生成 meta 可以调用 DomainMetaService.buildFieldMeta 方法
  // If you need to render a transient field in the next step, you can return it here, in the format below
  // Generating meta can call the DomainMetaService.buildFieldMeta method
  metas: [
    {
      title: "yyy",
      dataIndex: "yyy",
      key: "yyy",
      editable: true,
      display: true,
      updatable: true,
    }
  ]
  //下一步骤的 step 名称,
  //前台会根据此返回值,调整步骤之间的跳转逻辑,可返回此参数用来实现决策树
  //The name of the next step,
  //The frontend will adjust the logic between steps based on this return value, 
  //you can return this parameter to implement decision tree
  nextStepName: 'Step 2' 
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

# Widget 是否显示逻辑

# 注入变量

变量名称 变量类型 描述
userContext grails.plugin.springsecurity.userdetails.GrailsUser 当前操作的用户信息
application grails.core.GrailsApplication 当前的 grails 应用上下文
widget tech.muyan.dynamic.form.DynamicDashboardWidget widget 对象

# 返回结果

// 表示该 action 或 task 或 widget 是否启用
// Indicates whether this action or task or widget is enabled
[result: true | false]
1
2

# Widget 核心逻辑

# 注入变量

变量名称 变量类型 描述
userContext grails.plugin.springsecurity.userdetails.GrailsUser 当前操作的用户信息
application grails.core.GrailsApplication 当前的 grails 应用上下文
widget tech.muyan.dynamic.form.DynamicDashboardWidget widget 对象

# 返回结果

Widget 的核心逻辑返回结果的结构根据每种 widget 类型不同而不同,

# 传入系统集成

更多信息请参考 传入系统集成

# 注入变量

变量名称 变量类型 描述
integration tech.muyan.dynamic.integration.DynamicIntegration 当前执行的集成对象定义
headers Map<String, String> 请求头
parameters java.lang.Object 请求体或请求参数
requestTime java.time.LocalDateTime 请求的时间
requestUrl java.lang.String 不包含 queryString 的请求 URL
userContext grails.plugin.springsecurity.userdetails.GrailsUser 当前操作的用户信息
organization tech.muyan.Organization 执行集成对象的所属组织
application grails.core.GrailsApplication 当前的 grails 应用上下文
log Closure<?> 用于打印执行日志的 log 闭包

# Enable Logic 返回结果

// 表示该 action 或 task 或 widget 是否启用
// Indicates whether this action or task or widget is enabled
[result: true | false]
1
2

# Core Logic 返回结果

集成定义的 core logic 运行后,应返回 Map<String, Object> 类型的结果给系统,系 统会直接将该结果进行 JSON 化,并返回给调用方。

# 传出系统集成

更多信息请参考 传出系统集成

# 注入变量

变量名称 变量类型 描述
integration tech.muyan.dynamic.integration.DynamicIntegration 当前执行的集成对象定义
object <? extends GormEntity> 触发集成的对象实例
oldObject <? extends GormEntity> 修改前的对象(只包含被修改的属性)
newObject <? extends GormEntity> 修改后的对象
objectType tech.muyan.DomainClass 当前操作的对象类型
eventType tech.muyan.enums.OutgoingIntegrationListenEvent 触发集成的 Domain CUD 事件
userContext grails.plugin.springsecurity.userdetails.GrailsUser 当前操作的用户信息
organization tech.muyan.Organization 执行集成对象的所属组织
application grails.core.GrailsApplication 当前的 grails 应用上下文
log Closure<?> 用于打印执行日志的 log 闭包

# Enable Logic 返回结果

// 表示该 action 或 task 或 widget 是否启用
// Indicates whether this action or task or widget is enabled
[result: true | false]
1
2

# Core Logic 返回结果

[
  //是否需要平台调用集成的目标 Http 接口
  //Whether to call the target Http interface of the integrated platform
  requestNeeded? : true | false 
  //如需平台调用集成的目标 Http 接口,使用的请求头列表
  //The list of request headers used if let platform to call the target Http API
  headers? : Map<String, String> 
  //如需平台调用集成的目标 Http 接口,使用的请求体或请求参数及值列表
  //The list of request bodies or request parameters and values used if let platform to call the target Http API
  body? : Map<String, Object> 
]
1
2
3
4
5
6
7
8
9
10

# 动态服务

更多信息请参考 动态服务定制

# 注入变量

变量名称 变量类型 描述
name String 服务唯一名称
logic tech.muyan.dynamic.DynamicLogic 服务的执行逻辑
active Boolean 是否激活

# 动态过滤条件定义

动态过滤的条件定义格式如下所示, 更多信息请参考 动态过滤定义

// 下面的动态过滤条件的说明:
// 1. 状态字段等于 SUCCESS
// 2. type 是 FINDER, UPDATE 中的一个
// Below is the description of the dynamic filter conditions:
// 1. The status field is equal to SUCCESS
// 2. type is one of FINDER, UPDATE
{
  // key 是列名称: status 
  // key is the column name: status 
  "status": {  
    // 过滤的目标列
    // The target column to filter
    "columnKey": "status", 
    // 匹配规则:等于
    // Match rule: equal
    "matchMode": "=",      
    // 匹配的目标值: SUCCESS
    // Matching target value: SUCCESS
    "value": "SUCCESS",   
  },
  "type": { // key 是列名称: type
    // 过滤的目标列, 与上一行的 key 相同
    // The target column to filter, same as the key in the previous line
    "columnKey": "type",           
    // 过滤的匹配规则:isOneOf (是其中某一个)
    // Filter matching rule: isOneOf (is one of them)
    // 过滤的目标值: [FINDER, UPDATE]
    // Matching target value: [FINDER, UPDATE]
    "value": ["FINDER", "UPDATE"]  
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 动态匹配条件列表

如下列出了可在动态过滤中使用的,运行时动态渲染的匹配条件列表, 更多信息请参考 动态匹配条件

# 获取动态配置

更多详细信息请参考 获取动态配置

# 前端获取配置

更多信息请参考 前台获取配置 Api

import { useConfig } from "@utils/hooks";
// 举例如下: 获取系统配置中,key 为 register.self_register 的配置值
// 备注: 对于系统内置配置,前台会自动转换配置值的类型,如上述代码调用
// `useConfig` 返回的 `registerEnable` 变量,其类型为 `boolean`。
// Example: Get the configuration value of the key register.self_register in the system configuration
// Note: For system built-in configurations, the frontend will automatically convert the type of the configuration value, 
// as shown in the above code call
// The type of the registerEnable variable returned by `useConfig` is `boolean`.
const { value: registerEnable } = useConfig('register.self_register');
1
2
3
4
5
6
7
8

# 后台获取配置

更多信息请参考 后台获取配置 Api

  1. 在后台 Service 或 Controller 中,可直接注入 Bean DynamicConfigService, 或者调用 ConfigHelper.getDynamicConfigService(grailsApplication) 获取该 Bean。

  2. 在客制化代码中,可以通过如下方式获取系统配置中的值

 import tech.muyan.ConfigHelper
 String frontendUrl = ConfigHelper.getDynamicConfigService(grailsApplication)
                                  .getConfig("mail.frontend_url", String.class, "https://muyan.muyan.cloud")   
1
2
3

# 全局配置或数据共享

详细信息请参考 在 Dynamic Logic 执行间共享全局配置、连接、或进行数据缓存

当前系统提供了 tech.muyan.helper.RegistryHelper 类来进行全局共享数据的管理,可以通过

  • RegistryHelper.memoryGet(key) 来获取缓存数据,
  • RegistryHelper.memoryPut(key, value) 来设置缓存数据,并返回当前已经保存的数据,
  • RegistryHelper.memoryRemove(key) 来移除缓存数据。
注意 上述方法共享的全局数据保存在内存中,故只支持单服务器实例内的数据共享,不支持在多服务器实例之间进行数据共享。

# 可用 extInfo 列表

提示

详述配置中的 xxx?: 中的 ? 表示该配置是可选的,如果不配置则使用默认值,在 extInfo 字段的内容中,不应包含 ? 字符

# DomainClass 定义中

{
  // 用户快捷搜索时,使用 name 和 label 两个字段进行搜索匹配
  // When users perform quick search, use the name and label fields for search matching
  "inlineSearchColumns": ['name', 'label'],
  // 界面上显示 Object 控件时,显示其 label 字段的值作为标识
  // When displaying Object controls on the interface, show the value of its label field as identifier
  "labelField": 'label',
  // 导入 CSV 数据时,当前 Domain 会在 DynamicLogic 和 DynamicFieldDefinition 之后加载
  // When importing CSV data, the current Domain will be loaded after DynamicLogic and DynamicFieldDefinition
  "loadAfter": ['DynamicLogic', 'DynamicFieldDefinition'],
}
1
2
3
4
5
6
7
8
9
10

更多信息请参考 DomainClass 可用的 extInfo 列表

# DomainClassField 属性定义中

{
  // 适用于 Decimal 类型的字段,设置小数位数为 2
  // Applicable to Decimal type fields, set the number of decimal places to 2
  "scale": 2,
  // 适用于 Decimal 类型的字段,设置精度为 10
  // Applicable to Decimal type fields, set the precision to 10
  "precision": 10
  // 指定 ENUM 类型的字段的 Java 枚举类型定义
  // Specify the Java enum type definition of the ENUM type field
  // 该枚举类的定义可以放在动态插件中
  // The enum class definition can be in a dynamic plugin
  "enumClass": "tech.muyan.mes.enums.WorkTaskStatusEnum"
}
1
2
3
4
5
6
7
8
9
10
11
12

更多信息请参考 领域模型字段属性定义中的 extInfo

# Dynamic Action 定义中

更多信息请参考 DynamicAction 可用的 extInfo 列表

{
  /** 前台是否显示该 Action 的 label, 默认为 true, 如果只希望显示 Action 图标,可设置 displayLabel 为 false */
  /** Whether to display the label of this Action in the frontend, default is true. If you only want to display the Action icon, you can set displayLabel to false */
  "displayLabel"?: true | false,
  /** 是否在执行该 Action 后,刷新当前页面, 默认为 true, 如果 action 执行不更新显示数据,可以无需刷新页面 */
  /** Whether to refresh the current page after executing this Action, default is true. If the action execution does not update display data, you can choose not to refresh the page */
  "refreshPage"?: true | false
}
1
2
3
4
5
6
7

# Dynamic Form 定义中

# 通用属性

更多详细信息请参考 表单的 extInfo 支持

{
    /** form 默认的隐含过滤条件, 该过滤条件不会在界面上显示, 用户不可见 */
    /** Default implicit filter conditions for the form, these conditions are not displayed on the interface and are invisible to users */
    "conditions": {
        "fieldName": {
            /** 匹配的值 */
            /** Matching value */
            "value": xxxx,
            /** 匹配的字段名称, 支持 dot(.) 方式引用关联字段的某字段 */
            /** Matching field name, supports referencing associated fields using dot (.) notation */
            /** 如 organization.name 引用 organization 字段的 name */
            /** For example, organization.name refers to the name field of the organization */
            "columnKey": "xxx",
            /** 匹配规则 */
            /** Matching rule */
            "matchMode": matchMode
        }
    },
    /** 列表类型表单的表头中显示的 domain 标题,如果不想显示 domainTitle, 将其设置为空字符串即可 */
    /** Domain title displayed in the header of list-type forms. If you don't want to display domainTitle, set it to an empty string */
    "domainTitle"?: string;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# List form 属性

{
    /** 是否支持 realtime 实时刷新数据模式,当前为 beta 功能,只支持在列表页面启用 */
    /** Whether to support realtime data refresh mode, currently a beta feature, only supported on list pages */
    /** 默认的显示模式,realtime: 默认实时模式,manual: 手动刷新模式,不支持实时模式(默认模式) */
    /** Default display mode, realtime: default real-time mode, manual: manual refresh mode, does not support real-time mode (default mode) */
    /** auto 默认手动刷新模式,可切换为实时模式,disable: 禁用,等同不设置 */
    /** auto: default manual refresh mode, can switch to real-time mode, disable: disabled, equivalent to not setting */
    "dataRefreshMode"?: "auto" | "realtime" | "manual" | "disable";

    /** 默认显示模式 */
    /** Default display mode */
    "defaultTableMode"?: "table-list" | "card-list";

    /** card Form 每行的显示条数 */
    /** Number of records displayed per row in card form */
    "defaultRecordsPerRow"?: number;

    /** 指定在该表单显示页面上方点击创建按钮使用的创建表单名称 */
    /** Specify the name of the creation form used when clicking the create button at the top of this form display page */
    "createFormName"?: string;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# MasterDetail From 属性

{
  /** 对于 master detail 类型的 form, 其detail 部分的组件 form 类型 */
  /** For master-detail type forms, the form type of the detail component */
  /** 当前经测试可正常工作的可选值为 INLINE_DISPLAY | FULL_TEXT_SEARCH_LIST | Update */
  /** Currently tested and working optional values are INLINE_DISPLAY | FULL_TEXT_SEARCH_LIST | Update */
  "detailFormType": formType;
  /** 对于 master detail 类型的 form, 其 detail 部分的组件对应的字段的名称*/
  /** For master-detail type forms, the name of the field corresponding to the detail component */
  "detailField"?: string;
  /** 对于 master detail 类型的 form, 其 detail 部分的组件是否显示为可编辑组件 */
  /** For master-detail type forms, whether the detail component is displayed as an editable component */
  "detailUpdatable"?: boolean;
}
1
2
3
4
5
6
7
8
9
10
11
12

# Dashboard From 属性

{
  /** dashboard的自动刷新间隔 */
  /** Auto-refresh interval for the dashboard */
  "refreshInterval"?: number;
}
1
2
3
4

# Gantt From 属性

{
  /** 甘特图相关配置 */
  /** Gantt chart related configuration */
  "gantt"?: {
    /** 默认显示的甘特图中的开始时间, ISO8601 和 GB/T 7408-2005格式,例如 2023-05-22T00:00:00+08:00 */
    /** Default start time displayed in the Gantt chart, ISO8601 and GB/T 7408-2005 format, e.g., 2023-05-22T00:00:00+08:00 */
    "viewDateStart"?: string;
    /** 默认显示的甘特图的时间长度, ISO8601 和 GB/T 7408-2005 格式,例如 P5D */
    /** Default duration displayed in the Gantt chart, ISO8601 and GB/T 7408-2005 format, e.g., P5D */
    "viewDuration"?: string;
    /** 左侧行列表展示字段,默认显示 gantt 表单关联领域模型的所有字段 */
    /** Fields displayed in the left row list, by default shows all fields of the domain model associated with the Gantt form */
    "rowListDisplayColumns"?: [{
      // 字段名
      // Field name
      "key": string,
      // 显示名
      // Display name
      "title": string,
    }];
    /** 任务展示字段,默认显示被 hover 的 task 领域模型的所有字段 */
    /** Task display fields, by default shows all fields of the hovered task domain model */
    "tooltipDisplayColumns"?: [{
      // 字段名
      // Field name
      "key": string,
      // 显示名
      // Display name
      "title": string,
    }];
    /** 任务组字段 */
    /** Task group field */
    "taskGroupColumnKey"?: string;
    /** 任务是否可以更新, Since version 0.29 */
    /** Whether tasks can be updated, Since version 0.29 */
    "taskUpdatable"?: boolean;
  };
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

# Dynamic Form Field 定义中

Dynamic Form Field 可用的 extInfo 与字段的类型关联, 分类型详述如下:

更新详细信息请参考 表单字段的 extInfo 支持

# 通用属性

所有类型的字段,其 extInfo 中均可使用的扩展属性如下

{
  // 设定本字段是否显示右边的 detailPanel,
  // Determines whether to display the detailPanel on the right for this field
  // 无该属性时,值为 false, 本属性为 true 时,
  // When this property is absent, the value is false. When this property is true,
  // 需要对应字段控件实现了右边详情面板的显示控件
  // the corresponding field control needs to implement the display control for the right detail panel
  "hasDetailPanel"?: true | false;

  // 设置某字段支持按需显示,此处的设置值是支持按需显示的字段在全部内容未显示前,显示的概要信息
  // Sets a field to support on-demand display. The value set here is the summary information displayed for fields that support on-demand display before all content is shown
  // 对于设置了该属性的表单字段,如果从后端返回的数据中,此处所设置的字段的值为 null, 则在前端针对该对象,不启用按需显示
  // For form fields with this property set, if the value of the field set here is null in the data returned from the backend, on-demand display is not enabled for this object in the frontend
  // 举例如下:
  // Example:
  // 如对于文章对象,其内容 (content) 字段可能非常长,为了前端的用户体验考虑,考虑针对该字段启用按需显示,
  // For an article object, its content field might be very long. For better frontend user experience, consider enabling on-demand display for this field.
  // 此时可以在 content 表单字段的 extInfo 中设置如下:
  // In this case, you can set the following in the extInfo of the content form field:
  // "summayField": "summaryContent"
  // 表示使用名为 summaryContent 的字段作为 content 字段显示全部内容前的摘要字段,此时:
  // This indicates using a field named summaryContent as the summary field for the content field before displaying all content. In this case:
  // 1. 如果后端返回的数据中,summaryContent 字段的值不为 null, 则在前端默认不显示全部 content 字段的内容,
  //    If the value of the summaryContent field in the data returned from the backend is not null, the frontend by default does not display the full content of the content field,
  //    只显示 summaryContent 字段,用户可点击界面控件,以查看 content 字段的内容
  //    only displays the summaryContent field. Users can click on the interface control to view the content of the content field
  // 2. 如果后端返回的数据中,summaryContent 字段的值为 null, 则在前端不启用按需显示,
  //    If the value of the summaryContent field in the data returned from the backend is null, on-demand display is not enabled in the frontend,
  //    直接显示 content 字段的内容
  //    and the content of the content field is displayed directly
  "summayField"?: string;

  // meta 用于覆盖系统自动生成的表单字段的元数据,或者补充某一些属性,如 title, dataIndex, editable, updatable, elementType 等
  // meta is used to override the metadata of automatically generated form fields or to supplement certain properties such as title, dataIndex, editable, updatable, elementType, etc.
  // 在运行时,系统会将 meta 中的属性覆盖或者补充到系统自动生成的表单字段的元数据中
  // At runtime, the system will override or supplement the metadata of automatically generated form fields with the properties in meta
  "meta"?: {
      // 字段名
      // Field name
      "key": string;
      // 字段显示名
      // Field display name
      "title": string;
      // 字段在表单中的名字,应该和 key 一致
      // The name of the field in the form, should be the same as key
      "dataIndex": string;
      // 可编辑
      // Editable
      "editable"?: boolean;
      // 可更新
      // Updatable
      "updatable"?: boolean;
      ...
   }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

# file 字段

type 为 file 或 tech_muyan_storage_StorageFieldValue 时,可使用如下的 json 来设定控件的相关属性

{
  /** 接受的附件类型, 可参考 https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept  */
  /** Accepted attachment types, refer to https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept */
  "accept"?: string;
  /** 单个的最大文件大小, 单位 MB */
  /** Maximum size for a single file, in MB */
  "maxSizeMB"?: number;
  /** multiple 为 true 时, 单个字段中, 可上传的最大文件数量, 如果没有设置,默认为 20 */
  /** When multiple is true, the maximum number of files that can be uploaded in a single field. If not set, the default is 20 */
  /** multiple 根据关联关系的类型或者动态字段定义 (Dynamic Field Instance) 中的 multiple 属性确定 */
  /** multiple is determined by the type of association or the multiple property in the Dynamic Field Instance */
  "maxCount"?: number;
  /** 总的文件大小, 单位 MB */
  /** Total file size, in MB */
  "totalMaxSizeMB"?: number;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# code 字段

type 为 code 时,可以通过如下的 extInfo 设定高亮语法

{
  /** 代码编辑器控件显示时的高亮语法 */
  /** Syntax highlighting when displaying the code editor control */
  "codeLanguage"?: "css" | "javascript" | "markdown" | "groovy" .....,
  /** 是否在图标后,同时显示代码开始的 20 个字符 */
  /** Whether to display the first 20 characters of the code after the icon */
  "showBrief"?: boolean;
}
1
2
3
4
5
6
7

# object 字段

对于对象选择控件,可以使用如下的 extInfo 定义来设定其选择控件中的默认选项

{
    /** 默认显示的 options 的过滤条件
     * 系统打开页面时, 系统会使用该查询条件查询对象列表并作为对象选择控件的默认选项
     */
    /** Default filter conditions for displayed options
     * When the system opens the page, it will use this query condition to query the object list and use it as the default option for the object selection control
     */
    "defaultOptionsCondition"?: {
        "fieldName" : {
            /** 匹配的值 */
            /** Matching value */
            "value": xxxx,
            /** 匹配的字段名称, 支持 dot(.) 方式引用关联字段的某字段
             * 如 organization.name 引用 organization 字段的 name
             */
            /** Matching field name, supports referencing associated fields using dot (.) notation
             * For example, organization.name refers to the name field of the organization
             */
            "columnKey": "xxx",
            /** 匹配规则 */
            /** Matching rule */
            "matchMode": matchMode
        }
    },
    /** 是否禁用对象搜索功能, Since version 0.29 */
    /** Whether to disable object search functionality, Since version 0.29 */
    "disableObjectSearch"?: boolean
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 一对多对象字段

type 为 array 时(一对多的对象字段),可以使用如下的 extInfo 定义来设定其关联 列表的显示

{
  /** 在弹出抽屉中显示的关联对象列表中,显示时所使用的 form 名称 */
  /** The name of the form used to display the list of associated objects in the pop-up drawer */
  "displayForm"?: "Form used to display the list of objects"
}
1
2
3
4

# 子表字段

{
  /** 子表中的显示字段定义的表单名 */
  /** Name of the form defining the display fields in the sub-table */
  /**  Name of the form defining the display fields in the sub-table */
  "displayForm"?: "Form used to display the list of objects",
  /** 子表控件的相关属性 */
  /**  Related properties of the sub-table control */
  "subTable"?: {
    /** 子表中是否可创建、编辑、删除、搜索现有行 */
    /**  Whether rows in the sub-table can be created, edited, deleted, or searched */
    "updatable"?: true | false,
    "creatable"?: true | false,
    "deletable"?: true | false,
    "searchModal"?: true | false,
    /** 子表中的排序字段,默认为 displaySequence, 可以设置为其他字段 */
    /** Sorting field in the sub-table, default is displaySequence, can be set to other fields */
    "sortBy"?: "排序字段的 key" // Key of the sorting field
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Last Updated: 2024/10/26 09:20:23