修正分頁、Too many connection 問題
This commit is contained in:
@@ -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"
|
||||
|
@@ -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) {
|
||||
|
@@ -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,
|
||||
|
@@ -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') || ''
|
||||
|
@@ -973,16 +973,11 @@ export default function AIShowcasePlatform() {
|
||||
<SelectItem value="HQBU">HQBU</SelectItem>
|
||||
<SelectItem value="HRBU">HRBU</SelectItem>
|
||||
<SelectItem value="IBU">IBU</SelectItem>
|
||||
<SelectItem value="ICDU">ICDU</SelectItem>
|
||||
<SelectItem value="ICBU">ICBU</SelectItem>
|
||||
<SelectItem value="ITBU">ITBU</SelectItem>
|
||||
<SelectItem value="MBU1">MBU1</SelectItem>
|
||||
<SelectItem value="MBU5">MBU5</SelectItem>
|
||||
<SelectItem value="PJA">PJA</SelectItem>
|
||||
<SelectItem value="PBU">PBU</SelectItem>
|
||||
<SelectItem value="SBG">SBG</SelectItem>
|
||||
<SelectItem value="SBU">SBU</SelectItem>
|
||||
<SelectItem value="董事會">董事會</SelectItem>
|
||||
<SelectItem value="法務室">法務室</SelectItem>
|
||||
<SelectItem value="關係企業發展">關係企業發展</SelectItem>
|
||||
<SelectItem value="稽核室">稽核室</SelectItem>
|
||||
|
@@ -320,16 +320,11 @@ export default function RegisterPage() {
|
||||
<SelectItem value="HQBU">HQBU</SelectItem>
|
||||
<SelectItem value="HRBU">HRBU</SelectItem>
|
||||
<SelectItem value="IBU">IBU</SelectItem>
|
||||
<SelectItem value="ICDU">ICDU</SelectItem>
|
||||
<SelectItem value="ICBU">ICBU</SelectItem>
|
||||
<SelectItem value="ITBU">ITBU</SelectItem>
|
||||
<SelectItem value="MBU1">MBU1</SelectItem>
|
||||
<SelectItem value="MBU5">MBU5</SelectItem>
|
||||
<SelectItem value="PJA">PJA</SelectItem>
|
||||
<SelectItem value="PBU">PBU</SelectItem>
|
||||
<SelectItem value="SBG">SBG</SelectItem>
|
||||
<SelectItem value="SBU">SBU</SelectItem>
|
||||
<SelectItem value="董事會">董事會</SelectItem>
|
||||
<SelectItem value="法務室">法務室</SelectItem>
|
||||
<SelectItem value="關係企業發展">關係企業發展</SelectItem>
|
||||
<SelectItem value="稽核室">稽核室</SelectItem>
|
||||
|
Reference in New Issue
Block a user