Files
hi-server/doc/withdrawal-list-subscribe-fields-zh.md
T
shanshanzhong147 3e265bd837
Build docker and publish / build (20.15.1) (push) Failing after 13m47s
Build docker and publish / build (20.15.1) (pull_request) Failing after 15m7s
新功能: 还原 v1/public/user/invite_sales 接口 + promo schema 修复迁移
- 还原 /v1/public/user/invite_sales 接口及 /invite/sales 别名(与 invite_records 并存)
  逻辑/handler/types 与 197fed7d 删除前版本完全一致,按 fefbd4f5 新 routes 结构注册
- 新增迁移 02155_promo_schema_fix: 幂等修复 subscribe_promo / order 列类型与索引偏差
- 同步 etc/ppanel.yaml 数据库连接配置
- 补齐相关需求与设计文档
2026-05-28 20:46:37 -07:00

154 lines
5.8 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.
# 用户端提现列表 API — 订阅字段现状调研
> 调研日期:2026-05-27
> 调研范围:用户端「提现记录列表」接口当前返回字段,重点关注是否包含订阅相关信息
## 一、接口信息
| 项目 | 值 |
|------|-----|
| 方法 | `GET` |
| 路径 | `/v1/public/user/withdrawal_log` |
| 认证 | JWT Token`AuthMiddleware` + `DeviceMiddleware` |
| 分组 | `apis/public/user.api` |
## 二、文件定位
| 层 | 路径 |
|----|------|
| API DSL | `apis/public/user.api:118` (`WithdrawalLog`) / `apis/public/user.api:368` (路由) |
| Handler | `internal/handler/public/user/queryWithdrawalLogHandler.go` |
| Logic | `internal/logic/public/user/queryWithdrawalLogLogic.go:30` |
| 类型生成 | `internal/types/types.go``WithdrawalLog``QueryWithdrawalLogListRequest``QueryWithdrawalLogListResponse` |
| 数据模型 | `internal/model/user/user.go:167` (`Withdrawal`,表名 `withdrawals` |
## 三、请求参数
```go
QueryWithdrawalLogListRequest {
Page int `form:"page"`
Size int `form:"size"`
}
```
- 默认值:`page=1``size=10`(在 logic 内兜底)
## 四、响应结构
### 4.1 顶层响应
```go
QueryWithdrawalLogListResponse {
List []WithdrawalLog `json:"list"`
Total int64 `json:"total"`
}
```
### 4.2 列表项 `WithdrawalLog`
```go
WithdrawalLog {
Id int64 `json:"id"`
UserId int64 `json:"user_id"`
Amount int64 `json:"amount"` // 单位:分
Content string `json:"content"` // 收款附加信息
Status uint8 `json:"status"` // 0:Pending 1:Approved 2:Rejected 3:Cancelled
Reason string `json:"reason,omitempty"` // 拒绝原因
Method uint8 `json:"method"` // 0:其他 1:支付宝 2:微信 3:USDT
Account string `json:"account"` // 收款账号
QrCodeUrl string `json:"qr_code_url"` // 收款码图片 URL
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}
```
## 五、底层数据模型 `Withdrawal`
```go
type Withdrawal struct {
Id int64
UserId int64 // index:idx_user_id
Amount int64
Content string // type:text
Status uint8 // 0:Pending 1:Approved 2:Rejected 3:Cancelled
Reason string // varchar(500)
Method uint8 // 0:其他 1:支付宝 2:微信 3:USDT
Account string // varchar(255)
QrCodeUrl string // varchar(500)
CreatedAt time.Time
UpdatedAt time.Time
}
```
> 表名:`withdrawals`,与用户关联仅靠 `user_id` 外键,**无任何订阅 ID / 订阅快照字段**。
## 六、订阅字段现状(核心结论)
### 6.1 当前结论
| 维度 | 是否包含订阅信息 |
|------|------------------|
| API 响应(`WithdrawalLog` | ❌ 无 |
| 数据库表(`withdrawals` | ❌ 无 |
| Logic 查询逻辑 | ❌ 无 JOIN、无附加查询 `user_subscribe` |
提现记录与订阅之间**完全没有关联**。原因:佣金来源于多次订单累计,提现是从「佣金余额(`user.commission`)」整体扣减,不绑定到任何具体订阅。
### 6.2 Logic 当前实现要点
```go
// internal/logic/public/user/queryWithdrawalLogLogic.go:46-72
query := l.svcCtx.DB.WithContext(l.ctx).
Model(&user.Withdrawal{}).
Where("user_id = ?", u.Id)
// 仅按 user_id 过滤 + 分页 + 倒序,无任何 Preload / Join
```
## 七、已发现的隐患(与本次需求关联)
### 7.1 时间戳违反项目约定 ⚠️
`queryWithdrawalLogLogic.go:70-71`
```go
CreatedAt: row.CreatedAt.UnixMilli(),
UpdatedAt: row.UpdatedAt.UnixMilli(),
```
- 项目约定:**后端统一返回秒级 Unix 时间戳**(前端 `formatDate` 已按 `数字 × 1000` 处理)
- 当前实现返回毫秒级,前端会解析为约公元 +55000 年的日期,**展示必然异常**
- 修复方式:改为 `.Unix()`
> 该问题独立于「订阅字段」需求,但属于同一接口,建议同批修复。
## 八、可选扩展方向(待业务确认)
若产品希望在提现列表中展示订阅相关信息,可选方案如下:
| 方案 | 字段示意 | 实现成本 | 适用场景 |
|------|----------|----------|----------|
| A. 当前生效订阅摘要 | `current_subscribe: { id, name, expire_at }` | 中(每行额外查 `user_subscribe`) | 想让用户看到「我提的是哪个订阅产生的佣金对应的余额」 |
| B. 用户全部订阅列表 | `subscribes: [{ id, name, expire_at }]` | 高(N+1 风险) | 极少场景,需评估必要性 |
| C. 仅订阅 ID 数组 | `subscribe_ids: [int64]` | 低 | 仅前端跳详情用 |
| D. 不加,保持现状 | — | 0 | 若业务上提现与订阅本就无关 |
> **推荐先与产品确认动机**:提现是佣金余额提现,与订阅本身没有直接业务关系,加字段前需明确「让用户看到订阅信息要解决什么问题」。
## 九、相关接口(一并列出,便于对照)
| 接口 | 方法 | 路径 | 说明 |
|------|------|------|------|
| 提交提现 | POST | `/v1/public/user/commission_withdraw` | 入参 `CommissionWithdrawRequest`,返回 `WithdrawalLog` |
| 取消提现 | POST | `/v1/public/user/withdrawal_cancel` | 入参 `CancelWithdrawalRequest`,返回 `WithdrawalLog` |
| 提现记录列表 | GET | `/v1/public/user/withdrawal_log` | 本文主角 |
> 三个接口共用 `WithdrawalLog` 类型,**任何字段变更需统一同步**,否则前端类型会错位。
## 十、后续动作建议
1. **产品确认**:是否真的需要在提现列表里返回订阅字段?目的是什么?
2. **若需新增**:在 `apis/public/user.api` 修改 `WithdrawalLog`,运行 goctl 重新生成,再补 Logic 查询。
3. **顺手修复**:将 `UnixMilli()` 改为 `Unix()`(独立小 PR 即可)。
4. **如新增订阅字段**:注意三个接口(list / cancel / withdraw)的返回结构同步,避免前端类型联动断裂。