docs: add code template bundle design

This commit is contained in:
王鹏
2026-07-07 16:28:51 +08:00
parent a90edbafd3
commit b4dc71e176

View File

@@ -0,0 +1,250 @@
# 多代码模板包设计
## 目标
把当前固定使用 `qing` 的生成链路升级为可选择的代码模板包机制。`qing` 继续作为默认模板包,后续新增模板通过统一的模板包元数据、模板文件、结构树和生成选择策略接入,不再在生成服务里为每个模板反复增加硬编码分支。
第一期目标是支持多个技术栈或代码风格模板包,例如 `qing``qing-lite``vue3-plus`。行业业务提示词仍由现有 `industryTemplate` 表达,不和代码模板包混用。
## 当前上下文
现有 `qing` 生成能力由三部分组成:
- 文件系统基线模板:`ruoyi-generator/src/main/resources/qing/*.vm`
- 数据库模板记录:`sys_template``sys_template_file``sys_project_structure`,种子主要在 `sql/qing_templates.sql``sql/db.sql`
- 生成服务选择逻辑:`GenProjectServiceImpl` 根据 `templateType` 解析模板,当前优先选择 9201、9202、9203 这三个可运行模板 ID。
这说明新增模板不能只复制一个目录。一个可用模板必须同时具备模板包标识、每类模板文件、结构树、输出路径约定、预览下载支持和运行预览兼容性。
## 用户体验
前台生成工作台在创建或编辑项目时增加“代码模板”选择。默认选中 `qing`。选择项来自后端接口,只展示启用状态的模板包。
预览页不再写死三类页签,而是读取当前项目模板包支持的目标类型:
- `backend`
- `frontend`
- `admin_frontend`
- `sql`
如果模板包不支持某一类,前端不展示对应页签,下载全部源码时也跳过该类。`frontendEnabled = 0` 时仍按现有逻辑隐藏用户前台。
## 数据模型
新增模板包表 `sys_template_bundle`
```sql
bundle_id bigint primary key,
bundle_code varchar(64) not null unique,
bundle_name varchar(100) not null,
description varchar(500),
status char(1) not null default '0',
is_default char(1) not null default '0',
support_backend char(1) not null default '1',
support_frontend char(1) not null default '1',
support_admin_frontend char(1) not null default '1',
support_sql char(1) not null default '1',
sort_order int default 0,
create_by varchar(64),
create_time datetime,
update_by varchar(64),
update_time datetime
```
扩展 `sys_template`
- 增加 `bundle_code varchar(64)`,用于把 `backend``frontend``admin_frontend` 等模板记录归属到同一个模板包。
- 保留 `template_type` 表示目标类型,不改变现有模板文件和结构树关系。
- `qing` 现有 9201、9202、9203 记录补充 `bundle_code = 'qing'`
扩展前台项目表:
- 增加 `code_template varchar(64)`,默认 `qing`
- `FrontProjectCreateRequest``FrontProjectUpdateRequest``AiGenerationTaskCreateRequest` 同步增加 `codeTemplate`
- `FrontProjectConverter.toGenProject` 把该字段传给 `GenProject`,供预览和下载使用。
## 后端架构
新增模板包服务:
- `TemplateBundle` domain、mapper、service。
- `listEnabledBundles()`:前端创建项目时使用。
- `getBundle(code)`:生成服务解析模板时使用。
- `getDefaultBundle()`:项目未指定时回退到默认模板包,默认应为 `qing`
- `getSupportedTemplateTypes(code, frontendEnabled)`:预览页和下载逻辑使用。
调整 `GenProjectServiceImpl`
- `resolveProjectTemplate(project, type)` 先读取 `project.codeTemplate`
- 未指定时回退默认模板包 `qing`
- 通过 `bundle_code + template_type + template_status = 0` 查询模板。
- 移除 9201、9202、9203 作为固定优先模板的业务含义,只保留数据迁移兼容。
- 如果项目后台手动绑定了 `sys_project_template`,仍优先使用绑定记录,以保持现有后台配置能力。
生成入口需要统一使用同一个模板包:
- `getProjectStructure`
- `previewCode`
- `downloadStructure`
- `downloadAll`
- `run-preview` 源码准备
- 一键生成中 `SOURCE_PREVIEW` 阶段的结构校验
## 模板资源组织
第一期可以继续以数据库模板为渲染来源,文件系统模板作为内置基线和测试对照。后续可逐步收敛到以下目录规范:
```text
ruoyi-generator/src/main/resources/templates/
qing/
manifest.yml
backend/
frontend/
admin_frontend/
vue3-plus/
manifest.yml
backend/
frontend/
admin_frontend/
```
`manifest.yml` 描述模板包基本信息、支持类型、推荐端口、模板文件清单和结构树种子来源。第一期不强制实现自动导入 manifest但新增模板应按这个结构准备避免继续把 `qing` 当作特殊目录。
## 数据流
1. 用户创建项目,选择 `codeTemplate`
2. 后端保存项目草稿,未传则写入默认模板包 `qing`
3. AI 生成蓝图、数据库、业务动作和页面设计时继续使用现有行业提示词,不受代码模板选择影响。
4. 预览结构时,`GenProjectServiceImpl``project.codeTemplate + templateType` 找到模板记录。
5. 根据模板记录读取 `sys_template_file`,根据模板 ID 读取 `sys_project_structure`
6. Velocity 渲染模板内容,结构树里的 `category` 对应模板文件名或路径。
7. 下载全部源码时,后端遍历模板包支持的类型,合并 zip。
8. 运行预览从下载出的结构中启动后端、用户前台和后台前端;不支持的类型跳过。
## 错误处理
模板包不存在或未启用:
- 创建/更新项目时返回明确错误。
- 老项目没有 `codeTemplate` 时回退默认模板包。
模板包缺少某个目标类型:
- 前端不展示对应页签。
- 后端收到不支持的 `templateType` 时返回“当前模板包不支持该生成类型”。
模板记录存在但文件缺失:
- `getRequiredTemplateFiles` 继续抛出模板未配置文件错误。
- 错误信息补充模板包 code、templateType 和 templateId便于排查。
结构树 category 找不到模板文件:
- 预览单文件时提示未找到模板文件。
- 下载时记录失败模板路径,避免静默跳过。
运行预览不兼容:
- 源码下载仍可用。
- 运行预览返回失败状态和日志。
- 模板包元数据可在后续增加 `run_preview_supported` 做显式控制。
## SQL 和迁移
第一期迁移脚本做这些事:
- 创建 `sys_template_bundle`
-`sys_template` 增加 `bundle_code`
-`front_project` 增加 `code_template`
- 插入默认模板包 `qing`
- 将 9201、9202、9203 的 `bundle_code` 更新为 `qing`
- 更新历史前台项目 `code_template = 'qing'`
- 保证只有一个启用的默认模板包。
模板包种子建议独立文件:
- `sql/code_template_bundles.sql`:模板包表结构和 qing 默认数据。
- `sql/qing_templates.sql`:继续维护 qing 的模板文件和结构树。
- `sql/db.sql`:整合完整初始化脚本。
## 前端改造
`easycode-web` 增加接口:
- `listCodeTemplateBundles()`
- `getProjectSupportedTemplateTypes(projectId)`
创建和编辑项目表单增加代码模板选择。展示文案建议:
- `qing`:默认可运行 Spring Boot + Vue2 模板
- 新模板:按模板包元数据展示名称和描述
`PreviewView` 改造:
- `templateTypes` 来自后端,而不是固定数组。
- 下载全部源码默认调用现有下载接口。
- 单类下载时继续传 `templateType`
- 如果当前激活类型不在支持列表,自动切回第一个可用类型。
## 测试策略
后端单元测试:
- 未指定 `codeTemplate` 时回退 `qing`
- 指定模板包时按 `bundle_code + template_type` 选择模板。
- 后台项目模板绑定仍优先于模板包默认模板。
- 禁用模板包不可用于新项目。
- 不支持的 `templateType` 返回明确错误。
- 老项目迁移后可以继续预览 backend、frontend、admin_frontend 和 sql。
模板一致性测试:
- `qing` 模板包的 9201、9202、9203 都能找到文件和结构树。
- 结构树 `category` 都能匹配模板文件名或路径。
- 复制出的测试模板包不会被 9201、9202、9203 固定优先逻辑覆盖。
前端测试:
- 创建项目表单展示代码模板选择。
- 未选择时提交默认 `qing`
- 预览页按后端返回的支持类型渲染页签。
- `frontendEnabled = 0` 时隐藏用户前台。
人工验收:
1. 导入迁移脚本。
2. 创建项目,不手动选择模板,确认使用 `qing`
3. 创建项目,选择测试模板包,确认预览结构来自新模板包。
4. 下载全部源码,确认只包含模板包支持的目标类型。
5. 启动运行预览,确认 qing 模板仍可运行。
## 分期
第一期:
- 数据库增加模板包和项目模板选择字段。
- 后端模板包服务和选择策略。
- 前台创建/编辑项目支持代码模板选择。
- 预览页动态读取支持类型。
- qing 作为默认模板包完成迁移。
第二期:
- 引入 `manifest.yml` 导入工具。
- 增加模板包复制、启停、导入导出。
- 模板包运行预览能力声明。
- 模板包版本管理。
第三期:
- 模板市场化管理。
- 模板包依赖能力声明,例如业务块、图表、文件上传、认证方式。
- 模板包质量检查和在线试生成。
## 自检
- 范围聚焦在代码模板包,不混入行业业务模板。
- `qing` 作为默认行为保留,老项目有回退路径。
- 模板选择逻辑从固定 ID 改为模板包 code不再扩大硬编码。
- 数据库模板文件和结构树仍沿用现有模型,避免一次性重写生成器。
- 前端页签和下载逻辑从模板包能力派生,避免新增模板后继续改页面常量。