2026-05-09 18:25:04 +08:00
|
|
|
import { Injectable } from '@nestjs/common';
|
|
|
|
|
import { LearningActivityRepository } from './learning-activity.repository';
|
|
|
|
|
|
|
|
|
|
@Injectable()
|
|
|
|
|
export class LearningActivityService {
|
|
|
|
|
constructor(private readonly repository: LearningActivityRepository) {}
|
|
|
|
|
|
2026-05-17 00:39:46 +08:00
|
|
|
async getHeatmap(userId: string) {
|
|
|
|
|
const activities = await this.repository.findAll(userId);
|
2026-05-09 18:25:04 +08:00
|
|
|
const heatmap: Record<string, number> = {};
|
|
|
|
|
for (const a of activities) {
|
2026-05-17 00:39:46 +08:00
|
|
|
const dateStr = a.activityDate instanceof Date
|
|
|
|
|
? a.activityDate.toISOString().split('T')[0]
|
|
|
|
|
: String(a.activityDate).split('T')[0];
|
|
|
|
|
heatmap[dateStr] = a.durationSeconds;
|
2026-05-09 18:25:04 +08:00
|
|
|
}
|
|
|
|
|
return heatmap;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-17 00:39:46 +08:00
|
|
|
async getSummary(userId: string) {
|
|
|
|
|
const activities = await this.repository.findAll(userId);
|
|
|
|
|
const totalMinutes = Math.round(
|
|
|
|
|
activities.reduce((s, a) => s + a.durationSeconds, 0) / 60,
|
|
|
|
|
);
|
|
|
|
|
const totalCards = activities.reduce((s, a) => s + a.reviewCount, 0);
|
|
|
|
|
const activeDays = activities.filter((a) => a.durationSeconds > 0).length;
|
2026-05-09 18:25:04 +08:00
|
|
|
const dailyAverage = activeDays > 0 ? Math.round(totalMinutes / activeDays) : 0;
|
|
|
|
|
return { totalMinutes, totalCardsReviewed: totalCards, activeDays, dailyAverage };
|
|
|
|
|
}
|
|
|
|
|
}
|