diff --git a/src/modules/ai/prompts/schemas/learning-trend.schema.ts b/src/modules/ai/prompts/schemas/learning-trend.schema.ts index 0ddc93e..6f7cabc 100644 --- a/src/modules/ai/prompts/schemas/learning-trend.schema.ts +++ b/src/modules/ai/prompts/schemas/learning-trend.schema.ts @@ -8,6 +8,12 @@ export const TrendItemSchema = z.object({ detail: z.string().max(500), }); +export const DailySeriesItemSchema = z.object({ + date: z.string(), + value: z.number(), + label: z.string(), +}); + export const LearningTrendResultSchema = z.object({ periodSummary: z.string().min(1).max(2000), overallScore: z.number().int().min(0).max(100), @@ -17,9 +23,11 @@ export const LearningTrendResultSchema = z.object({ weaknesses: z.array(z.string().max(500)).max(10).default([]), recommendations: z.array(z.string().max(500)).max(10).default([]), nextFocusAreas: z.array(z.string().max(200)).max(5).default([]), + dailySeries: z.array(DailySeriesItemSchema).default([]), }); export type LearningTrendResult = z.infer; +export type DailySeriesItem = z.infer; export const LEARNING_TREND_OUTPUT_SCHEMA_DESC = `{ "periodSummary": "过去7天,你的学习时长为320分钟,完成了45次主动回忆和120张复习卡片。整体掌握水平有所提升。", diff --git a/src/modules/learning-activity/learning-activity.service.ts b/src/modules/learning-activity/learning-activity.service.ts index 359c497..f927180 100644 --- a/src/modules/learning-activity/learning-activity.service.ts +++ b/src/modules/learning-activity/learning-activity.service.ts @@ -66,6 +66,9 @@ export class LearningActivityService { const prevTotalMinutes = Math.round(sum(previous, 'durationSeconds') / 60); + // Build daily time-series for chart rendering + const dailySeries = this.buildDailySeries(recent, periodDays); + const trendInput = { userId, periodDays, @@ -86,6 +89,28 @@ export class LearningActivityService { } : undefined, }; - return this.trendWorkflow.execute(trendInput); + const aiResult = await this.trendWorkflow.execute(trendInput); + return { ...aiResult, dailySeries }; + } + + private buildDailySeries(activities: any[], days: number) { + const series: { date: string; value: number; label: string }[] = []; + const now = new Date(); + for (let i = days - 1; i >= 0; i--) { + const d = new Date(now); + d.setDate(d.getDate() - i); + const dateStr = d.toISOString().split('T')[0]; + const dayActs = activities.filter((a) => { + const ad = a.activityDate instanceof Date ? a.activityDate : new Date(a.activityDate); + return ad.toISOString().split('T')[0] === dateStr; + }); + const minutes = Math.round(dayActs.reduce((s: number, a: any) => s + a.durationSeconds, 0) / 60); + series.push({ + date: dateStr, + value: minutes, + label: `${minutes}分钟`, + }); + } + return series; } }