Procházet zdrojové kódy

添加保存和确认返回

s202226701051 před 7 měsíci
rodič
revize
4cf7a7d24b

+ 22 - 2
word-app/src/app/word-story/word-story.page.html

@@ -17,7 +17,11 @@
         <ion-icon name="boat-outline" class="title-icon"></ion-icon>
            串词成文
       </h1>
-      <div class="placeholder"></div>
+      <!-- 保存按钮:只在评分结果页面显示 -->
+      <div class="save-btn" *ngIf="showExerciseView && scoreResult" (click)="saveStory()">
+        <img src="assets/icon/保存故事.svg" alt="保存故事">
+      </div>
+      <div class="placeholder" *ngIf="!(showExerciseView && scoreResult)"></div>
     </div>
 
     <!-- ========== 做题页:挖空文章 + 词池 + 去评分 ========== -->
@@ -293,10 +297,26 @@
       </div>
     </div>
 
+    <!-- 退出确认弹窗 -->
+    <div class="wizard-modal-overlay" *ngIf="showExitModal">
+      <div class="wizard-modal-container exit-modal-container" (click)="$event.stopPropagation()">
+        <!-- 弹窗头部 -->
+        <div class="wizard-header">
+          <h3>提示</h3>
+        </div>
+
+        <!-- 弹窗底部按钮 -->
+        <div class="wizard-footer">
+          <button class="wizard-btn btn-secondary" (click)="confirmExit()">退出页面</button>
+          <button class="wizard-btn btn-primary btn-highlight" (click)="closeExitModal()">前往保存</button>
+        </div>
+      </div>
+    </div>
+
   </div>
 </ion-content>
 
-<ion-footer class="word-story-footer" [class.modal-open]="showStyleModal">
+<ion-footer class="word-story-footer" [class.modal-open]="showStyleModal || showExitModal">
 
   <!-- 非做题模式:底部操作栏 -->
   <div class="bottom-bar" *ngIf="!isGenerating && !storyResponse && !showExerciseView">

+ 46 - 0
word-app/src/app/word-story/word-story.page.scss

@@ -87,6 +87,28 @@ $seaweed: #4CAF50;          // 海藻绿(点缀)
       }
     }
 
+    .save-btn {
+      width: 40px;
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      background: transparent;
+      border-radius: 12px;
+      cursor: pointer;
+      transition: all 0.2s ease;
+
+      &:active {
+        transform: scale(0.9);
+      }
+
+      img {
+        width: 27px;
+        height: 27px;
+        object-fit: contain;
+      }
+    }
+
     .page-title {
       font-size: 1.6rem;
       font-weight: 600;
@@ -1068,6 +1090,30 @@ $seaweed: #4CAF50;          // 海藻绿(点缀)
     min-height: 120px;
   }
 
+  // 退出确认弹窗样式
+  .exit-modal-container {
+    max-width: 360px;
+  }
+
+  .exit-modal-text {
+    text-align: center;
+    padding: 20px 0;
+
+    p {
+      margin: 0;
+      font-size: 1.2rem;
+      font-weight: 600;
+      color: #333;
+    }
+
+    .exit-hint {
+      margin-top: 8px;
+      font-size: 0.9rem;
+      font-weight: 400;
+      color: #999;
+    }
+  }
+
   .step-content {
     display: flex;
     flex-direction: column;

+ 59 - 2
word-app/src/app/word-story/word-story.page.ts

@@ -18,7 +18,8 @@ import {
   sparklesOutline,
   chevronBackOutline,
   chevronForwardOutline,
-  createOutline
+  createOutline,
+  saveOutline
 } from 'ionicons/icons';
 
 // 单词数据接口
@@ -136,6 +137,9 @@ listSwipeDirection: 'left' | 'right' | null = null;
   showStyleModal: boolean = false;
   defaultStyles: string = '比如:童话、青春、悬疑、励志、科幻...';
 
+  // 退出确认弹窗状态
+  showExitModal: boolean = false;
+
   // 生成状态
   isGenerating: boolean = false;
 
@@ -179,7 +183,8 @@ listSwipeDirection: 'left' | 'right' | null = null;
       sparklesOutline,
       chevronBackOutline,
       chevronForwardOutline,
-      createOutline
+      createOutline,
+      saveOutline
     });
     // 从其他页通过 state 进入做题页时恢复故事
     const nav = this.router.getCurrentNavigation();
@@ -843,9 +848,15 @@ listSwipeDirection: 'left' | 'right' | null = null;
 
   // 返回上一页
   goBack() {
+    // 评分结果页面点击返回,弹出确认弹窗
+    if (this.showExerciseView && this.scoreResult) {
+      this.showExitModal = true;
+      return;
+    }
     if (this.showExerciseView) {
       this.showExerciseView = false;
       this.exerciseStory = null;
+      this.scoreResult = null;
       return;
     }
     if (this.isGenerating) {
@@ -856,4 +867,50 @@ listSwipeDirection: 'left' | 'right' | null = null;
       this.router.navigate(['/tabs/tab2']);
     }
   }
+
+  // 关闭退出确认弹窗
+  closeExitModal() {
+    this.showExitModal = false;
+  }
+
+  // 确认退出 - 重置状态并回到tab2页面
+  confirmExit() {
+    this.showExitModal = false;
+    this.resetState();
+    this.router.navigate(['/tabs/tab2']);
+  }
+
+  // 保存故事 - 存入数据库(先不实现),然后重置状态回到tab2页面
+  saveStory() {
+    // TODO: 将数据存入数据库
+    console.log('保存故事:', {
+      story: this.exerciseStory,
+      score: this.scoreResult,
+      answers: this.exerciseBlanks
+    });
+    
+    // 重置状态并回到tab2页面
+    this.resetState();
+    this.router.navigate(['/tabs/tab2']);
+  }
+
+  // 重置页面状态
+  private resetState() {
+    this.showExerciseView = false;
+    this.exerciseStory = null;
+    this.exerciseBlanks = [];
+    this.availableWords = [];
+    this.focusedBlankIndex = null;
+    this.scoreResult = null;
+    this.storyResponse = null;
+    this.storyError = null;
+    this.isGenerating = false;
+    this.flashWords = [];
+    this.currentFlashIndex = 0;
+    this.showStyleModal = false;
+    this.showExitModal = false;
+    // 重置单词选中状态
+    this.learningWords.forEach(word => word.selected = false);
+    this.learnedWords.forEach(word => word.selected = false);
+  }
 }

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
word-app/src/assets/icon/保存故事.svg


Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů