Files
yidaima/RuoYi-Vue/docs/superpowers/specs/2026-07-07-code-template-bundles-design.md
2026-07-07 16:28:51 +08:00

251 lines
9.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 多代码模板包设计
## 目标
把当前固定使用 `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不再扩大硬编码。
- 数据库模板文件和结构树仍沿用现有模型,避免一次性重写生成器。
- 前端页签和下载逻辑从模板包能力派生,避免新增模板后继续改页面常量。