代码生成脚本(0.generate.sh)

2 阅读3分钟

代码生成脚本(scripts/dev/0.generate.sh

1. 说明

scripts/dev/0.generate.sh 是一个面向业务模块快速初始化的编排脚本。
通过一次执行,串联生成并补齐:

  • 数据模型(repository models)
  • API 协议与服务代码
  • RPC 协议与服务代码
  • API/RPC 逻辑模板代码
  • 操作日志类型
  • 权限定义及 handler 权限替换
  • 前端 TS/TSX 模块模板代码

可快速生成一套前后端 CRUD 模块。


2. 使用前准备

在执行 0.generate.sh 前,需要先完成两件事:

  1. templates/sql/ 下创建表结构 SQL 文件,例如:templates/sql/users.sql
  2. 修改 0.generate.sh 中以下变量:
rpc_sev_client='Backend'
rpc_sev_module='BackendService'
model_name_zh='用户'
model_name='user'
model_names='users'

变量含义:

  • rpc_sev_client:API 调用 RPC 的客户端名(用于 API logic/handler 模板替换)
  • rpc_sev_module:RPC proto 内目标 service 名(例如 service BackendService {}
  • model_name_zh:中文模块名(日志、权限展示文案)
  • model_name:英文单数(如 user
  • model_names:英文复数/模块目录名(如 users

3. 执行方式

在项目根目录执行:

cd scripts/dev && bash 0.generate.sh

脚本会自动 source ./constants.sh,并完成 goctl/tool 校验(含 goctl 环境检查)。


4. 执行流程(按顺序)

0.generate.sh 依次调用多个子脚本,下面是每一步的输入、动作与结果。

Step 1:生成 model(1.sev-db.sh

调用:

bash ./1.sev-db.sh -name "$model_names"

主要动作:

  • 读取 templates/sql/${model_names}.sql
  • 使用 sql2gorm 生成 model
  • 输出/更新目录:core/repositories/models/${model_names}/
    • model.go(结构体与模型方法)
    • variables.go(字段常量、主键常量、Columns)
    • data.go(Item 转换模板,首次生成)
    • db.go(DB foundation 封装,首次生成)

说明:

  • 会临时修改 SQL(去掉 DEFAULT (JSON_ARRAY()))后恢复原文件
  • 会自动插入 ToMap/Columns/PrimaryKey/TableName/Correction/... 等通用方法

Step 2:注册 model 到 db service context(set-db-model.sh

调用:

bash ./set-db-model.sh -name "$model_names" -name-zh "$model_name_zh"

主要动作:

  • 确保 core/app/sev/db/internal/svc/service_context.go 中存在:
    • model import
    • ${PascalModel}Model *${model_names}.DB 字段
    • NewServiceContext 内对应初始化

结果:DB 服务上下文可以直接访问新模型。

Step 3:追加 API 描述(set-api.sh

调用:

bash ./set-api.sh -path ${MAIN_PATH}/templates/apis/backend-api.api -name $model_name -names $model_names -name-zh $model_name_zh

主要动作:

  • templates/apis/backend-api.api 追加模块 CRUD 路由定义(Create/Update/List/Row/Delete)
  • AuthMiddleware 和 group($model_names
  • 若已存在同类片段则跳过

结果:API 源描述文件具备新模块接口定义。

Step 4:生成 API 服务代码(2.sev-api.sh

调用:

bash ./2.sev-api.sh -name "backend"

主要动作:

  • goctl api go 基于 templates/apis/backend-api.api 生成/刷新 core/app/sev/backend
  • 期间临时替换默认 handler/logic 模板为自定义模板
  • 生成后恢复模板文件
  • 处理入口与配置:
    • backend.go -> main.go(若需要)
    • etc/backend-api.yaml -> etc/.backend-api.yaml

结果:backend API 项目生成完成(含新增接口骨架)。

Step 5:补齐 RPC proto 方法(set-db-proto.sh

调用:

bash ./set-db-proto.sh -path ${MAIN_PATH}/core/app/sev/db/db.proto -name $model_name -names $model_names -name-zh $model_name_zh -sev $rpc_sev_module

主要动作:

  • db.protoservice ${rpc_sev_module} 内补充缺失方法:
    • ${Model}Create
    • ${Model}Delete
    • ${Model}Update
    • ${Model}Row
    • ${Models}(列表)

结果:RPC 协议层具备新模块 CRUD 方法签名。

Step 6:生成 RPC 代码(3.sev-rpc.sh

调用:

bash ./3.sev-rpc.sh -name "db"

主要动作:

  • 基于 core/app/sev/db/db.proto 执行 goctl rpc protoc ...
  • 生成/刷新 core/app/sev/db 下 rpc 相关代码
  • 处理入口与配置:
    • db.go -> main.go
    • etc/db.yaml -> etc/.db-rpc.yaml

结果:RPC 服务代码与 proto 同步。

Step 7:生成 RPC 业务逻辑模板(5.sev-rpc-logic.sh

调用:

bash ./5.sev-rpc-logic.sh -sev-name "db" -module $rpc_sev_module -name $model_name -names $model_names -model-name $model_names

主要动作:

  • 使用自定义模板创建 db rpc 逻辑文件:
    • ${model_name}_create_logic.go
    • ${model_name}_delete_logic.go
    • ${model_name}_update_logic.go
    • ${model_names}_logic.go
    • ${model_name}_row_logic.go
  • 执行模板变量替换并格式化

结果:RPC 逻辑层生成标准 CRUD 模板代码。

Step 8:生成 API 逻辑与 handler 模板(4.sev-api-rpc-logic.sh

调用:

bash ./4.sev-api-rpc-logic.sh -sev-name "db" -module $rpc_sev_module -name $model_name -names $model_names -model-name $model_names -service-client $rpc_sev_client

主要动作:

  • core/app/sev/backend/internal/logic/${model_names} 生成 5 个 logic 文件
  • core/app/sev/backend/internal/handler/${model_names} 生成 5 个 handler 文件
  • 替换 ServiceClient/模块名/日志类型等模板变量

结果:API 层与 RPC 调用逻辑骨架全部补齐。

Step 9:注册操作日志类型(set-operation-type.sh

调用:

bash ./set-operation-type.sh -name $model_name -name-zh $model_name_zh

主要动作:

  • 修改 core/repositories/models/system-operation-logs/data.go
  • 增加该模块的 Create/Update/Delete 操作类型常量与显示文案

结果:新模块操作纳入统一操作日志类型系统。

Step 10:追加权限并回填 handler 权限(set-permissions.sh

调用:

output=$(bash ./set-permissions.sh -name-zh $model_name_zh -name $model_names -server-name "backend")

主要动作:

  • 修改权限定义文件:
    • core/common/source/permissions/backend.go
    • core/common/source/permissions/frontend.go
  • 自动生成新的权限 ID 段(如 P_0_xxP_1_xx
  • 回填 API handler 中 permissions.TODO 为具体权限常量
  • 输出:
    • backend_permissions_id=...
    • frontend_permissions_id=...

结果:后端权限树、前端权限树、接口权限绑定三者打通。

Step 11:生成前端 TSX 模板代码(set-tsx.sh

调用:

bash ./set-tsx.sh -name $model_name -names $model_names -backend-permissions $backend_permissions_id -frontend-permissions $frontend_permissions_id -model-path "${SERVER_REPOSITORIES_PATH}/models/${model_names}"

主要动作:

  • core/repositories/models/${model_names}/model.go 解析结构体字段
  • 自动映射为 TS 类型(number/string/boolean/any[]/...)
  • 套用模板输出到:
    • tmp/tsx/${model_names}/model.tsx
    • tmp/tsx/${model_names}/index.tsx
    • tmp/tsx/${model_names}/api.ts

结果:前端模块初始代码生成完成(位于 tmp/tsx/...,可再搬运到正式前端目录)。


5. 运行完成后的最终提示

脚本结束时会输出:

  • ✅ ${model_names} 模块创建完成
  • TODO: 数据表创建 autoMigrate: core/app/sev/db/internal/svc/init_database.go

这意味着:代码层面的模板已生成,但你仍需手动把新 model 接入 autoMigrate(或你的数据库迁移机制)。


6. 产物

执行成功后,通常会看到以下结果:

  • 新增/更新 model:core/repositories/models/${model_names}/
  • API 描述更新:templates/apis/backend-api.api
  • API 服务代码更新:core/app/sev/backend/...
  • RPC 协议与代码更新:core/app/sev/db/db.protocore/app/sev/db/...
  • 权限定义更新:core/common/source/permissions/backend.gofrontend.go
  • 操作日志类型更新:core/repositories/models/system-operation-logs/data.go
  • 前端模板输出:tmp/tsx/${model_names}/

7. 常见失败点排查

  • SQL 文件不存在:templates/sql/${model_names}.sql
  • db.proto 中不存在目标 service(rpc_sev_module 配错)
  • API 模板路径不正确(templates/apis/backend-api.api
  • goctl 或 sql2gorm 未安装/环境异常
  • 结构体命名不符合 set-tsx.sh 预期(会影响字段解析)

建议做法:先确认变量,再单独执行子脚本定位问题。


8. 示例(用户模块)

以用户模块为例:

  • SQL:templates/sql/users.sql
  • 变量:
    • model_name_zh='用户'
    • model_name='user'
    • model_names='users'
    • rpc_sev_module='BackendService'
    • rpc_sev_client='Backend'

执行后会得到:

  • 后端 users 的 model/api/rpc/logic/handler/权限/日志类型
  • 前端 tmp/tsx/users 模板代码