/** * 后台提现 API * GET: 查提现记录。PUT: 查库 + 更新提现状态 + 更新用户已提现金额(当前未接入微信打款) */ import { NextResponse } from 'next/server' import { query } from '@/lib/db' import { requireAdminResponse } from '@/lib/admin-auth' /** 安全转数组,避免 undefined.length;绝不返回 undefined */ function toArray(x: unknown): T[] { if (x == null) return [] if (Array.isArray(x)) return x as T[] if (typeof x === 'object' && x !== null) return [x] as T[] return [] } /** 安全取数组长度,避免对 undefined 读 .length */ function safeLength(x: unknown): number { if (x == null) return 0 if (Array.isArray(x)) return x.length return 0 } // ========== GET:只查提现记录 ========== export async function GET(request: Request) { console.log('[Withdrawals] GET 开始') try { const authErr = requireAdminResponse(request) if (authErr) return authErr const sql = ` SELECT w.id, w.user_id, w.amount, w.status, w.created_at, u.nickname as user_nickname, u.avatar as user_avatar FROM withdrawals w LEFT JOIN users u ON w.user_id = u.id ORDER BY w.created_at DESC LIMIT 100 ` const result = await query(sql) const rows = toArray(result) const withdrawals = rows.map((w: any) => ({ id: w.id, user_id: w.user_id, user_name: w.user_nickname || '未知用户', userAvatar: w.user_avatar, amount: parseFloat(w.amount) || 0, status: w.status === 'success' ? 'completed' : (w.status === 'failed' ? 'rejected' : w.status), created_at: w.created_at, method: 'wechat', })) return NextResponse.json({ success: true, withdrawals, stats: { total: safeLength(withdrawals) }, }) } catch (error: any) { console.error('[Withdrawals] GET 失败:', error?.message) return NextResponse.json( { success: false, error: '获取提现记录失败: ' + (error?.message || String(error)) }, { status: 500 } ) } } // ========== PUT:查库 + 更新状态 + 更新用户已提现,暂不调用微信打款 ========== export async function PUT(request: Request) { const STEP = '[Withdrawals PUT]' try { console.log(STEP, '1. 开始') const authErr = requireAdminResponse(request) if (authErr) return authErr console.log(STEP, '2. 鉴权通过') const body = await request.json() console.log(STEP, '3. body 已解析', typeof body, body ? 'ok' : 'null') const id = body?.id const action = body?.action const rejectReason = body?.errorMessage || body?.reason || '管理员拒绝' if (!id || !action) { return NextResponse.json({ success: false, error: '缺少 id 或 action' }, { status: 400 }) } console.log(STEP, '4. id/action 有效', id, action) console.log(STEP, '5. 即将 query SELECT') const result = await query('SELECT * FROM withdrawals WHERE id = ?', [id]) console.log(STEP, '6. query 返回', typeof result, 'length=', safeLength(result)) const rows = toArray(result) console.log(STEP, '7. toArray 后 length=', safeLength(rows)) if (safeLength(rows) === 0) { return NextResponse.json({ success: false, error: '提现记录不存在' }, { status: 404 }) } console.log(STEP, '8. 有记录') const row = rows[0] console.log(STEP, '9. row', row ? 'ok' : 'null') if (row.status !== 'pending') { return NextResponse.json({ success: false, error: '该记录已处理,不可重复审批' }, { status: 400 }) } console.log(STEP, '10. 状态 pending') const amount = parseFloat(String(row.amount ?? 0)) || 0 const userId = String(row.user_id ?? '') console.log(STEP, '11. amount/userId', amount, userId) if (action === 'approve') { console.log(STEP, '12. 执行 approve UPDATE withdrawals') await query( `UPDATE withdrawals SET status = 'success', processed_at = NOW(), transaction_id = ? WHERE id = ?`, [`manual_${Date.now()}`, id] ) console.log(STEP, '13. 执行 approve UPDATE users') await query( `UPDATE users SET withdrawn_earnings = COALESCE(withdrawn_earnings, 0) + ? WHERE id = ?`, [amount, userId] ) console.log(STEP, '14. 批准完成') return NextResponse.json({ success: true, message: '已批准,已更新提现状态与用户已提现金额(未发起微信打款)' }) } if (action === 'reject') { console.log(STEP, '15. 执行 reject UPDATE') await query( `UPDATE withdrawals SET status = 'failed', processed_at = NOW(), error_message = ? WHERE id = ?`, [rejectReason, id] ) console.log(STEP, '16. 拒绝完成') return NextResponse.json({ success: true, message: '已拒绝该提现申请' }) } return NextResponse.json({ success: false, error: '无效的 action' }, { status: 400 }) } catch (error: any) { console.error(STEP, '!!! 崩溃 !!!', error?.message) console.error(STEP, '堆栈:', error?.stack) return NextResponse.json( { success: false, error: '审批操作失败: ' + (error?.message || String(error)) }, { status: 500 } ) } }