fix: #159 getSummary/getTrend optimization + #160 admin auth guard
Some checks failed
Deploy API Server / build-and-deploy (push) Failing after 23s
Some checks failed
Deploy API Server / build-and-deploy (push) Failing after 23s
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
1442b9b69e
commit
8dfda9f10e
@ -1,7 +1,9 @@
|
|||||||
import { Controller, Get, Param, Post, Query, UseGuards } from '@nestjs/common';
|
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';
|
import { PrismaService } from '../../infrastructure/database/prisma.service';
|
||||||
|
|
||||||
@Controller('admin/learning')
|
@Controller('admin/learning')
|
||||||
|
@UseGuards(AdminJwtGuard)
|
||||||
export class AdminReadingController {
|
export class AdminReadingController {
|
||||||
constructor(private readonly prisma: PrismaService) {}
|
constructor(private readonly prisma: PrismaService) {}
|
||||||
|
|
||||||
|
|||||||
@ -110,43 +110,40 @@ export class ReadingController {
|
|||||||
@Get('learning/summary')
|
@Get('learning/summary')
|
||||||
async getSummary(@Req() req: any) {
|
async getSummary(@Req() req: any) {
|
||||||
const userId = req.user.id;
|
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 now = new Date();
|
||||||
const todayStr = now.toISOString().split('T')[0];
|
const todayStr = now.toISOString().split('T')[0];
|
||||||
const weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
|
const weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
|
||||||
|
|
||||||
let todaySeconds = 0, weekSeconds = 0, totalSeconds = 0, activeDays = 0;
|
// Query recent 90 days for week/today + aggregate totals
|
||||||
let sessionsCount = 0, materialsReadCount = 0, markedReadCount = 0;
|
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) {
|
if (!allActivities.length) {
|
||||||
const dateStr = a.activityDate instanceof Date ? a.activityDate.toISOString().split('T')[0] : String(a.activityDate).split('T')[0];
|
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;
|
totalSeconds += a.readingSeconds;
|
||||||
sessionsCount += a.sessionsCount;
|
sessionsCount += a.sessionsCount;
|
||||||
materialsReadCount += a.materialsReadCount;
|
materialsReadCount += a.materialsReadCount;
|
||||||
markedReadCount += a.markedReadCount;
|
markedReadCount += a.markedReadCount;
|
||||||
|
|
||||||
if (a.readingSeconds > 0) activeDays++;
|
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;
|
if (dateStr === todayStr) todaySeconds += a.readingSeconds;
|
||||||
|
|
||||||
const actDate = a.activityDate instanceof Date ? a.activityDate : new Date(a.activityDate);
|
const actDate = a.activityDate instanceof Date ? a.activityDate : new Date(a.activityDate);
|
||||||
if (actDate >= weekAgo) weekSeconds += a.readingSeconds;
|
if (actDate >= weekAgo) weekSeconds += a.readingSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
todaySeconds,
|
todaySeconds, weekSeconds, totalSeconds, activeDays,
|
||||||
weekSeconds,
|
sessionsCount, materialsReadCount, markedReadCount,
|
||||||
totalSeconds,
|
|
||||||
activeDays,
|
|
||||||
sessionsCount,
|
|
||||||
materialsReadCount,
|
|
||||||
markedReadCount,
|
|
||||||
dailyAverageSeconds: activeDays > 0 ? Math.round(totalSeconds / activeDays) : 0,
|
dailyAverageSeconds: activeDays > 0 ? Math.round(totalSeconds / activeDays) : 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -155,8 +152,10 @@ export class ReadingController {
|
|||||||
async getTrend(@Req() req: any, @Query('days') daysStr?: string) {
|
async getTrend(@Req() req: any, @Query('days') daysStr?: string) {
|
||||||
const userId = req.user.id;
|
const userId = req.user.id;
|
||||||
const days = Math.min(Number(daysStr ?? 7) || 7, 90);
|
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<string, number>();
|
const dataMap = new Map<string, number>();
|
||||||
for (const a of activities) {
|
for (const a of activities) {
|
||||||
const ds = a.activityDate instanceof Date ? a.activityDate.toISOString().split('T')[0] : String(a.activityDate).split('T')[0];
|
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 series: Array<{ date: string; value: number }> = [];
|
||||||
const now = new Date();
|
|
||||||
for (let i = days - 1; i >= 0; i--) {
|
for (let i = days - 1; i >= 0; i--) {
|
||||||
const d = new Date(now.getTime() - i * 24 * 60 * 60 * 1000);
|
const d = new Date(now.getTime() - i * 24 * 60 * 60 * 1000);
|
||||||
const ds = d.toISOString().split('T')[0];
|
const ds = d.toISOString().split('T')[0];
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user