Files
hotime/docs/CodeGen_代码生成.md
T
hoteas 6b689f3a1b chore(logging): 更新日志重定向与捕获功能
- 在 .gitignore 中添加调试日志文件的忽略规则,避免不必要的调试信息被提交
- 修改 application.go 中的 stdout 重定向逻辑,使用 log.CaptureStream 以支持更灵活的日志捕获
- 更新 README 文档,增加对日志重定向功能的说明
2026-07-13 07:45:51 +08:00

26 KiB
Raw Blame History

HoTime 代码生成

前置依赖:生成前请先满足 数据库设计规范(表命名、外键、COMMENT、必有字段)。代码生成器依赖规范的表结构与字段备注,才能正确识别类型、选项、外键关联与显示标签。

code 包提供了 HoTime 框架的自动代码生成功能,能够根据数据库表结构自动生成 CRUD 接口代码和配置文件。

目录


一、功能概述

代码生成器可以:

  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 中配置开发模式与代码生成:

{
    "mode": 2,
    "codeConfig": [
        {
            "table": "admin",
            "config": "config/admin.json",
            "rule": "config/rule.json",
            "mode": 0
        }
    ]
}

2.2 启动应用

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.jsonmode: 2(开发模式)
  2. 数据库设计规范 设计表结构并添加字段备注
  3. 启动应用,自动生成配置
  4. 检查生成的配置文件,按需调整
  5. 生产环境改为 mode: 0

三、配置体系

3.1 codeConfig

配置结构

{
    "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 控制器文件

多配置支持

可以配置多个独立的代码生成实例,适用于多端场景:

{
    "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)查看最新的数据库结构变化,手动调整配置

完整配置结构

{
    "id": "唯一标识(自动生成)",
    "name": "admin",
    "label": "管理平台名称",
    "labelConfig": { ... },
    "menus": [ ... ],
    "flow": { ... }
}

label / labelConfig

{
    "label": "HoTime管理平台",
    "labelConfig": {
        "show": "开启",
        "add": "添加",
        "delete": "删除",
        "edit": "编辑",
        "info": "查看详情",
        "download": "下载清单"
    }
}
操作 说明
show 显示/查看列表权限
add 添加数据权限
delete 删除数据权限
edit 编辑数据权限
info 查看详情权限
download 下载/导出权限

menus 配置

定义菜单结构,支持多级嵌套(目前只支持两级菜单):

{
    "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 图标名,如 SettingUserDocument
auth array 权限数组,定义该菜单/表拥有的操作权限
menus array 子菜单数组(支持嵌套)

name vs table

  • table:绑定数据表,拥有该表的增删查改等权限,自动生成 CRUD 接口
  • name:自定义功能标识,不绑定表,前端根据 name 和 auth 显示自定义内容(如首页 home、仪表盘 dashboard
    • 配置了 menus 子菜单 → 作为分组
    • 没有 menus → 作为独立自定义功能入口
// 使用 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_logssys_menussys_config → 归入 sys 分组
  • 表名 articlearticle_tag → 归入 article 分组

分组的显示名称(label)使用该分组下第一张表的名字,如果表有备注则使用备注名。

auth 配置

权限 对应接口 说明
show /search 列表查询
add /add 新增数据
delete /remove 删除数据
edit /update 编辑数据
info /info 查看详情
download /search?download=1 导出数据

auth 数组可以自由增删。新增的权限项会在前端菜单/功能中显示,并在角色管理(role)的权限设置中供管理员分配:

{
    "label": "文章管理",
    "table": "article",
    "auth": ["show", "add", "edit", "delete", "info", "publish", "audit", "top"]
}

上例中 publish(发布)、audit(审核)、top(置顶)为自定义权限。

flow 配置(数据权限)

flow 用于限制用户只能操作自己权限范围内的数据。

{
    "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 示例

{
    "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

定义字段在增删改查操作中的默认行为。

配置结构

[
    {
        "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 NULLIS_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 中覆盖)

主键和索引

{"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}

层级关系

{"name": "parent_id", "add": true, "list": true, "edit": true, "info": true}
{"name": "level", "add": false, "list": false, "edit": false, "info": true}

时间字段

{"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"}

状态字段

{"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"}

敏感字段

{"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}

媒体字段

{"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"}

文本字段

{"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}

特殊字段

{"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"}

自定义字段规则

[
    {
        "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):

字段名 列表显示 新增 编辑 详情 类型
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 的完整语法、选项写法与设计约定,以 数据库设计规范 为准。此处仅说明生成器如何消费备注。

支持从数据库字段备注中提取标签、提示与选项(括号支持 ()(){}):

-- 格式: 标签名(提示信息):选项1-名称1,选项2-名称2
status TINYINT COMMENT '状态(用户账号状态):0-禁用,1-启用'
parent_id INT COMMENT '父级ID(顶级为NULL'
phone VARCHAR(20) COMMENT '手机号(请输入11位手机号)'

生成的配置示例:

{
    "name": "status",
    "label": "状态",
    "type": "select",
    "ps": "用户账号状态",
    "options": [
        {"name": "禁用", "value": "0"},
        {"name": "启用", "value": "1"}
    ]
}

ps 字段在前端的展示效果:

  • 编辑/新增页面:输入框右侧灰色小字提示
  • 表格/详情页面:鼠标悬停字段名时气泡提示

4.4 外键关联

代码生成器会自动识别 _id 结尾的字段作为外键:

CREATE TABLE user (
    id INT PRIMARY KEY,
    name VARCHAR(50),
    role_id INT,        -- 自动关联 role 表
    org_id INT          -- 自动关联 org 表
);

生成的配置会包含 linkvalue 字段:

{
    "name": "role_id",
    "type": "number",
    "label": "角色",
    "link": "role",
    "value": "name"
}

parent_id 会被识别为树形结构的父级关联:

{
    "name": "parent_id",
    "type": "number",
    "label": "上级",
    "link": "org",
    "value": "name"
}

表命名、外键命名与 COMMENT 约定见 数据库设计规范

4.5 生成的代码结构

内嵌模式 (mode=0)

不生成代码文件,使用框架内置控制器,只生成配置文件:

config/
├── admin.json      # 接口/菜单权限配置
├── adminDB.json    # 数据库结构配置(可选)
└── rule.json       # 字段规则

生成模式 (mode≠0)

生成独立的控制器代码:

admin/              # 生成的包目录(由 codeConfig.name 决定)
├── init.go         # 包初始化和路由注册
├── user.go         # user 表控制器
├── role.go         # role 表控制器
└── ...             # 其他表控制器

生成的控制器结构

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 差异做兼容
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 中设置字段 labelpsoptions
{
    "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. 字段命名:使用规范字段名(idnamestatuscreate_timemodify_timexxx_idparent_idavatarcontent 等),便于自动识别。完整约定见 数据库设计规范
  2. 自定义扩展:默认规则不足时,可修改 rule.json、使用生成模式后手动改代码,或直接调整配置文件中的字段属性。
  3. 生产环境:开发用 mode: 2,上线改为 mode: 0,避免运行时反复改写配置/代码。

五、相关文档