Files
soul-yongping/app/api/db/users/referrals/route.ts

123 lines
4.1 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
* 获取指定用户的所有绑定用户列表
*
* 从 referral_bindings 表查询(已弃用 users.referred_by
*/
import { NextResponse } from 'next/server'
import { query } from '@/lib/db'
export async function GET(request: Request) {
try {
const { searchParams } = new URL(request.url)
const userId = searchParams.get('userId')
const referralCode = searchParams.get('code')
if (!userId && !referralCode) {
return NextResponse.json({
success: false,
error: '缺少用户ID或推广码'
}, { status: 400 })
}
// 如果传入userId先获取该用户的推广码
let code = referralCode
if (userId && !referralCode) {
const userRows = await query('SELECT referral_code FROM users WHERE id = ?', [userId]) as any[]
if (userRows.length === 0) {
return NextResponse.json({
success: false,
error: '用户不存在'
}, { status: 404 })
}
code = userRows[0].referral_code
}
let referrals: any[] = []
// 1. 首先从referral_bindings表查询绑定关系
try {
const bindingsReferrals = await query(`
SELECT
rb.id as binding_id,
rb.referee_id,
rb.status as binding_status,
rb.binding_date,
rb.expiry_date,
rb.commission_amount,
u.id, u.nickname, u.avatar, u.phone, u.open_id,
u.has_full_book, u.purchased_sections,
u.created_at, u.updated_at,
DATEDIFF(rb.expiry_date, NOW()) as days_remaining
FROM referral_bindings rb
JOIN users u ON rb.referee_id = u.id
WHERE rb.referrer_id = ?
ORDER BY rb.binding_date DESC
`, [userId]) as any[]
if (bindingsReferrals.length > 0) {
referrals = bindingsReferrals
}
} catch (e) {
console.log('[Referrals] referral_bindings表查询失败:', e)
// 注意:已弃用 users.referred_by只使用 referral_bindings
}
// 统计信息
const purchasedCount = referrals.filter(r =>
r.has_full_book ||
r.binding_status === 'converted' ||
(r.purchased_sections && r.purchased_sections !== '[]')
).length
// 查询该用户的收益信息
const earningsRows = await query(`
SELECT earnings, pending_earnings, withdrawn_earnings
FROM users WHERE id = ?
`, [userId]) as any[]
const earnings = earningsRows[0] || { earnings: 0, pending_earnings: 0, withdrawn_earnings: 0 }
// 格式化返回数据
const formattedReferrals = referrals.map(r => ({
id: r.referee_id || r.id,
nickname: r.nickname || '微信用户',
avatar: r.avatar,
phone: r.phone ? r.phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2') : null,
hasOpenId: !!r.open_id,
hasPurchased: r.has_full_book || r.binding_status === 'converted' || (r.purchased_sections && r.purchased_sections !== '[]'),
hasFullBook: !!r.has_full_book,
purchasedSections: typeof r.purchased_sections === 'string'
? JSON.parse(r.purchased_sections || '[]').length
: 0,
createdAt: r.binding_date || r.created_at,
bindingStatus: r.binding_status || 'active',
daysRemaining: r.days_remaining,
commission: parseFloat(r.commission_amount) || 0,
status: r.binding_status === 'converted' ? 'converted'
: r.has_full_book ? 'vip'
: (r.purchased_sections && r.purchased_sections !== '[]' ? 'paid' : 'active')
}))
return NextResponse.json({
success: true,
referrals: formattedReferrals,
stats: {
total: referrals.length,
purchased: purchasedCount,
free: referrals.length - purchasedCount,
earnings: parseFloat(earnings.earnings) || 0,
pendingEarnings: parseFloat(earnings.pending_earnings) || 0,
withdrawnEarnings: parseFloat(earnings.withdrawn_earnings) || 0
}
})
} catch (error) {
console.error('Get referrals error:', error)
return NextResponse.json({
success: false,
error: '获取绑定关系失败'
}, { status: 500 })
}
}