360 lines
10 KiB
Markdown
360 lines
10 KiB
Markdown
|
|
# 可提现金额计算修复
|
|||
|
|
|
|||
|
|
## 问题总结
|
|||
|
|
|
|||
|
|
### 发现的问题
|
|||
|
|
|
|||
|
|
**当前逻辑(错误)**:
|
|||
|
|
```javascript
|
|||
|
|
可提现金额 = 累计佣金 - 待审核金额
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**问题场景**:
|
|||
|
|
1. 用户累计佣金 ¥100,申请提现 ¥50
|
|||
|
|
2. 此时:可提现 = 100 - 50 = ¥50 ✅ 正确
|
|||
|
|
3. 审核通过后,提现记录状态改为 completed
|
|||
|
|
4. 此时:可提现 = 100 - 0 = ¥100 ❌ 错误!
|
|||
|
|
|
|||
|
|
**根本原因**:审核通过后,`pendingWithdrawAmount` 归零,但没有减去"已提现金额",导致可提现金额"回血"。
|
|||
|
|
|
|||
|
|
## 正确方案
|
|||
|
|
|
|||
|
|
### 计算公式
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
可提现金额 = 累计佣金 - 已提现金额 - 待审核金额
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 字段说明
|
|||
|
|
|
|||
|
|
| 字段 | 说明 | 来源 | 变化规律 |
|
|||
|
|
|------|------|------|----------|
|
|||
|
|
| `totalCommission` | 累计佣金总额 | `SUM(orders.amount) × distributorShare` | 有新订单就增加,只增不减 |
|
|||
|
|
| `withdrawnEarnings` | 已提现金额 | `users.withdrawn_earnings` | 审核通过时累加 |
|
|||
|
|
| `pendingWithdrawAmount` | 待审核金额 | `SUM(withdrawals.amount WHERE status='pending')` | 申请时增加,审核后归零 |
|
|||
|
|
| `availableEarnings` | 可提现金额 | 前端计算 | 动态变化 |
|
|||
|
|
|
|||
|
|
## 修复内容
|
|||
|
|
|
|||
|
|
### 1. 前端计算逻辑修正
|
|||
|
|
|
|||
|
|
**文件**:`miniprogram/pages/referral/referral.js`
|
|||
|
|
|
|||
|
|
**修改前**:
|
|||
|
|
```javascript
|
|||
|
|
// ❌ 错误:只减去待审核,没减去已提现
|
|||
|
|
const totalCommissionNum = realData?.totalCommission || 0
|
|||
|
|
const pendingWithdrawNum = realData?.pendingWithdrawAmount || 0
|
|||
|
|
const availableEarningsNum = totalCommissionNum - pendingWithdrawNum
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**修改后**:
|
|||
|
|
```javascript
|
|||
|
|
// ✅ 正确:三元素完整计算
|
|||
|
|
const totalCommissionNum = realData?.totalCommission || 0
|
|||
|
|
const withdrawnNum = realData?.withdrawnEarnings || 0
|
|||
|
|
const pendingWithdrawNum = realData?.pendingWithdrawAmount || 0
|
|||
|
|
const availableEarningsNum = totalCommissionNum - withdrawnNum - pendingWithdrawNum
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 详细日志输出
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
console.log('=== [Referral] 收益计算(完整版)===')
|
|||
|
|
console.log('累计佣金 (totalCommission):', totalCommissionNum)
|
|||
|
|
console.log('已提现金额 (withdrawnEarnings):', withdrawnNum)
|
|||
|
|
console.log('待审核金额 (pendingWithdrawAmount):', pendingWithdrawNum)
|
|||
|
|
console.log('可提现金额 = 累计 - 已提现 - 待审核 =', totalCommissionNum, '-', withdrawnNum, '-', pendingWithdrawNum, '=', availableEarningsNum)
|
|||
|
|
console.log('最低提现金额 (minWithdrawAmount):', minWithdrawAmount)
|
|||
|
|
console.log('按钮判断:', availableEarningsNum, '>=', minWithdrawAmount, '=', availableEarningsNum >= minWithdrawAmount)
|
|||
|
|
console.log('✅ 按钮应该:', availableEarningsNum >= minWithdrawAmount ? '🟢 启用(绿色)' : '⚫ 禁用(灰色)')
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 验证流程
|
|||
|
|
|
|||
|
|
### 完整场景测试
|
|||
|
|
|
|||
|
|
#### 场景1:初始状态
|
|||
|
|
```
|
|||
|
|
数据:
|
|||
|
|
- 累计佣金: ¥100
|
|||
|
|
- 已提现: ¥0
|
|||
|
|
- 待审核: ¥0
|
|||
|
|
|
|||
|
|
计算:
|
|||
|
|
availableEarnings = 100 - 0 - 0 = ¥100
|
|||
|
|
|
|||
|
|
验证:✅ 可提现 ¥100
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 场景2:申请提现
|
|||
|
|
```
|
|||
|
|
操作:申请提现 ¥50
|
|||
|
|
|
|||
|
|
数据:
|
|||
|
|
- 累计佣金: ¥100 (不变)
|
|||
|
|
- 已提现: ¥0 (不变)
|
|||
|
|
- 待审核: ¥50 (新增)
|
|||
|
|
|
|||
|
|
计算:
|
|||
|
|
availableEarnings = 100 - 0 - 50 = ¥50
|
|||
|
|
|
|||
|
|
验证:✅ 可提现 ¥50
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 场景3:审核通过(关键)
|
|||
|
|
```
|
|||
|
|
操作:管理员审核通过
|
|||
|
|
|
|||
|
|
数据:
|
|||
|
|
- 累计佣金: ¥100 (不变)
|
|||
|
|
- 已提现: ¥50 (users.withdrawn_earnings += 50)
|
|||
|
|
- 待审核: ¥0 (状态改为 completed)
|
|||
|
|
|
|||
|
|
计算:
|
|||
|
|
availableEarnings = 100 - 50 - 0 = ¥50
|
|||
|
|
|
|||
|
|
验证:✅ 可提现 ¥50(不会回血!)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 场景4:新订单产生
|
|||
|
|
```
|
|||
|
|
操作:用户购买新商品,产生佣金 ¥20
|
|||
|
|
|
|||
|
|
数据:
|
|||
|
|
- 累计佣金: ¥120 (100 + 20)
|
|||
|
|
- 已提现: ¥50 (不变)
|
|||
|
|
- 待审核: ¥0 (不变)
|
|||
|
|
|
|||
|
|
计算:
|
|||
|
|
availableEarnings = 120 - 50 - 0 = ¥70
|
|||
|
|
|
|||
|
|
验证:✅ 可提现 ¥70
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 场景5:二次提现
|
|||
|
|
```
|
|||
|
|
操作:申请提现 ¥30
|
|||
|
|
|
|||
|
|
数据:
|
|||
|
|
- 累计佣金: ¥120 (不变)
|
|||
|
|
- 已提现: ¥50 (不变)
|
|||
|
|
- 待审核: ¥30 (新增)
|
|||
|
|
|
|||
|
|
计算:
|
|||
|
|
availableEarnings = 120 - 50 - 30 = ¥40
|
|||
|
|
|
|||
|
|
验证:✅ 可提现 ¥40
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 数据库验证
|
|||
|
|
|
|||
|
|
#### 1. 检查 users 表
|
|||
|
|
```sql
|
|||
|
|
SELECT
|
|||
|
|
id,
|
|||
|
|
nickname,
|
|||
|
|
withdrawn_earnings
|
|||
|
|
FROM users
|
|||
|
|
WHERE id = 'YOUR_USER_ID';
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2. 检查 withdrawals 表
|
|||
|
|
```sql
|
|||
|
|
SELECT
|
|||
|
|
id,
|
|||
|
|
amount,
|
|||
|
|
status,
|
|||
|
|
created_at
|
|||
|
|
FROM withdrawals
|
|||
|
|
WHERE user_id = 'YOUR_USER_ID'
|
|||
|
|
ORDER BY created_at DESC;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 3. 检查 orders 表
|
|||
|
|
```sql
|
|||
|
|
SELECT
|
|||
|
|
SUM(amount) as total_amount
|
|||
|
|
FROM orders
|
|||
|
|
WHERE referrer_id = 'YOUR_USER_ID'
|
|||
|
|
AND status = 'paid';
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 4. 手动验证计算
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
-- 1. 累计佣金
|
|||
|
|
SET @total_orders = (SELECT SUM(amount) FROM orders WHERE referrer_id = 'YOUR_USER_ID' AND status = 'paid');
|
|||
|
|
SET @distributor_share = 0.9;
|
|||
|
|
SET @total_commission = @total_orders * @distributor_share;
|
|||
|
|
|
|||
|
|
-- 2. 已提现
|
|||
|
|
SET @withdrawn = (SELECT withdrawn_earnings FROM users WHERE id = 'YOUR_USER_ID');
|
|||
|
|
|
|||
|
|
-- 3. 待审核
|
|||
|
|
SET @pending = (SELECT SUM(amount) FROM withdrawals WHERE user_id = 'YOUR_USER_ID' AND status = 'pending');
|
|||
|
|
|
|||
|
|
-- 4. 可提现
|
|||
|
|
SET @available = @total_commission - @withdrawn - IFNULL(@pending, 0);
|
|||
|
|
|
|||
|
|
-- 显示结果
|
|||
|
|
SELECT
|
|||
|
|
@total_commission as '累计佣金',
|
|||
|
|
@withdrawn as '已提现',
|
|||
|
|
@pending as '待审核',
|
|||
|
|
@available as '可提现';
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 测试步骤
|
|||
|
|
|
|||
|
|
### 1. 清除缓存重新编译
|
|||
|
|
|
|||
|
|
微信开发者工具:
|
|||
|
|
```
|
|||
|
|
工具 → 清除缓存 → 清除全部缓存数据
|
|||
|
|
点击 编译 按钮
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 查看控制台日志
|
|||
|
|
|
|||
|
|
进入分销中心页面,查看日志输出:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
=== [Referral] 收益计算(完整版)===
|
|||
|
|
累计佣金 (totalCommission): 100
|
|||
|
|
已提现金额 (withdrawnEarnings): 0
|
|||
|
|
待审核金额 (pendingWithdrawAmount): 0
|
|||
|
|
可提现金额 = 累计 - 已提现 - 待审核 = 100 - 0 - 0 = 100
|
|||
|
|
最低提现金额 (minWithdrawAmount): 5
|
|||
|
|
按钮判断: 100 >= 5 = true
|
|||
|
|
✅ 按钮应该: 🟢 启用(绿色)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 测试提现流程
|
|||
|
|
|
|||
|
|
1. **申请提现**:点击提现按钮,申请提现
|
|||
|
|
2. **查看变化**:
|
|||
|
|
- 累计佣金不变
|
|||
|
|
- 待审核金额增加
|
|||
|
|
- 可提现金额减少
|
|||
|
|
3. **审核通过**:在管理后台审核通过
|
|||
|
|
4. **再次查看**:
|
|||
|
|
- 累计佣金不变
|
|||
|
|
- 已提现金额增加
|
|||
|
|
- 待审核金额归零
|
|||
|
|
- **可提现金额不应该回血**
|
|||
|
|
|
|||
|
|
### 4. 验证按钮状态
|
|||
|
|
|
|||
|
|
不同情况下按钮的状态:
|
|||
|
|
|
|||
|
|
| 可提现金额 | 最低提现 | 按钮状态 | 按钮文本 |
|
|||
|
|
|-----------|---------|---------|---------|
|
|||
|
|
| ¥10 | ¥5 | 启用 | 申请提现 ¥10 |
|
|||
|
|
| ¥3 | ¥5 | 禁用 | 满5元可提现 |
|
|||
|
|
| ¥0 | ¥5 | 禁用 | 满5元可提现 |
|
|||
|
|
|
|||
|
|
## 常见问题
|
|||
|
|
|
|||
|
|
### Q1: 为什么要分"累计佣金"和"可提现金额"?
|
|||
|
|
|
|||
|
|
**A**:
|
|||
|
|
- **累计佣金**:用户的成就感,"我总共赚了多少"
|
|||
|
|
- **可提现金额**:用户的可操作余额,"我现在能提多少"
|
|||
|
|
|
|||
|
|
### Q2: 已提现的钱还算在累计佣金里吗?
|
|||
|
|
|
|||
|
|
**A**: 是的。累计佣金是历史总和,只增不减。已提现只是资金流向,不影响累计数字。
|
|||
|
|
|
|||
|
|
示例:
|
|||
|
|
- 累计赚了 ¥100(成就)
|
|||
|
|
- 已提现 ¥50(已到手)
|
|||
|
|
- 还能提现 ¥50(余额)
|
|||
|
|
|
|||
|
|
### Q3: 如果审核拒绝会怎样?
|
|||
|
|
|
|||
|
|
**A**:
|
|||
|
|
1. 待审核金额归零(提现申请被取消)
|
|||
|
|
2. 已提现金额不变
|
|||
|
|
3. 可提现金额恢复(用户可以重新申请)
|
|||
|
|
|
|||
|
|
### Q4: users.withdrawn_earnings 会自动更新吗?
|
|||
|
|
|
|||
|
|
**A**: 是的,在两个地方会更新:
|
|||
|
|
- `app/api/withdraw/route.ts` - 自动审核通过时
|
|||
|
|
- `app/api/admin/withdrawals/route.ts` - 管理员审核通过时
|
|||
|
|
|
|||
|
|
### Q5: 为什么不直接从数据库读取可提现金额?
|
|||
|
|
|
|||
|
|
**A**:
|
|||
|
|
- 可提现金额是**动态计算值**,不是固定字段
|
|||
|
|
- 实时计算确保数据准确
|
|||
|
|
- 便于调试和验证逻辑
|
|||
|
|
|
|||
|
|
## 相关文件
|
|||
|
|
|
|||
|
|
- `miniprogram/pages/referral/referral.js` - 前端计算(已修改)✅
|
|||
|
|
- `app/api/referral/data/route.ts` - 数据查询(无需修改)
|
|||
|
|
- `app/api/withdraw/route.ts` - 提现接口(无需修改)
|
|||
|
|
- `app/api/admin/withdrawals/route.ts` - 审核接口(无需修改)
|
|||
|
|
|
|||
|
|
## 数据流图
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌────────────────────────────────────────────┐
|
|||
|
|
│ 订单产生佣金 │
|
|||
|
|
│ ↓ │
|
|||
|
|
│ 累计佣金 (totalCommission) │
|
|||
|
|
│ 持续累加,只增不减 │
|
|||
|
|
│ ↓ │
|
|||
|
|
│ ┌─────────────┴─────────────┐ │
|
|||
|
|
│ ↓ ↓ │
|
|||
|
|
│ 申请提现 继续积累 │
|
|||
|
|
│ ↓ │
|
|||
|
|
│ 待审核 (pendingWithdrawAmount) │
|
|||
|
|
│ 暂时冻结 │
|
|||
|
|
│ ↓ │
|
|||
|
|
│ 审核通过 │
|
|||
|
|
│ ↓ │
|
|||
|
|
│ 已提现 (withdrawnEarnings) │
|
|||
|
|
│ 累加记录 │
|
|||
|
|
│ │
|
|||
|
|
│ ┌─────────────────────────┐ │
|
|||
|
|
│ │ 可提现金额(实时计算) │ │
|
|||
|
|
│ │ = 累计佣金 │ │
|
|||
|
|
│ │ - 已提现金额 │ │
|
|||
|
|
│ │ - 待审核金额 │ │
|
|||
|
|
│ └─────────────────────────┘ │
|
|||
|
|
└────────────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 总结
|
|||
|
|
|
|||
|
|
### 修改前的问题
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
❌ 可提现 = 累计佣金 - 待审核金额
|
|||
|
|
|
|||
|
|
问题:审核通过后,待审核归零,可提现"回血"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 修改后的正确逻辑
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
✅ 可提现 = 累计佣金 - 已提现金额 - 待审核金额
|
|||
|
|
|
|||
|
|
优点:
|
|||
|
|
1. 审核通过后,可提现金额不会增加
|
|||
|
|
2. 只有新订单产生佣金时,可提现金额才会增加
|
|||
|
|
3. 逻辑清晰,符合资金流向
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 业务含义
|
|||
|
|
|
|||
|
|
- **累计佣金**:成就感 - "我赚了多少"
|
|||
|
|
- **已提现**:安全感 - "我拿到了多少"
|
|||
|
|
- **待审核**:期待感 - "我正在提多少"
|
|||
|
|
- **可提现**:行动力 - "我能提多少"
|
|||
|
|
|
|||
|
|
这样的设计既满足了用户查看历史成就的需求,又确保了资金安全和准确性。
|