签入版本

This commit is contained in:
小蚂蚁云
2026-10-25 17:24:27 +08:00
parent 48911cc08f
commit fdbeae092a
1010 changed files with 30682 additions and 95274 deletions
+38 -68
View File
@@ -1,93 +1,63 @@
# 3.11 常见问题与排错
# 3.12 常见问题与排错
## 后端问题
:::tip 概述
本页汇总模块开发高频问题。核心口诀:**新接口只加 RouteSpec 声明 + handler 方法,数据访问只走 Ctx,业务错误原样上抛。**
:::
### Q: 新增接口返回 401
## 路由与注册
A: 检查以下几点:
1. 请求头是否携带 `Authorization: Bearer <token>`
2. Token 是否过期(默认 2 小时)
3. 路由是否在 `route/app.php` 的需认证组中
**Q:加了 handler 方法但接口 404?**
### Q: 新增接口返回 403
方法签名不匹配。必须是 `func (c *CXxx) Method(ctx context.Context, req *dto.XxxReq) (*dto.XxxRes, error)`,且 RouteSpec 表中有同名键。反射扫描按签名识别,不匹配的方法静默跳过。
A: 权限不足,检查:
1. 是否在 Controller 方法上添加了 `#[Permission]` 注解
2. 权限码是否在菜单管理中配置
3. 用户角色是否包含该权限节点
**Q:改了 router.go 需要重启吗?**
### Q: 枚举显示名(typeText/statusText)为空
需要。路由注册发生在启动时,改动后重启服务(`make run`)。
A: 检查:
1. 字典表中是否存在对应的字典编码(如 `example_type`)
2. 字典项的 value 值是否与数据中的值匹配
3. Logic 中 `serializeMaps` 配置是否正确
**Q:新模块忘记在 registerControllers 加 Bind?**
```php
// ExampleLogic 中的配置
所有控制器必须在 `internal/router/router.go` 的 `registerControllers` 中有一条 `Bind` 声明,否则整个控制器不注册。代码生成器会自动追加。
/**
* 枚举显示名映射
*
* @var array
*/
protected array $serializeMaps = [
'type' => 'example_type',
'status' => 'example_status',
];
```
## 数据访问
### Q: 文件上传后 avatar 路径为空
**Q:查询能搜到已删除的数据?**
A: 检查:
1. `.env` 中 `FILE.UPLOAD_DIR` 是否配置
2. 上传目录是否存在且有写入权限
3. Logic 中是否配置了 `fileFields`
说明绕过了 `Ctx`。检查是否用了 `Raw()` 或裸 `*gorm.DB`——一切查询走 `NewXxxRepo().Ctx(ctx)`。
```php
// ExampleLogic 中的配置
protected array $fileFields = ['avatar'];
protected string $fileSaveDir = 'example';
```
**Q:租户 A 看到了租户 B 的数据?**
### Q: 排序不生效
两个检查点:表是否在 `internal/model/hooks` 的租户白名单中(必须含 tenant_id 列);写入时 Create 钩子是否正常补齐 tenant_id。
A: 检查 Logic 中 `pageOrderBy` 配置:
**Q:物理删除报错"被拦截"?**
```php
// ExampleLogic 中的配置
protected array $pageOrderBy = ['field' => 'sort', 'type' => 'asc'];
```
设计如此。业务删除用 `SoftDelete`;定时清理等场景用 `hooks.WithPhysicalDelete(ctx)` 显式放行。
前端可通过 `orderField` 和 `orderType` 参数覆盖默认排序。
## 业务层
## 前端问题
**Q:Update 后某些字段变回零值?**
### Q: 菜单不显示
Update 是全量表单语义:未提交的字段按零值落库。前端必须回传全部业务字段(未修改的传原值)。
A: 检查:
1. 后端菜单管理中是否添加了对应菜单
2. 菜单的组件路径是否正确(如 `tool/example/index`)
3. 前端 `views` 目录下是否有对应的 `.vue` 文件
4. 用户角色是否包含该菜单权限
**Q:字典字段没有 statusText?**
### Q: API 请求 404
检查三点:SerializeMaps 键是 snake 字段名(status)、字典编码正确(example_status)、DTO 中声明了 `StatusText` 字段。字典本身需在字典管理中有对应项。
A: 检查:
1. `route/app.php` 中是否注册了对应路由
2. 路由路径是否与前端 API 模块中的 `url` 一致
3. HTTP 方法是否正确(GET/POST/PUT/DELETE)
**Q:文件上传后访问 404?**
### Q: 表格数据不显示
上传先进 temp,**保存记录时**才经 saveTransform 转正到 `FileSaveDir`。只调上传接口不保存记录,文件不会出现在正式目录。域名问题见 [7.2 上传配置详解](/zh/tools/upload-config.html)。
A: 检查:
1. API 返回的数据结构是否正确(应包含 `records` 和 `total`)
2. 前端是否正确绑定了 `tableData`
3. 浏览器控制台是否有报错
## 钩子与事务
### Q: 导入失败
**Q:钩子里能做 HTTP 请求 / append 吗?**
A: 检查:
1. 文件格式是否为 `.xls` 或 `.xlsx`
2. 表头是否与 `headerMap` 中定义的中文名一致
3. 枚举字段的值是否在字典中存在
不能。钩子禁 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 模块逐字核对——它是全项目规约的参考实现