/** * 推荐码绑定API - 增强版 * * 核心规则: * 1. 链接带ID:谁发的链接,进的人就绑谁 * 2. 一级、一月:只有一级分销;绑定有效期一个月 * 3. 长期不发:别人发得多,客户会被「抢走」 * 4. 每天发:持续发的人绑定一直有效,收益越来越高 * 5. 约90%给分发:谁发得多谁拿得多 */ import { NextRequest, NextResponse } from 'next/server' import { query, getConfig } from '@/lib/db' // 绑定有效期(天) const BINDING_DAYS = 30 /** * POST - 绑定推荐关系(支持抢夺机制) */ export async function POST(request: NextRequest) { try { const body = await request.json() const { userId, referralCode, openId, source } = body // 验证参数 const effectiveUserId = userId || (openId ? `user_${openId.slice(-8)}` : null) if (!effectiveUserId || !referralCode) { return NextResponse.json({ success: false, error: '用户ID和推荐码不能为空' }, { status: 400 }) } // 查找推荐人 const referrers = await query( 'SELECT id, nickname, referral_code FROM users WHERE referral_code = ?', [referralCode] ) as any[] if (referrers.length === 0) { return NextResponse.json({ success: false, error: '推荐码无效' }, { status: 400 }) } const referrer = referrers[0] // 不能自己推荐自己 if (referrer.id === effectiveUserId) { return NextResponse.json({ success: false, error: '不能使用自己的推荐码' }, { status: 400 }) } // 检查用户是否存在 const users = await query( 'SELECT id, referred_by FROM users WHERE id = ? OR open_id = ?', [effectiveUserId, openId || effectiveUserId] ) as any[] if (users.length === 0) { return NextResponse.json({ success: false, error: '用户不存在' }, { status: 400 }) } const user = users[0] const now = new Date() // 检查现有绑定关系 const existingBindings = await query(` SELECT id, referrer_id, expiry_date, status FROM referral_bindings WHERE referee_id = ? AND status = 'active' ORDER BY binding_date DESC LIMIT 1 `, [user.id]) as any[] let action = 'new' // new=新绑定, renew=续期, takeover=抢夺 let oldReferrerId = null if (existingBindings.length > 0) { const existing = existingBindings[0] const expiryDate = new Date(existing.expiry_date) // 同一个推荐人 - 续期 if (existing.referrer_id === referrer.id) { action = 'renew' } // 不同推荐人 - 检查是否可以抢夺 else if (expiryDate < now) { // 已过期,可以被抢夺 action = 'takeover' oldReferrerId = existing.referrer_id // 将旧绑定标记为过期 await query( "UPDATE referral_bindings SET status = 'expired' WHERE id = ?", [existing.id] ) } else { // 未过期,不能被抢夺 return NextResponse.json({ success: false, error: '用户已绑定其他推荐人,绑定有效期内无法更换', expiryDate: expiryDate.toISOString() }, { status: 400 }) } } // 计算新的过期时间(30天) const expiryDate = new Date() expiryDate.setDate(expiryDate.getDate() + BINDING_DAYS) // 创建或更新绑定记录 const bindingId = 'bind_' + Date.now().toString(36) + Math.random().toString(36).substr(2, 6) if (action === 'renew') { // 续期:更新过期时间 await query(` UPDATE referral_bindings SET expiry_date = ?, binding_date = CURRENT_TIMESTAMP WHERE referee_id = ? AND referrer_id = ? AND status = 'active' `, [expiryDate, user.id, referrer.id]) console.log(`[Referral Bind] 续期: ${user.id} -> ${referrer.id}`) } else { // 新绑定或抢夺 await query(` INSERT INTO referral_bindings ( id, referrer_id, referee_id, referral_code, status, expiry_date, binding_date ) VALUES (?, ?, ?, ?, 'active', ?, CURRENT_TIMESTAMP) ON DUPLICATE KEY UPDATE referrer_id = VALUES(referrer_id), referral_code = VALUES(referral_code), expiry_date = VALUES(expiry_date), binding_date = CURRENT_TIMESTAMP, status = 'active' `, [bindingId, referrer.id, user.id, referralCode, expiryDate]) // 更新用户的推荐人 await query( 'UPDATE users SET referred_by = ? WHERE id = ?', [referrer.id, user.id] ) // 更新推荐人的推广数量(仅新绑定时) if (action === 'new') { await query( 'UPDATE users SET referral_count = referral_count + 1 WHERE id = ?', [referrer.id] ) } // 如果是抢夺,减少原推荐人的推广数量 if (action === 'takeover' && oldReferrerId) { await query( 'UPDATE users SET referral_count = GREATEST(referral_count - 1, 0) WHERE id = ?', [oldReferrerId] ) console.log(`[Referral Bind] 抢夺: ${user.id}: ${oldReferrerId} -> ${referrer.id}`) } else { console.log(`[Referral Bind] 新绑定: ${user.id} -> ${referrer.id}`) } } // 记录访问日志(用于统计「通过链接进的人数」) try { await query(` INSERT INTO referral_visits (referrer_id, visitor_id, source, created_at) VALUES (?, ?, ?, CURRENT_TIMESTAMP) `, [referrer.id, user.id, source || 'miniprogram']) } catch (e) { // 访问日志表可能不存在,忽略错误 } return NextResponse.json({ success: true, message: action === 'renew' ? '绑定已续期' : (action === 'takeover' ? '绑定已更新' : '绑定成功'), action, expiryDate: expiryDate.toISOString(), referrer: { id: referrer.id, nickname: referrer.nickname } }) } catch (error) { console.error('[Referral Bind] 错误:', error) return NextResponse.json({ success: false, error: '绑定失败: ' + (error as Error).message }, { status: 500 }) } } /** * GET - 查询推荐关系 */ export async function GET(request: NextRequest) { const { searchParams } = new URL(request.url) const userId = searchParams.get('userId') const referralCode = searchParams.get('referralCode') try { if (referralCode) { // 查询推荐码对应的用户 const users = await query( 'SELECT id, nickname, avatar FROM users WHERE referral_code = ?', [referralCode] ) as any[] if (users.length === 0) { return NextResponse.json({ success: false, error: '推荐码无效' }, { status: 404 }) } return NextResponse.json({ success: true, referrer: users[0] }) } if (userId) { // 查询用户的推荐关系 const users = await query( 'SELECT id, referred_by FROM users WHERE id = ?', [userId] ) as any[] if (users.length === 0) { return NextResponse.json({ success: false, error: '用户不存在' }, { status: 404 }) } const user = users[0] // 如果有推荐人,获取推荐人信息 let referrer = null if (user.referred_by) { const referrers = await query( 'SELECT id, nickname, avatar FROM users WHERE id = ?', [user.referred_by] ) as any[] if (referrers.length > 0) { referrer = referrers[0] } } // 获取该用户推荐的人 const referees = await query( 'SELECT id, nickname, avatar, created_at FROM users WHERE referred_by = ?', [userId] ) as any[] return NextResponse.json({ success: true, referrer, referees, referralCount: referees.length }) } return NextResponse.json({ success: false, error: '请提供userId或referralCode参数' }, { status: 400 }) } catch (error) { console.error('[Referral Bind] GET错误:', error) return NextResponse.json({ success: false, error: '查询失败: ' + (error as Error).message }, { status: 500 }) } }