From 8dfda9f10ee14792750fcddcc0bc92db3aa0a274 Mon Sep 17 00:00:00 2001 From: wangdl Date: Tue, 9 Jun 2026 21:50:31 +0800 Subject: [PATCH] fix: #159 getSummary/getTrend optimization + #160 admin auth guard Co-Authored-By: Claude Opus 4.7 --- .../reading-event/admin-reading.controller.ts | 2 + src/modules/reading/reading.controller.ts | 40 +++++++++---------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/modules/reading-event/admin-reading.controller.ts b/src/modules/reading-event/admin-reading.controller.ts index 9a26b6f..7e535f8 100644 --- a/src/modules/reading-event/admin-reading.controller.ts +++ b/src/modules/reading-event/admin-reading.controller.ts @@ -1,7 +1,9 @@ import { Controller, Get, Param, Post, Query, UseGuards } from '@nestjs/common'; +import { AdminJwtGuard } from '../../common/guards/admin-jwt.guard'; import { PrismaService } from '../../infrastructure/database/prisma.service'; @Controller('admin/learning') +@UseGuards(AdminJwtGuard) export class AdminReadingController { constructor(private readonly prisma: PrismaService) {} diff --git a/src/modules/reading/reading.controller.ts b/src/modules/reading/reading.controller.ts index ebd2c30..fc57ba3 100644 --- a/src/modules/reading/reading.controller.ts +++ b/src/modules/reading/reading.controller.ts @@ -110,43 +110,40 @@ export class ReadingController { @Get('learning/summary') async getSummary(@Req() req: any) { const userId = req.user.id; - const activities = await this.activityRepo.findAll(userId); - - if (!activities.length) { - return { todaySeconds: 0, weekSeconds: 0, totalSeconds: 0, activeDays: 0, sessionsCount: 0, materialsReadCount: 0, markedReadCount: 0, dailyAverageSeconds: 0 }; - } - const now = new Date(); const todayStr = now.toISOString().split('T')[0]; const weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000); - let todaySeconds = 0, weekSeconds = 0, totalSeconds = 0, activeDays = 0; - let sessionsCount = 0, materialsReadCount = 0, markedReadCount = 0; + // Query recent 90 days for week/today + aggregate totals + const from = new Date(now.getTime() - 90 * 24 * 60 * 60 * 1000); + const activities = await this.activityRepo.findByDateRange(userId, from, now); + const allActivities = await this.activityRepo.findAll(userId); - for (const a of activities) { - const dateStr = a.activityDate instanceof Date ? a.activityDate.toISOString().split('T')[0] : String(a.activityDate).split('T')[0]; + if (!allActivities.length) { + return { todaySeconds: 0, weekSeconds: 0, totalSeconds: 0, activeDays: 0, sessionsCount: 0, materialsReadCount: 0, markedReadCount: 0, dailyAverageSeconds: 0 }; + } + let todaySeconds = 0, weekSeconds = 0, recentSeconds = 0; + let totalSeconds = 0, activeDays = 0, sessionsCount = 0, materialsReadCount = 0, markedReadCount = 0; + + for (const a of allActivities) { totalSeconds += a.readingSeconds; sessionsCount += a.sessionsCount; materialsReadCount += a.materialsReadCount; markedReadCount += a.markedReadCount; - if (a.readingSeconds > 0) activeDays++; + } + for (const a of activities) { + const dateStr = a.activityDate instanceof Date ? a.activityDate.toISOString().split('T')[0] : String(a.activityDate).split('T')[0]; if (dateStr === todayStr) todaySeconds += a.readingSeconds; - const actDate = a.activityDate instanceof Date ? a.activityDate : new Date(a.activityDate); if (actDate >= weekAgo) weekSeconds += a.readingSeconds; } return { - todaySeconds, - weekSeconds, - totalSeconds, - activeDays, - sessionsCount, - materialsReadCount, - markedReadCount, + todaySeconds, weekSeconds, totalSeconds, activeDays, + sessionsCount, materialsReadCount, markedReadCount, dailyAverageSeconds: activeDays > 0 ? Math.round(totalSeconds / activeDays) : 0, }; } @@ -155,8 +152,10 @@ export class ReadingController { async getTrend(@Req() req: any, @Query('days') daysStr?: string) { const userId = req.user.id; const days = Math.min(Number(daysStr ?? 7) || 7, 90); + const now = new Date(); + const from = new Date(now.getTime() - days * 24 * 60 * 60 * 1000); - const activities = await this.activityRepo.findAll(userId); + const activities = await this.activityRepo.findByDateRange(userId, from, now); const dataMap = new Map(); for (const a of activities) { const ds = a.activityDate instanceof Date ? a.activityDate.toISOString().split('T')[0] : String(a.activityDate).split('T')[0]; @@ -164,7 +163,6 @@ export class ReadingController { } const series: Array<{ date: string; value: number }> = []; - const now = new Date(); for (let i = days - 1; i >= 0; i--) { const d = new Date(now.getTime() - i * 24 * 60 * 60 * 1000); const ds = d.toISOString().split('T')[0];