# 可提现金额计算修复 ## 问题总结 ### 发现的问题 **当前逻辑(错误)**: ```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. 逻辑清晰,符合资金流向 ``` ### 业务含义 - **累计佣金**:成就感 - "我赚了多少" - **已提现**:安全感 - "我拿到了多少" - **待审核**:期待感 - "我正在提多少" - **可提现**:行动力 - "我能提多少" 这样的设计既满足了用户查看历史成就的需求,又确保了资金安全和准确性。