初始化项目:基础设施 + 用户认证 + 后台管理系统 + AGPL 3.0 许可
This commit is contained in:
111
docs/code-style.md
Normal file
111
docs/code-style.md
Normal file
@ -0,0 +1,111 @@
|
||||
# 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 { ... }
|
||||
```
|
||||
Reference in New Issue
Block a user