Files
soul-yongping/开发文档/8、部署/后台提现审核数据对接.md
2026-02-09 15:09:29 +08:00

378 lines
9.7 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.

# 后台提现审核数据对接
## 需求
在后台管理的"交易中心-提现审核"页面,完善数据显示,让管理员能够:
1. 查看用户的累计佣金信息
2. 查看用户的已提现金额
3. 查看用户的待审核提现金额
4. 预判审核通过后用户的剩余余额
5. 识别超额提现风险
## 实现内容
### 1. 后端API增强
**文件**`app/api/admin/withdrawals/route.ts`
#### 数据库查询优化
添加了用户佣金相关信息的查询:
```typescript
SELECT
w.*,
u.nickname as user_nickname,
u.phone as user_phone,
u.avatar as user_avatar,
u.referral_code,
u.withdrawn_earnings,
u.earnings,
u.pending_earnings,
-- 计算累计佣金(从 orders 表)
(SELECT COALESCE(SUM(o.amount), 0)
FROM orders o
WHERE o.referrer_id = w.user_id AND o.status = 'paid') as total_order_amount,
-- 计算待审核提现金额(不包括当前这条)
(SELECT COALESCE(SUM(w2.amount), 0)
FROM withdrawals w2
WHERE w2.user_id = w.user_id AND w2.status = 'pending' AND w2.id != w.id) as other_pending_amount
FROM withdrawals w
LEFT JOIN users u ON w.user_id = u.id
```
#### 返回数据结构
新增 `userCommissionInfo` 字段:
```typescript
{
id: string,
userId: string,
userNickname: string,
amount: number,
status: string,
// ... 其他字段
// ✅ 新增:用户佣金信息
userCommissionInfo: {
totalCommission: number, // 累计佣金(订单金额 × 90%
withdrawnEarnings: number, // 已提现金额
pendingWithdrawals: number, // 待审核金额(包括当前这笔)
availableAfterThis: number // 审核通过后的剩余余额
}
}
```
#### 计算逻辑
```typescript
// 计算累计佣金90%分成)
const totalCommission = parseFloat(w.total_order_amount) * 0.9
// 已提现金额
const withdrawnEarnings = parseFloat(w.withdrawn_earnings) || 0
// 其他待审核金额(不包括当前这笔)
const otherPendingAmount = parseFloat(w.other_pending_amount) || 0
// 当前提现金额
const currentWithdrawAmount = parseFloat(w.amount)
// ✅ 审核后余额 = 累计佣金 - 已提现 - 其他待审核 - 当前提现
const availableAfterThis = totalCommission - withdrawnEarnings - otherPendingAmount - currentWithdrawAmount
```
### 2. 前端页面增强
**文件**`app/admin/withdrawals/page.tsx`
#### 新增列:用户佣金信息
在表格中添加了一列显示用户的完整佣金情况:
| 字段 | 说明 | 颜色 |
|------|------|------|
| 累计佣金 | 用户的历史总佣金 | 青色(#38bdac |
| 已提现 | 已到账的金额 | 灰色 |
| 待审核 | 所有待审核的提现申请总和 | 橙色 |
| 审核后余额 | 如果通过当前申请,用户剩余的可提现金额 | 绿色≥0/ 红色(<0 |
#### 界面效果
```
┌─────────────────────────────────────────┐
│ 用户佣金信息 │
├─────────────────────────────────────────┤
│ 累计佣金: ¥100.00 [青色] │
│ 已提现: ¥30.00 [灰色] │
│ 待审核: ¥50.00 [橙色] │
│ ───────────────────────────── │
│ 审核后余额: ¥20.00 [绿色] │
└─────────────────────────────────────────┘
```
#### 风险警告
`审核后余额 < 0`
- 显示为红色
- 批准时弹出警告提示
```typescript
if (withdrawal.userCommissionInfo.availableAfterThis < 0) {
confirm(`⚠️ 风险警告:该用户审核后余额为负数(¥${availableAfterThis}),可能存在超额提现。\n\n确认已核实用户账户并完成打款`)
}
```
## 数据示例
### 示例1正常提现
```
用户A
- 累计佣金: ¥100
- 已提现: ¥30
- 其他待审核: ¥20
- 当前申请: ¥40
审核后余额 = 100 - 30 - 20 - 40 = ¥10 ✅ 正常
```
### 示例2超额提现风险
```
用户B
- 累计佣金: ¥100
- 已提现: ¥30
- 其他待审核: ¥20
- 当前申请: ¥60
审核后余额 = 100 - 30 - 20 - 60 = -¥10 ❌ 超额!
```
**警告**用户B可能存在以下问题
1. 重复提现并发提交
2. 恶意超额提现
3. 数据异常
### 示例3多笔待审核
```
用户C
- 累计佣金: ¥200
- 已提现: ¥50
- 其他待审核: ¥80两笔¥50 + ¥30
- 当前申请: ¥50
审核后余额 = 200 - 50 - 80 - 50 = ¥20 ✅ 正常
但注意:如果三笔都通过,还能再提 ¥20
```
## 审核流程
### 管理员视角
```
1. 打开提现审核页面
2. 查看待审核列表
3. 查看用户佣金信息
- 累计佣金: 判断用户赚了多少
- 已提现: 判断之前提现过多少
- 待审核: 判断还有多少在审核中
- 审核后余额: 判断是否超额
4. 点击"批准"或"拒绝"
5. 如果审核后余额 < 0:
- ⚠️ 弹出风险警告
- 需要二次确认
6. 确认后执行操作
```
### 决策依据
**批准条件**
- 审核后余额 0
- 用户信息真实
- 已完成线下打款或准备自动转账
**拒绝条件**
- 审核后余额 < 0超额提现
- 用户信息异常
- 疑似恶意提现
- 未完成打款且不打算打款
## 统计信息
### 顶部统计卡片
显示全局提现统计
| 统计项 | 说明 |
|--------|------|
| 总申请 | 所有提现申请的数量 |
| 待处理 | 状态为 pending 的数量和金额 |
| 已完成 | 状态为 success 的数量和金额 |
| 已拒绝 | 状态为 failed 的数量 |
### 筛选功能
可以按状态筛选
- 全部
- 待处理pending
- 已完成success
- 已拒绝failed
## 状态说明
| 状态 | 英文 | 说明 | 可操作 |
|------|------|------|--------|
| 待处理 | pending | 用户刚提交等待审核 | 批准/拒绝 |
| 处理中 | processing | 已发起微信转账等待到账 | - |
| 已完成 | success | 已到账提现完成 | - |
| 已拒绝 | failed | 管理员拒绝余额已返还 | - |
## 测试步骤
### 1. 准备测试数据
```sql
-- 插入测试用户
INSERT INTO users (id, nickname, phone, withdrawn_earnings, referral_code)
VALUES ('test_user_1', '测试用户A', '13800138000', 0, 'SOULA001');
-- 插入测试订单(产生佣金)
INSERT INTO orders (id, user_id, amount, referrer_id, status, pay_time)
VALUES ('order_1', 'buyer_1', 100, 'test_user_1', 'paid', NOW());
-- 插入测试提现申请
INSERT INTO withdrawals (id, user_id, amount, status, created_at)
VALUES ('W001', 'test_user_1', 50, 'pending', NOW());
```
### 2. 访问页面
```
http://localhost:3006/admin/withdrawals
```
### 3. 验证数据
**查看提现记录**
- 用户昵称测试用户A
- 电话138****8000
- 提现金额:¥50.00
**查看佣金信息**
- 累计佣金:¥90.00100 × 90%
- 已提现:¥0.00
- 待审核:¥50.00
- 审核后余额:¥40.00
### 4. 测试超额提现
```sql
-- 再插入一笔超额提现
INSERT INTO withdrawals (id, user_id, amount, status, created_at)
VALUES ('W002', 'test_user_1', 60, 'pending', NOW());
```
**刷新页面**查看 W002
- 累计佣金:¥90.00
- 已提现:¥0.00
- 待审核:¥110.0050 + 60
- 审核后余额**-¥20.00** 红色显示
**点击批准**
- 应该弹出风险警告
- 需要二次确认
## 安全检查
### 防止超额提现
1. **前端校验**小程序端计算可提现金额
2. **后端校验**提现接口验证金额
3. **管理端提示**显示审核后余额红色警告
### 并发提现防护
如果用户快速提交多笔提现
- 后端查询会累加所有待审核金额
- 管理员能看到"待审核"总额
- "审核后余额"会提前减去所有待审核的金额
### 数据一致性
- 累计佣金实时从 orders 表计算
- 已提现 users.withdrawn_earnings 读取
- 待审核实时从 withdrawals 表查询
## 常见问题
### Q1: 为什么审核后余额是负数?
**A**: 可能原因
1. 用户并发提交多笔提现
2. 前端校验被绕过
3. 数据库数据异常
**处理**
- 拒绝超额提现申请
- 核查用户账户
- 只批准合理范围内的提现
### Q2: 如果有多笔待审核,应该如何处理?
**A**:
- 查看"待审核"总额
- 确保所有待审核的总和 可提现金额
- 按时间顺序逐笔审核
- 或者拒绝超额的申请
### Q3: 审核后余额为0还能再提现吗
**A**:
- 如果有新订单产生佣金可以
- 审核后余额0表示当前所有佣金都将被提走
- 新订单会增加累计佣金从而增加可提现金额
### Q4: 如何处理已拒绝的提现?
**A**:
- 拒绝时余额自动返还
- 用户可以在小程序重新申请
- "审核后余额"会恢复
## 相关文件
- `app/admin/withdrawals/page.tsx` - 前端页面
- `app/api/admin/withdrawals/route.ts` - 后端API
- `app/api/withdraw/route.ts` - 用户提现接口
- `miniprogram/pages/referral/referral.js` - 小程序提现页面
## 总结
这次数据对接实现了
### 功能增强
- 显示用户的完整佣金信息
- 计算审核后余额
- 风险警告超额提现
- 数据实时计算确保准确
### 管理便利
- 一眼看清用户的资金状况
- 提前识别超额提现风险
- 批准/拒绝决策有据可依
### 安全保障
- 三层校验前端后端管理端
- 并发提现检测
- 超额提现警告
**核心价值**让管理员能够**看到完整的资金流水**做出**明智的审核决策**防止**超额提现风险**。