Skip to content

4.11 扩展性设计 ​

概述

扩展性来自两方面:一是标准变更的操作清单(按变更类型给出 checklist,不漏步骤、不变异架构);二是逃生舱挂点(基座装不下的需求有明确的合法出口)。本节按变更类型组织。

变更类型 Checklist ​

1. 给现有模块新增一个接口 ​

text
□ api/v1/{模块}.go:新增 {Mod}{Action}Req(内嵌 gmeta.Meta,path 带 /api 前缀、
  permission、log、logType)+ {Mod}{Action}Res
□ controller:同名方法,签名 func (c *CXxx) Action(ctx, req) (res, err)
□ service/{模块}.go:接口追加方法声明(手维护)
□ logic:实现方法(基座可表达走 spec 钩子,复杂走手写)
□ 权限节点同步:若 permission 为新码,需在菜单管理为角色勾选
  (或插入 goframe_menu type=1 节点)
□ go build ./... && gofmt;重启;/api.json 核对新条目

2. 给现有模块加字段 ​

text
□ MySQL ALTER(列注释按枚举规范写"字段:1-x 2-y";需要唯一性则补 uk_*)
□ gf gen dao -c hack/config.yaml(刷新 entity/do/dao internal;service 不动)
□ api/v1:Req/Res/Item 结构体补字段(json 驼峰 + dc 注释)
□ logic:ToData 补键;枚举补 SerializeMaps(字典编码 {模块}_{字段});
  文件字段补 FileFields+FileSaveDir;富文本补 ContentFields
□ 前端:columns.ts / querySchemas.ts / edit.vue 同步
□ document/ 五方言脚本同步;必要时附录表清单更新
□ go build → 重启 → page/detail 黄金样本更新

3. 新增模块 ​

text
□ 设计表(统一审计列 + del_flag + uk_* + 注释枚举)→ DDL 落库
□ 租户级?→ hooks.tenantTables 登记
□ go run ./cmd/generator -tables "goframe_x|中文名"(或手动四件套)
□ logic 调整:spec 声明(筛选/树形/字典/文件/唯一 Group)、扩展接口
□ service 接口核对;router.go 注册行确认
□ go build ./... → 重启 → 角色勾选新权限节点

4. 新增中间件 ​

text
□ internal/middleware/{name}.go:func(r *ghttp.Request),职责单一;
  读配置用 cfgBool/cfgInt;客户端 IP 用 realClientIP;响应用 utility/response
□ 不得 import 业务包——需要业务数据时在 wire.go 增加 Loader 函数变量,
  由 logic init 注册(参照 IdentityLoader 模式)
□ router.Register 的 s.Use 链按序插入(顺序即语义,评审明确插入点)
□ public 路径行为:确认对 IsPublicPath 的放行策略

5. 新增定时任务 ​

text
□ internal/task/{task_name}.go + init RegisterJobHandler("TaskName", h)
□ handler 签名 (ctx, params) (string, error);长任务分批+上限;禁 HTTP 于事务内
□ 任务表配置:url="TaskName"、params JSON、cron(6 段或 # 5 段)、
  execute_policy/is_sync;发布(status=1)
□ 验证:daemonStatus 挂载 + runOnce + job/log 成功记录
□ go build 重启(init 注册发生在进程加载期)

6. 自定义 / 扩展 dao ​

text
□ dao/{m}.go 尾部"Add your custom methods"区追加方法(统计/联查等)
□ 修改模板本身:改 hack/tpl/dao_index.tpl 后 gf gen dao 重新生成
  (overwriteDao:false 保留手工扩展;新旧模板产物差异需人工合并)
□ 红线:自定义方法也必须以 Ctx(ctx) 为查询入口;禁止在 dao 内做业务判断

7. 配置变更 ​

text
□ manifest/config/config.yaml 修改
□ 多环境差异用 GF_ 环境变量覆盖,不改文件
□ 新增配置键:注释说明 + 代码 cfgBool/cfgInt 带默认值读取(缺失不 panic)
□ 影响限流/日志/上传/调度的键变更后跑对应回归

逃生舱与扩展挂点 ​

挂点场景说明
BodyUnmarshaler请求体形态不规则(平铺 map 等)Req 实现 UnmarshalBody(r) 跳过默认 Parse(自行做 gvalid)
ModuleSpec.Filter复杂查询条件不与 Like/Eq 重复声明
ModuleSpec.DataScope数据权限挂点共享工厂 ApplyDataScope(col),声明即生效
ModuleSpec 钩子装不下基座禁止按模块分支整个方法手写(合法逃生舱,如 job.Detail 因嵌入结构手写)
logic 包级共享函数跨模块复用放具体模块文件顶部(同包可见);横切能力进 base.go(15 导出上限)
RegisterJobHandler本地任务处理器全局注册表(重名 panic)
middleware wire业务与中间件解耦三 Loader/Sink 函数变量

未启用项与前端遗留 ​

项现状启用/处理要点
用户注册publicPaths 含 /api/register(路由未注册)启用时补建表逻辑 + 开放策略 + 租户归属规则
数据范围自定义档现四档纯列值(role.data_scope)第 5 档需部门关联表 + 角色表单部门树多选
导出增强当前导出返回临时文件 URL可加流式下载/异步导出
SendSms 任务task/send_sms.go 仅记日志接短信通道时替换实现
站内信/数据源/短信/OSS/WebSocket前端遗留死代码(后端桩已删除)不再调用即无影响

封板后的变更纪律 ​

text
1) 一切接口行为以 API 接口清单 + /api.json 为准,改动即更新文档
2) 表结构改动三同步:document/mysql/ 定稿 → 其余四方言脚本 → 迁移(跨环境时)
3) 破坏性变更(改名/删字段/改枚举值)必须走版本化说明 + 前端同步 +
   黄金样本更新,禁止静默变更
4) 架构红线复查:绕过 dao / 手写租户条件 / 反向依赖 task / 超 15 导出的 base /
   未登记 tenantTables——任何一项都应打回

小蚂蚁云团队 · 提供技术支持