853940c795
Co-authored-by: Cursor <cursoragent@cursor.com>
895 lines
28 KiB
Markdown
895 lines
28 KiB
Markdown
# HoTime 代码生成
|
||
|
||
前置依赖:生成前请先满足 [数据库设计规范](DatabaseDesign_数据库设计规范.md)(表命名、外键、COMMENT、必有字段)。代码生成器依赖规范的表结构与字段备注,才能正确识别类型、选项、外键关联与显示标签。
|
||
|
||
`code` 包提供了 HoTime 框架的自动代码生成功能,能够根据数据库表结构自动生成 CRUD 接口代码和配置文件。
|
||
|
||
## 目录
|
||
|
||
- [一、功能概述](#一功能概述)
|
||
- [二、使用方法](#二使用方法)
|
||
- [三、配置体系](#三配置体系)
|
||
- [3.1 codeConfig](#31-codeconfig)
|
||
- [3.2 菜单权限配置(admin.json)](#32-菜单权限配置adminjson)
|
||
- [3.3 字段规则配置(rule.json)](#33-字段规则配置rulejson)
|
||
- [3.4 配置检查清单](#34-配置检查清单)
|
||
- [四、生成规则与产物](#四生成规则与产物)
|
||
- [4.1 默认字段规则](#41-默认字段规则)
|
||
- [4.2 数据类型映射](#42-数据类型映射)
|
||
- [4.3 字段备注解析](#43-字段备注解析)
|
||
- [4.4 外键关联](#44-外键关联)
|
||
- [4.5 生成的代码结构](#45-生成的代码结构)
|
||
- [4.6 多库与备注注意事项](#46-多库与备注注意事项)
|
||
- [4.7 最佳实践](#47-最佳实践)
|
||
- [五、相关文档](#五相关文档)
|
||
|
||
---
|
||
|
||
## 一、功能概述
|
||
|
||
代码生成器可以:
|
||
|
||
1. **自动读取数据库表结构** - 支持 MySQL、SQLite 和达梦 DM8
|
||
2. **生成 CRUD 接口** - 增删改查、搜索、分页
|
||
3. **生成配置文件** - 表字段配置、菜单配置、权限配置
|
||
4. **智能字段识别** - 根据字段名自动识别类型和权限
|
||
5. **支持表关联** - 自动识别外键关系
|
||
|
||
配置体系概览:
|
||
|
||
```
|
||
config.json
|
||
└── codeConfig[] # 代码生成配置数组(支持多套)
|
||
├── config # 菜单权限配置文件路径(如 admin.json)
|
||
├── configDB # 数据库生成的完整配置
|
||
├── rule # 字段规则配置文件路径(如 rule.json)
|
||
├── table # 管理员表名
|
||
├── name # 生成代码的包名
|
||
└── mode # 生成模式
|
||
```
|
||
|
||
---
|
||
|
||
## 二、使用方法
|
||
|
||
### 2.1 基础配置
|
||
|
||
在 `config.json` 中配置开发模式与代码生成:
|
||
|
||
```json
|
||
{
|
||
"mode": 2,
|
||
"codeConfig": [
|
||
{
|
||
"table": "admin",
|
||
"config": "config/admin.json",
|
||
"rule": "config/rule.json",
|
||
"mode": 0
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### 2.2 启动应用
|
||
|
||
```go
|
||
package main
|
||
|
||
import (
|
||
. "code.hoteas.com/golang/hotime"
|
||
. "code.hoteas.com/golang/hotime/common"
|
||
)
|
||
|
||
func main() {
|
||
app := Init("config/config.json")
|
||
|
||
// 代码生成器在 Init 时自动执行
|
||
// 会读取数据库结构并生成配置
|
||
|
||
app.Run(Router{
|
||
// 路由配置
|
||
})
|
||
}
|
||
```
|
||
|
||
### 2.3 开发模式
|
||
|
||
在 `config.json` 中设置 `"mode": 2`(开发模式)时:
|
||
|
||
- 自动读取数据库表结构
|
||
- 自动生成/更新配置文件
|
||
- 自动生成代码(如果 `codeConfig.mode=1`)
|
||
|
||
### 2.4 推荐开发流程
|
||
|
||
1. 设置 `config.json` 中 `mode: 2`(开发模式)
|
||
2. 按 [数据库设计规范](DatabaseDesign_数据库设计规范.md) 设计表结构并添加字段备注
|
||
3. 启动应用,自动生成配置
|
||
4. 检查生成的配置文件,按需调整
|
||
5. 生产环境改为 `mode: 0`
|
||
|
||
---
|
||
|
||
## 三、配置体系
|
||
|
||
### 3.1 codeConfig
|
||
|
||
#### 配置结构
|
||
|
||
```json
|
||
{
|
||
"codeConfig": [
|
||
{
|
||
"config": "config/admin.json",
|
||
"configDB": "config/adminDB.json",
|
||
"mode": 0,
|
||
"name": "",
|
||
"rule": "config/rule.json",
|
||
"table": "admin"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
#### 配置项说明
|
||
|
||
| 字段 | 类型 | 必须 | 说明 |
|
||
|------|------|------|------|
|
||
| `table` | string | ✅ | 管理员/用户表名,用于身份验证和权限控制 |
|
||
| `config` | string | ✅ | 菜单权限配置文件路径,用于定义菜单结构、权限控制 |
|
||
| `configDB` | string | ❌ | 代码生成器输出的完整配置文件(有则每次自动生成) |
|
||
| `rule` | string | ❌ | 字段规则配置文件路径,无则使用默认规则 |
|
||
| `name` | string | ❌ | 生成的代码包名和目录名,为空则不生成独立代码文件 |
|
||
| `mode` | int | ❌ | 生成模式:0=仅配置不生成代码(内嵌模式),非 0=生成代码文件 |
|
||
|
||
#### 运行模式
|
||
|
||
- **mode=0(内嵌模式)**:不生成独立代码文件,使用框架内置的通用控制器
|
||
- **mode≠0(生成模式)**:为每张表生成独立的 Go 控制器文件
|
||
|
||
#### 多配置支持
|
||
|
||
可以配置多个独立的代码生成实例,适用于多端场景:
|
||
|
||
```json
|
||
{
|
||
"codeConfig": [
|
||
{
|
||
"config": "config/admin.json",
|
||
"table": "admin",
|
||
"rule": "config/rule.json"
|
||
},
|
||
{
|
||
"config": "config/user.json",
|
||
"table": "user",
|
||
"rule": "config/rule.json"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3.2 菜单权限配置(admin.json)
|
||
|
||
#### 配置文件更新机制
|
||
|
||
- **首次运行**:代码生成器会根据数据库表结构自动创建配置文件(如 admin.json)
|
||
- **后续运行**:配置文件**不会自动更新**,避免覆盖手动修改的内容
|
||
- **重新生成**:如需重新生成,删除配置文件后重新运行即可
|
||
- **参考更新**:可参考 `configDB` 指定的文件(如 adminDB.json)查看最新的数据库结构变化,手动调整配置
|
||
|
||
#### 完整配置结构
|
||
|
||
```json
|
||
{
|
||
"id": "唯一标识(自动生成)",
|
||
"name": "admin",
|
||
"label": "管理平台名称",
|
||
"labelConfig": { ... },
|
||
"menus": [ ... ],
|
||
"flow": { ... }
|
||
}
|
||
```
|
||
|
||
#### label / labelConfig
|
||
|
||
```json
|
||
{
|
||
"label": "HoTime管理平台",
|
||
"labelConfig": {
|
||
"show": "开启",
|
||
"add": "添加",
|
||
"delete": "删除",
|
||
"edit": "编辑",
|
||
"info": "查看详情",
|
||
"download": "下载清单"
|
||
}
|
||
}
|
||
```
|
||
|
||
| 操作 | 说明 |
|
||
|------|------|
|
||
| show | 显示/查看列表权限 |
|
||
| add | 添加数据权限 |
|
||
| delete | 删除数据权限 |
|
||
| edit | 编辑数据权限 |
|
||
| info | 查看详情权限 |
|
||
| download | 下载/导出权限 |
|
||
|
||
#### menus 配置
|
||
|
||
定义菜单结构,支持多级嵌套(目前只支持**两级菜单**):
|
||
|
||
```json
|
||
{
|
||
"menus": [
|
||
{
|
||
"label": "系统管理",
|
||
"name": "sys",
|
||
"icon": "Setting",
|
||
"auth": ["show"],
|
||
"menus": [
|
||
{
|
||
"label": "用户管理",
|
||
"table": "user",
|
||
"auth": ["show", "add", "delete", "edit", "info", "download"]
|
||
},
|
||
{
|
||
"label": "角色管理",
|
||
"table": "role",
|
||
"auth": ["show", "add", "delete", "edit", "info"]
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"label": "文章管理",
|
||
"table": "article",
|
||
"icon": "Document",
|
||
"auth": ["show", "add", "edit", "info"]
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| label | string | 菜单显示名称 |
|
||
| name | string | 菜单标识(用于分组,不绑定表时使用) |
|
||
| table | string | 绑定的数据表名(用于自动生成 CRUD) |
|
||
| icon | string | 菜单图标名称(Element Plus 图标名,如 `Setting`、`User`、`Document`) |
|
||
| auth | array | 权限数组,定义该菜单/表拥有的操作权限 |
|
||
| menus | array | 子菜单数组(支持嵌套) |
|
||
|
||
**name vs table**:
|
||
|
||
- **table**:绑定数据表,拥有该表的增删查改等权限,自动生成 CRUD 接口
|
||
- **name**:自定义功能标识,不绑定表,前端根据 name 和 auth 显示自定义内容(如首页 home、仪表盘 dashboard)
|
||
- 配置了 `menus` 子菜单 → 作为分组
|
||
- 没有 `menus` → 作为独立自定义功能入口
|
||
|
||
```json
|
||
// 使用 table:绑定数据表
|
||
{ "label": "用户管理", "table": "user", "auth": ["show", "add", "edit", "delete"] }
|
||
|
||
// 使用 name:自定义功能(无子菜单)
|
||
{ "label": "首页", "name": "home", "icon": "House", "auth": ["show"] }
|
||
|
||
// 使用 name:分组功能(有子菜单)
|
||
{ "label": "系统管理", "name": "sys", "icon": "Setting", "auth": ["show"], "menus": [...] }
|
||
```
|
||
|
||
**自动分组规则**:代码生成器会根据表名的 `_` 分词自动分组:
|
||
|
||
- 表名 `sys_logs`、`sys_menus`、`sys_config` → 归入 `sys` 分组
|
||
- 表名 `article`、`article_tag` → 归入 `article` 分组
|
||
|
||
分组的显示名称(label)使用该分组下**第一张表的名字**,如果表有备注则使用备注名。
|
||
|
||
#### auth 配置
|
||
|
||
| 权限 | 对应接口 | 说明 |
|
||
|------|----------|------|
|
||
| show | /search | 列表查询 |
|
||
| add | /add | 新增数据 |
|
||
| delete | /remove | 删除数据 |
|
||
| edit | /update | 编辑数据 |
|
||
| info | /info | 查看详情 |
|
||
| download | /search?download=1 | 导出数据 |
|
||
|
||
auth 数组**可以自由增删**。新增的权限项会在前端菜单/功能中显示,并在角色管理(role)的权限设置中供管理员分配:
|
||
|
||
```json
|
||
{
|
||
"label": "文章管理",
|
||
"table": "article",
|
||
"auth": ["show", "add", "edit", "delete", "info", "publish", "audit", "top"]
|
||
}
|
||
```
|
||
|
||
上例中 `publish`(发布)、`audit`(审核)、`top`(置顶)为自定义权限。
|
||
|
||
#### flow 配置(数据权限)
|
||
|
||
flow 用于限制用户只能操作自己权限范围内的数据。
|
||
|
||
```json
|
||
{
|
||
"flow": {
|
||
"role": {
|
||
"table": "role",
|
||
"stop": true,
|
||
"sql": {
|
||
"id": "role_id"
|
||
}
|
||
},
|
||
"article": {
|
||
"table": "article",
|
||
"stop": false,
|
||
"sql": {
|
||
"admin_id": "id"
|
||
}
|
||
},
|
||
"org": {
|
||
"table": "org",
|
||
"stop": false,
|
||
"sql": {
|
||
"parent_ids[~]": ",org_id,"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| table | string | 表名 |
|
||
| stop | bool | 是否禁止修改自身关联的数据 |
|
||
| sql | object | 数据过滤条件,自动填充查询/操作条件 |
|
||
|
||
**stop**:防止用户修改自己当前关联的敏感数据。例如当前用户 `role_id = 1`,配置 `stop: true` 后,不能修改 role 表中 `id = 1` 的记录,但可修改其他 role(若有权限)。典型用途:防止用户提升自己的角色权限、修改自己所属组织。
|
||
|
||
**sql**:格式为 `{ "目标表字段": "当前用户字段" }`。
|
||
|
||
| 格式 | 含义 | SQL 等价 |
|
||
|------|------|----------|
|
||
| `"field": "user_field"` | 精确匹配 | `field = 用户.user_field` |
|
||
| `"field[~]": ",value,"` | 模糊匹配 | `field LIKE '%,value,%'` |
|
||
|
||
示例效果(当前用户 `{ "id": 5, "role_id": 2, "org_id": 10 }`):
|
||
|
||
| 表 | 查询条件 | stop 效果 |
|
||
|-----|----------|-----------|
|
||
| role | `WHERE id = 2` | 不能修改 id=2 的角色 |
|
||
| article | `WHERE admin_id = 5` | 可以修改自己的文章 |
|
||
| org | `WHERE parent_ids LIKE '%,10,%'` | 可以修改下级组织 |
|
||
|
||
#### 完整 admin.json 示例
|
||
|
||
```json
|
||
{
|
||
"id": "74a8a59407fa7d6c7fcdc85742dbae57",
|
||
"name": "admin",
|
||
"label": "后台管理系统",
|
||
"labelConfig": {
|
||
"show": "开启",
|
||
"add": "添加",
|
||
"delete": "删除",
|
||
"edit": "编辑",
|
||
"info": "查看详情",
|
||
"download": "下载清单"
|
||
},
|
||
"menus": [
|
||
{
|
||
"label": "系统管理",
|
||
"name": "sys",
|
||
"icon": "Setting",
|
||
"auth": ["show"],
|
||
"menus": [
|
||
{
|
||
"label": "日志管理",
|
||
"table": "logs",
|
||
"auth": ["show", "download"]
|
||
},
|
||
{
|
||
"label": "角色管理",
|
||
"table": "role",
|
||
"auth": ["show", "add", "delete", "edit", "info"]
|
||
},
|
||
{
|
||
"label": "组织管理",
|
||
"table": "org",
|
||
"auth": ["show", "add", "delete", "edit", "info"]
|
||
},
|
||
{
|
||
"label": "员工管理",
|
||
"table": "admin",
|
||
"auth": ["show", "add", "delete", "edit", "info", "download"]
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"flow": {
|
||
"admin": {
|
||
"table": "admin",
|
||
"stop": false,
|
||
"sql": { "role_id": "role_id" }
|
||
},
|
||
"role": {
|
||
"table": "role",
|
||
"stop": true,
|
||
"sql": { "admin_id": "id", "id": "role_id" }
|
||
},
|
||
"org": {
|
||
"table": "org",
|
||
"stop": false,
|
||
"sql": { "admin_id": "id" }
|
||
},
|
||
"logs": {
|
||
"table": "logs",
|
||
"stop": false,
|
||
"sql": {}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
> 说明:生成器还会在配置中产生 `tables`(字段列、搜索项等)。首次生成可参考 `configDB`(如 adminDB.json)中的结构;持久化自定义请写入 `config` 指定的文件(如 admin.json),因 configDB 会在每次启动时重新生成。
|
||
|
||
---
|
||
|
||
### 3.3 字段规则配置(rule.json)
|
||
|
||
定义字段在增删改查操作中的默认行为。
|
||
|
||
#### 配置结构
|
||
|
||
```json
|
||
[
|
||
{
|
||
"name": "id",
|
||
"add": false,
|
||
"edit": false,
|
||
"info": true,
|
||
"list": true,
|
||
"must": false,
|
||
"strict": true,
|
||
"type": ""
|
||
},
|
||
{
|
||
"name": "status",
|
||
"list": true,
|
||
"add": true,
|
||
"edit": true,
|
||
"info": true,
|
||
"must": false,
|
||
"strict": false,
|
||
"type": "select"
|
||
},
|
||
{
|
||
"name": "user.special_field",
|
||
"list": true,
|
||
"add": true,
|
||
"edit": true,
|
||
"info": true,
|
||
"type": "text",
|
||
"strict": true
|
||
}
|
||
]
|
||
```
|
||
|
||
#### 字段属性说明
|
||
|
||
| 属性 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| name | string | 字段名或关键词;支持 `表名.字段名` 精确匹配 |
|
||
| add | bool | 新增时是否显示 |
|
||
| edit | bool | 编辑时是否显示 |
|
||
| info | bool | 详情页是否显示 |
|
||
| list | bool | 列表页是否显示 |
|
||
| must | bool | 是否必填(见下方) |
|
||
| strict | bool | 是否严格匹配字段名(true=完全匹配,false=包含匹配) |
|
||
| type | string | 字段类型(影响前端控件和数据处理) |
|
||
|
||
#### must 必填字段规则
|
||
|
||
**自动识别**:
|
||
|
||
1. **MySQL**:字段为 `NOT NULL`(`IS_NULLABLE='NO'`)时自动 `must=true`
|
||
2. **SQLite**:字段为主键(`pk=1`)时自动 `must=true`
|
||
|
||
**规则覆盖**:`rule.json` 中的 `must` 会覆盖数据库自动识别结果。
|
||
|
||
**效果**:
|
||
|
||
- 前端:`must=true` 显示必填标记(*),提交时校验
|
||
- 后端:新增时若 `must=true` 字段为空,返回「请求参数不足」
|
||
|
||
#### type 类型说明
|
||
|
||
| 类型 | 说明 | 前端控件 |
|
||
|------|------|----------|
|
||
| (空) | 普通文本 | 文本输入框 |
|
||
| text | 文本 | 文本输入框 |
|
||
| number | 数字 | 数字输入框 |
|
||
| select | 选择 | 下拉选择框(根据注释自动生成选项) |
|
||
| time | 时间(datetime) | 日期时间选择器 |
|
||
| unixTime | 时间戳 | 日期时间选择器(存储为 Unix 时间戳) |
|
||
| password | 密码 | 密码输入框(自动 MD5 加密) |
|
||
| textArea | 多行文本 | 文本域 |
|
||
| image | 图片 | 图片上传 |
|
||
| file | 文件 | 文件上传 |
|
||
| money | 金额 | 金额输入框 |
|
||
| auth | 权限 | 权限树选择器 |
|
||
| form | 表单 | 动态表单 |
|
||
| index | 索引 | 隐藏字段(用于 parent_ids 等) |
|
||
| tree | 树形选择 | 树形选择器 |
|
||
| table | 动态表 | 表名选择器 |
|
||
| table_id | 动态表ID | 根据 table 字段动态关联 |
|
||
|
||
#### 内置字段规则(可在 rule.json 中覆盖)
|
||
|
||
**主键和索引**:
|
||
|
||
```json
|
||
{"name": "id", "add": false, "list": true, "edit": false, "info": true, "strict": true}
|
||
{"name": "sn", "add": false, "list": true, "edit": false, "info": true}
|
||
{"name": "parent_ids", "add": false, "list": false, "edit": false, "info": false, "type": "index", "strict": true}
|
||
{"name": "index", "add": false, "list": false, "edit": false, "info": false, "type": "index", "strict": true}
|
||
```
|
||
|
||
**层级关系**:
|
||
|
||
```json
|
||
{"name": "parent_id", "add": true, "list": true, "edit": true, "info": true}
|
||
{"name": "level", "add": false, "list": false, "edit": false, "info": true}
|
||
```
|
||
|
||
**时间字段**:
|
||
|
||
```json
|
||
{"name": "create_time", "add": false, "list": false, "edit": false, "info": true, "type": "time", "strict": true}
|
||
{"name": "modify_time", "add": false, "list": true, "edit": false, "info": true, "type": "time", "strict": true}
|
||
{"name": "time", "add": true, "list": true, "edit": true, "info": true, "type": "time"}
|
||
```
|
||
|
||
**状态字段**:
|
||
|
||
```json
|
||
{"name": "status", "add": true, "list": true, "edit": true, "info": true, "type": "select"}
|
||
{"name": "state", "add": true, "list": true, "edit": true, "info": true, "type": "select"}
|
||
{"name": "sex", "add": true, "list": true, "edit": true, "info": true, "type": "select"}
|
||
```
|
||
|
||
**敏感字段**:
|
||
|
||
```json
|
||
{"name": "password", "add": true, "list": false, "edit": true, "info": false, "type": "password"}
|
||
{"name": "pwd", "add": true, "list": false, "edit": true, "info": false, "type": "password"}
|
||
{"name": "delete", "add": false, "list": false, "edit": false, "info": false}
|
||
{"name": "version", "add": false, "list": false, "edit": false, "info": false}
|
||
```
|
||
|
||
**媒体字段**:
|
||
|
||
```json
|
||
{"name": "image", "add": true, "list": false, "edit": true, "info": true, "type": "image"}
|
||
{"name": "img", "add": true, "list": false, "edit": true, "info": true, "type": "image"}
|
||
{"name": "avatar", "add": true, "list": false, "edit": true, "info": true, "type": "image"}
|
||
{"name": "icon", "add": true, "list": false, "edit": true, "info": true, "type": "image"}
|
||
{"name": "file", "add": true, "list": false, "edit": true, "info": true, "type": "file"}
|
||
```
|
||
|
||
**文本字段**:
|
||
|
||
```json
|
||
{"name": "info", "add": true, "list": false, "edit": true, "info": true, "type": "textArea"}
|
||
{"name": "content", "add": true, "list": false, "edit": true, "info": true, "type": "textArea"}
|
||
{"name": "description", "add": true, "list": false, "edit": true, "info": true}
|
||
{"name": "note", "add": true, "list": false, "edit": true, "info": true}
|
||
{"name": "address", "add": true, "list": true, "edit": true, "info": true}
|
||
```
|
||
|
||
**特殊字段**:
|
||
|
||
```json
|
||
{"name": "amount", "add": true, "list": true, "edit": true, "info": true, "type": "money", "strict": true}
|
||
{"name": "auth", "add": true, "list": false, "edit": true, "info": true, "type": "auth", "strict": true}
|
||
{"name": "rule", "add": true, "list": true, "edit": true, "info": true, "type": "form"}
|
||
{"name": "table", "add": false, "list": true, "edit": false, "info": true, "type": "table"}
|
||
{"name": "table_id", "add": false, "list": true, "edit": false, "info": true, "type": "table_id"}
|
||
```
|
||
|
||
#### 自定义字段规则
|
||
|
||
```json
|
||
[
|
||
{
|
||
"name": "company_name",
|
||
"add": true,
|
||
"edit": true,
|
||
"info": true,
|
||
"list": true,
|
||
"must": true,
|
||
"strict": true,
|
||
"type": ""
|
||
},
|
||
{
|
||
"name": "user.nickname",
|
||
"add": true,
|
||
"edit": true,
|
||
"info": true,
|
||
"list": true,
|
||
"strict": true,
|
||
"type": ""
|
||
}
|
||
]
|
||
```
|
||
|
||
---
|
||
|
||
### 3.4 配置检查清单
|
||
|
||
#### codeConfig
|
||
|
||
- [ ] config 文件路径正确
|
||
- [ ] rule 文件路径正确
|
||
- [ ] table 指定的管理员表存在
|
||
|
||
#### 菜单权限配置
|
||
|
||
- [ ] 所有 table 指向的表在数据库中存在
|
||
- [ ] auth 数组包含需要的权限
|
||
- [ ] menus 结构正确(有子菜单用 name,无子菜单用 table)
|
||
- [ ] flow 配置的 sql 条件字段存在
|
||
|
||
#### 字段规则配置
|
||
|
||
- [ ] strict=true 的规则字段名完全匹配
|
||
- [ ] type 类型与前端控件需求一致
|
||
- [ ] 敏感字段(password 等)的 list 和 info 为 false
|
||
|
||
---
|
||
|
||
## 四、生成规则与产物
|
||
|
||
### 4.1 默认字段规则
|
||
|
||
代码生成器内置的字段识别一览(完整内置规则见 [3.3](#33-字段规则配置rulejson)):
|
||
|
||
| 字段名 | 列表显示 | 新增 | 编辑 | 详情 | 类型 |
|
||
|--------|----------|------|------|------|------|
|
||
| `id` | ✅ | ❌ | ❌ | ✅ | number |
|
||
| `name` | ✅ | ✅ | ✅ | ✅ | text |
|
||
| `status` | ✅ | ✅ | ✅ | ✅ | select |
|
||
| `create_time` | ❌ | ❌ | ❌ | ✅ | time |
|
||
| `modify_time` | ✅ | ❌ | ❌ | ✅ | time |
|
||
| `password` | ❌ | ✅ | ✅ | ❌ | password |
|
||
| `image/img/avatar` | ❌ | ✅ | ✅ | ✅ | image |
|
||
| `file` | ❌ | ✅ | ✅ | ✅ | file |
|
||
| `content/info` | ❌ | ✅ | ✅ | ✅ | textArea |
|
||
| `parent_id` | ✅ | ✅ | ✅ | ✅ | number |
|
||
| `parent_ids/index` | ❌ | ❌ | ❌ | ❌ | index |
|
||
| `delete` | ❌ | ❌ | ❌ | ❌ | - |
|
||
|
||
### 4.2 数据类型映射
|
||
|
||
| 数据库类型 | 生成类型 |
|
||
|------------|----------|
|
||
| `int`, `integer`, `float`, `double`, `decimal` | number |
|
||
| `char`, `varchar`, `text`, `blob` | text |
|
||
| `date`, `datetime`, `time`, `timestamp`, `year` | time |
|
||
|
||
### 4.3 字段备注解析
|
||
|
||
字段 COMMENT 的完整语法、选项写法与设计约定,以 [数据库设计规范](DatabaseDesign_数据库设计规范.md) 为准。此处仅说明生成器如何消费备注。
|
||
|
||
支持从数据库字段备注中提取标签、提示与选项(括号支持 `()`、`()`、`{}`):
|
||
|
||
```sql
|
||
-- 格式: 标签名(提示信息):选项1-名称1,选项2-名称2
|
||
status TINYINT COMMENT '状态(用户账号状态):0-禁用,1-启用'
|
||
parent_id INT COMMENT '父级ID(顶级为NULL)'
|
||
phone VARCHAR(20) COMMENT '手机号(请输入11位手机号)'
|
||
```
|
||
|
||
生成的配置示例:
|
||
|
||
```json
|
||
{
|
||
"name": "status",
|
||
"label": "状态",
|
||
"type": "select",
|
||
"ps": "用户账号状态",
|
||
"options": [
|
||
{"name": "禁用", "value": "0"},
|
||
{"name": "启用", "value": "1"}
|
||
]
|
||
}
|
||
```
|
||
|
||
`ps` 字段在前端的展示效果:
|
||
|
||
- 编辑/新增页面:输入框右侧灰色小字提示
|
||
- 表格/详情页面:鼠标悬停字段名时气泡提示
|
||
|
||
### 4.4 外键关联
|
||
|
||
代码生成器会自动识别 `_id` 结尾的字段作为外键:
|
||
|
||
```sql
|
||
CREATE TABLE user (
|
||
id INT PRIMARY KEY,
|
||
name VARCHAR(50),
|
||
role_id INT, -- 自动关联 role 表
|
||
org_id INT -- 自动关联 org 表
|
||
);
|
||
```
|
||
|
||
生成的配置会包含 `link` 和 `value` 字段:
|
||
|
||
```json
|
||
{
|
||
"name": "role_id",
|
||
"type": "number",
|
||
"label": "角色",
|
||
"link": "role",
|
||
"value": "name"
|
||
}
|
||
```
|
||
|
||
`parent_id` 会被识别为树形结构的父级关联:
|
||
|
||
```json
|
||
{
|
||
"name": "parent_id",
|
||
"type": "number",
|
||
"label": "上级",
|
||
"link": "org",
|
||
"value": "name"
|
||
}
|
||
```
|
||
|
||
表命名、外键命名与 COMMENT 约定见 [数据库设计规范](DatabaseDesign_数据库设计规范.md)。
|
||
|
||
#### 树形表查询参数(parent_id / showself / showall)
|
||
|
||
带 `parent_id` 列的表,通用 CRUD 的 `search` 接口支持树查询参数,语义如下(`code/makecode.go` 树节点分支):
|
||
|
||
| 请求参数组合 | WHERE 语义 | 典型场景 |
|
||
| --- | --- | --- |
|
||
| 不传 `parent_id` 或 `parent_id=0` | `id=当前用户锚点 OR parent_id IS NULL`(返回根层) | 树侧栏根节点加载 |
|
||
| `parent_id=X` | `parent_id=X`,仅直接子级 | 树节点懒加载展开 |
|
||
| `parent_id=X&showall=1` | `parent_ids LIKE '%,X,%'`,X 及其全部子孙(X 自身的 parent_ids 含 `,X,`) | 列表按树节点过滤 |
|
||
| `parent_id=X&showall=1&showself=1` | 在 showall 基础上再 `OR id=X`,显式保证含 X 自身 | 管理端列表树筛选(Table.vue) |
|
||
|
||
**规则**:`showself=1` 仅在 `showall=1` 时生效。普通子级查询(仅 `parent_id=X`)**不会**把 id=X 的行本身混入结果——否则前端树会把节点当作自己的子级,造成无限嵌套(历史缺陷,已修复;回归用例见 `example/app/makecode_tree_test.go`,`go test ./app/ -count=1 -run 'TestApi/admin/department/search'`)。
|
||
|
||
#### 通用列表字段筛选语义(text 类型只走模糊匹配)
|
||
|
||
通用 CRUD 的 `search` 接口为每个 `list` 可见字段自动生成筛选条件(`code/makecode.go` `(*MakeCode).Search`),按字段最终生效的 `type`(见 [4.2 数据类型映射](#42-数据类型映射),可被 [3.3 字段规则配置(rule.json)](#33-字段规则配置rulejson) 覆盖)分两种语义:
|
||
|
||
| 字段 type | 请求 `?字段名=值` 的 WHERE 语义 | 说明 |
|
||
| --- | --- | --- |
|
||
| 含 `"text"` 子串(`text`/`textArea`) | `字段名 LIKE '%值%'`(模糊,仅此一条) | 前端筛选框允许只填部分关键词 |
|
||
| 其他(`number`/`select`/`time`/`money`… 等非 text) | `字段名 = 值`(精确等值) | 维持现状不变 |
|
||
|
||
**规则**:文本类型字段**只生成模糊匹配条件,不再叠加同名等值条件**。历史缺陷:曾对所有 list 字段先生成等值条件 `字段名=值`,再对 text 类型**额外**叠加模糊条件 `字段名[~]=值`,两者在 where 里以 AND 叠加——前端筛选框只传部分关键词时等值条件必不命中,AND 之后整条查询恒为空(下游"文本列筛选查不出数据"的通用根因)。已修复;`keyword`+`keywordtable` 全局关键词搜索逻辑不受影响。回归用例见 `example/app/makecode_tree_test.go` 的「文本字段部分关键词命中模糊匹配」「非文本字段等值筛选行为不变」两个用例,`go test ./app/ -count=1 -run 'TestApi/admin/department/search'`。
|
||
|
||
### 4.5 生成的代码结构
|
||
|
||
#### 内嵌模式 (mode=0)
|
||
|
||
不生成代码文件,使用框架内置控制器,只生成配置文件:
|
||
|
||
```
|
||
config/
|
||
├── admin.json # 接口/菜单权限配置
|
||
├── adminDB.json # 数据库结构配置(可选)
|
||
└── rule.json # 字段规则
|
||
```
|
||
|
||
#### 生成模式 (mode≠0)
|
||
|
||
生成独立的控制器代码:
|
||
|
||
```
|
||
admin/ # 生成的包目录(由 codeConfig.name 决定)
|
||
├── init.go # 包初始化和路由注册
|
||
├── user.go # user 表控制器
|
||
├── role.go # role 表控制器
|
||
└── ... # 其他表控制器
|
||
```
|
||
|
||
#### 生成的控制器结构
|
||
|
||
```go
|
||
package admin
|
||
|
||
var userCtr = Ctr{
|
||
"info": func(that *Context) {
|
||
// 查询单条记录
|
||
},
|
||
"add": func(that *Context) {
|
||
// 新增记录
|
||
},
|
||
"update": func(that *Context) {
|
||
// 更新记录
|
||
},
|
||
"remove": func(that *Context) {
|
||
// 删除记录
|
||
},
|
||
"search": func(that *Context) {
|
||
// 搜索列表(分页)
|
||
},
|
||
}
|
||
```
|
||
|
||
### 4.6 多库与备注注意事项
|
||
|
||
#### 达梦 DM8
|
||
|
||
代码生成器已原生支持达梦 DM8,会自动读取表结构和字段备注。注意:
|
||
|
||
- 表注释通过 `COMMENT ON TABLE` 单独设置,建表后需额外执行
|
||
- 字段备注通过 `COMMENT ON COLUMN` 设置
|
||
- 已对 DM 的 `USER_TAB_COLUMNS` 与 MySQL `information_schema` 差异做兼容
|
||
|
||
```sql
|
||
COMMENT ON TABLE "user" IS '用户管理';
|
||
COMMENT ON COLUMN "user"."state" IS '状态:0-正常,1-异常,2-隐藏';
|
||
COMMENT ON COLUMN "user"."name" IS '用户名';
|
||
```
|
||
|
||
#### SQLite 备注替代方案
|
||
|
||
SQLite 不支持表/字段 COMMENT,生成器会使用表名/字段名作为默认显示名称。可利用配置覆盖机制手动设置:
|
||
|
||
1. 首次运行生成配置文件(如 admin.json)
|
||
2. 在菜单中设置表的 `label`
|
||
3. 在 `tables.表名.columns` 中设置字段 `label`、`ps`、`options` 等
|
||
|
||
```json
|
||
{
|
||
"tables": {
|
||
"user": {
|
||
"label": "用户管理",
|
||
"columns": [
|
||
{
|
||
"name": "name",
|
||
"label": "用户名",
|
||
"ps": "请输入用户名",
|
||
"must": true
|
||
},
|
||
{
|
||
"name": "status",
|
||
"label": "状态",
|
||
"type": "select",
|
||
"options": [
|
||
{"name": "正常", "value": "0"},
|
||
{"name": "禁用", "value": "1"}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**注意**:`configDB` 文件每次启动会重新生成。持久化修改应写入 `config` 指定的文件(如 admin.json)。
|
||
|
||
### 4.7 最佳实践
|
||
|
||
1. **字段命名**:使用规范字段名(`id`、`name`、`status`、`create_time`、`modify_time`、`xxx_id`、`parent_id`、`avatar`、`content` 等),便于自动识别。完整约定见 [数据库设计规范](DatabaseDesign_数据库设计规范.md)。
|
||
2. **自定义扩展**:默认规则不足时,可修改 `rule.json`、使用生成模式后手动改代码,或直接调整配置文件中的字段属性。
|
||
3. **生产环境**:开发用 `mode: 2`,上线改为 `mode: 0`,避免运行时反复改写配置/代码。
|
||
|
||
---
|
||
|
||
## 五、相关文档
|
||
|
||
- [数据库设计规范](DatabaseDesign_数据库设计规范.md)(代码生成前置依赖)
|
||
- [HoTimeDB 使用说明](HoTimeDB_使用说明.md)
|
||
- [快速上手](QuickStart_快速上手.md)
|
||
- [Common 工具类](Common_工具类.md)
|