Files
2026-09-12 23:12:15 +08:00

212 lines
7.0 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.
:::tip 本章概要
代码生成引擎的工作原理,包括配置解析、模板渲染、文件写入和自动注册的完整流程。
:::
# 代码生成引擎
`generator_config.py` 中的 `CodeGenerator` 类是代码生成器的执行层,负责接收配置字典、渲染模板、写入文件、自动注册路由和菜单。
## 核心类:CodeGenerator
```python
from generator_config import CodeGenerator
generator = CodeGenerator(config)
generator.generate() # 交互模式(询问迁移和菜单创建)
generator.generate(auto=True) # 自动模式(Web 界面调用)
```
### 构造参数
| 参数 | 说明 |
|:----|:----|
| `config` | 配置字典(由 `TableSchemaParser.parse()` 或 JSON 文件提供) |
构造时自动:
- 设置模板目录:`public/templates/`
- 设置输出目录:`application/{app_name}/`
- 初始化 Jinja2 模板环境(`trim_blocks=True`, `lstrip_blocks=True`)
## generate() 主方法
### 执行流程
```
步骤1: 创建输出目录 application/{app_name}/
│
步骤2: 准备模板上下文 _prepare_context()
│ - 处理字段信息、选项、标识
│ - 分类字段:form_fields / list_fields / filter_fields
│
步骤3: 渲染后端模板并写入文件
│ - models.py (ORM 模型)
│ - forms.py (Django 表单验证)
│ - services.py (业务逻辑层)
│ - views.py (视图层)
│ - urls.py (路由配置)
│ - apps.py (应用配置)
│ - admin.py (后台管理)
│
步骤3.5: 创建 __init__.py 和 migrations/__init__.py
│
步骤3.6: 更新 settings.py 的 INSTALLED_APPS
│ - 自动追加 'application.{app_name}'
│
步骤3.7: 更新 application/urls.py
│ - 自动追加路由配置
│
步骤4: 渲染前端模板并写入文件
│ - ui/ 或 ui2/ 目录下的 Vue 组件
│ - API 接口文件
│
步骤5: 数据库迁移(仅交互模式)
│ - python manage.py makemigrations
│ - python manage.py migrate
│
步骤6: 创建菜单权限节点
- 主菜单节点(type=0)
- 8 个权限节点(type=1)
```
### 参数
| 参数 | 说明 |
|:----|:----|
| `auto` | 自动模式(True: 跳过交互确认,直接执行迁移和创建菜单) |
## 模板上下文
### _prepare_context()
准备后端模板的渲染上下文:
| 变量 | 类型 | 说明 |
|:----|:----|:----|
| `app_name` | str | 模块名(如 `example`) |
| `module_comment` | str | 中文名(如 `案例`) |
| `module_name` | str | 模块名称(下划线移除) |
| `model_class_name` | str | 类名(如 `Example`) |
| `model_class_name_camel` | str | 驼峰类名(首字母小写) |
| `route_prefix` | str | 路由前缀 |
| `permission_prefix` | str | 权限前缀(如 `sys:example`) |
| `display_field` | str | 显示字段(如 `name`) |
| `has_sort` | bool | 有排序字段 |
| `has_status` | bool | 有状态字段 |
| `has_unique_code` | bool | 有唯一编码字段 |
| `has_image_field` | bool | 有图片字段 |
| `has_rich_text_field` | bool | 有富文本字段 |
| `fields` | list | 全部字段 |
| `form_fields` | list | 表单字段 |
| `list_fields` | list | 列表显示字段 |
| `filter_fields` | list | 筛选字段 |
| `filterable_fields` | list | 可过滤字段 |
| `searchable_fields` | list | 可搜索字段 |
| `editable_fields` | list | 可编辑字段 |
### _prepare_vue_context()
在后端上下文基础上扩展前端专用变量:
| 变量 | 类型 | 说明 |
|:----|:----|:----|
| `api_path` | str | API 路径(如 `tool/example`) |
| `has_export` | bool | 有导出功能 |
| `is_tree_structure` | bool | 是否树形结构 |
| `parent_id_field` | str | 父级字段名 |
| `has_search_form` | bool | 显示搜索表单 |
| `show_selection` | bool | 显示复选框(树形结构) |
## 文件生成
### 后端文件
| 模板 | 输出路径 | 说明 |
|:----|:----|:----|
| `models.py.tpl` | `application/{name}/models.py` | ORM 模型 |
| `forms.py.tpl` | `application/{name}/forms.py` | Django 表单验证 |
| `services.py.tpl` | `application/{name}/services.py` | 业务逻辑层 |
| `views.py.tpl` | `application/{name}/views.py` | 视图层 |
| `urls.py.tpl` | `application/{name}/urls.py` | 路由配置 |
| `apps.py.tpl` | `application/{name}/apps.py` | 应用配置 |
| `admin.py.tpl` | `application/{name}/admin.py` | 后台管理 |
### 前端文件(普通列表)
| 模板 | 输出路径 |
|:----|:----|
| `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` |
### 前端文件(树状列表)
当表包含 `parent_id` / `pid` 字段时,自动切换为树形模板:
| 模板 | 输出路径 |
|:----|:----|
| `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` |
| `ui2/columns.ts.tpl` | `ui/src/views/tool/{name}/columns.ts` |
| `ui/api.ts.tpl` | `ui/src/api/tool/{name}.ts` |
树状列表与普通列表共用 `api.ts.tpl`。
## 自动注册
### 应用注册
`_update_installed_apps()` 在 `application/settings.py` 的 `INSTALLED_APPS` 列表末尾追加:
```python
'application.example', # 案例管理
```
幂等操作:如果已存在,跳过。
### 路由注册
`_update_main_urls()` 在 `application/urls.py` 的 `urlpatterns` 列表末尾追加:
```python
# 案例模块路由
# 访问地址: /example/
path('example/', include('application.example.urls')),
```
路由前缀支持下划线转斜杠:`order_item` -> `order/item/`。
幂等操作:如果路由已存在,跳过。
### 菜单创建
`_create_permission_nodes()` 在数据库中创建:
1. **主菜单**(type=0):模块入口菜单
- name: 模块中文名
- path: `/{menu_group}/{module_path}`
- component: `/{menu_group}/{module_path}/index`
- parent_id: 配置中的 `parent_menu_id`
2. **权限节点**(type=1)x 8 个:
| 排序 | 权限名称 | 权限标识 |
|:----|:----|:----|
| 1 | 查询分页 | `{prefix}:page` |
| 5 | 查询列表 | `{prefix}:list` |
| 10 | 查询详情 | `{prefix}:detail` |
| 15 | 添加 | `{prefix}:add` |
| 20 | 更新 | `{prefix}:update` |
| 25 | 设置状态 | `{prefix}:status` |
| 30 | 删除 | `{prefix}:delete` |
| 35 | 批量删除 | `{prefix}:batchDelete` |
幂等操作:如果主菜单已存在(path + type 匹配),更新信息并删除旧权限节点后重建。
## 总结
代码生成引擎根据配置字典,通过 Jinja2 模板渲染生成后端(models/forms/services/views/urls/apps/admin)和前端(index.vue/edit.vue/columns.ts/querySchemas.ts/api.ts)全套代码,生成后自动注册应用、路由和权限。