Browse Source

fix: preserve teacher word selection context

彭峰 1 tháng trước cách đây
mục cha
commit
c2ca73c314

+ 11 - 2
projects/xiaoshu-mobile/src/app/core/home-learning-modules.integration.spec.ts

@@ -186,13 +186,14 @@ class LearningModulesApiService {
 
 describe('home learning modules', () => {
   const user = signal<AppUser | null>({ userId: 100, userName: 'student', honeyName: '张雅茜', groupId: 1 });
+  const selectedStudent = signal<AppUser | null>(null);
   const session = {
     user,
     token: signal('test-token'),
-    student: signal<AppUser | null>(null),
+    student: selectedStudent,
     isLoggedIn: signal(true),
     groupId: signal(1),
-    setStudent: () => undefined,
+    setStudent: (student: AppUser | null) => selectedStudent.set(student),
     patchUser: () => undefined,
     logout: () => undefined,
   };
@@ -517,6 +518,14 @@ describe('home learning modules', () => {
     harness.fixture.detectChanges();
     expect((harness.routeNativeElement?.querySelector('.student-filter select') as HTMLSelectElement).selectedOptions[0]?.textContent).toContain('张雅茜');
     expect(harness.routeNativeElement?.querySelectorAll('.learning-record-card .learning-item').length).toBe(2);
+    expect(session.student()?.userId).toBe(100);
+    const teacherCourse = harness.routeNativeElement?.querySelector('.current-learning-list button') as HTMLButtonElement;
+    expect(teacherCourse.disabled).toBeFalse();
+    expect(teacherCourse.classList.contains('readonly')).toBeFalse();
+    expect(teacherCourse.textContent).toContain('选择本次学习单元');
+    teacherCourse.click();
+    await harness.fixture.whenStable();
+    expect(TestBed.inject(Router).url).toContain('/pages/stu/stu_list');
 
     await harness.navigateByUrl('/pages/home/ucenter');
     await harness.fixture.whenStable();

+ 38 - 2
projects/xiaoshu-mobile/src/app/features/study-records/study-records-page.component.ts

@@ -7,7 +7,8 @@ import { catchError, finalize, forkJoin, of } from 'rxjs';
 import { ApiError, ApiService } from '../../core/api.service';
 import { extractReadingWords } from '../../core/external-reading';
 import { canStartTeacherLedLearning } from '../../core/learning-access';
-import { PageMeta } from '../../core/models';
+import { AppUser, PageMeta } from '../../core/models';
+import { PlatformService } from '../../core/platform.service';
 import { SessionService } from '../../core/session.service';
 
 type Item = Record<string, unknown>;
@@ -108,6 +109,7 @@ export class StudyRecordsPageComponent implements OnInit {
   private readonly route = inject(ActivatedRoute);
   private readonly router = inject(Router);
   private readonly api = inject(ApiService);
+  private readonly platform = inject(PlatformService);
   readonly session = inject(SessionService);
   private syncingHistoryQuery = false;
 
@@ -152,6 +154,7 @@ export class StudyRecordsPageComponent implements OnInit {
 
   onFilterChange(): void {
     this.studentId = Number(this.studentId || 0);
+    this.syncSelectedStudentContext();
     this.selectedDate = this.dateKey(this.selectedDate);
     this.syncDatePickerMonth();
     this.syncHistoryState();
@@ -241,6 +244,13 @@ export class StudyRecordsPageComponent implements OnInit {
 
   openCourse(item: Item): void {
     if (!this.canOpenCourse(item)) return;
+    if (this.canStartPointReading) {
+      this.syncSelectedStudentContext();
+      if (!this.session.student()?.userId) {
+        this.platform.toast('请先选择本次学习的学员', 'error');
+        return;
+      }
+    }
     const courseId = this.courseId(item);
     const bindingId = this.courseBindingId(item);
     void this.router.navigate(['/pages/stu/stu_list'], {
@@ -424,10 +434,18 @@ export class StudyRecordsPageComponent implements OnInit {
       next: ({ result }) => {
         const students = this.asList(result);
         this.students.set(students);
-        if (this.studentId || !students.length) return;
+        if (this.studentId) {
+          this.syncSelectedStudentContext();
+          return;
+        }
+        if (!students.length) {
+          this.session.setStudent(null);
+          return;
+        }
         const firstStudentId = students.map((student) => this.studentValue(student)).find((value) => value > 0) ?? 0;
         if (!firstStudentId) return;
         this.studentId = firstStudentId;
+        this.syncSelectedStudentContext();
         this.syncHistoryState();
         this.load();
       },
@@ -435,6 +453,24 @@ export class StudyRecordsPageComponent implements OnInit {
     });
   }
 
+  private syncSelectedStudentContext(): void {
+    if (this.session.groupId() !== 3) return;
+    const source = this.students().find((student) => this.studentValue(student) === this.studentId);
+    if (!source || !this.studentId) {
+      this.session.setStudent(null);
+      return;
+    }
+    const student: AppUser = {
+      ...source,
+      userId: this.studentId,
+      userName: String(source['UserName'] ?? source['username'] ?? source['userName'] ?? ''),
+      honeyName: this.studentName(source),
+      mobile: String(source['Mobile'] ?? source['mobile'] ?? ''),
+      groupId: 1,
+    };
+    this.session.setStudent(student);
+  }
+
   private loadAppeals(uid: number): void {
     const pubid = this.activeTab() === 0 ? 10 : 11;
     this.api.get<unknown>('pub_list', { uid, pubid, cpage: 1, psize: 100 }).pipe(finalize(() => this.loading.set(false))).subscribe({