Przeglądaj źródła

fix: 保持学习记录筛选状态

彭峰 2 miesięcy temu
rodzic
commit
8587b58834

+ 1 - 1
src/app/features/study-records/study-records-page.component.html

@@ -1,6 +1,6 @@
 <section class="records-page">
   @if (meta.path === 'pages/his/his' && session.groupId() === 3) {
-    <form class="filter-row" (change)="load()"><label><span>学员</span><select name="student" [(ngModel)]="studentId"><option [ngValue]="0">选择学员</option>@for (student of students(); track $index) { <option [ngValue]="student['szyh']">{{ student['honeyname'] || student['HoneyName'] }}</option> }</select></label><label><span>日期</span><input name="date" type="date" [(ngModel)]="selectedDate" /></label></form>
+    <form class="filter-row" (change)="onFilterChange()"><label><span>学员</span><select name="student" [(ngModel)]="studentId"><option [ngValue]="0">选择学员</option>@for (student of students(); track $index) { <option [ngValue]="student['szyh']">{{ student['honeyname'] || student['HoneyName'] }}</option> }</select></label><label><span>日期</span><input name="date" type="date" [(ngModel)]="selectedDate" /></label></form>
   }
   @if (meta.path === 'pages/his/his') {
     <section class="ai-reading-feature" aria-labelledby="ai-reading-title">

+ 63 - 2
src/app/features/study-records/study-records-page.component.ts

@@ -88,9 +88,10 @@ export class StudyRecordsPageComponent implements OnInit {
   private readonly api = inject(ApiService);
   readonly session = inject(SessionService);
   private calendarInitialized = false;
+  private syncingHistoryQuery = false;
 
   ngOnInit(): void {
-    this.studentId = Number(this.route.snapshot.queryParamMap.get('uid') ?? 0);
+    this.restoreHistoryState();
     if (this.meta.path === 'pages/his/his' && this.session.groupId() === 3) this.loadStudents();
     this.load();
   }
@@ -125,15 +126,30 @@ export class StudyRecordsPageComponent implements OnInit {
 
   selectTab(index: number): void { this.activeTab.set(index); this.load(); }
 
+  onFilterChange(): void {
+    this.studentId = Number(this.studentId || 0);
+    this.selectedDate = this.dateKey(this.selectedDate);
+    this.calendarInitialized = false;
+    if (this.selectedDate) {
+      this.calendarSelectedDate.set(this.selectedDate);
+      this.calendarMonth.set(this.firstOfMonth(this.parseDate(this.selectedDate)));
+      this.calendarInitialized = true;
+    }
+    this.syncHistoryState();
+    this.load();
+  }
+
   shiftCalendarMonth(amount: number): void {
     const month = this.calendarMonth();
     this.calendarMonth.set(new Date(month.getFullYear(), month.getMonth() + amount, 1, 12));
     this.calendarSelectedDate.set('');
+    this.syncHistoryState();
   }
 
   showCurrentMonth(): void {
     this.calendarMonth.set(this.firstOfMonth(new Date()));
     this.calendarSelectedDate.set('');
+    this.syncHistoryState();
   }
 
   selectCalendarDay(day: CalendarDay): void {
@@ -142,9 +158,13 @@ export class StudyRecordsPageComponent implements OnInit {
       const [year, month] = day.date.split('-').map(Number);
       this.calendarMonth.set(new Date(year, month - 1, 1, 12));
     }
+    this.syncHistoryState();
   }
 
-  showAllRecords(): void { this.calendarSelectedDate.set(''); }
+  showAllRecords(): void {
+    this.calendarSelectedDate.set('');
+    this.syncHistoryState();
+  }
 
   courseId(item: Item): string {
     return String(item['kcid'] ?? item['kcId'] ?? item['NodeID'] ?? item['nodeId'] ?? '');
@@ -279,6 +299,38 @@ export class StudyRecordsPageComponent implements OnInit {
   private asList(value: unknown): Item[] { return Array.isArray(value) ? value.filter((item): item is Item => Boolean(item) && typeof item === 'object') : []; }
   private formatDate(value: unknown): string { const date = new Date(String(value ?? '')); return Number.isNaN(date.getTime()) ? String(value ?? '') : date.toLocaleString('zh-CN', { hour12: false }); }
 
+  private restoreHistoryState(): void {
+    if (this.meta.path !== 'pages/his/his') return;
+    const query = this.route.snapshot.queryParamMap;
+    this.studentId = Number(query.get('uid') ?? 0);
+    this.selectedDate = this.dateKey(query.get('date') ?? '');
+    const selectedCalendarDate = this.dateKey(query.get('hisDay') ?? '') || this.selectedDate;
+    const restoredMonth = this.parseMonth(query.get('hisMonth') ?? '');
+
+    if (selectedCalendarDate) this.calendarSelectedDate.set(selectedCalendarDate);
+    if (restoredMonth) this.calendarMonth.set(restoredMonth);
+    else if (selectedCalendarDate) this.calendarMonth.set(this.firstOfMonth(this.parseDate(selectedCalendarDate)));
+    if (restoredMonth || selectedCalendarDate) this.calendarInitialized = true;
+  }
+
+  private syncHistoryState(): void {
+    if (this.meta.path !== 'pages/his/his' || this.syncingHistoryQuery) return;
+    this.syncingHistoryQuery = true;
+    const teacherStudentId = this.session.groupId() === 3 && this.studentId ? this.studentId : null;
+    void this.router.navigate([], {
+      relativeTo: this.route,
+      queryParams: {
+        uid: teacherStudentId,
+        name: null,
+        date: this.selectedDate || null,
+        hisDay: this.calendarSelectedDate() || null,
+        hisMonth: this.monthKey(this.calendarMonth()),
+      },
+      queryParamsHandling: 'merge',
+      replaceUrl: true,
+    }).finally(() => { this.syncingHistoryQuery = false; });
+  }
+
   private initializeCalendar(items: Item[]): void {
     if (this.calendarInitialized) return;
     this.calendarInitialized = true;
@@ -306,4 +358,13 @@ export class StudyRecordsPageComponent implements OnInit {
 
   private firstOfMonth(date: Date): Date { return new Date(date.getFullYear(), date.getMonth(), 1, 12); }
   private monthKey(date: Date): string { return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`; }
+  private parseDate(value: string): Date {
+    const [year, month, day] = value.split('-').map(Number);
+    return new Date(year, month - 1, day, 12);
+  }
+  private parseMonth(value: string): Date | null {
+    const matched = value.match(/^(\d{4})-(\d{1,2})$/);
+    if (!matched) return null;
+    return new Date(Number(matched[1]), Number(matched[2]) - 1, 1, 12);
+  }
 }