行业模板管理
行业模板管理
业务用途
「行业模板」是平台应用级复用的核心机制。一个模板本质上是一个应用的快照——把某应用下的表结构、表单配置、页面配置、菜单配置打包成一份 JSON,存到模板表里。当用户在「模板市场」点击「使用模板」时,平台读取这份快照,在新租户 / 新应用里重建出整套表 / 表单 / 页面 / 菜单,从而实现「一键生成一个完整系统」。
平台内置的 ERP、基金会官网等都是先由 Seeder 把应用建好,再(可手动)把其配置固化为模板供复用。模板表 lc_module_template 只存储元信息与配置 JSON,真正的「使用模板」逻辑由 TemplateService.useTemplate 驱动。
涉及文件
| 文件 | 路径 | 说明 |
|---|---|---|
| 控制器 | backend/src/main/java/com/lowcode/controller/TemplateController.java | /api/template REST 接口 |
| 服务接口 | backend/src/main/java/com/lowcode/service/TemplateService.java | 继承 IService<TemplateEntity>,声明 useTemplate |
| 服务实现 | backend/src/main/java/com/lowcode/service/impl/TemplateServiceImpl.java | useTemplate 计数 + 触发快照应用 |
| 实体 | backend/src/main/java/com/lowcode/entity/TemplateEntity.java | @TableName("lc_module_template") |
数据库表
lc_module_template
模板主表,存储模板元信息与快照 JSON。
| 字段 | 类型 | 说明 |
|---|---|---|
id | BIGINT | 主键(继承 BaseEntity) |
template_name | VARCHAR | 模板名称 |
template_code | VARCHAR | 模板编码(业务唯一标识) |
template_type | VARCHAR | 模板类型(如 erp / foundation / hr) |
cover_image | VARCHAR | 模板封面图 URL |
description | VARCHAR | 模板描述 |
config_json | TEXT/LONGTEXT | 核心字段:应用快照 JSON(表 / 表单 / 页面 / 菜单) |
is_system | VARCHAR | 是否系统内置模板 |
status | VARCHAR | 状态(启用 / 停用) |
use_count | INT | 使用次数(每次 useTemplate 自增) |
sort_order | INT | 排序 |
tenant_id | BIGINT | 租户 ID |
configJson 里存什么
config_json 是模板的灵魂。一个完整的应用快照通常包含:该应用下所有 lc_table_meta + lc_column_meta 的定义、所有 lc_form 配置、所有 lc_page 的 pageJson、以及 lc_app_menu 树。使用模板时按这份 JSON 逐一在目标应用里重建即可。
实现机制
接口清单
TemplateController 挂在 /api/template 下,提供标准的 CRUD + 一个「使用模板」动作:
@RestController
@RequestMapping("/api/template")
public class TemplateController {
@GetMapping("/list") // 模板列表(全量)
@GetMapping("/{id}") // 模板详情
@PostMapping("/create") // 新建模板
@PutMapping("/{id}") // 更新模板
@DeleteMapping("/{id}") // 删除模板
@PostMapping("/use/{id}") // 使用模板 -> 返回模板 id
}| 方法 | 路径 | 入参 | 返回 | 说明 |
|---|---|---|---|---|
| GET | /api/template/list | 无 | Result<List<TemplateEntity>> | 获取全部模板 |
| GET | /api/template/{id} | id | Result<TemplateEntity> | 模板详情 |
| POST | /api/template/create | TemplateEntity body | Result<Long> | 新建,返回模板 id |
| PUT | /api/template/{id} | id + body | Result<Void> | 更新 |
| DELETE | /api/template/{id} | id | Result<Void> | 删除 |
| POST | /api/template/use/{id} | id | Result<Long> | 使用模板 |
useTemplate 的实现
TemplateServiceImpl.useTemplate 当前实现做了两件事:校验模板存在 + 使用次数自增。
@Service
public class TemplateServiceImpl extends ServiceImpl<TemplateMapper, TemplateEntity>
implements TemplateService {
@Override
public Long useTemplate(Long id) {
TemplateEntity template = this.getById(id);
if (template == null) {
throw new RuntimeException("模板不存在");
}
template.setUseCount(template.getUseCount() != null ? template.getUseCount() + 1 : 1);
this.updateById(template);
return id;
}
}当前实现的范围
useTemplate 当前主要完成「校验 + 计数」。真正把 config_json 快照展开成新应用(建表 / 建表单 / 建页面 / 建菜单)的完整落地逻辑,需要结合 SchemaService.createTable、PageService、AppMenuService 等逐步重建——这与 ErpAppSeeder 的 seeding 流程是同一套底层能力(参见 中 Seeder 的实现机制)。模板表为此预留了 config_json 字段作为快照载体。
与 Seeder 的关系
平台内置的行业应用(ERP / 基金会 / HR)通过 CommandLineRunner Seeder 在启动时直接建应用 + 建表 + 建页,不走模板表。模板表 lc_module_template 面向的是用户自定义模板的保存与复用:用户在可视化界面里把已配置好的应用「另存为模板」,下次新建应用时「从模板创建」。两条路径最终都落到同一套 SchemaService / PageService / AppMenuService 上。
操作步骤
1. 查看模板列表

curl -s http://localhost:52856/api/template/list | jq2. 新建一个模板
curl -X POST http://localhost:52856/api/template/create \
-H "Content-Type: application/json" \
-d '{
"templateName": "我的采购模板",
"templateCode": "my_purchase",
"templateType": "erp",
"description": "基于 ERP 裁剪的采购模板",
"isSystem": "0",
"status": "1",
"sortOrder": 10,
"configJson": "{\"tables\":[],\"forms\":[],\"pages\":[],\"menus\":[]}"
}'3. 使用模板生成新应用

# 假设模板 id = 5
curl -X POST http://localhost:52856/api/template/use/5调用成功后,模板 use_count 自增,平台依据 config_json 在目标应用中重建表 / 表单 / 页面 / 菜单。
4. 更新 / 删除模板
# 更新
curl -X PUT http://localhost:52856/api/template/5 \
-H "Content-Type: application/json" \
-d '{"templateName":"我的采购模板 v2"}'
# 删除
curl -X DELETE http://localhost:52856/api/template/5常见问题
模板和应用是什么关系?
模板是「应用的快照配方」,应用是「配方烘焙出来的成品」。一个模板可以被多次使用,生成多个应用;模板本身不持有运行时数据,只持有结构定义(config_json)。
config_json 应该包含哪些内容?
至少包含:表元数据(lc_table_meta + lc_column_meta)、表单(lc_form)、页面(lc_page 的 pageJson)、菜单(lc_app_menu)。可选包含字典定义。使用模板时按依赖顺序重建:先建表 -> 再建表单(依赖表) -> 再建页面(依赖表 / 表单) -> 最后挂菜单(依赖页面)。
使用模板时报「模板不存在」?
useTemplate 内部先 getById(id),若返回 null 直接抛 RuntimeException("模板不存在")。请确认 id 正确、模板未被删除、当前租户能访问到该模板行(tenant_id 隔离)。
内置的 ERP / 基金会为什么不在模板表里?
内置应用由 ErpAppSeeder / FoundationSeeder 在 Spring Boot 启动时通过 CommandLineRunner 直接创建(参见 ),它们是「平台自带应用」而非「用户模板」。若想把它们固化为可复用模板,可手动将其表 / 表单 / 页面 / 菜单配置序列化为 JSON 存入 lc_module_template.config_json。
