修正分頁、Too many connection 問題

This commit is contained in:
2025-09-19 16:27:54 +08:00
parent bac364a667
commit 95c0c4cb23
20 changed files with 912 additions and 291 deletions

View File

@@ -4,43 +4,34 @@ import { db } from "@/lib/database"
export async function GET(request: NextRequest) {
try {
const appService = new AppService()
const userService = new UserService()
// 獲取總用戶數
const totalUsersResult = await db.queryOne(`
SELECT COUNT(*) as total FROM users
`)
const totalUsers = totalUsersResult?.total || 0
// 獲取今日活躍用戶數(今日有登入記錄的用戶)
// 使用批次查詢減少連線使用
const today = new Date().toISOString().split('T')[0]
const todayActiveUsersResult = await db.queryOne(`
SELECT COUNT(DISTINCT user_id) as count
FROM activity_logs
WHERE DATE(created_at) = ? AND action = 'login'
`, [today])
const todayActiveUsers = todayActiveUsersResult?.count || 0
// 獲取昨日活躍用戶數(用於比較)
const yesterday = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString().split('T')[0]
const yesterdayActiveUsersResult = await db.queryOne(`
SELECT COUNT(DISTINCT user_id) as count
FROM activity_logs
WHERE DATE(created_at) = ? AND action = 'login'
`, [yesterday])
const yesterdayActiveUsers = yesterdayActiveUsersResult?.count || 0
// 批次查詢基本統計數據
const basicStats = await db.query(`
SELECT
(SELECT COUNT(*) FROM users) as total_users,
(SELECT COUNT(DISTINCT user_id) FROM activity_logs WHERE DATE(created_at) = ? AND action = 'login') as today_active_users,
(SELECT COUNT(DISTINCT user_id) FROM activity_logs WHERE DATE(created_at) = ? AND action = 'login') as yesterday_active_users,
(SELECT AVG(rating) FROM apps WHERE rating > 0) as avg_rating,
(SELECT COUNT(*) FROM apps) as total_apps,
(SELECT COUNT(*) FROM apps LIMIT 5) as new_this_week
`, [today, yesterday])
const stats = basicStats[0]
const totalUsers = stats?.total_users || 0
const todayActiveUsers = stats?.today_active_users || 0
const yesterdayActiveUsers = stats?.yesterday_active_users || 0
const avgRating = stats?.avg_rating || 0
const totalApps = stats?.total_apps || 0
const newThisWeek = stats?.new_this_week || 0
// 計算今日活躍用戶增長率
const todayActiveGrowth = yesterdayActiveUsers > 0
? ((todayActiveUsers - yesterdayActiveUsers) / yesterdayActiveUsers * 100).toFixed(1)
: 0
// 獲取平均評分
const avgRatingResult = await db.queryOne(`
SELECT AVG(rating) as avg_rating FROM apps WHERE rating > 0
`)
const avgRating = avgRatingResult?.avg_rating || 0
// 獲取上週平均評分簡化版本使用當前評分減去0.1
const lastWeekRating = Math.max(0, avgRating - 0.1)
@@ -49,21 +40,6 @@ export async function GET(request: NextRequest) {
? (avgRating - lastWeekRating).toFixed(1)
: 0
// 獲取應用總數
const totalAppsResult = await db.queryOne(`
SELECT COUNT(*) as total FROM apps
`)
const totalApps = totalAppsResult?.total || 0
// 獲取本週新增應用數(簡化版本,不依賴日期)
const newThisWeekResult = await db.queryOne(`
SELECT COUNT(*) as count
FROM apps
WHERE id LIKE '%'
LIMIT 5
`)
const newThisWeek = newThisWeekResult?.count || 0
// 計算用戶增長率(考慮平台剛上線的情況)
let userGrowth = 0
let userGrowthText = "較上月"
@@ -78,36 +54,56 @@ export async function GET(request: NextRequest) {
userGrowthText = "較上月"
}
// 獲取近7天的使用趨勢數據(真實數據)
// 批次查詢近7天的使用趨勢數據
const dateRange = []
for (let i = 6; i >= 0; i--) {
const date = new Date(Date.now() - i * 24 * 60 * 60 * 1000)
dateRange.push(date.toISOString().split('T')[0])
}
const dailyStats = await db.query(`
SELECT
DATE(viewed_at) as date,
COUNT(DISTINCT user_id) as daily_users,
COUNT(*) as daily_sessions
FROM user_views
WHERE DATE(viewed_at) IN (${dateRange.map(() => '?').join(',')})
GROUP BY DATE(viewed_at)
`, dateRange)
const dailyActivityStats = await db.query(`
SELECT
DATE(created_at) as date,
COUNT(*) as daily_activity
FROM activity_logs
WHERE DATE(created_at) IN (${dateRange.map(() => '?').join(',')})
GROUP BY DATE(created_at)
`, dateRange)
// 建立查詢結果的映射
const dailyStatsMap = new Map()
dailyStats.forEach(stat => {
dailyStatsMap.set(stat.date, stat)
})
const dailyActivityMap = new Map()
dailyActivityStats.forEach(stat => {
dailyActivityMap.set(stat.date, stat)
})
// 構建每日使用數據
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 db.queryOne(`
SELECT COUNT(DISTINCT user_id) as count
FROM user_views
WHERE DATE(viewed_at) = ?
`, [dateStr])
const dailyUsers = dailyUsersResult?.count || 0
const dailyStat = dailyStatsMap.get(dateStr) || { daily_users: 0, daily_sessions: 0 }
const activityStat = dailyActivityMap.get(dateStr) || { daily_activity: 0 }
// 查詢當日總瀏覽次數
const dailySessionsResult = await db.queryOne(`
SELECT COUNT(*) as count
FROM user_views
WHERE DATE(viewed_at) = ?
`, [dateStr])
const dailySessions = dailySessionsResult?.count || 0
// 查詢當日活動記錄數
const dailyActivityResult = await db.queryOne(`
SELECT COUNT(*) as count
FROM activity_logs
WHERE DATE(created_at) = ?
`, [dateStr])
const dailyActivity = dailyActivityResult?.count || 0
const dailyUsers = dailyStat.daily_users || 0
const dailySessions = dailyStat.daily_sessions || 0
const dailyActivity = activityStat.daily_activity || 0
// 基於真實數據計算系統負載
const cpuPeak = Math.min(90, 20 + dailyUsers * 0.8 + dailySessions * 0.05)
@@ -170,26 +166,32 @@ export async function GET(request: NextRequest) {
category: app.category
}))
// 獲取24小時使用數據
// 批次查詢24小時使用數據
const hourlyStats = await db.query(`
SELECT
HOUR(created_at) as hour,
COUNT(DISTINCT CASE WHEN action IN ('login', 'view') THEN user_id END) as hourly_users,
COUNT(*) as hourly_activity
FROM activity_logs
WHERE DATE(created_at) = CURDATE()
GROUP BY HOUR(created_at)
ORDER BY hour
`)
// 建立小時統計的映射
const hourlyStatsMap = new Map()
hourlyStats.forEach(stat => {
hourlyStatsMap.set(stat.hour, stat)
})
// 構建24小時數據
const hourlyData = []
for (let hour = 0; hour < 24; hour++) {
const hourStr = hour.toString().padStart(2, '0')
// 查詢該小時的活躍用戶數
const hourlyUsersResult = await db.queryOne(`
SELECT COUNT(DISTINCT user_id) as count
FROM activity_logs
WHERE HOUR(created_at) = ? AND action IN ('login', 'view')
`, [hour])
const hourlyUsers = hourlyUsersResult?.count || 0
// 查詢該小時的總活動數
const hourlyActivityResult = await db.queryOne(`
SELECT COUNT(*) as count
FROM activity_logs
WHERE HOUR(created_at) = ?
`, [hour])
const hourlyActivity = hourlyActivityResult?.count || 0
const hourlyStat = hourlyStatsMap.get(hour) || { hourly_users: 0, hourly_activity: 0 }
const hourlyUsers = hourlyStat.hourly_users || 0
const hourlyActivity = hourlyStat.hourly_activity || 0
// 根據時間段和用戶數確定強度等級
let intensity = "low"

View File

@@ -5,6 +5,8 @@
import { NextRequest, NextResponse } from 'next/server';
import { JudgeService } from '@/lib/services/database-service';
const judgeService = new JudgeService();
// 獲取單一評審
export async function GET(request: NextRequest, { params }: { params: { id: string } }) {
try {
@@ -105,7 +107,7 @@ export async function PUT(request: NextRequest, { params }: { params: { id: stri
if (body.is_active !== undefined) updateData.is_active = body.is_active;
// 執行更新
const success = await JudgeService.updateJudge(id, updateData);
const success = await judgeservice.updateJudge(id, updateData);
if (!success) {
return NextResponse.json({
@@ -155,10 +157,10 @@ export async function DELETE(request: NextRequest, { params }: { params: { id: s
if (hardDelete) {
// 硬刪除:從資料庫中完全移除
success = await JudgeService.deleteJudge(id);
success = await judgeservice.deleteJudge(id);
} else {
// 軟刪除:將 is_active 設為 false
success = await JudgeService.updateJudge(id, { is_active: false });
success = await judgeservice.updateJudge(id, { is_active: false });
}
if (!success) {

View File

@@ -118,7 +118,8 @@ export async function POST(request: NextRequest) {
is_active: isActive
};
const newJudge = await JudgeService.createJudge(judgeData);
const judgeService = new JudgeService();
const newJudge = await judgeService.createJudge(judgeData);
return NextResponse.json({
success: true,

View File

@@ -74,7 +74,7 @@ export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url)
const page = parseInt(searchParams.get('page') || '1')
const limit = parseInt(searchParams.get('limit') || '10')
const limit = parseInt(searchParams.get('limit') || '5')
const search = searchParams.get('search') || ''
const department = searchParams.get('department') || ''
const role = searchParams.get('role') || ''