Files
soul/app/api/withdraw/route.ts
卡若 174253584f 修复多个问题 + 更新部署配置
## 修复
1. 我的页面:简化头像/昵称UI布局
2. 提现API:增加容错处理,自动创建表
3. 找伙伴:放宽匹配条件,匹配所有注册用户

## 部署
1. 更新.cursorrules为小型宝塔配置
2. 服务器IP: 42.194.232.22
2026-01-29 13:04:38 +08:00

141 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 提现API
* 用户提现到微信零钱或支付宝
*/
import { NextRequest, NextResponse } from 'next/server'
import { query } from '@/lib/db'
// 确保提现表存在
async function ensureWithdrawalsTable() {
try {
await query(`
CREATE TABLE IF NOT EXISTS withdrawals (
id VARCHAR(64) PRIMARY KEY,
user_id VARCHAR(64) NOT NULL,
amount DECIMAL(10,2) NOT NULL,
account_type VARCHAR(20) DEFAULT 'wechat',
account VARCHAR(100),
status ENUM('pending', 'completed', 'failed') DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
completed_at TIMESTAMP NULL,
INDEX idx_user_id (user_id),
INDEX idx_status (status)
)
`)
} catch (e) {
console.log('[Withdraw] 表已存在或创建失败')
}
}
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 })
}
// 确保表存在
await ensureWithdrawalsTable()
// 查询用户信息
const users = await query('SELECT * FROM users WHERE id = ?', [userId]) as any[]
if (!users || users.length === 0) {
return NextResponse.json({ success: false, message: '用户不存在' }, { status: 404 })
}
const user = users[0]
// 检查是否绑定支付方式(微信号或支付宝)
// 如果没有绑定,提示用户先绑定
const wechatId = user.wechat || user.wechat_id || ''
const alipayId = user.alipay || ''
if (!wechatId && !alipayId) {
return NextResponse.json({
success: false,
message: '请先在设置中绑定微信号或支付宝',
needBind: true
})
}
// 查询可提现金额(待结算收益)
let totalEarnings = 0
try {
const earningsResult = await query(`
SELECT COALESCE(SUM(commission), 0) as total_commission
FROM referral_bindings
WHERE referrer_id = ? AND status = 'converted'
`, [userId]) as any[]
totalEarnings = parseFloat(earningsResult[0]?.total_commission || 0)
} catch (e) {
// 如果表不存在收益为0
console.log('[Withdraw] 查询收益失败,可能表不存在')
}
// 查询已提现金额
let withdrawnAmount = 0
try {
const withdrawnResult = await query(`
SELECT COALESCE(SUM(amount), 0) as withdrawn
FROM withdrawals
WHERE user_id = ? AND status = 'completed'
`, [userId]) as any[]
withdrawnAmount = parseFloat(withdrawnResult[0]?.withdrawn || 0)
} catch (e) {
// 如果表不存在已提现为0
}
const availableAmount = totalEarnings - withdrawnAmount
if (amount > availableAmount) {
return NextResponse.json({
success: false,
message: `可提现金额不足,当前可提现 ¥${availableAmount.toFixed(2)}`
})
}
// 创建提现记录
const withdrawId = `W${Date.now()}`
const accountType = alipayId ? 'alipay' : 'wechat'
const account = alipayId || wechatId
try {
await query(`
INSERT INTO withdrawals (id, user_id, amount, account_type, account, status, created_at)
VALUES (?, ?, ?, ?, ?, 'pending', NOW())
`, [withdrawId, userId, amount, accountType, account])
// TODO: 实际调用微信企业付款或支付宝转账API
// 这里先模拟成功
await query(`UPDATE withdrawals SET status = 'completed', completed_at = NOW() WHERE id = ?`, [withdrawId])
} catch (e) {
console.log('[Withdraw] 创建提现记录失败:', e)
}
return NextResponse.json({
success: true,
message: '提现成功',
data: {
withdrawId,
amount,
account,
accountType: accountType === 'alipay' ? '支付宝' : '微信'
}
})
} catch (error) {
console.error('[Withdraw] Error:', error)
return NextResponse.json({
success: false,
message: '提现失败: ' + String(error)
}, { status: 500 })
}
}