签入版本

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
@@ -1,120 +1,64 @@
# 12.6 后端编码规范
# 12.8 后端编码规范
:::tip 概述
本节定义后端 PHP 代码的编写规范,包括 Model、Logic、Controller、Validate 各层的命名和结构规范,确保团队代码风格统一。
:::tip 建议遵守
在数据访问铁律与模块规约之上,后端编码的通用风格约定:命名、注释、错误、并发、依赖方向。
:::
## Model 层规范
## 命名
```php
// 继承 BaseModel
class Example extends BaseModel
{
/**
* 对应数据库表名(不含前缀)
*
* @var string
*/
protected $name = 'example';
}
| 对象 | 规约 | 示例 |
|---|---|---|
| 模块文件 | 小写下划线,与表名对应 | user.go、dict_item.go |
| 控制器 | C + 模块名 Pascal | CUser |
| 服务 | s + 模块名 | sUser |
| 仓储 | 模块名 + Repo | UserRepo |
| 声明变量 | 模块名 + Spec | userSpec |
| 常量 | 语义化大驼峰 | CodeRecordNotFound |
| 缓存键 | consts 键函数生成 | CacheKeyCaptcha(uuid) |
## 注释
- 包注释一句说明模块职责;文件头不加横幅
- 导出函数注释以函数名开头,说明行为/约束/降级
- 反直觉处(顺序依赖、红线原因)必须注释"为什么"
- 注释直述现状,不写改造过程与来源对比
## 错误处理
- 业务失败用哨兵/apperr,**原样上抛不 wrap**
- 不吞错只记日志;日志与返回二选一时优先返回
- panic 仅限编程错误(如 ToData 类型不匹配)——运行时输入不 panic
## 并发
- service 单例方法必须并发安全(无请求态字段)
- ctx 贯穿一切(身份/事务/追踪),不用全局变量传请求态
- 缓存读写经 utility/cache(自带降级),不直连 go-redis
## 依赖方向
```text
handler → service → repository → db
utility 被任意层引用;utility 不 import internal
task → service(单向);service 不反向依赖 task
```
## Logic 层规范
禁止反向与横向环依赖;跨模块协作经同包直调或显式接口。
```php
// 系统共享模块继承 BaseLogic
class ExampleLogic extends BaseLogic
{
/**
* 关联的模型类
*
* @var string
*/
protected string $modelClass = Example::class;
## 性能习惯
/**
* LIKE 模糊匹配字段
*
* @var array
*/
protected array $pageLikeFields = ['name'];
- 查询指定列优先(大表 SELECT * 慎用)
- 循环内不做 N+1 查询(批量 IN)
- 大结果集导出走分批,不一次载入
- 热点读经缓存(键走 consts 函数)
/**
* 精确匹配字段
*
* @var array
*/
protected array $pageEqFields = ['status'];
## 提交前
/**
* 新增前处理
*
* @param array $data 待新增的数据
* @return array 处理后的数据
*/
protected function beforeAdd(array $data): array
{
return $data;
}
}
// 租户模块继承 BaseTenantLogic
class UserLogic extends BaseTenantLogic { ... }
```bash
make check # fmt + vet + test-short + check-config
```
## Controller 层规范
## 相关
```php
class ExampleController extends BaseController
{
protected ExampleLogic $logic;
protected function initialize(): void
{
$this->logic = new ExampleLogic();
}
// 使用注解
#[Log('模块-操作', Log::TYPE_ADD)]
#[Permission('sys:example:add', '添加')]
public function add(): Json
{
return parent::_add($this->logic, $this->getJsonBody());
}
}
```
## Validate 层规范
```php
class ExampleValidate extends Validate
{
protected $rule = [
'name' => 'require',
'categoryId' => 'require', // ✅ 驼峰命名
// 'category_id' => 'require', // ❌ 禁止下划线
];
protected $message = [
'name.require' => '名称不能为空',
'categoryId.require' => '分类不能为空',
];
protected $scene = [
'add' => ['name', 'categoryId'],
'update' => ['name'],
];
}
```
:::warning 字段名必须使用驼峰
Validate 中的字段名必须使用 camelCase(驼峰),与前端传参一致。
因为校验发生在 `BaseLogic::beforeAdd` 之后、`array_camel_to_snake` 转换之前,
此时数据键名还是驼峰形式。使用下划线会导致校验规则匹配不到字段。
:::
## 注解规范
- 所有写操作(POST/PUT/DELETE)必须标注 `#[Log]`
- 所有需要权限控制的接口必须标注 `#[Permission]`
- 权限码格式:`sys:{模块名}:{操作}`
- [12.4 模块开发规约](/zh/standards/module-code.html)
- [12.3 数据访问铁律](/zh/standards/data-access.html)