Become a sponsor

本章概要
代码生成引擎的工作原理,包括配置解析、模板渲染、文件写入和自动注册的完整流程。
src/modules/generator/code_generator.py 是代码生成器的执行层,负责接收配置字典、渲染模板、写入文件、自动注册路由和菜单。
from modules.generator.code_generator import CodeGenerator
generator = CodeGenerator(config)
generator.generate(auto=True)| 参数 | 说明 |
|---|---|
config | 配置字典(由 parser.parse() 或 JSON 文件提供) |
构造时自动:
normalize_config() 标准化配置(幂等,已标准化的配置原样返回)src/modules/{app_name}trim_blocks=True, lstrip_blocks=True)def generate(self, auto=False, request=None):1. 校验输出目录不存在(避免覆盖已有模块)
2. 创建输出目录 src/modules/{app_name}/
3. 准备模板上下文数据
4. 渲染后端模板 → 写入 modules 目录
5. 渲染 endpoint 模板 → 写入 api/v1/endpoints/ 目录
6. 渲染前端模板 → 写入 ui/src/views/ 和 ui/src/api/
7. 自动注册到 router.py
8. 自动创建菜单 + 权限节点| 参数 | 说明 |
|---|---|
auto | 自动模式(当前无交互差异) |
request | FastAPI 请求对象(用于获取操作人信息) |
normalize_config() 将 parser 产出的配置转为模板可用的标准格式:
# parser 产出的字段
{"name": "type", "db_type": "Integer", "comment": "案例类型:1-类型1 2-类型2"}
# 标准化后
{
"name": "type",
"camel_name": "type", # 驼峰命名
"db_type": "Integer",
"form_type": "int", # Pydantic 类型
"comment": "案例类型:1-类型1 2-类型2",
"py_comment": "案例类型:1-类型1 2-类型2", # 转义后
"default_repr": "1", # 默认值表示
"is_status": False, # 状态字段标识
"is_sort": False, # 排序字段标识
}准备后端模板的渲染上下文:
| 变量 | 类型 | 说明 |
|---|---|---|
app_name | str | 模块名(如 example) |
module_comment | str | 中文名(如 案例) |
model_class_name | str | 类名(如 Example) |
permission_prefix | str | 权限前缀(如 sys:example) |
display_field | str | 显示字段(如 name) |
has_sort | bool | 有排序字段 |
has_status | bool | 有状态字段 |
has_status_route | bool | 生成状态路由 |
has_image_field | bool | 有图片字段 |
has_rich_text_field | bool | 有富文本字段 |
serialize_maps | dict | 枚举映射 |
sort_field | str | 排序字段名 |
fields | list | 全部字段 |
form_fields | list | 表单字段 |
filter_fields | list | 精确匹配字段 |
like_fields | list | 模糊查询字段 |
在后端上下文基础上扩展前端专用变量:
| 变量 | 类型 | 说明 |
|---|---|---|
module_name | str | 驼峰模块名 |
model_class_name_camel | str | 驼峰类名(首字母小写) |
list_fields | list | 列表展示字段 |
searchable_fields | list | 可搜索字段 |
editable_fields | list | 可编辑字段 |
has_export | bool | 有导出功能 |
route_prefix | str | 路由前缀 |
api_path | str | API 路径 |
is_tree_structure | bool | 是否树形结构 |
parent_id_field | str | 父级字段名 |
has_search_form | bool | 显示搜索表单 |
show_selection | bool | 显示复选框 |
| 模板 | 输出路径 | 说明 |
|---|---|---|
__init__.py.tpl | src/modules/{name}/__init__.py | 模块初始化 |
models.py.tpl | src/modules/{name}/models.py | ORM 模型 |
schemas.py.tpl | src/modules/{name}/schemas.py | Pydantic 表单 |
repository.py.tpl | src/modules/{name}/repository.py | 数据访问层 |
service.py.tpl | src/modules/{name}/service.py | 业务逻辑层 |
endpoint.py.tpl | src/api/v1/endpoints/{name}.py | HTTP 端点 |
| 模板 | 输出路径 |
|---|---|
ui/index.vue.tpl | ui/src/views/tool/{name}/index.vue |
ui/edit.vue.tpl | ui/src/views/tool/{name}/edit.vue |
ui/detail.vue.tpl | ui/src/views/tool/{name}/detail.vue |
ui/columns.ts.tpl | ui/src/views/tool/{name}/columns.ts |
ui/querySchemas.ts.tpl | ui/src/views/tool/{name}/querySchemas.ts |
ui/api.ts.tpl | ui/src/api/tool/{name}.ts |
| 模板 | 输出路径 |
|---|---|
ui2/index.vue.tpl | ui/src/views/tool/{name}/index.vue |
ui2/edit.vue.tpl | ui/src/views/tool/{name}/edit.vue |
ui2/detail.vue.tpl | ui/src/views/tool/{name}/detail.vue |
ui/api.ts.tpl | ui/src/api/tool/{name}.ts |
树状列表与普通列表共用 api.ts.tpl。
_register_module() 在 src/api/v1/router.py 中追加:
# 导入语句(插入到最后一个 from api.v1.endpoints 导入之后)
from api.v1.endpoints.example import router as example_router
# 注册语句(追加到文件末尾)
v1.include_router(example_router, prefix="/example", tags=["案例"])幂等操作:如果导入语句已存在,跳过。
_create_menus() 在数据库中创建:
二级菜单(type=0):页面路由
/tool/{module_camel}/tool/{module_camel}/index三级权限节点(type=1)× 10 个:
| 权限 | 标识 |
|---|---|
| 分页查询 | {prefix}:page |
| 列表查询 | {prefix}:list |
| 详情查询 | {prefix}:detail |
| 新增 | {prefix}:add |
| 编辑 | {prefix}:update |
| 删除 | {prefix}:delete |
| 批量删除 | {prefix}:batchDelete |
| 状态管理 | {prefix}:status |
| 导入 | {prefix}:import |
| 导出 | {prefix}:export |
幂等操作:如果 path 已存在,跳过。创建后自动清除所有用户权限缓存。
代码生成引擎根据数据库表结构和配置信息,通过 Jinja2 模板渲染生成后端(models/schemas/repository/service/endpoint)和前端(index.vue/edit.vue/columns.ts/querySchemas.ts/api.ts)全套代码,生成后自动注册路由和权限。