Files
ai-showcase-platform/app/api/admin/analytics/route.ts
2025-09-19 08:29:51 +08:00

212 lines
7.2 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server"
import { DatabaseService } from "@/lib/services/database-service"
const dbService = new DatabaseService()
export async function GET(request: NextRequest) {
try {
// 獲取總用戶數
const totalUsersResult = await dbService.query(`
SELECT COUNT(*) as total FROM users WHERE is_active = TRUE
`)
const totalUsers = totalUsersResult[0]?.total || 0
// 獲取今日活躍用戶數(今日有登入記錄的用戶)
const today = new Date().toISOString().split('T')[0]
const todayActiveUsersResult = await dbService.query(`
SELECT COUNT(DISTINCT user_id) as count
FROM activity_logs
WHERE DATE(created_at) = ? AND action = 'login'
`, [today])
const todayActiveUsers = todayActiveUsersResult[0]?.count || 0
// 獲取昨日活躍用戶數(用於比較)
const yesterday = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString().split('T')[0]
const yesterdayActiveUsersResult = await dbService.query(`
SELECT COUNT(DISTINCT user_id) as count
FROM activity_logs
WHERE DATE(created_at) = ? AND action = 'login'
`, [yesterday])
const yesterdayActiveUsers = yesterdayActiveUsersResult[0]?.count || 0
// 計算今日活躍用戶增長率
const todayActiveGrowth = yesterdayActiveUsers > 0
? ((todayActiveUsers - yesterdayActiveUsers) / yesterdayActiveUsers * 100).toFixed(1)
: 0
// 獲取平均評分
const avgRatingResult = await dbService.query(`
SELECT AVG(rating) as avg_rating FROM apps WHERE is_active = TRUE AND rating > 0
`)
const avgRating = avgRatingResult[0]?.avg_rating || 0
// 獲取上週平均評分(用於比較)
const lastWeek = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0]
const lastWeekRatingResult = await dbService.query(`
SELECT AVG(rating) as avg_rating
FROM apps
WHERE is_active = TRUE AND rating > 0 AND created_at < ?
`, [lastWeek])
const lastWeekRating = lastWeekRatingResult[0]?.avg_rating || 0
// 計算評分增長
const ratingGrowth = lastWeekRating > 0
? (avgRating - lastWeekRating).toFixed(1)
: 0
// 獲取應用總數
const totalAppsResult = await dbService.query(`
SELECT COUNT(*) as total FROM apps WHERE is_active = TRUE
`)
const totalApps = totalAppsResult[0]?.total || 0
// 獲取本週新增應用數
const weekStart = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0]
const newThisWeekResult = await dbService.query(`
SELECT COUNT(*) as count
FROM apps
WHERE is_active = TRUE AND DATE(created_at) >= ?
`, [weekStart])
const newThisWeek = newThisWeekResult[0]?.count || 0
// 獲取上月用戶數(用於比較)
const lastMonth = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0]
const lastMonthUsersResult = await dbService.query(`
SELECT COUNT(*) as total
FROM users
WHERE is_active = TRUE AND created_at < ?
`, [lastMonth])
const lastMonthUsers = lastMonthUsersResult[0]?.total || 0
// 計算用戶增長率
const userGrowth = lastMonthUsers > 0
? ((totalUsers - lastMonthUsers) / lastMonthUsers * 100).toFixed(1)
: 0
// 獲取近7天的使用趨勢數據
const dailyUsageData = []
for (let i = 6; i >= 0; i--) {
const date = new Date(Date.now() - i * 24 * 60 * 60 * 1000)
const dateStr = date.toISOString().split('T')[0]
const dayName = ["日", "一", "二", "三", "四", "五", "六"][date.getDay()]
// 獲取當日活躍用戶數
const dailyUsersResult = await dbService.query(`
SELECT COUNT(DISTINCT user_id) as count
FROM activity_logs
WHERE DATE(created_at) = ? AND action IN ('login', 'view')
`, [dateStr])
const dailyUsers = dailyUsersResult[0]?.count || 0
// 獲取當日會話數
const dailySessionsResult = await dbService.query(`
SELECT COUNT(*) as count
FROM activity_logs
WHERE DATE(created_at) = ? AND action = 'view'
`, [dateStr])
const dailySessions = dailySessionsResult[0]?.count || 0
dailyUsageData.push({
date: `${date.getMonth() + 1}/${date.getDate()}`,
fullDate: date.toLocaleDateString("zh-TW"),
dayName: dayName,
users: dailyUsers,
sessions: dailySessions,
cpuPeak: Math.min(80, 40 + dailyUsers * 0.1), // 模擬CPU使用率
avgCpu: Math.min(70, 30 + dailyUsers * 0.08),
memoryPeak: Math.min(75, 35 + dailyUsers * 0.12),
requests: dailySessions * 5 // 模擬請求數
})
}
// 獲取應用類別分布
const categoryDataResult = await dbService.query(`
SELECT
type as category,
COUNT(*) as app_count,
SUM(views_count) as total_views
FROM apps
WHERE is_active = TRUE
GROUP BY type
ORDER BY app_count DESC
`)
const totalAppCount = categoryDataResult.reduce((sum, item) => sum + item.app_count, 0)
const categoryData = categoryDataResult.map((item, index) => {
const colors = ["#3b82f6", "#ef4444", "#10b981", "#f59e0b", "#8b5cf6"]
return {
name: item.category,
value: Math.round((item.app_count / totalAppCount) * 100),
color: colors[index % colors.length],
users: Math.round(item.total_views * 0.3), // 估算用戶數
apps: item.app_count
}
})
// 獲取熱門應用排行
const topAppsResult = await dbService.query(`
SELECT
a.name,
a.views_count as views,
a.rating,
a.type as category
FROM apps a
WHERE a.is_active = TRUE
ORDER BY a.views_count DESC
LIMIT 5
`)
const topApps = topAppsResult.map(app => ({
name: app.name,
views: app.views || 0,
rating: parseFloat(app.rating) || 0,
category: app.category
}))
// 獲取用戶滿意度數據
const satisfactionResult = await dbService.query(`
SELECT
AVG(rating) as avg_rating,
COUNT(*) as total_ratings
FROM user_ratings
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
`)
const satisfaction = satisfactionResult[0] || { avg_rating: 0, total_ratings: 0 }
const satisfactionRate = satisfaction.avg_rating > 0
? Math.round((satisfaction.avg_rating / 5) * 100)
: 92 // 預設值
return NextResponse.json({
success: true,
data: {
// 關鍵指標
totalUsers,
todayActiveUsers,
todayActiveGrowth: parseFloat(todayActiveGrowth),
avgRating: parseFloat(avgRating.toFixed(1)),
ratingGrowth: parseFloat(ratingGrowth),
totalApps,
newThisWeek,
userGrowth: parseFloat(userGrowth),
// 趨勢數據
dailyUsageData,
categoryData,
topApps,
// 滿意度數據
satisfactionRate,
weeklyFeedback: satisfaction.total_ratings || 0
}
})
} catch (error) {
console.error('獲取分析數據錯誤:', error)
return NextResponse.json(
{ success: false, error: '獲取分析數據時發生錯誤' },
{ status: 500 }
)
}
}