规范: 新增枚举与状态字段规范并修复代理充值状态描述错误
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
- 新增 docs/enum-status-standards.md:完整的枚举/状态规范,涵盖 int vs string 选择、起始值约定、description 格式统一、constants 唯一真相来源、Response DTO 必须提供 status_name - 更新 dto-standards SKILL.md:加入枚举规范要点,AI 写 DTO 时自动触发 - 更新 AGENTS.md:常量管理章节和 Code Review 检查清单各加入枚举检查项 - 修复 agent_recharge_dto.go:description 从错误的 3 个状态改为正确的 5 个状态(原 3:已取消 实为 3:已完成) - 修复 agent_recharge service:toResponse 补充 StatusName 中文字段,防止前端映射出错
This commit is contained in:
@@ -14,6 +14,8 @@ description: DTO 数据传输对象规范。创建或修改 DTO 文件、请求/
|
||||
- 创建 `XXXRequest`、`XXXResponse`、`XXXReq`、`XXXResp` 结构体
|
||||
- 添加或修改 API 接口的输入输出参数
|
||||
|
||||
---
|
||||
|
||||
## 必须项(MUST)
|
||||
|
||||
### 1. Description 标签规范
|
||||
@@ -36,59 +38,150 @@ type CreateUserRequest struct {
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 枚举字段必须列出所有可能值(中文)
|
||||
### 2. 枚举字段:int vs string 选择
|
||||
|
||||
**所有枚举类型字段必须在 `description` 中列出所有可能值和对应的中文含义**
|
||||
**必须按以下规则选择类型,禁止混用:**
|
||||
|
||||
| 场景 | 类型 | 示例 |
|
||||
|------|------|------|
|
||||
| 状态类(生命周期阶段) | `int` | 待支付→已完成→已关闭 |
|
||||
| 布尔状态(启用/禁用) | `int` | `0=禁用, 1=启用` |
|
||||
| 类型/方式类(种类) | `string` | `"wechat"`, `"single_card"` |
|
||||
| 平台/标识符类 | `string` | `"web"`, `"h5"`, `"all"` |
|
||||
|
||||
```go
|
||||
// 用户类型
|
||||
UserType int `json:"user_type" description:"用户类型 (1:超级管理员, 2:平台用户, 3:代理账号, 4:企业账号)"`
|
||||
// ✅ 状态 → int
|
||||
Status int `json:"status"`
|
||||
PaymentStatus int `json:"payment_status"`
|
||||
|
||||
// 角色类型
|
||||
RoleType int `json:"role_type" description:"角色类型 (1:平台角色, 2:客户角色)"`
|
||||
|
||||
// 权限类型
|
||||
PermType int `json:"perm_type" description:"权限类型 (1:菜单, 2:按钮)"`
|
||||
|
||||
// 状态字段
|
||||
Status int `json:"status" description:"状态 (0:禁用, 1:启用)"`
|
||||
|
||||
// 适用端口
|
||||
Platform string `json:"platform" description:"适用端口 (all:全部, web:Web后台, h5:H5端)"`
|
||||
// ✅ 类型/方式 → string
|
||||
PaymentMethod string `json:"payment_method" validate:"required,oneof=wechat offline"`
|
||||
OrderType string `json:"order_type" validate:"required,oneof=single_card device"`
|
||||
```
|
||||
|
||||
❌ **禁止使用英文枚举值**:
|
||||
### 3. Int 状态值约定
|
||||
|
||||
#### 3.1 通用禁用/启用
|
||||
|
||||
**必须用全局常量,禁止自定义(尤其禁止 1=启用 2=禁用 这种反向写法)**:
|
||||
|
||||
```go
|
||||
UserType int `json:"user_type" description:"用户类型 (1:SuperAdmin, 2:Platform)"` // 错误!
|
||||
// pkg/constants/constants.go 已定义,直接使用
|
||||
StatusDisabled = 0 // 禁用
|
||||
StatusEnabled = 1 // 启用
|
||||
```
|
||||
|
||||
### 3. 验证标签与 OpenAPI 标签一致
|
||||
✅ 正确:`description:"状态 (0:禁用, 1:启用)"`
|
||||
❌ 禁止:`description:"状态 (1:启用, 2:禁用)"`
|
||||
|
||||
**所有验证约束必须同时在 `validate` 和 OpenAPI 标签中声明**
|
||||
#### 3.2 生命周期状态
|
||||
|
||||
从 **1** 开始递增,0 不使用(避免与 Go 零值混淆):
|
||||
|
||||
```go
|
||||
const (
|
||||
RechargeStatusPending = 1 // 待支付
|
||||
RechargeStatusPaid = 2 // 已支付
|
||||
RechargeStatusCompleted = 3 // 已完成
|
||||
RechargeStatusClosed = 4 // 已关闭
|
||||
)
|
||||
```
|
||||
|
||||
### 4. 枚举列表必须从 constants 原文抄写
|
||||
|
||||
**DTO description 的枚举列表必须与 `pkg/constants/` 定义完全一致,不可凭记忆填写。**
|
||||
|
||||
操作步骤:
|
||||
1. 先查/定义 `pkg/constants/` 中的枚举常量
|
||||
2. 将常量注释**原文抄写**到 description
|
||||
|
||||
```go
|
||||
// constants.go 中:
|
||||
RechargeStatusPending = 1 // 待支付
|
||||
RechargeStatusPaid = 2 // 已支付
|
||||
RechargeStatusCompleted = 3 // 已完成
|
||||
RechargeStatusClosed = 4 // 已关闭
|
||||
RechargeStatusRefunded = 5 // 已退款
|
||||
|
||||
// DTO description 从上面抄:
|
||||
Status int `json:"status" description:"状态 (1:待支付, 2:已支付, 3:已完成, 4:已关闭, 5:已退款)"`
|
||||
```
|
||||
|
||||
❌ 禁止(description 与 constants 不一致,是历史 bug 的根因):
|
||||
```go
|
||||
// constants 说 3=已完成,description 却写 3:已取消
|
||||
Status int `json:"status" description:"状态 (1:待支付, 2:已完成, 3:已取消)"`
|
||||
```
|
||||
|
||||
### 5. description 格式标准
|
||||
|
||||
**统一格式**:`字段含义 (值1:中文含义1, 值2:中文含义2)`
|
||||
|
||||
- 值与含义之间用**冒号** `:`(禁止用等号 `=`)
|
||||
- 多个值之间用**逗号加空格** `, `
|
||||
- 含义必须是**中文**
|
||||
|
||||
```go
|
||||
// ✅ 统一格式
|
||||
Status int `description:"状态 (1:待支付, 2:已支付, 3:已完成)"`
|
||||
Platform string `description:"适用端口 (all:全部, web:Web后台, h5:H5端)"`
|
||||
|
||||
// ❌ 格式混乱
|
||||
Status int `description:"状态 (0=禁用, 1=启用)"` // 用等号
|
||||
Status int `description:"0=禁用 1=启用"` // 无括号无逗号
|
||||
```
|
||||
|
||||
### 6. Response DTO 的状态字段必须同时返回 int 和 text
|
||||
|
||||
**所有 Response DTO 中的 int 状态字段,必须同时提供对应的 `_name` 文字字段。**
|
||||
|
||||
原因:防止前端维护映射表出错(历史上已有因此产生 bug 的案例)。
|
||||
|
||||
```go
|
||||
// ✅ Response DTO 标准写法
|
||||
type XxxResponse struct {
|
||||
Status int `json:"status" description:"状态 (1:待支付, 2:已支付, 3:已完成, 4:已关闭, 5:已退款)"`
|
||||
StatusName string `json:"status_name" description:"状态名称(中文)"`
|
||||
}
|
||||
|
||||
// toResponse 函数中赋值
|
||||
func rechargeStatusName(status int) string {
|
||||
switch status {
|
||||
case constants.RechargeStatusPending:
|
||||
return "待支付"
|
||||
case constants.RechargeStatusCompleted:
|
||||
return "已完成"
|
||||
// ...
|
||||
default:
|
||||
return "未知"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
字段命名约定:`status` → `status_name`,`payment_status` → `payment_status_name`
|
||||
|
||||
**例外**:Request DTO(查询过滤、创建请求)不需要 `_name` 字段。
|
||||
|
||||
### 7. 验证标签与 OpenAPI 标签一致
|
||||
|
||||
```go
|
||||
Username string `json:"username" validate:"required,min=3,max=50" required:"true" minLength:"3" maxLength:"50" description:"用户名"`
|
||||
```
|
||||
|
||||
**标签对照表**:
|
||||
| validate 标签 | OpenAPI 标签 |
|
||||
|--------------|--------------|
|
||||
| `required` | `required:"true"` |
|
||||
| `min=N,max=M`(数值) | `minimum:"N" maximum:"M"` |
|
||||
| `min=N,max=M`(字符串) | `minLength:"N" maxLength:"M"` |
|
||||
| `oneof=A B C` | description 中说明枚举值 |
|
||||
|
||||
| validate 标签 | OpenAPI 标签 | 说明 |
|
||||
|--------------|--------------|------|
|
||||
| `required` | `required:"true"` | 必填字段 |
|
||||
| `min=N,max=M` | `minimum:"N" maximum:"M"` | 数值范围 |
|
||||
| `min=N,max=M` (字符串) | `minLength:"N" maxLength:"M"` | 字符串长度 |
|
||||
| `len=N` | `minLength:"N" maxLength:"N"` | 固定长度 |
|
||||
| `oneof=A B C` | `description` 中说明 | 枚举值 |
|
||||
|
||||
### 4. 请求参数类型标签
|
||||
|
||||
**Query 参数和 Path 参数必须添加对应标签**
|
||||
### 8. 请求参数类型标签
|
||||
|
||||
```go
|
||||
// Query 参数
|
||||
type ListRequest struct {
|
||||
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码"`
|
||||
UserType *int `json:"user_type" query:"user_type" validate:"omitempty,min=1,max=4" minimum:"1" maximum:"4" description:"用户类型 (1:超级管理员, 2:平台用户, 3:代理账号, 4:企业账号)"`
|
||||
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码"`
|
||||
Status *int `json:"status" query:"status" validate:"omitempty,min=1,max=4" minimum:"1" maximum:"4" description:"状态 (1:待支付, 2:已支付, 3:已完成, 4:已关闭)"`
|
||||
}
|
||||
|
||||
// Path 参数
|
||||
@@ -97,43 +190,50 @@ type IDReq struct {
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 响应 DTO 完整性
|
||||
|
||||
**所有响应 DTO 的字段都必须有完整的 `description` 标签**
|
||||
### 9. 响应 DTO 完整性
|
||||
|
||||
```go
|
||||
type AccountResponse struct {
|
||||
ID uint `json:"id" description:"账号ID"`
|
||||
Username string `json:"username" description:"用户名"`
|
||||
UserType int `json:"user_type" description:"用户类型 (1:超级管理员, 2:平台用户, 3:代理账号, 4:企业账号)"`
|
||||
Status int `json:"status" description:"状态 (0:禁用, 1:启用)"`
|
||||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" description:"更新时间"`
|
||||
ID uint `json:"id" description:"账号ID"`
|
||||
Username string `json:"username" description:"用户名"`
|
||||
UserType int `json:"user_type" description:"用户类型 (1:超级管理员, 2:平台用户, 3:代理账号, 4:企业账号)"`
|
||||
Status int `json:"status" description:"状态 (0:禁用, 1:启用)"`
|
||||
StatusName string `json:"status_name" description:"状态名称(中文)"`
|
||||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" description:"更新时间"`
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## AI 助手必须执行的检查
|
||||
|
||||
**在创建或修改任何 DTO 文件后,必须执行以下检查:**
|
||||
|
||||
1. ✅ 检查所有字段是否有 `description` 标签
|
||||
2. ✅ 检查枚举字段是否列出了所有可能值(中文)
|
||||
3. ✅ 检查状态字段是否说明了 0 和 1 的含义
|
||||
4. ✅ 检查 validate 标签与 OpenAPI 标签是否一致
|
||||
5. ✅ 检查是否禁止使用行内注释替代 description
|
||||
6. ✅ 检查枚举值是否使用中文而非英文
|
||||
7. ✅ 重新生成 OpenAPI 文档验证:`go run cmd/gendocs/main.go`
|
||||
1. ✅ 所有字段有 `description` 标签(无行内注释)
|
||||
2. ✅ 枚举类型选择正确(状态用 int,类型/方式用 string)
|
||||
3. ✅ 禁用/启用使用 `0=禁用, 1=启用`(禁止 1=启用 2=禁用)
|
||||
4. ✅ description 枚举列表已从 `pkg/constants/` 原文抄写,无遗漏
|
||||
5. ✅ description 格式统一(冒号 `:`,括号,逗号)
|
||||
6. ✅ Response DTO 有 `_name` 伴生字段
|
||||
7. ✅ validate 标签与 OpenAPI 标签一致
|
||||
8. ✅ 重新生成 OpenAPI 文档验证:`go run cmd/gendocs/main.go`
|
||||
|
||||
**详细检查清单**: 参见 `docs/code-review-checklist.md`
|
||||
**完整枚举规范**: 参见 [`docs/enum-status-standards.md`](../../docs/enum-status-standards.md)
|
||||
|
||||
---
|
||||
|
||||
## 常见枚举字段标准值
|
||||
|
||||
```go
|
||||
// 用户类型
|
||||
// 用户类型(从 constants.UserType* 抄)
|
||||
description:"用户类型 (1:超级管理员, 2:平台用户, 3:代理账号, 4:企业账号)"
|
||||
|
||||
// 角色类型
|
||||
description:"角色类型 (1:平台角色, 2:客户角色)"
|
||||
// 通用启用/禁用(从 constants.StatusEnabled/Disabled 抄)
|
||||
description:"状态 (0:禁用, 1:启用)"
|
||||
|
||||
// 充值状态(从 constants.RechargeStatus* 抄)
|
||||
description:"状态 (1:待支付, 2:已支付, 3:已完成, 4:已关闭, 5:已退款)"
|
||||
|
||||
// 权限类型
|
||||
description:"权限类型 (1:菜单, 2:按钮)"
|
||||
@@ -141,9 +241,6 @@ description:"权限类型 (1:菜单, 2:按钮)"
|
||||
// 适用端口
|
||||
description:"适用端口 (all:全部, web:Web后台, h5:H5端)"
|
||||
|
||||
// 状态
|
||||
description:"状态 (0:禁用, 1:启用)"
|
||||
|
||||
// 店铺层级
|
||||
description:"店铺层级 (1-7级)"
|
||||
```
|
||||
|
||||
25
AGENTS.md
25
AGENTS.md
@@ -113,6 +113,24 @@ Handler → Service → Store → Model
|
||||
- 禁止硬编码字符串和 magic numbers
|
||||
- **必须为所有常量添加中文注释**
|
||||
|
||||
### 枚举与状态字段(必须遵守)
|
||||
|
||||
**两个强制规则**:
|
||||
|
||||
1. **int vs string**:状态类(生命周期)用 `int`,类型/方式类用 `string`
|
||||
2. **DTO description 必须从 constants 原文抄写**,禁止凭记忆填写枚举值(历史上已有 description 与 constants 不一致导致前端显示错误的案例)
|
||||
|
||||
```go
|
||||
// ✅ description 从 constants 原文抄,格式统一用冒号+逗号
|
||||
Status int `json:"status" description:"状态 (1:待支付, 2:已支付, 3:已完成, 4:已关闭, 5:已退款)"`
|
||||
StatusName string `json:"status_name" description:"状态名称(中文)"` // Response DTO 必须加
|
||||
|
||||
// ❌ 禁止:启用/禁用用 1=启用 2=禁用(全局约定是 0=禁用, 1=启用)
|
||||
// ❌ 禁止:description 枚举值与 constants 不一致
|
||||
```
|
||||
|
||||
**完整规范**: 参见 [`docs/enum-status-standards.md`](docs/enum-status-standards.md)
|
||||
|
||||
### 注释规范
|
||||
|
||||
- **所有注释使用中文**,导出符号必须有文档注释(包、函数、类型、接口、常量)
|
||||
@@ -220,6 +238,13 @@ Handler → Service → Store → Model
|
||||
- [ ] 常量定义在 `pkg/constants/`
|
||||
- [ ] 使用 Go 惯用法(非 Java 风格)
|
||||
|
||||
### 枚举与状态
|
||||
|
||||
- [ ] 状态类字段用 `int`,类型/方式类字段用 `string`
|
||||
- [ ] 禁用/启用使用 `0=禁用, 1=启用`(禁止 `1=启用, 2=禁用`)
|
||||
- [ ] DTO description 枚举列表已从 `pkg/constants/` 原文抄写,无遗漏、无错误
|
||||
- [ ] Response DTO 的 int 状态字段有对应的 `_name` 文字字段
|
||||
|
||||
### 文档和注释
|
||||
|
||||
- [ ] 所有注释使用中文
|
||||
|
||||
250
docs/enum-status-standards.md
Normal file
250
docs/enum-status-standards.md
Normal file
@@ -0,0 +1,250 @@
|
||||
# 枚举与状态字段规范
|
||||
|
||||
**背景**:系统历史上存在 int/string 枚举混用、description 与常量定义脱节、响应字段不统一等问题,导致前端映射错误、接口文档失真。本规范统一所有枚举相关写法。
|
||||
|
||||
---
|
||||
|
||||
## 1. 类型选择:int vs string
|
||||
|
||||
### 选择规则
|
||||
|
||||
| 场景 | 类型 | 理由 |
|
||||
|------|------|------|
|
||||
| **状态类**:表示生命周期阶段(待支付→已完成→已关闭) | `int` | 便于范围查询、数值比较、DB 索引优化 |
|
||||
| **布尔状态**:启用/禁用、激活/未激活 | `int` | 与全局常量统一,`0=禁用, 1=启用` |
|
||||
| **类型/方式类**:支付方式、订单类型、运营商、平台 | `string` | 语义更清晰,无需记忆数字含义 |
|
||||
| **标识符类**:平台类型(web/h5/all)、角色来源 | `string` | 约定字符串值,自文档化 |
|
||||
|
||||
### 判断依据
|
||||
|
||||
```
|
||||
这个字段表示"现在处于哪个阶段"? → int
|
||||
这个字段表示"它属于哪种类别/使用什么方式"? → string
|
||||
```
|
||||
|
||||
### ✅ 正确示例
|
||||
|
||||
```go
|
||||
// 状态类 → int
|
||||
Status int `json:"status"` // 充值状态:1=待支付, 2=已支付...
|
||||
PaymentStatus int `json:"payment_status"` // 订单支付状态
|
||||
|
||||
// 类型/方式类 → string
|
||||
PaymentMethod string `json:"payment_method"` // "wechat" | "offline"
|
||||
OrderType string `json:"order_type"` // "single_card" | "device"
|
||||
Platform string `json:"platform"` // "web" | "h5" | "all"
|
||||
```
|
||||
|
||||
### ❌ 错误示例
|
||||
|
||||
```go
|
||||
// ❌ 状态用 string(无法范围查询,数字对比失效)
|
||||
Status string `json:"status"` // "pending" | "completed"
|
||||
|
||||
// ❌ 支付方式用 int(前端必须维护不直观的数字映射)
|
||||
PaymentMethod int `json:"payment_method"` // 1=微信, 2=线下
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Int 状态值约定
|
||||
|
||||
### 2.1 通用禁用/启用
|
||||
|
||||
**必须使用全局常量,禁止自定义**:
|
||||
|
||||
```go
|
||||
// pkg/constants/constants.go
|
||||
StatusDisabled = 0 // 禁用
|
||||
StatusEnabled = 1 // 启用
|
||||
```
|
||||
|
||||
✅ 正确:
|
||||
|
||||
```go
|
||||
Status int `gorm:"comment:状态(0-禁用 1-启用);default:1"`
|
||||
```
|
||||
|
||||
❌ 禁止(与全局常量语义相反):
|
||||
|
||||
```go
|
||||
// ❌ 不可以用 1=启用 2=禁用 这种方式
|
||||
Status int `gorm:"comment:状态(1-启用 2-禁用)"`
|
||||
```
|
||||
|
||||
### 2.2 生命周期状态
|
||||
|
||||
从 **1** 开始递增(0 保留,避免与"未赋值/零值"混淆):
|
||||
|
||||
```go
|
||||
// 充值状态(标准示例)
|
||||
const (
|
||||
RechargeStatusPending = 1 // 待支付
|
||||
RechargeStatusPaid = 2 // 已支付
|
||||
RechargeStatusCompleted = 3 // 已完成
|
||||
RechargeStatusClosed = 4 // 已关闭
|
||||
RechargeStatusRefunded = 5 // 已退款
|
||||
)
|
||||
```
|
||||
|
||||
### 2.3 特殊值
|
||||
|
||||
- 跳跃值(如 `99`)仅用于明确需要人工干预的异常状态,必须加注释说明原因
|
||||
- 禁止在同一枚举中混用 0 起始和 1 起始
|
||||
|
||||
---
|
||||
|
||||
## 3. String 枚举值约定
|
||||
|
||||
- 全小写字母 + 下划线 `snake_case`(禁止驼峰、禁止大写)
|
||||
- 必须在 `pkg/constants/` 定义常量,禁止硬编码字符串
|
||||
- DTO 中必须加 `validate:"oneof=..."` 约束
|
||||
|
||||
```go
|
||||
// pkg/constants/constants.go
|
||||
const (
|
||||
PaymentMethodWechat = "wechat" // 微信支付
|
||||
PaymentMethodOffline = "offline" // 线下转账
|
||||
)
|
||||
|
||||
// DTO 中
|
||||
PaymentMethod string `json:"payment_method" validate:"required,oneof=wechat offline" description:"支付方式 (wechat:微信支付, offline:线下转账)"`
|
||||
```
|
||||
|
||||
❌ 禁止:
|
||||
|
||||
```go
|
||||
// ❌ 硬编码字符串
|
||||
if record.PaymentMethod == "wechat" { ... }
|
||||
|
||||
// ❌ 大写或驼峰
|
||||
const PaymentMethodWechat = "Wechat"
|
||||
const PaymentMethodWechat = "WECHAT"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Constants 是唯一真相来源
|
||||
|
||||
**DTO 的 description 枚举列表必须与 `pkg/constants/` 定义完全一致。**
|
||||
|
||||
### 操作规程
|
||||
|
||||
1. 先在 `pkg/constants/` 定义(或查找已有)枚举常量及注释
|
||||
2. 将常量的注释**原文抄写**到 DTO description
|
||||
|
||||
```go
|
||||
// 步骤1:constants.go 中定义
|
||||
const (
|
||||
RechargeStatusPending = 1 // 待支付
|
||||
RechargeStatusPaid = 2 // 已支付
|
||||
RechargeStatusCompleted = 3 // 已完成
|
||||
RechargeStatusClosed = 4 // 已关闭
|
||||
RechargeStatusRefunded = 5 // 已退款
|
||||
)
|
||||
|
||||
// 步骤2:DTO description 从上面抄写,格式统一
|
||||
Status int `json:"status" description:"状态 (1:待支付, 2:已支付, 3:已完成, 4:已关闭, 5:已退款)"`
|
||||
```
|
||||
|
||||
### 禁止行为
|
||||
|
||||
```go
|
||||
// ❌ description 中的枚举值与 constants 不一致(本次 bug 根因)
|
||||
// constants: RechargeStatusCompleted=3(已完成)
|
||||
// dto 写的: 3:已取消 ← 完全错误!
|
||||
Status int `json:"status" description:"状态 (1:待支付, 2:已完成, 3:已取消)"`
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. description 格式标准
|
||||
|
||||
**统一格式**:`字段含义 (值1:中文含义1, 值2:中文含义2, ...)`
|
||||
|
||||
规则:
|
||||
- 必须用**中文圆括号外**、**英文括号内**
|
||||
- 值和含义之间用**冒号** `:`,不用等号 `=`
|
||||
- 多个值之间用**逗号加空格** `, `
|
||||
- 含义必须是**中文**,不可用英文
|
||||
|
||||
```go
|
||||
// ✅ 统一格式
|
||||
Status int `description:"状态 (1:待支付, 2:已支付, 3:已完成, 4:已关闭, 5:已退款)"`
|
||||
Platform string `description:"适用端口 (all:全部, web:Web后台, h5:H5端)"`
|
||||
UserType int `description:"用户类型 (1:超级管理员, 2:平台用户, 3:代理账号, 4:企业账号)"`
|
||||
|
||||
// ❌ 格式混乱
|
||||
Status int `description:"状态 (0=禁用, 1=启用)"` // 用等号
|
||||
Status int `description:"0=禁用 1=启用"` // 无括号无逗号
|
||||
Status int `description:"状态:0待生效 1生效中 2已用完"` // 格式不统一
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Response DTO 的状态字段
|
||||
|
||||
**所有 Response DTO 中的 int 状态字段,必须同时提供对应的 `xxx_name` 文字字段。**
|
||||
|
||||
这是防止前端映射错误的关键措施。
|
||||
|
||||
```go
|
||||
// ✅ Response DTO 标准写法
|
||||
type AgentRechargeResponse struct {
|
||||
Status int `json:"status" description:"状态 (1:待支付, 2:已支付, 3:已完成, 4:已关闭, 5:已退款)"`
|
||||
StatusName string `json:"status_name" description:"状态名称(中文)"`
|
||||
// ...
|
||||
}
|
||||
|
||||
// Service 层 toResponse 函数中赋值
|
||||
func statusName(status int) string {
|
||||
switch status {
|
||||
case constants.RechargeStatusPending:
|
||||
return "待支付"
|
||||
case constants.RechargeStatusPaid:
|
||||
return "已支付"
|
||||
case constants.RechargeStatusCompleted:
|
||||
return "已完成"
|
||||
case constants.RechargeStatusClosed:
|
||||
return "已关闭"
|
||||
case constants.RechargeStatusRefunded:
|
||||
return "已退款"
|
||||
default:
|
||||
return "未知"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**字段命名约定**:
|
||||
- `status` → `status_name`
|
||||
- `payment_status` → `payment_status_name`
|
||||
- `commission_status` → `commission_status_name`
|
||||
|
||||
**例外**:Request DTO(查询过滤、创建请求)不需要 `_name` 字段。
|
||||
|
||||
---
|
||||
|
||||
## 7. Code Review 检查项
|
||||
|
||||
```
|
||||
□ int/string 类型选择是否符合规则?
|
||||
□ 禁/启用是否用了 0=禁用, 1=启用?(禁止 1=启用, 2=禁用)
|
||||
□ string 枚举常量是否在 pkg/constants/ 定义?
|
||||
□ dto description 是否从 constants 注释原文抄写?
|
||||
□ description 格式是否统一(冒号、逗号、括号)?
|
||||
□ Response DTO 是否同时有 status int 和 status_name string?
|
||||
□ 是否有遗漏的枚举值没有在 description 中列出?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 现存已知不一致(技术债,待修复)
|
||||
|
||||
| 文件 | 问题 | 正确值 |
|
||||
|------|------|--------|
|
||||
| `internal/model/shop_package_allocation.go` | `1-启用 2-禁用` | 应改为 `0-禁用 1-启用` |
|
||||
| `internal/model/system.go` | `1-启用 2-禁用` | 需确认是否改 DB |
|
||||
| `internal/model/dto/agent_recharge_dto.go` | description `2:已完成, 3:已取消` | 应为 `2:已支付, 3:已完成, 4:已关闭, 5:已退款` |
|
||||
| `internal/model/dto/asset_wallet_dto.go` | 只有 `status_text` 无 `status int` | 需补充 `status int` |
|
||||
|
||||
> ⚠️ 已有数据的状态起始值(如 `1-启用 2-禁用`)改变前必须做 DB 数据迁移,改动前先评估影响。
|
||||
@@ -30,7 +30,8 @@ type AgentRechargeResponse struct {
|
||||
PaymentChannel string `json:"payment_channel" description:"实际支付通道 (wechat_direct:微信直连, fuyou:富友, offline:线下转账)"`
|
||||
PaymentConfigID *uint `json:"payment_config_id" description:"关联支付配置ID,线下充值为null"`
|
||||
PaymentTransactionID string `json:"payment_transaction_id" description:"第三方支付流水号"`
|
||||
Status int `json:"status" description:"状态 (1:待支付, 2:已完成, 3:已取消)"`
|
||||
Status int `json:"status" description:"状态 (1:待支付, 2:已支付, 3:已完成, 4:已关闭, 5:已退款)"`
|
||||
StatusName string `json:"status_name" description:"状态名称(中文)"`
|
||||
PaidAt *string `json:"paid_at" description:"支付时间"`
|
||||
CompletedAt *string `json:"completed_at" description:"完成时间"`
|
||||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||||
@@ -42,7 +43,7 @@ type AgentRechargeListRequest struct {
|
||||
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码,默认1"`
|
||||
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页条数,默认20,最大100"`
|
||||
ShopID *uint `json:"shop_id" query:"shop_id" description:"按店铺ID过滤"`
|
||||
Status *int `json:"status" query:"status" description:"按状态过滤 (1:待支付, 2:已完成, 3:已取消)"`
|
||||
Status *int `json:"status" query:"status" description:"按状态过滤 (1:待支付, 2:已支付, 3:已完成, 4:已关闭, 5:已退款)"`
|
||||
StartDate string `json:"start_date" query:"start_date" description:"创建时间起始日期(YYYY-MM-DD)"`
|
||||
EndDate string `json:"end_date" query:"end_date" description:"创建时间截止日期(YYYY-MM-DD)"`
|
||||
}
|
||||
|
||||
@@ -469,6 +469,23 @@ func (s *Service) generateRechargeNo() string {
|
||||
return fmt.Sprintf("%s%s%06d", constants.AgentRechargeOrderPrefix, timestamp, randomNum)
|
||||
}
|
||||
|
||||
func agentRechargeStatusName(status int) string {
|
||||
switch status {
|
||||
case constants.RechargeStatusPending:
|
||||
return "待支付"
|
||||
case constants.RechargeStatusPaid:
|
||||
return "已支付"
|
||||
case constants.RechargeStatusCompleted:
|
||||
return "已完成"
|
||||
case constants.RechargeStatusClosed:
|
||||
return "已关闭"
|
||||
case constants.RechargeStatusRefunded:
|
||||
return "已退款"
|
||||
default:
|
||||
return "未知"
|
||||
}
|
||||
}
|
||||
|
||||
// toResponse 将模型转换为响应 DTO
|
||||
func toResponse(record *model.AgentRechargeRecord, shopName string) *dto.AgentRechargeResponse {
|
||||
resp := &dto.AgentRechargeResponse{
|
||||
@@ -480,6 +497,7 @@ func toResponse(record *model.AgentRechargeRecord, shopName string) *dto.AgentRe
|
||||
Amount: record.Amount,
|
||||
PaymentMethod: record.PaymentMethod,
|
||||
Status: record.Status,
|
||||
StatusName: agentRechargeStatusName(record.Status),
|
||||
CreatedAt: record.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
UpdatedAt: record.UpdatedAt.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user