/** * 推荐码绑定API - 增强版 * * 核心规则: * 1. 链接带ID:谁发的链接,进的人就绑谁 * 2. 一级、一月:只有一级分销;绑定有效期一个月 * 3. 长期不发:别人发得多,客户会被「抢走」 * 4. 每天发:持续发的人绑定一直有效,收益越来越高 * 5. 约90%给分发:谁发得多谁拿得多 */ import { NextRequest, NextResponse } from 'next/server' import { query, getConfig } from '@/lib/db' // 绑定有效期(天)- 默认值,优先从配置读取 const DEFAULT_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 }) } // 获取绑定天数配置 let bindingDays = DEFAULT_BINDING_DAYS try { const config = await getConfig('referral_config') if (config?.bindingDays) { bindingDays = Number(config.bindingDays) } } catch (e) { console.warn('[Referral Bind] 读取配置失败,使用默认值', DEFAULT_BINDING_DAYS) } // 查找推荐人 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 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=续期, switch=立即切换 let oldReferrerId = null if (existingBindings.length > 0) { const existing = existingBindings[0] // 同一个推荐人 - 续期(刷新30天) if (existing.referrer_id === referrer.id) { action = 'renew' } // 不同推荐人 - 立即切换(新逻辑:无条件切换) else { action = 'switch' oldReferrerId = existing.referrer_id // 将旧绑定标记为 cancelled(被切换) await query( "UPDATE referral_bindings SET status = 'cancelled' WHERE id = ?", [existing.id] ) console.log(`[Referral Bind] 立即切换: ${user.id}: ${oldReferrerId} -> ${referrer.id}`) } } // 计算新的过期时间(从配置读取天数) const expiryDate = new Date() expiryDate.setDate(expiryDate.getDate() + bindingDays) // 创建或更新绑定记录 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},新过期时间: ${expiryDate.toISOString()}`) } 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]) // 注意:不再更新 users.referred_by(已弃用,只使用 referral_bindings) // 更新推荐人的推广数量(仅新绑定时) if (action === 'new') { await query( 'UPDATE users SET referral_count = referral_count + 1 WHERE id = ?', [referrer.id] ) console.log(`[Referral Bind] 新绑定: ${user.id} -> ${referrer.id}`) } // 如果是立即切换,更新双方的推广数量 if (action === 'switch' && oldReferrerId) { // 减少旧推荐人的数量 await query( 'UPDATE users SET referral_count = GREATEST(referral_count - 1, 0) WHERE id = ?', [oldReferrerId] ) // 增加新推荐人的数量 await query( 'UPDATE users SET referral_count = referral_count + 1 WHERE id = ?', [referrer.id] ) console.log(`[Referral Bind] 立即切换完成: ${user.id}: ${oldReferrerId} -> ${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) { // 访问日志表可能不存在,忽略错误 } const messages = { new: '绑定成功', renew: '绑定已续期', switch: '已切换推荐人' } return NextResponse.json({ success: true, message: messages[action] || '绑定成功', action, expiryDate: expiryDate.toISOString(), bindingDays, referrer: { id: referrer.id, nickname: referrer.nickname }, ...(oldReferrerId && { oldReferrerId }) }) } 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 FROM users WHERE id = ?', [userId] ) as any[] if (users.length === 0) { return NextResponse.json({ success: false, error: '用户不存在' }, { status: 404 }) } // 从 referral_bindings 查询当前有效的推荐人 let referrer = null const activeBinding = await query(` SELECT rb.referrer_id, u.nickname, u.avatar, rb.expiry_date, rb.purchase_count FROM referral_bindings rb JOIN users u ON rb.referrer_id = u.id WHERE rb.referee_id = ? AND rb.status = 'active' AND rb.expiry_date > NOW() ORDER BY rb.binding_date DESC LIMIT 1 `, [userId]) as any[] if (activeBinding.length > 0) { referrer = { id: activeBinding[0].referrer_id, nickname: activeBinding[0].nickname, avatar: activeBinding[0].avatar, expiryDate: activeBinding[0].expiry_date, purchaseCount: activeBinding[0].purchase_count } } // 获取该用户推荐的人(所有活跃绑定) const referees = await query(` SELECT u.id, u.nickname, u.avatar, rb.binding_date as created_at, rb.purchase_count, rb.total_commission FROM referral_bindings rb JOIN users u ON rb.referee_id = u.id WHERE rb.referrer_id = ? AND rb.status = 'active' AND rb.expiry_date > NOW() ORDER BY rb.binding_date DESC `, [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 }) } }