# 基础表单定制
# 目标读者
本文档的目标读者为:本系统的开发和实施人员
# 概述
系统的菜单、表单、表单字段分组、表单字段均保存在数据库中,可以在界面上维护,也可以写成 CSV 种子数据随系统导入。本文按「菜单 → 表单 → 字段分组 → 字段」的顺序说明各自的配置方法,最后给出一套完整的 CSV 示例。
# 菜单
# 定义
系统界面左侧的菜单由 DynamicMenu 对象渲染,在界面上通过 开发配置 > 界面显示 > 菜单 维护。页面左侧是菜单树,点击某个节点后,右侧显示该菜单的编辑表单,可以保存、删除,或在其下创建新菜单:
菜单的属性如下:
| 属性 | 说明 |
|---|---|
| 上级菜单(parent) | 为空表示顶级菜单 |
| 名称(name) | 必填,租户内唯一,创建后不能修改。CSV 导入时用它定位菜单 |
| 类型(type) | 菜单类型,见下文 |
| 显示名称(label) | 必填,菜单上显示的文字 |
| 图标(icon) | antd 图标名称,见下文 |
| 关联表单(form) | 类型为 FORM 时,点击菜单要打开的表单 |
| 链接地址(link) | 类型为 INTERNAL_LINK / EXTERNAL_LINK 时的地址 |
| 显示顺序(displaySequence) | 越小越靠前 |
| 访问要求(accessRequirement) | 可见性要求,取值为 USER、DEVELOPER、ADMIN 等访问要求的名称。界面上没有这个字段,只能通过 CSV 设置 |
菜单显示名称的翻译
侧边栏显示菜单时,会以 label 为 key 到 menu 翻译命名空间中查找翻译(在 开发配置 > 国际化 > 界面翻译 中维护),所以上面菜单树里看到的是 label 原文,侧边栏里看到的是翻译后的文字。
# 与表单的关联
菜单和表单的关联关系保存在菜单上:编辑菜单,把类型设为 FORM,在「关联表单」中选择要打开的表单即可。表单上没有「所属菜单」字段。
# 可见性
菜单是否显示,由菜单和表单各自的 accessRequirement 共同决定:
FORM类型菜单:如果菜单设置了 accessRequirement,先检查当前用户是否满足;再检查关联表单的 accessRequirement(表单未设置时所有人都满足)。两者都通过才显示。因此表单菜单一般不需要单独设置 accessRequirement,由表单决定即可。- 菜单组、内部链接、外部链接:必须设置 accessRequirement。没有设置时,任何用户(包括管理员)都看不到这个菜单。
- 菜单组只有在至少有一个可见的子菜单时才会显示。
注意
菜单的编辑界面上没有「访问要求」字段。在界面上新建的菜单组或链接菜单,因为没有 accessRequirement,保存后不会出现在任何人的侧边栏中。请通过 CSV 导入菜单并填写 accessRequirement.name 列(见 菜单定义的 CSV 文件)。
# 类型
当前系统支持的菜单类型包括:
MENU_GROUP菜单组:包含子菜单,可以通过嵌套菜单组实现多级菜单FORM表单:点击后打开「关联表单」,关于表单的定义见 表单 章节INTERNAL_LINK内部链接、EXTERNAL_LINK外部链接:菜单地址取link属性。内部链接的 link 为空时,该菜单不会显示
# 图标
菜单的图标使用 antd 的图标,填写图标组件名称即可(如 UserOutlined),无需包括 <> 部分。图标列表请查看 Ant Design 图标 (opens new window)
# 表单
# 定义
自定义表单保存在 DynamicForm 对象中,在界面上通过 开发配置 > 表单 > 表单 维护。下图是新建一个只显示已锁定用户的列表表单:
表单的属性如下:
| 属性 | 说明 |
|---|---|
| 类型(type) | 必填,见 表单类型 |
| 名称(name) | 必填,租户内唯一,创建后不能修改。菜单、字段、字段组都通过它引用表单 |
| 显示名称(label) | 表单在页面上显示的标题 |
| 描述(description) | 说明 |
| 关联对象类型(objectType) | 表单所展示的领域对象 |
| 扩展信息(extInfo) | JSON 格式的扩展属性,见 表单的 extInfo 支持 |
| Form Hook(formHook) | 表单级客制化动态逻辑,用于字段默认值、联动、显隐、只读、必填等,详见 表单客制化(Form Hook) |
| Form Hook 触发字段(formHookTriggerFields) | 逗号分隔的字段名,这些字段的值在界面上变化时,重新执行 Form Hook |
| Data Hook(dataHook) | 数据级客制化动态逻辑,用于对列表、详情返回的数据做变换 |
| 访问要求(accessRequirement) | 可以使用该表单的用户范围,未设置时所有用户都可以使用 |
提示
界面上的创建表单只包含「类型、名称、显示名称、描述、关联对象类型、扩展信息」。Form Hook、Form Hook 触发字段、Data Hook、访问要求需要通过 CSV 设置。在表单列表中点击「修改」,编辑弹窗中还会以子表的形式列出该表单的字段和字段组。
创建、编辑弹窗的标题按以下顺序取值(从菜单打开的页面,标题显示菜单名称):
- 表单的显示名称(label)
- extInfo 中的
domainTitle - 关联对象名称的翻译(
domainTitle翻译命名空间)
# 表单类型
表单类型保存在 DynamicFormType 对象中,系统预置了 24 个类型。当前前端只为其中一部分提供了渲染器,把没有渲染器的类型挂到菜单上,页面只会显示 Unknown form 类型名。
| 类型 | 用途 | 当前前端 |
|---|---|---|
LIST | 对象列表页面 | 支持 |
CREATE | 对象创建表单 | 支持 |
UPDATE | 对象编辑表单 | 支持 |
FINDER | 列表上方的搜索区;也可以单独挂到菜单上 | 支持 |
DOMAIN | 领域对象表单 | 支持 |
DEFAULT | 通用表单,按字段定义渲染一组输入项 | 支持 |
MASTER_DETAIL_LIST | 左树右表单的头行结构,见 头行结构表单定义 | 支持 |
TREE_LIST | 树状列表 | 支持 |
DASHBOARD | 仪表盘,详见 仪表盘 | 支持 |
AMIS | 使用 AMIS Schema 描述的页面,见 AMIS 表单 | 支持 |
ACTION | 对象动作的参数表单 | 支持 |
IFRAME | 内嵌页面,地址取 extInfo 的 url | 支持 |
SUB_TABLE | 子表使用的表单,通过子表字段的 displayForm 按名称引用,按列表方式渲染 | 仅作子表 |
INLINE_DISPLAY | 同上,旧版本用于内联详情 | 仅作子表 |
INLINE_EDITABLE_DISPLAY | 同上,旧版本用于内联可编辑详情 | 仅作子表 |
DELETE | 删除确认表单 | 未实现 |
INLINE_FULL_TEXT_SEARCH_LIST | 内联全文检索结果 | 未实现 |
FULL_TEXT_SEARCH_LIST | 全文检索结果 | 未实现 |
RELATED_DETAIL_LIST | 关联详情列表 | 未实现 |
CARD_LIST | 卡片列表 | 未实现 |
DYNAMIC_FRAME | 动态框架 | 未实现 |
WIZARD | 向导,1.0 起已移除(多步骤数据收集请使用 Form Hook) | 已移除 |
GANTT | 甘特图,1.0 起已移除 | 已移除 |
GANTT_TOOLTIP | 甘特图详情卡片,1.0 起已移除 | 已移除 |
提示
「仅作子表」的三种类型没有独立的渲染器:子表字段按名称找到表单后,一律用列表方式渲染,和表单类型无关。前端插件可以通过 FrontendPluginManifest.forms 为任意表单类型注册自定义渲染器。
# AMIS 表单
平台内置 AMIS (opens new window) 低代码前端框架作为表单渲染器之一。类型为 AMIS 的表单,其 AMIS Schema 保存在表单 extInfo 的 amis 属性中。
# 能力
- 可视化编辑:打开 AMIS 表单所在的页面后,如果当前用户对该表单有修改权限,页面上会出现浮动的「编辑」按钮。点击后进入 AMIS 可视化编辑器,保存后 Schema 写回表单 extInfo 的
amis属性 - 页面数据:打开页面时调用
GET /form/data/{formId},执行表单的 Data Hook,返回的对象作为 AMIS 页面的数据,Schema 中可以用${字段名}引用。未配置 Data Hook 时页面数据为空 - 统一鉴权:AMIS 组件发出的数据请求走平台统一请求通道,自动携带登录凭证
# 启用方式
- 在
开发配置 > 表单 > 表单中创建表单,类型选择AMIS - 把表单挂到一个
FORM类型的菜单上 - 从菜单打开页面,点击浮动的「编辑」按钮设计页面并保存
# 示例
下面的 Schema 显示 Data Hook 返回的 customerCount、vipCount 两个值:
{
"type": "page",
"title": "客户概况",
"body": [
{ "type": "tpl", "tpl": "客户总数:${customerCount},其中 VIP 客户 ${vipCount} 个" }
]
}
2
3
4
5
6
7
# 表单字段分组
表单字段在对象的创建、编辑界面上,可以按可折叠的字段分组展示。
# 定义
字段分组保存在 DynamicFormGroup 对象中,在界面上通过 开发配置 > 表单 > 表单字段组 查看(下图隐藏了帮助信息、显示顺序等列,以便看全图标列):
注意
当前版本在「表单字段组」页面点击创建、修改、详情,弹窗会一直停留在加载状态,无法编辑。可以在 开发配置 > 表单 > 表单 中「修改」某个表单,在编辑弹窗的「字段组」子表中查看该表单已有的分组;新增、修改分组请通过 CSV 导入。
包含字段组的表单在界面上的显示效果如下(开发定制 > 定时任务 > 创建,其中「Logics」分组已折叠):
提示
当前前端直接显示字段组的显示名称(label),不做翻译,所以上图中系统预置的分组名称是英文。自己定义的字段组,label 直接写中文即可。上图中的字段标签「Start date」同样是当前版本未翻译的界面文字,与字段组无关。
字段组的属性如下:
| 属性 | 说明 |
|---|---|
| 名称(name) | 必填,同一表单内唯一,创建后不能修改 |
| 显示名称(label) | 必填,分组标题 |
| 显示顺序(displaySequence) | 越小越靠前 |
| 帮助信息(helpText) | 分组的帮助信息 |
| 图标(icon) | antd 图标名称,参见 图标 |
| 所属表单(form) | 必填,创建后不能修改 |
字段通过自己的「所属字段组」属性归入某个分组。
注意
当前版本不能动态隐藏整个字段组:接口返回的字段组不带显示状态,表单客制化(Form Hook) 只能逐个控制字段的显示。即使用 Form Hook 把组内字段全部隐藏,分组标题仍会显示。
# 命名建议
字段组名称只要求在同一表单内唯一。为了便于在 CSV 中识别,建议按 <表单类型>_<对象名>_<分组名> 命名,例如创建客户表单的基本信息分组命名为 c_customers_basic,编辑表单的为 u_customers_basic。
# 表单字段
# 定义
表单字段保存在 DynamicFormField 对象中,在界面上通过 开发配置 > 表单 > 表单字段 维护(下图省略了扩展信息编辑框下方的空白部分):
字段的属性如下:
| 属性 | 说明 |
|---|---|
| 所属表单(form) | 必填 |
| 所属字段组(group) | 字段所在的分组,可为空 |
| 字段类型(fieldType) | 必填,STATIC_FIELD 静态字段或 TRANSIENT_FIELD 瞬态字段 |
| 字段名称(fieldName) | 必填。静态字段必须是关联对象上已有的字段名 |
| 显示名称(label) | 必填 |
| 帮助信息(helpText) | 显示在字段旁的帮助信息 |
| Decides(decides) | 逗号分隔的字段名,旧版本用于「本字段变化后刷新其他字段」。当前版本不生效(前端请求的 /column/refresh/{domainName} 接口不存在),字段联动请使用表单的 Form Hook 触发字段 |
| 字段显示类型(displayType) | 控件类型,自由文本,取值见 显示控件。留空时按对象字段的类型自动选择 |
| 是否可为空(nullable) | 表单中该字段是否可以为空 |
| 扩展信息(extInfo) | JSON 格式的扩展属性,见 表单字段的 extInfo 支持 |
| 显示顺序(displaySequence) | 必填,越小越靠前 |
| 可编辑(editable) | 只对瞬态字段生效,界面上没有这个字段,只能通过 CSV 设置。静态字段如需只读,在 extInfo 的 meta 中设置 editable(创建表单)或 updatable(编辑表单)为 false |
提示
截图中「字段类型」下拉框里的 Static field、字段标签 Decides 当前界面未翻译。
针对不同的表单类型,字段定义控制的内容如下:
- 列表页面:显示哪些列、列的顺序、显示控件
- 查询(FINDER)表单:显示哪些查询条件、顺序、显示控件
- 创建、编辑表单:显示哪些字段、顺序、是否必填、帮助信息、显示控件、所属分组
# 显示控件
displayType 是自由文本,后端只做一步转换:如果填写的是旧版本的控件名称(如 Sub table、Single file),会转换成对应的 key(subTable、file),其余值原样传给前端。前端找不到对应控件时,字段位置会显示 Unsupported displayType: xxx。
当前前端支持的控件 key 如下:
| key | 控件 |
|---|---|
id | 标识符 |
string | 单行文本 |
text | 多行文本 |
password | 密码 |
integer、int、long | 整数 |
decimal | 小数 |
percentage | 百分比 |
currency | 货币 |
date | 日期 |
dateRange | 日期范围 |
datetime | 日期时间 |
zonedDatetime | 带时区的日期时间 |
boolean | 开关 |
enum | 枚举下拉 |
httpMethod | HTTP 方法(枚举下拉) |
valueSelect | 值选择 |
link | 链接,可用 extInfo 的 link 设置显示文字和打开方式 |
progress | 进度条 |
icon | 图标 |
treeSelect | 树选择 |
roles | 角色 |
code | 代码编辑器 |
json | JSON 编辑器 |
markdown | Markdown 编辑器 |
stacktrace | 堆栈信息 |
functionEditor | 函数编辑器 |
file | 单个文件 |
fileList | 多个文件 |
image | 图片 |
video | 视频 |
object | 单个对象选择 |
objects | 多个对象选择 |
genericObject、genericObjects | 任意类型对象的只读显示 |
array | 一对多关联对象列表 |
subTable | 子表,见 高级字段控件 |
relativeSubTable | 按关联路径显示的子表,见 高级字段控件 |
authentication | 用户信息(如创建人)的只读显示 |
popOverSteps | 步骤状态 |
lineChart | 折线图 |
tableChart | 表格图 |
注意
旧版本文档中的 Array with details、Array Inline、Multiple select、Object multiple select、Tags、Tag list、Static field、Updated ids、Series、Cron expression、Object ids、Document、Grouped grand child、Url、Entity Attributes、Comments 在当前前端没有对应控件,填写后会显示 Unsupported displayType。前端插件可以通过 FrontendPluginManifest.fields 注册更多控件。
# 瞬态字段
瞬态字段是对象上不存在、也不会保存到数据库的字段,把字段类型设为 TRANSIENT_FIELD 即可。瞬态字段:
- 必须填写字段显示类型(displayType),否则保存时报错
- 字段的值由用户在界面上输入,或者由 Form Hook、Data Hook 提供,平台不做计算
- 可以在 extInfo 中用
domainName指定对象类型(配合object、objects控件选择该类型的对象),或用enumClass指定枚举类(配合enum控件生成下拉选项) - 可以用「可编辑」(editable)属性控制是否只读
瞬态字段最常用于 ACTION 类型的动作参数表单,例如系统预置的批量添加用户到用户组动作,其参数表单中的 user 字段就是 displayType 为 objects、extInfo 为 {"domainName": "User"} 的瞬态字段。
# 推荐做法
推荐在开发过程中,把菜单、表单、字段分组和字段的定义保存在 CSV 文件中,作为种子数据 (Seed Data) 随系统导入,这样系统启动时会自动读取并更新这些定义。关于种子数据的导入请参考 数据导入。
# 真实系统中的使用示例
下面以 快速上手教程 中的 Customers(客户)对象为例,给出一套菜单、表单、字段分组和字段的 CSV。表头与系统预置种子数据一致,列名后带 (*) 的列用于查找已有记录并更新,以 ; 开头的行是注释。
# 菜单定义的 CSV 文件
parent.name,label,icon,link,type,displaySequence,name(*),form.name,accessRequirement.name
; 一级菜单组:菜单组必须设置 accessRequirement,否则所有人都看不到
NULL,客户管理,TeamOutlined,,MENU_GROUP,10,CRM,,USER
; 表单菜单:不设置 accessRequirement,可见性由关联表单决定
CRM,客户,UserOutlined,,FORM,1,Customers,List of customers,
CRM,VIP 客户,CrownOutlined,,FORM,2,VIP customers,List of VIP customers,
2
3
4
5
6
7
8
name(*)是菜单的唯一标识,parent.name引用上级菜单的 name,NULL表示顶级菜单form.name引用表单的名称,菜单与表单的关联在这里建立accessRequirement.name取值为访问要求的名称,系统预置USER、DEVELOPER、ADMIN
提示
displaySequence 更小的菜单或字段会先显示
# 表单定义的 CSV 文件
name(*),label,description,objectType.shortName(*),type.name(*),formHook.name,formHookTriggerFields,dataHook.name,extInfo,accessRequirement.name
List of customers,客户,,Customers,LIST,,,,,USER
List of VIP customers,VIP 客户,只显示 VIP 分组的客户,Customers,LIST,,,,"{""listForm"": {""searchConditions"": {""group"": {""columnKey"": ""group"", ""matchMode"": ""="", ""value"": ""VIP""}}}}",USER
Create customer,新建客户,,Customers,CREATE,customer_form_hook,group,,,USER
Update customer,编辑客户,,Customers,UPDATE,customer_form_hook,group,,,USER
Find customers,,,Customers,FINDER,,,,,USER
2
3
4
5
6
7
type.name取值见 表单类型List of VIP customers在 extInfo 中设置了默认过滤条件,只列出分组为 VIP 的客户- 创建、编辑表单配置了 Form Hook(
customer_form_hook,需要事先在动态逻辑中创建)和触发字段group:客户分组变化时重新执行 Form Hook accessRequirement.name为USER,表示所有登录用户都可以使用这些表单
# 表单字段组定义的 CSV 文件
displaySequence,name(*),label,icon,form.name(*),helpText
1,c_customers_basic,基本信息,UserOutlined,Create customer,客户的基本资料
2,c_customers_extra,补充信息,ProfileOutlined,Create customer,
1,u_customers_basic,基本信息,UserOutlined,Update customer,客户的基本资料
2,u_customers_extra,补充信息,ProfileOutlined,Update customer,
2
3
4
5
分别为创建表单和编辑表单定义了「基本信息」「补充信息」两个分组。
# 表单字段定义的 CSV 文件
form.name(*),fieldName(*),label,displaySequence,helpText,fieldType,nullable,group.name,extInfo,displayType,editable
; 列表
List of customers,name,客户名称,1,,STATIC_FIELD,,,,,
List of customers,companyName,公司,2,,STATIC_FIELD,,,,,
List of customers,group,客户分组,3,,STATIC_FIELD,,,,,
List of VIP customers,name,客户名称,1,,STATIC_FIELD,,,,,
List of VIP customers,companyName,公司,2,,STATIC_FIELD,,,,,
; 创建
Create customer,name,客户名称,1,,STATIC_FIELD,,c_customers_basic,,,
Create customer,contactInfo,联系方式,2,手机号或邮箱,STATIC_FIELD,,c_customers_basic,,,
Create customer,group,客户分组,3,,STATIC_FIELD,,c_customers_basic,,,
Create customer,companyName,公司,4,,STATIC_FIELD,Y,c_customers_extra,,,
Create customer,position,职位,5,,STATIC_FIELD,Y,c_customers_extra,,,
Create customer,birthday,生日,6,,STATIC_FIELD,Y,c_customers_extra,,,
; 编辑:客户名称只读
Update customer,name,客户名称,1,,STATIC_FIELD,,u_customers_basic,"{""meta"": {""updatable"": false}}",,
Update customer,contactInfo,联系方式,2,手机号或邮箱,STATIC_FIELD,,u_customers_basic,,,
Update customer,group,客户分组,3,,STATIC_FIELD,,u_customers_basic,,,
Update customer,companyName,公司,4,,STATIC_FIELD,Y,u_customers_extra,,,
Update customer,position,职位,5,,STATIC_FIELD,Y,u_customers_extra,,,
Update customer,birthday,生日,6,,STATIC_FIELD,Y,u_customers_extra,,,
; 查询
Find customers,name,客户名称,1,,STATIC_FIELD,,,,,
Find customers,group,客户分组,2,,STATIC_FIELD,,,,,
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
form.name与fieldName一起定位一条字段定义nullable为Y表示该字段在表单中可以不填group.name引用上一节定义的字段组,把字段归入对应分组- 编辑表单中的
name字段通过 extInfo 的meta.updatable设为只读
# 头行结构表单定义
MASTER_DETAIL_LIST 类型的表单显示为左右结构,布局是固定的:
- 左侧是关联对象的树,宽 500px。对象需要有
parent字段来表示上下级,节点标题取对象的标签字段(labelField),同级节点按displaySequence排序;表单配置了 Data Hook 时,树的数据由 Data Hook 返回 - 点击树节点后,右侧显示该对象的编辑(UPDATE)表单,带「保存」「删除」「创建」按钮;点击「创建」时右侧切换为创建(CREATE)表单
开发配置 > 界面显示 > 菜单 页面就是一个头行结构表单。
树节点图标
如果对象上有 icon 字段,其值为 antd 图标名称(如 SortAscendingOutlined),树节点前会显示该图标。
旧版本的 Simple list 左侧、detailFormType / detailField / detailUpdatable 配置 1.0 起已不再生效。
# 表单的 extInfo 支持
表单的 extInfo 是一段 JSON,用于定制表单的扩展属性。extInfo 中可以使用 动态匹配条件 中的时间类占位符,返回给前端前会被替换。
# 通用属性
{
/** 表单标题。仅在表单的 label(显示名称)为空时使用;两者都为空时显示对象名称的翻译 */
/** Form title. Used only when the form's label is empty; if both are empty, the translated domain name is shown */
"domainTitle"?: string;
/** 表单内字段是否横向排列(标签与输入框在同一行) */
/** Whether fields are laid out horizontally (label and input on the same line) */
"horizontal"?: boolean;
} 2
3
4
5
6
7
# LIST 表单属性
{
/** 数据刷新模式。当前只有 realtime 生效:列表会订阅数据变化并实时刷新;其他取值等同不设置 */
/** Data refresh mode. Only realtime takes effect: the list subscribes to data changes and refreshes in real time; other values are the same as not setting it */
"dataRefreshMode"?: "realtime";
/** 点击列表右上角「创建」按钮时使用的创建表单名称,不设置时使用该对象的 CREATE 表单 */
/** Name of the create form used by the "Create" button of the list; defaults to the CREATE form of the domain */
"createFormName"?: string;
/** 点击行内「修改」时使用的编辑表单名称,不设置时使用该对象的 UPDATE 表单 */
/** Name of the update form used by the row "Edit" link; defaults to the UPDATE form of the domain */
"updateFormName"?: string;
/** 列表上方搜索区使用的查询表单名称,不设置时使用该对象的 FINDER 表单 */
/** Name of the finder form used by the search panel; defaults to the FINDER form of the domain */
"finderFormName"?: string;
"listForm"?: {
/** 是否隐藏列表上方的搜索区 */
/** Whether to hide the search panel above the list */
"disableSearchPanel"?: boolean;
/** 默认过滤条件,格式与动态过滤的 conditions 相同;用户在搜索区输入同名条件时会覆盖这里的条件 */
/** Default filter conditions, same format as dynamic filter conditions; a search condition with the same key entered by the user overrides it */
"searchConditions"?: {
"fieldName": {
"columnKey": "fieldName",
"matchMode": "=",
"value": xxx
}
};
};
/** 行内编辑时是否按表单字段的 decides 刷新其他列(decides 当前版本不生效) */
/** Whether inline editing refreshes the columns listed in the field's decides (decides does not work in the current version) */
"enableRefreshColumn"?: boolean;
/** 操作列宽度,默认 120 */
/** Width of the operations column, default 120 */
"operationsColumnWidth"?: number;
/** 覆盖列表的按钮权限,只影响按钮是否显示,后端仍按对象权限校验;create 为 false 时隐藏「创建」按钮 */
/** Overrides list button permissions; only affects button visibility, the backend still checks domain permissions; create=false hides the "Create" button */
"permissions"?: {
"create"?: boolean;
"view"?: boolean;
"update"?: boolean;
"delete"?: boolean;
};
} 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
# 默认过滤条件
列表表单可以通过 extInfo 中的 listForm.searchConditions 设置默认过滤条件,用户在界面上看不到这些条件。条件的格式与 动态过滤 的 conditions 相同:
// 列表表单的默认过滤条件写在 extInfo.listForm.searchConditions 中
// Default filter conditions of a list form go into extInfo.listForm.searchConditions
{
"listForm": {
"searchConditions" : {
// key 是列名称: status
// key is the column name: status
"status": {
// 过滤的目标列
// The target column for filtering
"columnKey": "status",
// 匹配规则:等于
// Matching rule: equals
"matchMode": "=",
// 匹配的目标值: SUCCESS
// The target value to match: SUCCESS
"value": "SUCCESS"
},
// key 是列名称: type
// key is the column name: type
"type": {
// 过滤的目标列, 与上一行的 key 相同
// The target column for filtering, same as the key in the previous line
"columnKey": "type",
// 过滤的匹配规则:isOneOf (是其中某一个)
// Filtering matching rule: isOneOf (is one of them)
"matchMode": "isOneOf",
// 过滤的目标值: [FINDER, UPDATE]
// The target values for filtering: [FINDER, UPDATE]
"value": [
"FINDER",
"UPDATE"
]
}
}
}
} 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
注意
- 默认过滤条件只在前端请求列表数据时附加,如果用户在搜索区输入了同一字段的条件,会覆盖这里的条件。TREE_LIST 右侧的列表、作为子表内嵌显示的列表不读取这个配置。它不是权限控制手段,需要限制数据访问时请使用对象权限或 Data Hook
- 旧版本写在 extInfo 顶层的
conditions1.0 起已不再生效,需要改写到listForm.searchConditions中
# TREE_LIST 表单属性
TREE_LIST 表单左侧显示一棵树,右侧显示列表,点击树节点后按该节点过滤列表。必须配置 treeTable.domainFilterField,否则页面只显示 domainFilterField is not defined:
{
"treeTable": {
// 列表对象上指向树形对象的字段名,该字段必须是这个表单的字段;
// 树形对象的类型由该字段的关联类型决定
"domainFilterField": "category",
// 可选:树形对象上的字段名,会作为查询条件显示在树的上方,
// 全部填写后才按这些字段(等于匹配)加载树
"treeFilterFields": ["catalog"]
}
}
2
3
4
5
6
7
8
9
10
# IFRAME 表单属性
{
// 内嵌页面的地址
"url": "https://example.com/report"
}
2
3
4
# MASTER_DETAIL_LIST 表单属性
{
/** MASTER_DETAIL_LIST 表单当前没有可配置的 extInfo 属性。 */
/** MASTER_DETAIL_LIST forms currently have no configurable extInfo properties. */
/** 左侧固定为对象的树,右侧固定为该对象的 UPDATE / CREATE 表单。 */
/** The left side is always the object tree, the right side is always the UPDATE / CREATE form of the object. */
/** 旧版本的 detailFormType、detailField、detailUpdatable 已不再生效。 */
/** The legacy detailFormType, detailField and detailUpdatable are no longer used. */
} 2
3
4
5
6
7
# DASHBOARD 表单属性
{
/** DASHBOARD 表单当前没有可配置的 extInfo 属性,旧版本的 refreshInterval 已不再生效。 */
/** DASHBOARD forms currently have no configurable extInfo properties; the legacy refreshInterval is no longer used. */
} 2
3
# 表单字段的 extInfo 支持
表单字段的 extInfo 同样是一段 JSON,用于定制字段的扩展属性。
# 通用属性
所有类型的字段,其 extInfo 中均可使用的扩展属性如下
{
// 隐藏字段的标签,只显示控件本身
// Hides the field label and shows only the control
"hideLabel"?: boolean;
// 字段标签与只读值的 CSS 样式,例如 {"color": "#cf1322"}
// CSS styles of the field label and of the read-only value, e.g. {"color": "#cf1322"}
"labelStyle"?: object;
"valueStyle"?: object;
// 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;
// 在创建表单中是否可编辑,false 时显示为只读
// Whether the field is editable in create forms; false renders it read-only
"editable"?: boolean;
// 在编辑表单中是否可编辑,false 时显示为只读
// Whether the field is editable in update forms; false renders it read-only
"updatable"?: boolean;
...
}
} 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
# 数字字段
integer、int、long、decimal 控件支持以下属性(suffix 只对这几种生效,percentage 固定显示 %,currency 不读取 suffix):
{
// 最小值、最大值,超出时提示错误
"min": 0,
"max": 100,
// 输入框后显示的单位
"suffix": "元"
}
2
3
4
5
6
7
# file 字段
{
/** file、fileList、image、video 控件当前不读取 extInfo。 */
/** The file, fileList, image and video controls currently do not read extInfo. */
/** 旧版本的 accept、maxSizeMB、maxCount、totalMaxSizeMB 已不再生效。 */
/** The legacy accept, maxSizeMB, maxCount and totalMaxSizeMB are no longer used. */
} 2
3
4
5
# code 字段
displayType 为 code、json、markdown 等代码类控件时,可以通过如下的 extInfo 设定高亮语法
{
/** 代码编辑器控件显示时的高亮语法 */
/** Syntax highlighting when displaying the code editor control */
/** 不设置时使用字段的显示类型(code、json、markdown 等) */
/** Defaults to the field's display type (code, json, markdown, ...) */
"codeLanguage"?: "css" | "javascript" | "markdown" | "groovy" .....,
} 2
3
4
5
6
# object 字段
对于对象选择控件(object、objects),可以使用如下的 extInfo:
{
/** 候选项的过滤条件
* 控件加载时用该条件查询前 20 条作为默认选项;输入关键字搜索时也会带上该条件
*/
/** Filter conditions of the candidate options
* Used to query the first 20 records as default options when the control loads, and also applied to keyword search
*/
"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
}
},
/** 输入关键字搜索时最多返回的候选项数量,默认 20 */
/** Maximum number of candidates returned by keyword search, default 20 */
"objectOptionsLimit"?: number,
/** 在下拉框底部显示「创建」「编辑」按钮,用于直接新建被关联的对象。当前版本只有单选控件的「创建」可用 */
/** Shows "Create" and "Edit" buttons at the bottom of the dropdown. Currently only "Create" of single-object controls works */
"enableObjectOperations"?: boolean,
/** 通过上述「创建」按钮打开的创建表单中,各字段的默认值查询条件;key 为被关联对象的对象类型字段名,取查询到的第一条 */
/** Default value conditions for the create form opened by the "Create" button; each key is an object field of the target domain, the first match is used */
"createFormDefaultValueConditions"?: {
"fieldName": { "columnKey": "xxx", "matchMode": "=", "value": xxx }
},
/** 覆盖上述创建表单中字段的属性,例如 {"owner": {"disabled": true}} */
/** Overrides field properties in that create form, e.g. {"owner": {"disabled": true}} */
"overwriteCreateFormFieldProps"?: object
} 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
# 一对多的对象字段
displayType 为 array 时(一对多的对象字段),可以使用如下的 extInfo 定义关联列表的显示
{
/** 显示关联对象列表时使用的表单名称,不设置时使用关联对象的 LIST 表单 */
/** Name of the form used to display the associated objects; defaults to the LIST form of the associated domain */
"displayForm"?: "Form used to display the list of objects"
} 2
3
4
# 子表字段
displayType 为 subTable 或 relativeSubTable 时的配置,详见 高级字段控件
// 1. 子表字段(表单字段)的 extInfo
// 1. extInfo of the sub-table form field
{
/** 子表使用的表单名称(决定子表显示哪些列),不设置时使用子对象的 LIST 表单 */
/** Name of the form rendering the sub-table (decides the columns); defaults to the LIST form of the child domain */
"displayForm"?: "UserGroup Sub Table Form For User",
/** 仅 relativeSubTable 使用:从当前对象出发的一对多字段路径,用点号分隔 */
/** Only for relativeSubTable: path of a one-to-many field starting from the current object, separated by dots */
"subTable"?: {
"relativeNamePath"?: "customer.contacts"
}
}
// 2. displayForm 指向的那个表单的 extInfo(行操作权限等写在这里,不是写在字段上)
// 2. extInfo of the form referenced by displayForm (row permissions etc. go here, not on the field)
{
"subTable"?: {
/** 是否可修改、新增、删除行;设置后覆盖默认值(默认可修改;带 mappedBy 的一对多子表要求主对象已保存才可删除,且当前不显示「创建」按钮) */
/** Whether rows can be updated, created, deleted; overrides the defaults (updatable by default; for one-to-many with mappedBy, delete requires the owner to be saved and the "Create" button is currently not shown) */
"updatable"?: true | false,
"creatable"?: true | false,
"deletable"?: true | false,
/** 是否可拖拽排序 */
/** Whether rows can be reordered by drag and drop */
"dragSort"?: true | false,
/** 为 true 时「创建」按钮放在表格底部(默认在顶部);可拖拽排序的子表中新增行也追加到末尾 */
/** When true the "Create" button is placed at the bottom (top by default); in drag-sortable sub-tables new rows are appended */
"asc"?: true | false,
/** 在操作列中提供行级对象动作,只读状态下也显示操作列 */
/** Offers row-level object actions in the operations column, which is shown even when read-only */
"enableActions"?: true | false
}
} 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
← 🗿 旧领域模型(不推荐) 🔍 动态过滤 →