/** * 管理端分销数据概览API - 从真实数据库查询 */ import { NextRequest, NextResponse } from 'next/server' import { query } from '@/lib/db' import { requireAdminResponse } from '@/lib/admin-auth' export async function GET(req: NextRequest) { // 验证管理员权限 const authErr = requireAdminResponse(req) if (authErr) return authErr try { const now = new Date() const today = now.toISOString().split('T')[0] const monthStart = new Date(now.getFullYear(), now.getMonth(), 1).toISOString() const sevenDaysLater = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000).toISOString() // === 1. 订单数据统计 === let orderStats = { todayOrders: 0, todayAmount: 0, monthOrders: 0, monthAmount: 0, totalOrders: 0, totalAmount: 0 } try { const orderResults = await query(` SELECT COUNT(*) as total_count, COALESCE(SUM(amount), 0) as total_amount, COALESCE(SUM(CASE WHEN DATE(created_at) = ? THEN 1 ELSE 0 END), 0) as today_count, COALESCE(SUM(CASE WHEN DATE(created_at) = ? THEN amount ELSE 0 END), 0) as today_amount, COALESCE(SUM(CASE WHEN created_at >= ? THEN 1 ELSE 0 END), 0) as month_count, COALESCE(SUM(CASE WHEN created_at >= ? THEN amount ELSE 0 END), 0) as month_amount FROM orders WHERE status = 'paid' `, [today, today, monthStart, monthStart]) as any[] if (orderResults.length > 0) { const r = orderResults[0] orderStats = { todayOrders: parseInt(r.today_count) || 0, todayAmount: parseFloat(r.today_amount) || 0, monthOrders: parseInt(r.month_count) || 0, monthAmount: parseFloat(r.month_amount) || 0, totalOrders: parseInt(r.total_count) || 0, totalAmount: parseFloat(r.total_amount) || 0 } } } catch (e) { console.error('[Admin Overview] 订单统计失败:', e) } // === 2. 绑定数据统计 === let bindingStats = { todayBindings: 0, todayConversions: 0, monthBindings: 0, monthConversions: 0, totalBindings: 0, totalConversions: 0, activeBindings: 0, expiredBindings: 0, expiringBindings: 0 } try { const bindingResults = await query(` SELECT COUNT(*) as total_count, SUM(CASE WHEN status = 'active' AND expiry_date > NOW() THEN 1 ELSE 0 END) as active_count, SUM(CASE WHEN status = 'converted' THEN 1 ELSE 0 END) as converted_count, SUM(CASE WHEN status = 'expired' OR (status = 'active' AND expiry_date <= NOW()) THEN 1 ELSE 0 END) as expired_count, SUM(CASE WHEN DATE(binding_date) = ? THEN 1 ELSE 0 END) as today_count, SUM(CASE WHEN DATE(binding_date) = ? AND status = 'converted' THEN 1 ELSE 0 END) as today_converted, SUM(CASE WHEN binding_date >= ? THEN 1 ELSE 0 END) as month_count, SUM(CASE WHEN binding_date >= ? AND status = 'converted' THEN 1 ELSE 0 END) as month_converted, SUM(CASE WHEN status = 'active' AND expiry_date <= ? AND expiry_date > NOW() THEN 1 ELSE 0 END) as expiring_count FROM referral_bindings `, [today, today, monthStart, monthStart, sevenDaysLater]) as any[] if (bindingResults.length > 0) { const r = bindingResults[0] bindingStats = { todayBindings: parseInt(r.today_count) || 0, todayConversions: parseInt(r.today_converted) || 0, monthBindings: parseInt(r.month_count) || 0, monthConversions: parseInt(r.month_converted) || 0, totalBindings: parseInt(r.total_count) || 0, totalConversions: parseInt(r.converted_count) || 0, activeBindings: parseInt(r.active_count) || 0, expiredBindings: parseInt(r.expired_count) || 0, expiringBindings: parseInt(r.expiring_count) || 0 } } } catch (e) { console.error('[Admin Overview] 绑定统计失败:', e) } // === 3. 收益数据统计 === let earningsStats = { totalEarnings: 0, todayEarnings: 0, monthEarnings: 0, pendingEarnings: 0 } try { // 从 users 表累加所有用户的收益 const earningsResults = await query(` SELECT COALESCE(SUM(earnings), 0) as total_earnings, COALESCE(SUM(pending_earnings), 0) as pending_earnings FROM users `) as any[] if (earningsResults.length > 0) { earningsStats.totalEarnings = parseFloat(earningsResults[0].total_earnings) || 0 earningsStats.pendingEarnings = parseFloat(earningsResults[0].pending_earnings) || 0 } // 今日和本月收益:从 orders 表计算(status='paid' 的订单) const periodEarningsResults = await query(` SELECT COALESCE(SUM(CASE WHEN DATE(pay_time) = ? THEN amount * 0.9 ELSE 0 END), 0) as today_earnings, COALESCE(SUM(CASE WHEN pay_time >= ? THEN amount * 0.9 ELSE 0 END), 0) as month_earnings FROM orders WHERE status = 'paid' `, [today, monthStart]) as any[] if (periodEarningsResults.length > 0) { earningsStats.todayEarnings = parseFloat(periodEarningsResults[0].today_earnings) || 0 earningsStats.monthEarnings = parseFloat(periodEarningsResults[0].month_earnings) || 0 } } catch (e) { console.error('[Admin Overview] 收益统计失败:', e) } // === 4. 提现数据统计 === let withdrawalStats = { pendingCount: 0, pendingAmount: 0 } try { const withdrawalResults = await query(` SELECT COUNT(*) as pending_count, COALESCE(SUM(amount), 0) as pending_amount FROM withdrawals WHERE status = 'pending' `) as any[] if (withdrawalResults.length > 0) { withdrawalStats.pendingCount = parseInt(withdrawalResults[0].pending_count) || 0 withdrawalStats.pendingAmount = parseFloat(withdrawalResults[0].pending_amount) || 0 } } catch (e) { console.error('[Admin Overview] 提现统计失败:', e) } // === 5. 访问数据统计 === let visitStats = { todayVisits: 0, monthVisits: 0, totalVisits: 0 } try { const visitResults = await query(` SELECT COUNT(*) as total_count, COUNT(DISTINCT CASE WHEN DATE(created_at) = ? THEN id END) as today_count, COUNT(DISTINCT CASE WHEN created_at >= ? THEN id END) as month_count FROM referral_visits `, [today, monthStart]) as any[] if (visitResults.length > 0) { visitStats.totalVisits = parseInt(visitResults[0].total_count) || 0 visitStats.todayVisits = parseInt(visitResults[0].today_count) || 0 visitStats.monthVisits = parseInt(visitResults[0].month_count) || 0 } } catch (e) { console.error('[Admin Overview] 访问统计失败:', e) // 访问表可能不存在,使用绑定数作为替代 visitStats = { todayVisits: bindingStats.todayBindings, monthVisits: bindingStats.monthBindings, totalVisits: bindingStats.totalBindings } } // === 6. 分销商数据统计 === let distributorStats = { totalDistributors: 0, activeDistributors: 0 } try { const distributorResults = await query(` SELECT COUNT(*) as total_count, SUM(CASE WHEN earnings > 0 THEN 1 ELSE 0 END) as active_count FROM users WHERE referral_code IS NOT NULL AND referral_code != '' `) as any[] if (distributorResults.length > 0) { distributorStats.totalDistributors = parseInt(distributorResults[0].total_count) || 0 distributorStats.activeDistributors = parseInt(distributorResults[0].active_count) || 0 } } catch (e) { console.error('[Admin Overview] 分销商统计失败:', e) } // === 7. 计算转化率 === const conversionRate = visitStats.totalVisits > 0 ? ((bindingStats.totalConversions / visitStats.totalVisits) * 100).toFixed(2) : '0.00' // 返回完整概览数据 const overview = { // 今日数据 todayClicks: visitStats.todayVisits, todayBindings: bindingStats.todayBindings, todayConversions: bindingStats.todayConversions, todayEarnings: earningsStats.todayEarnings, // 本月数据 monthClicks: visitStats.monthVisits, monthBindings: bindingStats.monthBindings, monthConversions: bindingStats.monthConversions, monthEarnings: earningsStats.monthEarnings, // 总计数据 totalClicks: visitStats.totalVisits, totalBindings: bindingStats.totalBindings, totalConversions: bindingStats.totalConversions, totalEarnings: earningsStats.totalEarnings, // 其他统计 expiringBindings: bindingStats.expiringBindings, pendingWithdrawals: withdrawalStats.pendingCount, pendingWithdrawAmount: withdrawalStats.pendingAmount, conversionRate, totalDistributors: distributorStats.totalDistributors, activeDistributors: distributorStats.activeDistributors, } console.log('[Admin Overview] 数据统计完成:', overview) return NextResponse.json({ success: true, overview }) } catch (error) { console.error('[Admin Overview] 统计失败:', error) return NextResponse.json({ success: false, error: '获取分销概览失败: ' + (error as Error).message }, { status: 500 }) } }