# 后台提现审核数据对接 ## 需求 在后台管理的"交易中心-提现审核"页面,完善数据显示,让管理员能够: 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.00(100 × 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.00(50 + 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` - 小程序提现页面 ## 总结 这次数据对接实现了: ### 功能增强 - ✅ 显示用户的完整佣金信息 - ✅ 计算审核后余额 - ✅ 风险警告(超额提现) - ✅ 数据实时计算,确保准确 ### 管理便利 - ✅ 一眼看清用户的资金状况 - ✅ 提前识别超额提现风险 - ✅ 批准/拒绝决策有据可依 ### 安全保障 - ✅ 三层校验(前端、后端、管理端) - ✅ 并发提现检测 - ✅ 超额提现警告 **核心价值**:让管理员能够**看到完整的资金流水**,做出**明智的审核决策**,防止**超额提现风险**。