Files
soul-yongping/app/api/admin/distribution/overview/route.ts

269 lines
9.4 KiB
TypeScript
Raw Normal View History

/**
* 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 })
}
}