Просмотр исходного кода

fix: clarify incomplete companion plans

彭峰 1 месяц назад
Родитель
Сommit
8b8d642aa7

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

@@ -108,6 +108,7 @@ class LearningModulesApiService {
         schedules: [
           { GeneralID: 901, bxrq: '2026-08-10 00:00:00', sdsd: '19:00', Title: '同步伴学', plxm: '张老师', dszt: 10 },
           { GeneralID: 902, bxrq: '2026-08-03 00:00:00', sdsd: '18:00', Title: '历史伴学', plxm: '李老师', dszt: 30 },
+          { GeneralID: 903, bxrq: '2099-01-01 00:00:00', sdsd: '18:00', Title: '未来计划', plxm: '王老师', dszt: 0 },
         ],
         refreshedAt: '2026-08-26T00:00:00.000Z',
       });
@@ -298,9 +299,19 @@ describe('home learning modules', () => {
       .find((button) => button.textContent?.trim() === '全部') as HTMLButtonElement;
     allDates.click();
     harness.fixture.detectChanges();
-    expect(harness.routeNativeElement?.querySelectorAll('.schedule-list article').length).toBe(2);
+    expect(harness.routeNativeElement?.querySelectorAll('.schedule-list article').length).toBe(3);
     expect(harness.routeNativeElement?.textContent).toContain('同步伴学');
     expect(harness.routeNativeElement?.textContent).toContain('历史伴学');
+    const plannedIncompleteFilter = Array.from(harness.routeNativeElement?.querySelectorAll('.schedule-filters button') ?? [])
+      .find((button) => button.textContent?.includes('计划未完成')) as HTMLButtonElement;
+    expect(plannedIncompleteFilter.textContent).toContain('1');
+    plannedIncompleteFilter.click();
+    harness.fixture.detectChanges();
+    expect(harness.routeNativeElement?.querySelectorAll('.schedule-list article').length).toBe(1);
+    expect(harness.routeNativeElement?.textContent).toContain('计划未完成');
+    expect(harness.routeNativeElement?.textContent).not.toContain('未来计划');
+    (harness.routeNativeElement?.querySelector('.schedule-filters button') as HTMLButtonElement).click();
+    harness.fixture.detectChanges();
     const api = TestBed.inject(ApiService) as unknown as LearningModulesApiService;
     expect(api.lastScheduleParams['mode']).toBe('student');
     expect(api.lastScheduleParams['limit']).toBe(500);

+ 2 - 2
projects/xiaoshu-mobile/src/app/features/course-center/course-center-page.component.html

@@ -37,7 +37,7 @@
 
           <nav class="schedule-filters" [attr.aria-label]="isCoach ? '陪练排课状态筛选' : '伴学记录筛选'">
             <button type="button" [class.active]="scheduleFilter() === 'all'" (click)="setScheduleFilter('all')">全部 <span>{{ scopedSchedules().length }}</span></button>
-            <button type="button" [class.active]="scheduleFilter() === 'pending'" (click)="setScheduleFilter('pending')">待完成 <span>{{ pendingCount() }}</span></button>
+            <button type="button" [class.active]="scheduleFilter() === 'pending'" (click)="setScheduleFilter('pending')">计划未完成 <span>{{ pendingCount() }}</span></button>
             <button type="button" [class.active]="scheduleFilter() === 'finished'" (click)="setScheduleFilter('finished')">已结束 <span>{{ finishedCount() }}</span></button>
           </nav>
 
@@ -76,7 +76,7 @@
       } @else if (!isCoach && schedules().length) {
         <nav class="schedule-filters" aria-label="伴学记录筛选">
           <button type="button" [class.active]="scheduleFilter() === 'all'" (click)="setScheduleFilter('all')">全部 <span>{{ schedules().length }}</span></button>
-          <button type="button" [class.active]="scheduleFilter() === 'pending'" (click)="setScheduleFilter('pending')">待完成 <span>{{ pendingCount() }}</span></button>
+          <button type="button" [class.active]="scheduleFilter() === 'pending'" (click)="setScheduleFilter('pending')">计划未完成 <span>{{ pendingCount() }}</span></button>
           <button type="button" [class.active]="scheduleFilter() === 'finished'" (click)="setScheduleFilter('finished')">已结束 <span>{{ finishedCount() }}</span></button>
         </nav>
       }

+ 3 - 3
projects/xiaoshu-mobile/src/app/features/course-center/course-center-page.component.ts

@@ -66,7 +66,7 @@ export class CourseCenterPageComponent implements OnInit, OnDestroy {
   readonly scopedSchedules = computed(() => this.schedules().filter((item) => this.matchesStudent(item)));
   readonly filteredSchedulePool = computed(() => this.scopedSchedules().filter((item) => this.matchesStatus(item)));
   readonly visibleSchedules = computed(() => this.filteredSchedulePool().filter((item) => this.matchesRange(item)));
-  readonly pendingCount = computed(() => this.scopedSchedules().filter((item) => !this.isFinished(item)).length);
+  readonly pendingCount = computed(() => this.scopedSchedules().filter((item) => this.isOverdueUnfinished(item)).length);
   readonly finishedCount = computed(() => this.scopedSchedules().filter((item) => this.isFinished(item)).length);
   readonly calendarDays = computed(() => this.buildCalendarDays());
   readonly calendarLabel = computed(() => new Intl.DateTimeFormat('zh-CN', { year: 'numeric', month: 'long' }).format(this.calendarMonth()));
@@ -186,7 +186,7 @@ export class CourseCenterPageComponent implements OnInit, OnDestroy {
   scheduleId(item: Item): unknown { return item['GeneralID'] ?? item['ID'] ?? item['id']; }
 
   statusText(item: Item): string {
-    if (this.isOverdueUnfinished(item)) return '未完课';
+    if (this.isOverdueUnfinished(item)) return '计划未完成';
     return ({ 0: '未开始', 10: '已开始', 11: '已上课', 20: '已评价', 30: '已结课' } as Record<number, string>)[this.rawStatus(item)] ?? '--';
   }
 
@@ -361,7 +361,7 @@ export class CourseCenterPageComponent implements OnInit, OnDestroy {
 
   private matchesStatus(item: Item): boolean {
     if (this.scheduleFilter() === 'finished') return this.isFinished(item);
-    if (this.scheduleFilter() === 'pending') return !this.isFinished(item);
+    if (this.scheduleFilter() === 'pending') return this.isOverdueUnfinished(item);
     return true;
   }