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