Files
mce/docs/code-style.md

112 lines
3.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Go 代码规范
## 文件大小
| 层次 | 单文件行数上限 | 说明 |
|---|---|---|
| Controller | ≤ 120 行 | 只管参数绑定 + 调用服务 + 返回 |
| Service | ≤ 300 行 | 承载业务逻辑,超过则拆子服务 |
| Repository | ≤ 200 行 | 纯数据库操作 |
| Model | ≤ 80 行 | 纯结构体 |
| Middleware | ≤ 60 行 | 单一职责 |
| Router | ≤ 60 行 | 只做路由映射 |
## 瘦控制器铁律
Controller 每个方法不超过三步:
1. 绑定请求参数
2. 调用 Service
3. 返回响应
```go
// ✅ 正确
func (c *PostController) Create(ctx *gin.Context) {
var req dto.CreatePostRequest
if err := ctx.ShouldBind(&req); err != nil {
common.Error(ctx, common.ErrInvalidParam, "参数错误")
return
}
post, err := c.postService.Create(ctx, req, getCurrentUser(ctx))
if err != nil {
common.Error(ctx, common.ErrInternal, "创建失败")
return
}
common.Ok(ctx, post)
}
// ❌ 错误Controller 里写 if-else 业务分支
func (c *PostController) Create(ctx *gin.Context) {
// ... 参数绑定 ...
if req.Type == "draft" {
// 草稿逻辑写在这里 ↓ 错误!
post.Status = 0
} else {
// 发布逻辑写在这里 ↓ 错误!
post.Status = 1
if post.Score > 100 { ... }
}
}
```
业务判断全部放在 Service 层。
## Controller 禁止事项
- ❌ 直接调用 Repository
- ❌ 调用另一个 Controller
- ❌ 写 if-else 业务分支
- ❌ 在 handler 里直接操作数据库
- ❌ 代码回滚、重试等编排逻辑
## 命名规范
### 文件
- Go 文件:`snake_case.go`
- 模板文件:`snake_case.html`
- CSS/JS 文件:`kebab-case.css` / `camelCase.js`
### 结构体与方法
- Controller`type PostController struct{}`,方法 `func (c *PostController) Create(...)`
- Service`type PostService struct{ repo *PostRepo }`,方法 `func (s *PostService) Create(...)`
- Repository`type PostRepo struct{ db *gorm.DB }`,方法 `func (r *PostRepo) FindByID(...)`
### 响应格式
统一使用 `common` 包的响应函数:
```go
common.Ok(ctx, data) // 200 成功
common.Error(ctx, common.ErrInvalidParam, msg) // 400 参数错误
common.Error(ctx, common.ErrUnauthorized, msg) // 401 未认证
common.Error(ctx, common.ErrForbidden, msg) // 403 无权限
common.Error(ctx, common.ErrNotFound, msg) // 404 未找到
common.Error(ctx, common.ErrInternal, msg) // 500 服务器错误
```
### 模板变量
使用驼峰命名,与模板文件保持一致:
```go
gin.H{
"Title": "页面标题",
"ExtraCSS": "/static/css/page.css",
"Guidelines": template.HTML(content), // HTML 内容需显式标记类型
}
```
## 依赖注入
当前阶段 Controller 直接在方法内创建 Service 实例。后期引入 DI 容器后统一管理。
```go
// 当前
func (ac *AuthController) RegisterPage(c *gin.Context) { ... }
// 后期
func NewAuthController(svc *AuthService) *AuthController { ... }
```