64 lines
2.8 KiB
Markdown
64 lines
2.8 KiB
Markdown
# 3.12 常见问题与排错
|
||
|
||
:::tip 概述
|
||
本页汇总模块开发高频问题。核心口诀:**新接口只加 RouteSpec 声明 + handler 方法,数据访问只走 Ctx,业务错误原样上抛。**
|
||
:::
|
||
|
||
## 路由与注册
|
||
|
||
**Q:加了 handler 方法但接口 404?**
|
||
|
||
方法签名不匹配。必须是 `func (c *CXxx) Method(ctx context.Context, req *dto.XxxReq) (*dto.XxxRes, error)`,且 RouteSpec 表中有同名键。反射扫描按签名识别,不匹配的方法静默跳过。
|
||
|
||
**Q:改了 router.go 需要重启吗?**
|
||
|
||
需要。路由注册发生在启动时,改动后重启服务(`make run`)。
|
||
|
||
**Q:新模块忘记在 registerControllers 加 Bind?**
|
||
|
||
所有控制器必须在 `internal/router/router.go` 的 `registerControllers` 中有一条 `Bind` 声明,否则整个控制器不注册。代码生成器会自动追加。
|
||
|
||
## 数据访问
|
||
|
||
**Q:查询能搜到已删除的数据?**
|
||
|
||
说明绕过了 `Ctx`。检查是否用了 `Raw()` 或裸 `*gorm.DB`——一切查询走 `NewXxxRepo().Ctx(ctx)`。
|
||
|
||
**Q:租户 A 看到了租户 B 的数据?**
|
||
|
||
两个检查点:表是否在 `internal/model/hooks` 的租户白名单中(必须含 tenant_id 列);写入时 Create 钩子是否正常补齐 tenant_id。
|
||
|
||
**Q:物理删除报错"被拦截"?**
|
||
|
||
设计如此。业务删除用 `SoftDelete`;定时清理等场景用 `hooks.WithPhysicalDelete(ctx)` 显式放行。
|
||
|
||
## 业务层
|
||
|
||
**Q:Update 后某些字段变回零值?**
|
||
|
||
Update 是全量表单语义:未提交的字段按零值落库。前端必须回传全部业务字段(未修改的传原值)。
|
||
|
||
**Q:字典字段没有 statusText?**
|
||
|
||
检查三点:SerializeMaps 键是 snake 字段名(status)、字典编码正确(example_status)、DTO 中声明了 `StatusText` 字段。字典本身需在字典管理中有对应项。
|
||
|
||
**Q:文件上传后访问 404?**
|
||
|
||
上传先进 temp,**保存记录时**才经 saveTransform 转正到 `FileSaveDir`。只调上传接口不保存记录,文件不会出现在正式目录。域名问题见 [7.2 上传配置详解](/zh/tools/upload-config.html)。
|
||
|
||
## 钩子与事务
|
||
|
||
**Q:钩子里能做 HTTP 请求 / append 吗?**
|
||
|
||
不能。钩子禁 HTTP/文件 IO、禁 append(可就地改元素),错误原样上抛。
|
||
|
||
**Q:事务里查到的还是旧数据?**
|
||
|
||
事务内必须用回调入参的 ctx:`db.WithTrans(ctx, func(ctx context.Context) error { ... })`——内层 ctx 才携带事务连接。
|
||
|
||
## 效率建议
|
||
|
||
- 建表后先跑 `make gen TABLES="gin_xxx|说明"` 让生成器出四件套与前端,再手工改——比从零手写快且不违例
|
||
- 新配置键记得同步 `.env.example`,否则 `make check` 卡 check-config
|
||
- 不确定写法时,对照本章 example 模块逐字核对——它是全项目规约的参考实现
|