元表格
ArchForge 提供低代码元表格能力,管理员可在后台界面定义表、字段、索引与约束,系统自动创建物理 PostgreSQL 表、执行 Schema 演进、管理行数据,并生成前后端完整模块脚手架。
功能特性
可视化表设计
通过管理端界面定义表元数据:
| 属性 | 说明 |
|---|---|
| 表格编码 | 唯一机器可读标识,作为物理表名后缀 |
| 表格名称 | 人类可读展示名 |
| 表前缀 | 物理表前缀,默认 meta_。只能是小写字母、数字、_,最长 32 位;前缀 + 编码 不得以 sys_、qrtz_、pg_、sql_、information_schema_、flyway_ 开头 |
| 状态 | 启用(1)/ 禁用(0) |
| 描述 | 可选备注 |
支持的字段类型
| 类型 | PostgreSQL 映射 | 说明 |
|---|---|---|
| STRING | VARCHAR(length) | 默认长度 255 |
| TEXT | TEXT | 长文本 |
| INTEGER | BIGINT | 整数 |
| DECIMAL | NUMERIC(precision, scale) | 默认 NUMERIC(18,2) |
| BOOLEAN | BOOLEAN | 布尔值 |
| DATE | DATE | 日期 |
| DATETIME | TIMESTAMP | 无时区时间戳 |
| TIMESTAMPTZ | TIMESTAMPTZ | 带时区时间戳 |
| ENUM | VARCHAR(length) | 值必须是该列字典(dictCode)里的项 |
| JSON | JSONB | JSON 文档——可以传对象 / 数组,也可以传 JSON 文本 |
| GEO | JSONB | {"lat": …, "lng": …}(对象或 JSON 文本) |
| FILE | VARCHAR(512) | 文件引用 |
| UUID | UUID | UUID 值 |
| ARRAY | element_type[] | STRING、INTEGER、DECIMAL、BOOLEAN 数组 |
字段属性
每个字段可配置:
- 长度 / 精度 / 小数位 — 用于字符串、小数与数组元素大小。按 PostgreSQL 的上限校验:长度 ≤ 10485760、精度 ≤ 1000、0 ≤ 小数位 ≤ 精度(未设置时为 18);ARRAY 的元素类型只能是 STRING、INTEGER、DECIMAL 或 BOOLEAN
- 可空 / 必填 — 控制
NOT NULL - 默认值 — 执行任何 DDL 之前按字段类型校验:数值会被解析后重新输出,文本会被转义加引号;与类型不符的值直接拒绝
- 唯一 — 未删除的行之间值唯一;重复是校验错误(
10408,<字段> 的值已存在),不是服务端错误 - 索引 / 索引类型 / 索引分组 — 单列或组合索引(
BTREE、GIN、GIST、FULLTEXT) - 可搜索 — 在数据列表搜索表单中显示
- 列表可见 — 默认在数据表格中显示
- 租户字段 / 所有者字段 — 用于多租户或行所有者语义
- 字典 — ENUM 的值按该列字典校验;字典不存在或为空时拒绝一切写入(失败关闭)。字典尚未创建时,旧的内联选项仍然有效
- 引用表 / 引用列 / 显示表达式 — 用于
REFERENCE字段。显示表达式只允许ref.<列名>(可加::text)、'字符串'与||,例如ref.username || ' (' || ref.email || ')';函数、运算符、子查询一律拒绝。被引用的表只能是本表或已登记的元表格——平台表(sys_*等)一律不会被关联,显示表达式读不到sys_user.password之类的列
Schema 演进
当表定义更新时,SchemaDiffEngine 比较旧字段列表与新字段列表,生成有序的迁移计划:
RENAME_COLUMN(重命名列)DROP_COLUMN(删除列)ADD_COLUMN(新增列)ALTER_TYPE(修改类型)ALTER_DEFAULT(修改默认值)ALTER_NULL(修改可空性)ALTER_INDEX(修改索引)
AlterTableDdlGenerator 将每个变更转换为安全的 PostgreSQL ALTER TABLE DDL。迁移历史保存在 sys_meta_table_migration,可导出为 Flyway SQL 文件。
数据 CRUD
表定义完成且物理表创建后,可进行:
- 分页查询行数据并支持动态过滤
- 插入新行
- 更新已有行
- 软删除行
- 从 CSV/JSON 导入数据
每次写入都先按字段定义校验;非法值、不在字典里的 ENUM 值、唯一字段上的重复值都返回 10408 并带上字段名。
- 导出为 EXCEL/CSV/JSON
代码生成
每个元表格可一键生成完整模块脚手架,使用 FreeMarker 模板:
后端(默认 example/<tableCode>)
build.gradle.ktsdomain/{Entity}.javadao/{Entity}Dao.javadto/{Entity}CreateRequest.javadto/{Entity}UpdateRequest.javadto/{Entity}ListRequest.javadto/{Entity}Response.javadto/{Entity}PageResult.javaservice/{Entity}Service.javarest/{Entity}Controller.java- 错误码 / 异常 / 项目模块类
- 集成测试骨架
前端(默认 src/views/<tableCode>)
src/api/<tableCode>.tssrc/router/modules/<tableCode>.tssrc/views/<tableCode>/utils/types.tssrc/views/<tableCode>/utils/hook.tsxsrc/views/<tableCode>/index.vuesrc/views/<tableCode>/form/index.vue
生成的 Controller 将列表、导出、导入委托给 MetaTableCrudService,复用动态表运行时。
数据模型
sys_meta_table
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT | 主键 |
| table_code | VARCHAR(64) | 表格编码,唯一 |
| table_name | VARCHAR(128) | 展示名称 |
| description | VARCHAR(512) | 备注 |
| table_prefix | VARCHAR(32) | 物理表前缀,默认 meta_ |
| status | INT | 启用 1 / 禁用 0 |
| creator_id | BIGINT | 创建人 |
| create_time | TIMESTAMP | 创建时间 |
| updater_id | BIGINT | 更新人 |
| update_time | TIMESTAMP | 更新时间 |
| deleted | INT | 软删除标记 |
sys_meta_table_column
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT | 主键 |
| table_id | BIGINT | 关联 sys_meta_table |
| column_code | VARCHAR(64) | 字段编码 |
| column_name | VARCHAR(128) | 展示名称 |
| data_type | VARCHAR(32) | 支持的字段类型之一 |
| length | INT | 长度或最大尺寸 |
| precision | INT | 数值精度 |
| scale | INT | 数值小数位 |
| nullable | INT | 1 可空,0 必填 |
| default_value | VARCHAR(255) | 默认值 |
| is_unique | INT | 唯一标记 |
| is_required | INT | 必填标记 |
| is_searchable | INT | 可搜索标记 |
| is_list_visible | INT | 列表可见标记 |
| is_index | INT | 索引标记 |
| sort | INT | 显示顺序 |
| options | TEXT | JSON 选项列表 |
| reference_table | VARCHAR | 引用表 |
| reference_column | VARCHAR | 引用列 |
| tenant_column | BOOLEAN | 租户字段 |
| owner_column | BOOLEAN | 所有者字段 |
| index_type | VARCHAR | 索引类型 |
| index_group | VARCHAR | 索引分组 |
| array_element_type | VARCHAR | 数组元素类型 |
sys_meta_table_migration
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT | 主键 |
| table_id | BIGINT | 关联元表格 |
| version | INT | 版本号 |
| change_type | VARCHAR(32) | RENAME/DROP/ADD/ALTER_* |
| column_code | VARCHAR(64) | 受影响字段 |
| old_column_code | VARCHAR(64) | 重命名前列名 |
| old_type / new_type | VARCHAR(64) | 变更前后类型 |
| old_default / new_default | VARCHAR(255) | 变更前后默认值 |
| ddl_sql | TEXT | 生成的 DDL |
| status | VARCHAR(16) | PENDING / EXECUTED |
| executed_at | TIMESTAMP | 执行时间 |
API 接口
元表格一律用 tableCode 定位,不用数据库 id(各环境的 id 不同)。每个接口都声明了自己的权限——只有类级的 ADMIN 角色不够。
| 方法 | 接口 | 权限 | 说明 |
|---|---|---|---|
| POST | /admin/meta-table | meta-table:list | 元表格分页列表 |
| GET | /admin/meta-table/{tableCode} | meta-table:list | 元表格详情(含字段) |
| POST | /admin/meta-table/create | meta-table:add | 创建元表格 |
| PUT | /admin/meta-table/{tableCode} | meta-table:edit | 更新表与字段 |
| PATCH | /admin/meta-table/{tableCode} | meta-table:edit | 只更新名称 / 描述 / 状态 |
| POST | /admin/meta-table/{tableCode}/schema-preview | meta-table:edit | 保存前预览结构变更 |
| GET | /admin/meta-table/importable-tables | meta-table:list | 可纳管的物理表 |
| GET | /admin/meta-table/import-preview?tableName= | meta-table:list | 预览导入的字段映射 |
| POST | /admin/meta-table/import | meta-table:add | 纳管已有物理表 |
| POST | /admin/meta-table/{tableCode}/copy | meta-table:add | 复制元表格,返回副本的 tableCode |
| POST | /admin/meta-table/{tableCode}/generate | meta-table:generate | 生成前后端代码 |
| GET | /admin/meta-table/{tableCode}/delete-check | meta-table:remove | 删除前查看数据行数 |
| DELETE | /admin/meta-table/{tableCode}?force={false|true} | meta-table:remove | 删除元表格 |
| GET | /admin/meta-table/{tableCode}/migrations | meta-table:list | 查询 Schema 迁移历史 |
| GET | /admin/meta-table/{tableCode}/export-migration | meta-table:edit | 导出迁移为 Flyway SQL |
| POST | /admin/meta-table/{tableCode}/data | meta-table:list | 查询动态表数据 |
| POST | /admin/meta-table/{tableCode}/data/create | meta-table:add | 插入一行 |
| PUT | /admin/meta-table/{tableCode}/data/{dataId} | meta-table:edit | 更新一行 |
| POST | /admin/meta-table/{tableCode}/data/{dataId}/delete | meta-table:remove | 软删除一行 |
| GET | /admin/meta-table/{tableCode}/export?format=EXCEL | meta-table:export | 导出表数据 |
| POST | /admin/meta-table/{tableCode}/import?format=CSV | meta-table:add | 导入表数据 |
管理端界面
管理端元表格模块位于 /src/views/meta-table/:
- 元表格列表 — 按编码/名称搜索、分页展示、新增/修改/复制/删除/生成代码
- 表设计器 — 弹窗编辑表元数据与字段列表
- 数据管理 — 打开某张表的数据网格,执行增删改查、搜索、导入、导出
- 所有按钮受
meta-table:*权限控制
权限点
| 权限 | 说明 |
|---|---|
meta-table:list | 查看元表格、详情与迁移历史;查询数据行 |
meta-table:query | 查询元表格数据 |
meta-table:add | 创建、复制、纳管元表格;插入 / 导入数据行 |
meta-table:edit | 更新元表格、导出迁移;更新数据行 |
meta-table:remove | 删除元表格(含删除前检查);删除数据行 |
meta-table:export | 导出元表格数据 |
meta-table:design | 设计字段 |
meta-table:data | 管理行数据 |
meta-table:generate | 生成代码脚手架 |
典型使用流程
- 创建元表格,填写唯一编码、名称与表前缀。
- 添加字段:选择类型、长度、约束、索引等。
- 保存设计;后端自动创建物理表
{prefix}{table_code}。若同名物理表已存在则拒绝保存——已有的表请用导入纳管。 - 切换到数据视图,进行增删改查、导入或导出。
- (可选)点击生成代码生成前后端完整模块脚手架。
- 需求变更时再次编辑表格;系统自动计算并应用 Schema 迁移 DDL。
定义文件
表定义也可以作为 project-definition/meta/<tableCode>.yaml 纳入版本控制:./archforge meta export 从数据库导出,./archforge meta import 把文件同步进数据库(不加 --apply 只做演练),./archforge meta check 在出现漂移时退出码为 1。设置 arch-forge.meta.source=file 后以文件为准——启动时应用定义文件,设计器 / 导入的写操作会被拒绝。
同步本身从不执行 DDL:物理表来自 Flyway 或设计器。因此登记了但物理表不存在时,meta check 同样失败,meta import、file 模式启动与 shadow 校验会告警。