/** * 提现API - 使用 Prisma ORM * 用户提现到微信零钱 * * Prisma 优势: * - 完全类型安全 * - 自动防SQL注入 * - 简化复杂查询 */ import { NextRequest, NextResponse } from 'next/server' import { prisma } from '@/lib/prisma' import { Decimal } from '@/lib/generated/prisma/runtime/library' // 读取系统配置(使用 Prisma) async function getPrismaConfig(key: string): Promise { try { const config = await prisma.system_config.findUnique({ where: { config_key: key } }) return config?.config_value } catch (e) { console.warn(`[Config] 读取配置 ${key} 失败:`, e) return null } } export async function POST(request: NextRequest) { try { const body = await request.json() const { userId, amount } = body if (!userId) { return NextResponse.json({ success: false, message: '缺少用户ID' }, { status: 400 }) } if (!amount || amount <= 0) { return NextResponse.json({ success: false, message: '提现金额无效' }, { status: 400 }) } // 1. 读取最低提现门槛 let minWithdrawAmount = 10 // 默认值 try { const config = await getPrismaConfig('referral_config') if (config?.minWithdrawAmount) { minWithdrawAmount = Number(config.minWithdrawAmount) } } catch (e) { console.warn('[Withdraw] 读取配置失败,使用默认值 10 元') } // 检查最低提现门槛 if (amount < minWithdrawAmount) { return NextResponse.json({ success: false, message: `最低提现金额为 ¥${minWithdrawAmount},当前 ¥${amount}` }, { status: 400 }) } // 2. 查询用户信息(Prisma 保证类型安全) const user = await prisma.users.findUnique({ where: { id: userId }, select: { id: true, open_id: true, wechat_id: true, withdrawn_earnings: true } }) if (!user) { return NextResponse.json({ success: false, message: '用户不存在' }, { status: 404 }) } const openId = user.open_id || '' if (!openId) { return NextResponse.json({ success: false, message: '提现到微信零钱需先使用微信登录', needBind: true }) } // 提现需绑定微信号(用于后台展示收款账号) const wechatId = user.wechat_id?.trim() || '' if (!wechatId) { return NextResponse.json({ success: false, message: '请先到「设置」中绑定微信号后再提现', needBindWechat: true }) } // 3. 计算累计佣金(从 orders 表查询) let totalCommission = 0 try { // 读取分成比例 let distributorShare = 0.9 // 默认90% try { const config = await getPrismaConfig('referral_config') if (config?.distributorShare) { distributorShare = Number(config.distributorShare) } } catch (e) { console.warn('[Withdraw] 读取分成比例失败,使用默认值 90%') } // 使用 Prisma 聚合查询 const ordersResult = await prisma.orders.aggregate({ where: { referrer_id: userId, status: 'paid' }, _sum: { amount: true } }) const totalAmount = Number(ordersResult._sum.amount || 0) totalCommission = totalAmount * distributorShare console.log('[Withdraw] 佣金计算:') console.log('- 订单总金额:', totalAmount) console.log('- 分成比例:', distributorShare * 100 + '%') console.log('- 累计佣金:', totalCommission) } catch (e) { console.log('[Withdraw] 查询收益失败:', e) } // 4. 已提现金额与待审核金额均以提现表为准(与分销页展示一致,避免 user.withdrawn_earnings 不同步导致负数或超额提现) const [pendingResult, successResult] = await Promise.all([ prisma.withdrawals.aggregate({ where: { user_id: userId, status: 'pending' }, _sum: { amount: true } }), prisma.withdrawals.aggregate({ where: { user_id: userId, status: 'success' }, _sum: { amount: true } }) ]) const withdrawnEarnings = Number(successResult._sum.amount || 0) const pendingWithdrawAmount = Number(pendingResult._sum.amount || 0) // 5. 计算可提现金额(不低于 0) const availableAmount = Math.max(0, totalCommission - withdrawnEarnings - pendingWithdrawAmount) console.log('[Withdraw] 提现验证(完整版):') console.log('- 累计佣金:', totalCommission) console.log('- 已提现金额:', withdrawnEarnings) console.log('- 待审核金额:', pendingWithdrawAmount) console.log('- 可提现金额 =', availableAmount) console.log('- 申请提现金额:', amount) if (amount > availableAmount) { return NextResponse.json({ success: false, message: `可提现金额不足。当前可提现 ¥${availableAmount.toFixed(2)}(累计 ¥${totalCommission.toFixed(2)} - 已提现 ¥${withdrawnEarnings.toFixed(2)} - 待审核 ¥${pendingWithdrawAmount.toFixed(2)})` }) } // 7. 创建提现记录(使用 Prisma,无SQL注入风险) const withdrawId = `W${Date.now()}` const withdrawal = await prisma.withdrawals.create({ data: { id: withdrawId, user_id: userId, amount: new Decimal(amount), status: 'pending', wechat_openid: openId, wechat_id: wechatId, created_at: new Date() } }) return NextResponse.json({ success: true, message: '提现申请已提交,正在审核中,通过后会自动到账您的微信零钱', data: { withdrawId: withdrawal.id, amount: Number(withdrawal.amount), accountType: '微信', status: withdrawal.status } }) } catch (error) { console.error('[Withdraw] Error:', error) return NextResponse.json({ success: false, message: '提现失败: ' + String(error) }, { status: 500 }) } }