|
|
@@ -3,7 +3,7 @@ import { LearningDraft } from '../../core/learning-draft';
|
|
|
import { ReviewPage, reviewCalendar } from '../../core/review-page';
|
|
|
import { CommonModule } from '@angular/common';
|
|
|
import { ChangeDetectionStrategy, Component, computed, inject, OnDestroy, OnInit, signal } from '@angular/core';
|
|
|
-import { ActivatedRoute, Router } from '@angular/router';
|
|
|
+import { ActivatedRoute, Router, RouterLink } from '@angular/router';
|
|
|
import {
|
|
|
Activity,
|
|
|
BookOpen,
|
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
Volume2,
|
|
|
X,
|
|
|
} from 'lucide-angular';
|
|
|
-import { catchError, finalize, forkJoin, Observable, of, Subscription, switchMap, throwError } from 'rxjs';
|
|
|
+import { catchError, finalize, forkJoin, map, Observable, of, Subscription, switchMap, throwError } from 'rxjs';
|
|
|
import { GAME_AUDIO } from '../../core/app.constants';
|
|
|
import { ApiError, ApiService } from '../../core/api.service';
|
|
|
import {
|
|
|
@@ -103,7 +103,7 @@ const WORD_CATALOG_CATEGORIES = [
|
|
|
@Component({
|
|
|
selector: 'app-learning-page',
|
|
|
standalone: true,
|
|
|
- imports: [DropdownDirective, CommonModule, LucideAngularModule],
|
|
|
+ imports: [DropdownDirective, CommonModule, LucideAngularModule, RouterLink],
|
|
|
templateUrl: './learning-page.component.html',
|
|
|
styleUrl: './learning-page.component.scss',
|
|
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
|
@@ -134,6 +134,7 @@ export class LearningPageComponent implements OnInit, OnDestroy {
|
|
|
readonly submitting = signal(false);
|
|
|
readonly selectionTotal=signal(0);readonly selectionPage=signal(1);readonly selectionLoading=signal(false);private selectionRequest?:Subscription;
|
|
|
readonly error = signal('');
|
|
|
+ readonly recordWordless = signal(false);
|
|
|
|
|
|
readonly studyStep = signal<1 | 2 | 3>(1);
|
|
|
readonly repetitions = signal<Record<string, number>>({});
|
|
|
@@ -440,6 +441,7 @@ export class LearningPageComponent implements OnInit, OnDestroy {
|
|
|
if (this.isSelectionPage) {
|
|
|
this.loadSelection();
|
|
|
return;
|
|
|
+ this.recordWordless.set(false);
|
|
|
}
|
|
|
if (this.isCalendarPage) {
|
|
|
this.loadCalendar(true);
|
|
|
@@ -1564,11 +1566,37 @@ export class LearningPageComponent implements OnInit, OnDestroy {
|
|
|
private loadRecord(): void {
|
|
|
const user = this.session.user();
|
|
|
const learnerId = Number(user?.groupId) === 3 ? this.session.student()?.userId : user?.userId;
|
|
|
- this.api.post<unknown>('e_record_detail', { id: this.query('id'), studentId: learnerId }).pipe(finalize(() => this.loading.set(false))).subscribe({
|
|
|
+ const recordId = this.query('id');
|
|
|
+ const detailParams = { id: recordId, studentId: learnerId };
|
|
|
+ const hasWords = (result: unknown) => this.findList(result).some((item) => this.toWord(item).word);
|
|
|
+ let originalRecord: SourceItem | undefined;
|
|
|
+ this.api.post<unknown>('e_record_detail', detailParams).pipe(
|
|
|
+ switchMap((detail) => hasWords(detail.result) ? of(detail) : this.api.get<unknown>('content_get', { id: recordId }).pipe(
|
|
|
+ map(({ result }) => {
|
|
|
+ originalRecord = this.findList(result)[0];
|
|
|
+ return { ...detail, result: this.parseArray(originalRecord?.['xxqs']) };
|
|
|
+ }),
|
|
|
+ catchError(() => of(detail)),
|
|
|
+ )),
|
|
|
+ switchMap((detail) => hasWords(detail.result) ? of(detail) : this.api.post<unknown>('app_learning_overview', {
|
|
|
+ studentId: learnerId, page: 1, pageSize: 1, refresh: true,
|
|
|
+ }).pipe(
|
|
|
+ switchMap(() => this.api.post<unknown>('e_record_detail', detailParams)),
|
|
|
+ catchError(() => of(detail)),
|
|
|
+ )),
|
|
|
+ finalize(() => this.loading.set(false)),
|
|
|
+ ).subscribe({
|
|
|
next: ({ result, addon }) => {
|
|
|
const words = this.findList(result).map((item) => this.toWord(item)).filter((word) => word.word);
|
|
|
if (!words.length) {
|
|
|
- this.error.set('这条复习任务暂时没有读取到单词,请点击重新加载;任务进度不会被修改。');
|
|
|
+ const wordless = originalRecord && 'xxqs' in originalRecord
|
|
|
+ && !this.parseArray(originalRecord['xxqs']).length
|
|
|
+ && Number(originalRecord['learned'] ?? 0) === 0;
|
|
|
+ this.recordWordless.set(Boolean(wordless));
|
|
|
+ const writingRecord = wordless && String(originalRecord?.['con'] ?? '').includes('写作');
|
|
|
+ this.error.set(wordless
|
|
|
+ ? `${writingRecord ? '这条任务关联的是写作学习记录,原本没有单词' : '这条任务关联的原学习记录没有保存单词'},无法进行单词复习。任务进度不会被修改。`
|
|
|
+ : '这条复习任务暂时没有读取到单词,请点击重新加载;任务进度不会被修改。');
|
|
|
return;
|
|
|
}
|
|
|
this.words.set(words);
|