2 Commits 2b50110c72 ... 5b0a5fbfe9

Author SHA1 Message Date
  xukang 5b0a5fbfe9 fix: fix some potential page bugs 4 months ago
  xukang 2b46b8a726 fix:fixed some potential page bugs 4 months ago

+ 28 - 27
TFPower-app/src/app/tab2/agent/agent.json.ts

@@ -42,45 +42,46 @@ export function extactAndParseJsonFromString(inputString: string) {
         return {}
         return {}
     }
     }
 }
 }
+/**
+ * 从字符串中提取所有 JSON 对象并解析
+ * 
+ * @param inputString 输入的字符串
+ * @returns 返回一个包含所有 JSON 对象的数组
+ */
 export function extractAllJsonFromString(inputString: string) {
 export function extractAllJsonFromString(inputString: string) {
-    let startIndex = inputString.indexOf("{");
-    let count = 0;
-    let jsonObjects = [];  // 用来存储所有提取的JSON对象
+    const jsonObjects: any[] = [];
+    let startIndex = -1;  // 用于记录 JSON 开始的位置
+    let count = 0;        // 用于记录花括号的数量(平衡)
 
 
-    while (startIndex !== -1) {
-        let endIndex = startIndex;
-        count = 0;
+    // 遍历整个字符串,查找并提取所有 JSON 对象
+    for (let i = 0; i < inputString.length; i++) {
+        const char = inputString[i];
 
 
-        // 遍历字符串,计算花括号平衡
-        for (let i = startIndex; i < inputString.length; i++) {
-            if (inputString[i] === "{") {
-                count++;
-            } else if (inputString[i] === "}") {
-                count--;
-            }
-            // 找到完整的JSON数据
-            if (count === 0) {
-                endIndex = i;
-                break;
-            }
+        // 找到 JSON 对象的开始
+        if (char === '{' && count === 0) {
+            startIndex = i;  // 记录 JSON 开始的位置
         }
         }
 
 
-        // 如果找到了平衡的花括号,提取JSON并解析
-        if (count === 0) {
-            const jsonString = inputString.slice(startIndex, endIndex + 1);
+        // 计算花括号的平衡
+        if (char === '{') {
+            count++;
+        } else if (char === '}') {
+            count--;
+        }
+
+        // 如果花括号平衡,表示找到了一个完整的 JSON 对象
+        if (count === 0 && startIndex !== -1) {
+            const jsonString = inputString.slice(startIndex, i + 1);
             try {
             try {
                 const jsonObject = JSON.parse(jsonString);
                 const jsonObject = JSON.parse(jsonString);
-                jsonObjects.push(jsonObject);  // 将解析的对象添加到数组中
+                jsonObjects.push(jsonObject);  // 将解析的 JSON 对象添加到数组中
             } catch (error) {
             } catch (error) {
                 console.error("Failed to parse JSON:", error);
                 console.error("Failed to parse JSON:", error);
             }
             }
-
-            // 更新startIndex,继续查找下一个 JSON
-            startIndex = inputString.indexOf("{", endIndex + 1);
-        } else {
-            break;
+            startIndex = -1;  // 重置 startIndex,继续查找下一个 JSON 对象
         }
         }
     }
     }
 
 
     return jsonObjects;
     return jsonObjects;
 }
 }
+

+ 33 - 14
TFPower-app/src/app/tab2/edit-plan-modal/edit-plan-modal.component.html

@@ -15,38 +15,57 @@
     <ion-card-content>
     <ion-card-content>
       <!-- 日期输入框 -->
       <!-- 日期输入框 -->
       <ion-item lines="none">
       <ion-item lines="none">
-        <ion-input label="日期" [value]="plan.get('date')" (ionBlur)="onChange('date', $event)"></ion-input>
+        <ion-input label="日期:" [value]="plan.get('date')" (ionBlur)="onChange('date', $event)" placeholder="请输入日期">
+        </ion-input>
       </ion-item>
       </ion-item>
-
       <!-- 部位输入框 -->
       <!-- 部位输入框 -->
       <ion-item lines="none">
       <ion-item lines="none">
-        <ion-input label="部位" [value]="plan.get('trainingPart')" (ionBlur)="onChange(  'trainingPart', $event)">
-        </ion-input>
+        <ion-input label="部位" [value]="plan.get('trainingPart')" (ionBlur)="onChange(  'trainingPart', $event)"
+          placeholder="请输入训练部位"></ion-input>
       </ion-item>
       </ion-item>
-
       <!-- 训练计划 -->
       <!-- 训练计划 -->
       <ion-label>训练计划</ion-label>
       <ion-label>训练计划</ion-label>
+
       <ion-row *ngFor="let task of plan.get('trainingItems'); let i = index" class="plan-row">
       <ion-row *ngFor="let task of plan.get('trainingItems'); let i = index" class="plan-row">
-        <ion-col size="4" class="plan-column">
+        <ion-col size="12" size-md="4" class="plan-column">
           <ion-item lines="none">
           <ion-item lines="none">
-            <ion-input label="项目{{i + 1}}" [value]="task.item || ''" (ionBlur)="onTaskChange(i, 'item', $event)">
-            </ion-input>
+            <ion-input label="项目{{i + 1}}" [value]="task.item || ''" (ionBlur)="onTaskChange(i, 'item', $event)"
+              placeholder="请输入项目名称"></ion-input>
           </ion-item>
           </ion-item>
         </ion-col>
         </ion-col>
-        <ion-col size="3">
+        <ion-col size="6" size-md="3">
           <ion-item lines="none">
           <ion-item lines="none">
-            <ion-input label="组数" [value]="task.sets" (ionBlur)="onTaskChange(i, 'sets', $event)"></ion-input>
+            <ion-input label="组数:" [value]="task.sets" (ionBlur)="onTaskChange(i, 'sets', $event)" placeholder="请输入组数">
+            </ion-input>
           </ion-item>
           </ion-item>
         </ion-col>
         </ion-col>
-        <ion-col size="3">
+        <ion-col size="6" size-md="3">
           <ion-item lines="none">
           <ion-item lines="none">
-            <ion-input label="次数" [value]="task.reps" (ionBlur)="onTaskChange(i, 'reps', $event)"></ion-input>
+            <ion-input label="次数:" [value]="task.reps" (ionBlur)="onTaskChange(i, 'reps', $event)" placeholder="请输入次数">
+            </ion-input>
           </ion-item>
           </ion-item>
         </ion-col>
         </ion-col>
       </ion-row>
       </ion-row>
 
 
-      <!-- 保存按钮 -->
-      <ion-button expand="full" color="primary" (click)="saveChanges()">保存修改</ion-button>
+      <ion-grid>
+        <ion-row>
+          <!-- 左侧按钮 -->
+          <ion-col size="6">
+            <ion-button expand="full" (click)="saveChanges()" shape="round" class="confirm-btn">
+              <ion-icon name="checkmark-circle-outline"></ion-icon>
+              保存修改
+            </ion-button>
+          </ion-col>
+
+          <!-- 右侧按钮 -->
+          <ion-col size="6">
+            <ion-button expand="full" color="light" shape="round" (click)="deletePlan(plan)" class="discard-btn">
+              <ion-icon name="close-circle-outline"></ion-icon>
+              删除计划
+            </ion-button>
+          </ion-col>
+        </ion-row>
+      </ion-grid>
     </ion-card-content>
     </ion-card-content>
   </ion-card>
   </ion-card>
 </ion-content>
 </ion-content>

+ 2 - 1
TFPower-app/src/app/tab2/edit-plan-modal/edit-plan-modal.component.scss

@@ -1,5 +1,5 @@
 .plan-row {
 .plan-row {
-  margin-bottom: 15px;
+  margin-bottom: 5px;
 }
 }
 
 
 .plan-column {
 .plan-column {
@@ -24,3 +24,4 @@ ion-item {
 .horizontal-item ion-input {
 .horizontal-item ion-input {
   flex: 1 1 auto; /* 输入框扩展占满剩余空间 */
   flex: 1 1 auto; /* 输入框扩展占满剩余空间 */
 }
 }
+

+ 40 - 2
TFPower-app/src/app/tab2/edit-plan-modal/edit-plan-modal.component.ts

@@ -1,14 +1,18 @@
 import { Component, Input } from '@angular/core';
 import { Component, Input } from '@angular/core';
-import { ModalController } from '@ionic/angular/standalone';
+import { AlertController, IonGrid, IonIcon, ModalController } from '@ionic/angular/standalone';
 import { IonRow, IonCol, IonHeader, IonToolbar, IonTitle, IonButtons, IonButton, IonContent, IonCard, IonCardHeader, IonCardTitle, IonCardContent, IonItem, IonLabel, IonInput, IonToggle } from '@ionic/angular/standalone';
 import { IonRow, IonCol, IonHeader, IonToolbar, IonTitle, IonButtons, IonButton, IonContent, IonCard, IonCardHeader, IonCardTitle, IonCardContent, IonItem, IonLabel, IonInput, IonToggle } from '@ionic/angular/standalone';
 import { FormsModule } from '@angular/forms';
 import { FormsModule } from '@angular/forms';
 import { CommonModule } from '@angular/common';
 import { CommonModule } from '@angular/common';
+import { addIcons } from 'ionicons';
+import { closeCircleOutline, checkmarkCircleOutline } from 'ionicons/icons';
 @Component({
 @Component({
   selector: 'app-edit-plan-modal',
   selector: 'app-edit-plan-modal',
   templateUrl: './edit-plan-modal.component.html',
   templateUrl: './edit-plan-modal.component.html',
   styleUrls: ['./edit-plan-modal.component.scss'],
   styleUrls: ['./edit-plan-modal.component.scss'],
   standalone: true,
   standalone: true,
   imports: [
   imports: [
+    IonIcon,
+    IonGrid,
     IonRow,
     IonRow,
     IonCol,
     IonCol,
     IonHeader,
     IonHeader,
@@ -31,7 +35,9 @@ import { CommonModule } from '@angular/common';
 })
 })
 export class EditPlanModalComponent {
 export class EditPlanModalComponent {
   @Input() plan: any;  // 接收传入的计划数据
   @Input() plan: any;  // 接收传入的计划数据
-  constructor(private modalCtrl: ModalController) { }
+  constructor(private modalCtrl: ModalController, private alertController: AlertController) {
+    addIcons({ closeCircleOutline, checkmarkCircleOutline, });
+  }
   // 更新数据字段
   // 更新数据字段
   onChange(field: string, event: any) {
   onChange(field: string, event: any) {
     const value = event.target.value;
     const value = event.target.value;
@@ -55,6 +61,38 @@ export class EditPlanModalComponent {
       console.error('保存失败:', error);
       console.error('保存失败:', error);
     }
     }
   }
   }
+  async deletePlan(day: any) {
+    const alert = await this.alertController.create({
+      header: '确认删除',
+      message: '确定要删除此计划吗?',
+      buttons: [
+        {
+          text: '取消',
+          role: 'cancel',
+          cssClass: 'secondary',
+          handler: () => {
+            console.log('删除操作被取消');
+          }
+        },
+        {
+          text: '确认',
+          handler: () => {
+            day.destroy()
+              .then(() => {
+                console.log('计划已删除');
+
+                this.dismiss();
+              })
+              .catch((error: any) => {
+                console.error('删除失败:', error);
+              });
+          }
+        }
+      ]
+    });
+
+    await alert.present();
+  }
   dismiss() {
   dismiss() {
     this.modalCtrl.dismiss();
     this.modalCtrl.dismiss();
   }
   }

+ 115 - 125
TFPower-app/src/app/tab2/tab2.page.html

@@ -19,7 +19,6 @@
 
 
 <ion-content [fullscreen]="true">
 <ion-content [fullscreen]="true">
   <div style="height: 56px;"></div>
   <div style="height: 56px;"></div>
-
   <!-- 打卡 -->
   <!-- 打卡 -->
   <div *ngIf="selectedTab === 'checkin'" class="checkin-container">
   <div *ngIf="selectedTab === 'checkin'" class="checkin-container">
     <ion-card>
     <ion-card>
@@ -61,161 +60,152 @@
 
 
   <!-- 计划 -->
   <!-- 计划 -->
   <div *ngIf="selectedTab === 'plan'" class="plan-container">
   <div *ngIf="selectedTab === 'plan'" class="plan-container">
-    <ion-card>
-      <ion-card-header>
-        <ion-card-title>我的本周计划</ion-card-title>
-      </ion-card-header>
-      <ion-card-content>
+
+
+    <ion-card-content>
+      <ion-card>
+        <ion-card-header>
+          <ion-card-title>我的本周计划</ion-card-title>
+        </ion-card-header>
+
         <div class="plan-table">
         <div class="plan-table">
           <ion-grid class="table">
           <ion-grid class="table">
             <ion-row>
             <ion-row>
               <ion-col size="1" class="grid-header">日期</ion-col>
               <ion-col size="1" class="grid-header">日期</ion-col>
               <ion-col size="1" class="grid-header">部位</ion-col>
               <ion-col size="1" class="grid-header">部位</ion-col>
-              <ion-col size="1.5" class="grid-header">项目1</ion-col>
-              <ion-col size="1.5" class="grid-header">项目2</ion-col>
-              <ion-col size="1.5" class="grid-header">项目3</ion-col>
-              <ion-col size="1.5" class="grid-header">项目4</ion-col>
-              <ion-col size="1.5" class="grid-header">状态</ion-col>
-              <ion-col size="2" class="grid-header">操作</ion-col> <!-- 操作列 -->
+              <ion-col size="2.5" class="grid-header">项目1</ion-col>
+              <ion-col size="2.5" class="grid-header">项目2</ion-col>
+              <ion-col size="2.5" class="grid-header">项目3</ion-col>
+              <ion-col size="2.5" class="grid-header">项目4</ion-col>
             </ion-row>
             </ion-row>
 
 
             <!-- 绑定计划数据 -->
             <!-- 绑定计划数据 -->
-            <ion-row *ngFor="let day of planList">
+            <ion-row *ngFor="let day of planList" (click)="editPlan(day)">
               <ion-col size="1" class="plan-column">{{ day.get('date') }}</ion-col>
               <ion-col size="1" class="plan-column">{{ day.get('date') }}</ion-col>
               <ion-col size="1" class="plan-column">{{ day.get('trainingPart') }}</ion-col>
               <ion-col size="1" class="plan-column">{{ day.get('trainingPart') }}</ion-col>
 
 
               <!-- 显示每个训练项目,确保即使为空也占位 -->
               <!-- 显示每个训练项目,确保即使为空也占位 -->
-              <ion-col size="1.5" *ngFor="let task of day.get('trainingItems'); let i = index" class="plan-column">
-                {{ task.item || '' }}: {{task.sets}} x {{task.reps}}
-              </ion-col>
-
-              <ion-col size="1.5" class="plan-column">
-                <ion-list>
-                  <ion-item>
-                    <ion-select aria-label="fruit" value="未完成">
-                      <ion-select-option value="未完成">未完成</ion-select-option>
-                      <ion-select-option value="已完成">已完成</ion-select-option>
-                      <ion-select-option value="修改中">修改中</ion-select-option>
-                    </ion-select>
-                  </ion-item>
-                </ion-list>
-              </ion-col>
-
-              <!-- 修改和删除按钮 -->
-              <ion-col size="2" class="ion-text-center">
-                <ion-buttons>
-                  <ion-button color="success" (click)="editPlan(day)">
-                    <ion-icon slot="start" name="create"></ion-icon> 修改
-                  </ion-button>
-                  <ion-button color="danger" (click)="deletePlan(day)">
-                    <ion-icon slot="start" name="trash"></ion-icon> 删除
-                  </ion-button>
-                </ion-buttons>
+              <ion-col size="2.5" *ngFor="let task of day.get('trainingItems'); let i = index" class="plan-column">
+                <!-- 使用 div 或 span 来分隔 item 和 sets, reps -->
+                <div class="task-container">
+                  <span class="task-item">{{ task.item || '' }}</span>
+                  <span class="sets-reps">{{ task.sets }} x {{ task.reps }}</span>
+                </div>
               </ion-col>
               </ion-col>
             </ion-row>
             </ion-row>
           </ion-grid>
           </ion-grid>
         </div>
         </div>
 
 
-        <ion-button expand="full" color="primary" (click)="goToPage('test-page')">重新生成计划</ion-button>
-      </ion-card-content>
-    </ion-card>
+      </ion-card>
+      <ion-card-subtitle>
+        <ion-icon name="alert-circle-outline" style="margin-right: 5px;"></ion-icon>点击行内数据可对计划进行修改哦!
+      </ion-card-subtitle>
+      <ion-button expand="full" shape="round" class="reverse" (click)="goToPage('test-page')">
+        <ion-icon name="infinite-outline" style="margin-right:5px ;"></ion-icon>重新生成计划
+      </ion-button>
+    </ion-card-content>
   </div>
   </div>
 
 
   <!-- 问诊 -->
   <!-- 问诊 -->
   <div *ngIf="selectedTab === 'consultation'" class="consult">
   <div *ngIf="selectedTab === 'consultation'" class="consult">
-    <!-- 健康问诊卡片 -->
-    <ion-card>
-      <ion-card-header>
-        <ion-card-title>健康问诊</ion-card-title>
-      </ion-card-header>
-      <ion-card-content>
-        <p>有任何不适,可以随时询问!</p>
 
 
-        <!-- 健身建议和疼痛咨询左右分布 -->
+    <ion-card-content>
+      <ion-card>
+        <ion-card-header>
+          <ion-card-title>健康问诊</ion-card-title>
+          <ion-card-subtitle>让健身更聪明,让健康更持久!</ion-card-subtitle>
+        </ion-card-header>
         <ion-row>
         <ion-row>
           <!-- 健身建议 -->
           <!-- 健身建议 -->
-          <ion-col size="6" class="ion-text-center">
+          <ion-col class="ion-text-center">
             <ion-img src="../../assets/images/action.png" alt="健身建议"></ion-img>
             <ion-img src="../../assets/images/action.png" alt="健身建议"></ion-img>
-            <ion-button expand="full" color="secondary" (click)="doPoemTask()">生成健身动作</ion-button>
+            <ion-button shape="round" color="secondary" (click)="doPoemTask()">
+              <ion-icon name="bicycle-outline" style="margin-right:5px;"></ion-icon>生成健身动作
+            </ion-button>
           </ion-col>
           </ion-col>
 
 
           <!-- 疼痛咨询 -->
           <!-- 疼痛咨询 -->
-          <ion-col size="6" class="ion-text-center">
+          <ion-col class="ion-text-center">
             <ion-img src="../../assets/images/ache.jpg" alt="疼痛咨询"></ion-img>
             <ion-img src="../../assets/images/ache.jpg" alt="疼痛咨询"></ion-img>
-            <ion-button expand="full" color="tertiary" (click)="doInqueryTask()">疼?点这里!</ion-button>
+            <ion-button shape="round" color="tertiary" (click)="doInqueryTask()">
+              <ion-icon name="alert-circle-outline" style="margin-right:5px;"></ion-icon>疼?点这里!
+            </ion-button>
           </ion-col>
           </ion-col>
         </ion-row>
         </ion-row>
+      </ion-card>
+
+      <!-- 任务区域 -->
+      <ion-card>
+        <ion-card-header>
+          <ion-card-title>健康任务</ion-card-title>
+        </ion-card-header>
+        <ion-card-content>
+          <div *ngFor="let step of taskList">
+            <ion-item>
+              <ion-icon *ngIf="step.progress === 0 && !step.error" name="radio-button-off-outline"></ion-icon>
+              <ion-icon *ngIf="step.progress !== 0 && step.progress !== 1" name="reload-outline"></ion-icon>
+              <ion-icon *ngIf="step.progress === 1" name="checkmark-circle-outline"></ion-icon>
+              <ion-icon *ngIf="step.error" name="close-circle-outline"></ion-icon>
+              {{ step.title }}
+              <span *ngIf="step.progress">{{ step.progress * 100 | number:'2.0-0' }}%</span>
+              <span *ngIf="step.error" style="color:red;">{{ step.error }}</span>
+            </ion-item>
+          </div>
+        </ion-card-content>
+      </ion-card>
+
+      <!-- 图片展示 -->
+      <ion-card *ngIf="shareData.images">
+        <ion-card-header>
+          <ion-card-title>动作展示</ion-card-title>
+        </ion-card-header>
+        <ion-card-content>
+          <div *ngFor="let imageUrl of shareData.images">
+            <img [src]="imageUrl" alt="诊断图片" style="width: 100%; height: 400px; object-fit: cover;" />
+          </div>
+        </ion-card-content>
+      </ion-card>
+
+      <!-- 诊断结果 -->
+      <ion-card *ngIf="shareData.diagResult">
+        <ion-card-header>
+          <ion-card-title>{{ shareData.diagResult.title }}</ion-card-title>
+        </ion-card-header>
+        <ion-card-content>
+          <h2>{{ shareData.diagResult.desc }}</h2>
+          <fm-markdown-preview class="content-style" [content]=shareData.diagResult.content>
+          </fm-markdown-preview>
+        </ion-card-content>
+      </ion-card>
+
+      <!-- AI教练互动 -->
+      <ion-card id="coaches">
+        <ion-card-header>
+          <ion-card-title>教练简介</ion-card-title>
+          <ion-card-subtitle>顶级教练</ion-card-subtitle>
+        </ion-card-header>
+        <ion-card-content style="padding: 5px;">
+          <ion-list>
+            <ion-item *ngFor="let coach of coachList" lines="none">
+              <ion-thumbnail slot="start">
+                <img [src]="coach.get('avater') || '../../assets/images/coach1.jpg'" [alt]="coach.get('name')" />
+              </ion-thumbnail>
+              <div class="coach-info" style="width: 100px;">
+                <h3>{{ coach.get('name') }}({{ coach.get('age') }}岁)</h3>
+                <p>擅长领域:{{ coach.get('specialize')}}</p>
+                <p>WiseFitness俱乐部</p>
+              </div>
+              <div style="margin-left: 10px;">
+                <ion-button shape="round" size="small" (click)="openInquiry(coach)">
+                  <ion-icon name="logo-gitlab" style="margin-right: 5px;"></ion-icon>
+                  立即咨询
+                </ion-button>
+              </div>
+            </ion-item>
+          </ion-list>
+        </ion-card-content>
+      </ion-card>
+    </ion-card-content>
 
 
-        <!-- 任务区域 -->
-        <ion-card>
-          <ion-card-header>
-            <ion-card-title>健康任务</ion-card-title>
-          </ion-card-header>
-          <ion-card-content>
-            <div *ngFor="let step of taskList">
-              <ion-item>
-                <!-- 待开始 -->
-                <ion-icon *ngIf="step.progress === 0 && !step.error" name="radio-button-off-outline"></ion-icon>
-                <!-- 进行中 -->
-                <ion-icon *ngIf="step.progress !== 0 && step.progress !== 1" name="reload-outline"></ion-icon>
-                <!-- 已完成 -->
-                <ion-icon *ngIf="step.progress === 1" name="checkmark-circle-outline"></ion-icon>
-                <!-- 已出错 -->
-                <ion-icon *ngIf="step.error" name="close-circle-outline"></ion-icon>
-                {{ step.title }}
-                <span *ngIf="step.progress">{{ step.progress * 100 | number:'2.0-0' }}%</span>
-                <span *ngIf="step.error" style="color:red;">{{ step.error }}</span>
-              </ion-item>
-            </div>
-          </ion-card-content>
-        </ion-card>
-
-        <!-- 图片展示 -->
-        <ion-card *ngIf="shareData.images">
-          <ion-card-header>
-            <ion-card-title>动作展示</ion-card-title>
-          </ion-card-header>
-          <ion-card-content>
-            <div *ngFor="let imageUrl of shareData.images">
-              <img [src]="imageUrl" alt="诊断图片" style="width: 100%; height: 400px; object-fit: cover;" />
-            </div>
-          </ion-card-content>
-        </ion-card>
-
-        <!-- 诊断结果 -->
-        <ion-card *ngIf="shareData.diagResult">
-          <ion-card-header>
-            <ion-card-title>{{ shareData.diagResult.title }}</ion-card-title>
-          </ion-card-header>
-          <ion-card-content>
-            <h2>{{ shareData.diagResult.desc }}</h2>
-            <fm-markdown-preview class="content-style" [content]=shareData.diagResult.content>
-            </fm-markdown-preview>
-          </ion-card-content>
-        </ion-card>
-
-        <!-- AI教练互动 -->
-        <ion-card>
-          <ion-card-header>
-            <ion-card-title>顶级教练专区</ion-card-title>
-            <ion-card-subtitle>教练简介</ion-card-subtitle>
-          </ion-card-header>
-          <ion-card-content>
-            <ion-list>
-              <ion-item (click)="openInquiry(coach)" *ngFor="let coach of coachList" lines="none">
-                <ion-thumbnail slot="start">
-                  <img src="../../assets/images/coach1.jpg" alt="coach.get('name')">
-                </ion-thumbnail>
-                <div class="coach-info">
-                  <h3>{{ coach.get('name') }}({{ coach.get('age') }}岁)</h3>
-                  <p>擅长领域:{{ coach.get('specialize')}}</p>
-                  <p>WiseFitness俱乐部</p>
-                </div>
-              </ion-item>
-            </ion-list>
-          </ion-card-content>
-        </ion-card>
-      </ion-card-content>
-    </ion-card>
   </div>
   </div>
 </ion-content>
 </ion-content>

+ 100 - 83
TFPower-app/src/app/tab2/tab2.page.scss

@@ -45,7 +45,7 @@ ion-content {
 // plan部分css
 // plan部分css
 /* 给表格增加阴影和圆角 */
 /* 给表格增加阴影和圆角 */
 .plan-table ion-grid {
 .plan-table ion-grid {
-  margin-top: 20px;
+  
   box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
   box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
   width: 100%; 
   width: 100%; 
 
 
@@ -59,6 +59,9 @@ ion-content {
 .plan-table ion-col {
 .plan-table ion-col {
   margin-bottom: 1px;
   margin-bottom: 1px;
   border-bottom: 1px solid #ddd;
   border-bottom: 1px solid #ddd;
+    display: flex;
+    justify-content: center;
+    align-items: center;
   
   
 }
 }
 
 
@@ -78,91 +81,43 @@ ion-content {
   padding: 12px;
   padding: 12px;
   border-bottom: 1px solid #ddd;
   border-bottom: 1px solid #ddd;
 }
 }
-.plan-table ion-select {
-  width: 50%;  /* 调整宽度 */
-  height: 50%;
-  margin: 1px;
-}
-
-/* 修改状态框的选项 */
-.plan-table ion-select .select-interface-option {
-  font-size: 12px;  /* 修改选项字体大小 */
-  color: #555;  /* 修改选项字体颜色 */
-}
-
-/* 修改选中时的背景颜色 */
-.plan-table ion-select .select-placeholder {
-  color: #719e8c;  /* 占位符字体颜色 */
-}
-
-/* 修改下拉箭头的颜色 */
-.plan-table ion-select .select-icon {
-  color: #719e8c;  /* 下拉箭头颜色 */
-}
-
-/* 当选择框被激活时的样式 */
-
-.plan-table ion-button {  
-  margin-right: 10px; 
-  text-align: center; 
-  justify-content: center; 
-}
-.plan-table ion-button[color="success"]::part(native)
-{
-   justify-content: center;
-  align-items: center;
-color: white !important; /* 强制修改文本颜色为黑色 */
-}
-.plan-table ion-button[color="danger"]::part(native)
-{
-   justify-content: center;
-  align-items: center;
-color: white !important; /* 强制修改文本颜色为黑色 */
-}
-/* 按钮 */
-.plan-table ion-button[color="success"] {
-  background-color: #59beec; /* 绿色背景 */
-  border-radius: 4px;
-  padding: 5px 5px;
-  font-weight: bold;
-   justify-content: center;
-  align-items: center;
-  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
-  transition: background-color 0.3s ease, transform 0.3s ease;
-}
-
-.plan-table ion-button[color="success"]:hover {
-  background-color: #48a7cc; /* 悬停时颜色变深 */
-  transform: scale(1.05); /* 悬停时按钮放大 */
-}
-
-.plan-table ion-button[color="danger"] {
-  background-color: #f44336; /* 红色背景 */
-  border-radius: 4px;
-  padding: 5px 5px;
-  font-weight: bold;
-  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
-  transition: background-color 0.3s ease, transform 0.3s ease;
-}
-.plan-table ion-button[color="danger"]:hover {
-  background-color: #d32f2f; /* 悬停时颜色变深 */
-  transform: scale(1.05); /* 悬停时按钮放大 */
-}
-/* 优化按钮在行中的显示位置 */
-.plan-table ion-buttons {
-  display: flex;
-  justify-content: center;
-  align-items: center;
-}
 
 
-/* 给每个section加标题 */
 .section-title {
 .section-title {
   font-size: 20px;
   font-size: 20px;
   font-weight: bold;
   font-weight: bold;
   color: #333;
   color: #333;
   margin-bottom: 20px;
   margin-bottom: 20px;
 }
 }
+@media (max-width: 768px) {
+  /* 更小的屏幕尺寸(如手机) */
+  .plan-table ion-col {
+    padding: 6px;
+    font-size: 14px;
+  }
 
 
+  .plan-table ion-select {
+    width: 100%;
+    font-size: 12px;
+  }
+
+  .plan-table ion-button {
+    min-width: 70px;
+    padding: 5px;
+  }
+}
+
+@media (max-width: 480px) {
+  /* 极小的屏幕尺寸(如小手机) */
+  .plan-table ion-col {
+    padding: 2px;
+    font-size: 12px;
+  }
+
+  .plan-table ion-button {
+    min-width: 60px;
+    padding: 2px;
+  }
+}
 /* 问诊部分的设计 */
 /* 问诊部分的设计 */
 /* 确保图片等大 */
 /* 确保图片等大 */
 .consult .ion-text-center ion-img {
 .consult .ion-text-center ion-img {
@@ -177,11 +132,14 @@ color: white !important; /* 强制修改文本颜色为黑色 */
   box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); /* 添加卡片阴影 */
   box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); /* 添加卡片阴影 */
   background-color: #ffffff; /* 卡片背景色 */
   background-color: #ffffff; /* 卡片背景色 */
 }
 }
-
+.consult .thumbnail {
+  width: 160px;  /* 可以根据需要设置尺寸 */
+  height: 160px;  /* 高度和宽度一致使图片为正方形 */
+  margin-bottom: 10px;  /* 图片和按钮之间的间距 */
+}
 .consult ion-thumbnail {
 .consult ion-thumbnail {
   width: 60px; /* 缩略图宽度 */
   width: 60px; /* 缩略图宽度 */
   height: 60px; /* 缩略图高度 */
   height: 60px; /* 缩略图高度 */
-  border-radius: 50%; /* 圆形头像 */
 }
 }
 
 
 .consult .coach-info {
 .consult .coach-info {
@@ -196,19 +154,78 @@ color: white !important; /* 强制修改文本颜色为黑色 */
   font-size: 16px;
   font-size: 16px;
   font-weight: bold;
   font-weight: bold;
 }
 }
-
+.consult ion-card-subtitle {
+  font-size: 14px;
+  margin: 4px 0;
+  font-weight: bold;
+  color: rgb(22, 16, 16);
+}
 .consult .coach-info p {
 .consult .coach-info p {
   margin: 4px 0;
   margin: 4px 0;
-  font-size: 14px;
+  font-size: 12px;
   color: #666; /* 字体颜色 */
   color: #666; /* 字体颜色 */
 }
 }
+.consult ion-button {
+  --background: rgb(244, 245, 244);
+  --color: #13120e;
+  --border-radius: 15px;
+  --border-color: #000;
+  --border-style: solid;
+  --border-width: 1px;
+  --box-shadow: 0 2px 6px 0 rgb(0, 0, 0, 0.25);
+  --ripple-color: deeppink;
+  --padding-top: 10px;
+  --padding-bottom: 10px;
+}
+.reverse
+{
+  --background: #32548f;
+  --color: white;
+  --border-radius: 15px;
+  --border-color: #000;
+  --border-style: solid;
+  --border-width: 1px;
+  --box-shadow: 0 2px 6px 0 rgb(0, 0, 0, 0.25);
+  --ripple-color: deeppink;
+  --padding-top: 10px;
+  --padding-bottom: 10px;
+}
+.plan-column {
+  transition: background-color 0.3s ease, box-shadow 0.3s ease;  /* 平滑过渡效果 */
+}
+/* 鼠标悬停时的样式 */
+.plan-column:hover {
+  background-color: #f4f4f4;  /* 设置背景色变化 */
+  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);  /* 添加阴影效果 */
+}
+.task-container {
+  display: flex; /* 设置为 flexbox */
+  flex-direction: column; /* 让子元素垂直排列 */
+  align-items: center; /* 水平居中 */
+  justify-content: center; /* 垂直居中 */
+  text-align: center; /* 确保文本在水平上居中 */
+}
 
 
-
+.task-item {
+  font-weight: bold;
+  margin-bottom: 5px; /* 为了分隔上下两个span */
+}
 /* 打卡部分的设计 */
 /* 打卡部分的设计 */
 .checkin-container p {
 .checkin-container p {
   font-size: 18px;
   font-size: 18px;
   color: #555;
   color: #555;
 }
 }
+ion-card {
+    border-radius: 15px; /* 圆角边框 */
+    background-color: #f9f9f9; /* 卡片内部背景颜色 */
+    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); /* 添加阴影效果 */
+    border: 1px solid #e0e0e0; /* 边框颜色 */
+  }
+ion-card:hover {
+    transform: scale(1.02); /* 悬停时放大效果 */
+    transition: transform 0.2s; /* 动画过渡效果 */
+  }
+
 
 
 
 
 
 

+ 35 - 36
TFPower-app/src/app/tab2/tab2.page.ts

@@ -1,7 +1,7 @@
 import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
 import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
 import { Router } from '@angular/router';
 import { Router } from '@angular/router';
 import { addIcons } from 'ionicons';
 import { addIcons } from 'ionicons';
-import { checkmarkCircle, trash, calendar, helpCircle, create } from 'ionicons/icons';
+import { checkmarkCircle, infiniteOutline, alertCircleOutline, bicycleOutline, logoGitlab, trash, calendar, helpCircle, create } from 'ionicons/icons';
 import { CommonModule } from '@angular/common';
 import { CommonModule } from '@angular/common';
 import { FormsModule } from '@angular/forms';
 import { FormsModule } from '@angular/forms';
 import { IonSelect, IonThumbnail, IonCardSubtitle, IonImg, IonCard, IonButtons, IonItem, IonList, IonHeader, IonIcon, IonToolbar, IonContent, IonSegment, IonSegmentButton, IonGrid, IonRow, IonCol, IonButton, IonLabel, IonBadge, IonInput, ModalController, IonCardTitle, IonCardContent, IonCardHeader, IonSelectOption } from '@ionic/angular/standalone';
 import { IonSelect, IonThumbnail, IonCardSubtitle, IonImg, IonCard, IonButtons, IonItem, IonList, IonHeader, IonIcon, IonToolbar, IonContent, IonSegment, IonSegmentButton, IonGrid, IonRow, IonCol, IonButton, IonLabel, IonBadge, IonInput, ModalController, IonCardTitle, IonCardContent, IonCardHeader, IonSelectOption } from '@ionic/angular/standalone';
@@ -62,7 +62,7 @@ export class Tab2Page implements OnInit {
   ];
   ];
   currentUser: CloudUser | undefined
   currentUser: CloudUser | undefined
   constructor(private router: Router, private modalCtrl: ModalController, private cdr: ChangeDetectorRef, private alertController: AlertController) {
   constructor(private router: Router, private modalCtrl: ModalController, private cdr: ChangeDetectorRef, private alertController: AlertController) {
-    addIcons({ checkmarkCircle, calendar, helpCircle, trash, create });
+    addIcons({ alertCircleOutline, checkmarkCircle, calendar, helpCircle, trash, create, logoGitlab, bicycleOutline, infiniteOutline });
     this.currentUser = new CloudUser();
     this.currentUser = new CloudUser();
   }
   }
   async loadPlanList() {
   async loadPlanList() {
@@ -113,7 +113,6 @@ export class Tab2Page implements OnInit {
       componentProps: { plan: day }
       componentProps: { plan: day }
     }).then(modal => {
     }).then(modal => {
       modal.present();
       modal.present();
-
       modal.onDidDismiss().then((result) => {
       modal.onDidDismiss().then((result) => {
         if (result.data) {
         if (result.data) {
           const updatedPlan = result.data;
           const updatedPlan = result.data;
@@ -122,41 +121,41 @@ export class Tab2Page implements OnInit {
             this.planList[index] = updatedPlan;
             this.planList[index] = updatedPlan;
           }
           }
         }
         }
+        this.loadPlanList()
       });
       });
     });
     });
   }
   }
-  async deletePlan(day: any) {
-    const alert = await this.alertController.create({
-      header: '确认删除',
-      message: '确定要删除此计划吗?',
-      buttons: [
-        {
-          text: '取消',
-          role: 'cancel',
-          cssClass: 'secondary',
-          handler: () => {
-            console.log('删除操作被取消');
-          }
-        },
-        {
-          text: '确认',
-          handler: () => {
-            day.destroy()
-              .then(() => {
-                console.log('计划已删除');
-                this.loadPlanList();
-              })
-              .catch((error: any) => {
-                console.error('删除失败:', error);
-              });
-          }
-        }
-      ]
-    });
-
-    await alert.present();
-  }
+  // async deletePlan(day: any) {
+  //   const alert = await this.alertController.create({
+  //     header: '确认删除',
+  //     message: '确定要删除此计划吗?',
+  //     buttons: [
+  //       {
+  //         text: '取消',
+  //         role: 'cancel',
+  //         cssClass: 'secondary',
+  //         handler: () => {
+  //           console.log('删除操作被取消');
+  //         }
+  //       },
+  //       {
+  //         text: '确认',
+  //         handler: () => {
+  //           day.destroy()
+  //             .then(() => {
+  //               console.log('计划已删除');
+  //               this.loadPlanList();
+  //             })
+  //             .catch((error: any) => {
+  //               console.error('删除失败:', error);
+  //             });
+  //         }
+  //       }
+  //     ]
+  //   });
 
 
+  //   await alert.present();
+  // }
   //任务链
   //任务链
   taskList: AgentTaskStep[] = []
   taskList: AgentTaskStep[] = []
   //一个等待一秒的函数  每经过一秒
   //一个等待一秒的函数  每经过一秒
@@ -238,9 +237,9 @@ export class Tab2Page implements OnInit {
         console.log("onChatInit");
         console.log("onChatInit");
         console.log("预设角色", chat.role);
         console.log("预设角色", chat.role);
         chat.role.set("name", coach?.get("name"));
         chat.role.set("name", coach?.get("name"));
-        chat.role.set("title", "职业教练");
+        chat.role.set("title", "职业健身教练");
         chat.role.set("tags", coach?.get("specialize"));
         chat.role.set("tags", coach?.get("specialize"));
-        chat.role.set("avatar", "../../assets/images/coach2.jpg")
+        chat.role.set("avatar", coach?.get("avater") || "../../assets/images/coach1.jpg")
         chat.role.set("prompt", `
         chat.role.set("prompt", `
 # 角色设定
 # 角色设定
 您是${coach?.get("name")},年龄${coach?.get("age")},特长为${coach?.get("specialize")},要完成一次教练与学员之间的锻炼部位交流。
 您是${coach?.get("name")},年龄${coach?.get("age")},特长为${coach?.get("specialize")},要完成一次教练与学员之间的锻炼部位交流。

+ 3 - 1
TFPower-app/src/app/tab2/tag-input/tag-input.component.html

@@ -6,7 +6,9 @@
   <ion-card-content>
   <ion-card-content>
     <div class="input-container">
     <div class="input-container">
       <ion-input [(ngModel)]="tagInput" placeholder="例如:减脂,增肌..." (keydown.enter)="addTag()"></ion-input>
       <ion-input [(ngModel)]="tagInput" placeholder="例如:减脂,增肌..." (keydown.enter)="addTag()"></ion-input>
-      <ion-button expand="full" (click)="addTag()">添加标签</ion-button>
+      <ion-button expand="full" (click)="addTag()" shape="round" size="small">
+        <ion-icon name="pricetag-outline"></ion-icon>添加标签
+      </ion-button>
     </div>
     </div>
 
 
     <!-- 标签显示区域 -->
     <!-- 标签显示区域 -->

+ 4 - 1
TFPower-app/src/app/tab2/tag-input/tag-input.component.scss

@@ -11,7 +11,10 @@
   gap: 10px;
   gap: 10px;
   margin-top: 10px;
   margin-top: 10px;
 }
 }
-
+ion-button
+{
+  --background: #32548f;
+}
 .tag-chip {
 .tag-chip {
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;

+ 2 - 2
TFPower-app/src/app/tab2/tag-input/tag-input.component.ts

@@ -3,7 +3,7 @@ import { IonCard, IonCardHeader, IonCardTitle, IonCardContent, IonInput, IonButt
 import { CommonModule } from '@angular/common';
 import { CommonModule } from '@angular/common';
 import { FormsModule } from '@angular/forms';
 import { FormsModule } from '@angular/forms';
 import { addIcons } from 'ionicons';
 import { addIcons } from 'ionicons';
-import { close, barbellOutline, personOutline, square, alarmOutline } from 'ionicons/icons';
+import { close, barbellOutline, personOutline, square, alarmOutline, pricetagOutline } from 'ionicons/icons';
 @Component({
 @Component({
   selector: 'app-tag-input',
   selector: 'app-tag-input',
   templateUrl: './tag-input.component.html',
   templateUrl: './tag-input.component.html',
@@ -34,6 +34,6 @@ export class TagInputComponent {
     this.tagsChanged.emit(this.tags);  // 发射更新后的标签列表
     this.tagsChanged.emit(this.tags);  // 发射更新后的标签列表
   }
   }
   constructor() {
   constructor() {
-    addIcons({ close, personOutline, barbellOutline, alarmOutline, square });
+    addIcons({ close, personOutline, barbellOutline, alarmOutline, square, pricetagOutline });
   }
   }
 }
 }

+ 25 - 9
TFPower-app/src/app/tab2/test-page/test-page.component.html

@@ -1,5 +1,4 @@
 <ion-header translucent="true">
 <ion-header translucent="true">
-
   <ion-toolbar>
   <ion-toolbar>
     <ion-title>制定个人健身计划</ion-title>
     <ion-title>制定个人健身计划</ion-title>
     <ion-back-button></ion-back-button>
     <ion-back-button></ion-back-button>
@@ -8,11 +7,6 @@
 
 
 <ion-content [fullscreen]="true">
 <ion-content [fullscreen]="true">
   <div class="content">
   <div class="content">
-
-    <ion-button (click)="goBack()">
-      <ion-icon slot="icon-only" name="arrow-back"></ion-icon>
-    </ion-button>
-    健身目标选择
     <div class="module">
     <div class="module">
       <h2>请输入您的健身目标</h2>
       <h2>请输入您的健身目标</h2>
       <app-tag-input (tagsChanged)="onTagsChanged($event)"></app-tag-input>
       <app-tag-input (tagsChanged)="onTagsChanged($event)"></app-tag-input>
@@ -90,10 +84,15 @@
     </div>
     </div>
 
 
     <!-- 生成计划按钮 -->
     <!-- 生成计划按钮 -->
-    <ion-button expand="full" (click)="generatePlan()" [disabled]="isGenerating">生成健身计划</ion-button>
+    <ion-button expand="full" shape="round" (click)="generatePlan()" [disabled]="isGenerating"
+      class="generate-plan-btn">
+      <ion-icon slot="start" style="margin-right: 5px;" name="fitness"></ion-icon>
+      生成健身计划
+    </ion-button>
 
 
     <!-- 显示健身计划结果 -->
     <!-- 显示健身计划结果 -->
     <div *ngIf="generatedPlan" class="result-container">
     <div *ngIf="generatedPlan" class="result-container">
+      <ion-progress-bar *ngIf="isRevert" type="indeterminate" color="secondary"></ion-progress-bar>
       <h3>您的健身计划:</h3>
       <h3>您的健身计划:</h3>
       <ion-card>
       <ion-card>
         <ion-card-header>
         <ion-card-header>
@@ -101,11 +100,28 @@
         </ion-card-header>
         </ion-card-header>
         <ion-card-content>
         <ion-card-content>
           <div *ngIf="isGenerating">
           <div *ngIf="isGenerating">
-            <ion-spinner name="crescent"></ion-spinner>
-            <p>生成中...</p>
+            <p>${{this.generatedPlan}}</p>
           </div>
           </div>
           <div *ngIf="!isGenerating">
           <div *ngIf="!isGenerating">
             <fm-markdown-preview class="content-style" [content]="generatedPlan"></fm-markdown-preview>
             <fm-markdown-preview class="content-style" [content]="generatedPlan"></fm-markdown-preview>
+            <ion-grid>
+              <ion-row>
+                <!-- 左侧按钮 -->
+                <ion-col size="6">
+                  <ion-button *ngIf="planReady" expand="full" (click)="confirmPlan()" shape="round" class="confirm-btn">
+                    <ion-icon name="checkmark-circle-outline"></ion-icon>确认计划
+                  </ion-button>
+                </ion-col>
+
+                <!-- 右侧按钮 -->
+                <ion-col size="6">
+                  <ion-button *ngIf="planReady" expand="full" color="light" shape="round" (click)="discardPlan()"
+                    class="discard-btn">
+                    <ion-icon name="close-circle-outline"></ion-icon>放弃计划
+                  </ion-button>
+                </ion-col>
+              </ion-row>
+            </ion-grid>
           </div>
           </div>
         </ion-card-content>
         </ion-card-content>
       </ion-card>
       </ion-card>

+ 12 - 2
TFPower-app/src/app/tab2/test-page/test-page.component.scss

@@ -34,5 +34,15 @@ ion-col {
 }
 }
 ion-button {
 ion-button {
   margin-top: 20px;
   margin-top: 20px;
-  --background: #3880ff;
-}
+  --background: #32548f;
+}
+ion-card {
+    border-radius: 15px; /* 圆角边框 */
+    background-color: #f9f9f9; /* 卡片内部背景颜色 */
+    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); /* 添加阴影效果 */
+    border: 1px solid #e0e0e0; /* 边框颜色 */
+  }
+ion-card:hover {
+    transform: scale(1.02); /* 悬停时放大效果 */
+    transition: transform 0.2s; /* 动画过渡效果 */
+  }

+ 24 - 51
TFPower-app/src/app/tab2/test-page/test-page.component.ts

@@ -4,10 +4,10 @@ import { FormsModule } from '@angular/forms';
 import { CommonModule } from '@angular/common';
 import { CommonModule } from '@angular/common';
 import { TagInputComponent } from '../tag-input/tag-input.component';
 import { TagInputComponent } from '../tag-input/tag-input.component';
 import { addIcons } from 'ionicons';
 import { addIcons } from 'ionicons';
-import { barbellOutline, personOutline, square, alarmOutline, arrowBack } from 'ionicons/icons';
+import { barbellOutline, closeCircleOutline, checkmarkCircleOutline, fitness, personOutline, square, alarmOutline, arrowBack } from 'ionicons/icons';
 import { DalleOptions, FmodeChatCompletion, MarkdownPreviewModule } from 'fmode-ng';
 import { DalleOptions, FmodeChatCompletion, MarkdownPreviewModule } from 'fmode-ng';
 import { LoadingController } from '@ionic/angular';
 import { LoadingController } from '@ionic/angular';
-import { AlertController, IonThumbnail, IonBadge, IonButton, IonButtons, IonCard, IonCardContent, IonCardHeader, IonCardSubtitle, IonCardTitle, IonCol, IonContent, IonGrid, IonHeader, IonIcon, IonImg, IonInput, IonItem, IonLabel, IonList, IonRow, IonSegment, IonSegmentButton, IonSelect, IonSelectOption, IonToolbar, IonTitle, IonSpinner, IonTextarea } from '@ionic/angular/standalone';
+import { AlertController, IonThumbnail, IonBadge, IonButton, IonButtons, IonCard, IonCardContent, IonCardHeader, IonCardSubtitle, IonCardTitle, IonCol, IonContent, IonGrid, IonHeader, IonIcon, IonImg, IonInput, IonItem, IonLabel, IonList, IonRow, IonSegment, IonSegmentButton, IonSelect, IonSelectOption, IonToolbar, IonTitle, IonSpinner, IonTextarea, IonProgressBar } from '@ionic/angular/standalone';
 import { NavController } from '@ionic/angular';
 import { NavController } from '@ionic/angular';
 import { Router } from '@angular/router';
 import { Router } from '@angular/router';
 import { CloudObject, CloudQuery, CloudUser } from 'src/lib/ncloud';
 import { CloudObject, CloudQuery, CloudUser } from 'src/lib/ncloud';
@@ -51,7 +51,8 @@ import { IonBackButton } from '@ionic/angular/standalone';
     IonLabel,
     IonLabel,
     IonBadge,
     IonBadge,
     IonInput,
     IonInput,
-    TagInputComponent
+    TagInputComponent,
+    IonProgressBar
   ]  // 添加 CommonModule
   ]  // 添加 CommonModule
 })
 })
 export class TestPageComponent implements OnInit {
 export class TestPageComponent implements OnInit {
@@ -64,7 +65,9 @@ export class TestPageComponent implements OnInit {
   goalDescription: string = '';
   goalDescription: string = '';
   generatedPlan: string = '';  // 用来存储生成的健身计划
   generatedPlan: string = '';  // 用来存储生成的健身计划
   isGenerating: boolean = false;  // 是否正在生成计划
   isGenerating: boolean = false;  // 是否正在生成计划
+  isRevert: boolean = false
   messageList: any[] = [];  // 存储消息列表
   messageList: any[] = [];  // 存储消息列表
+  planReady: boolean = false;  // 是否可以显示确认按钮
   constructor(private toastController: ToastController,
   constructor(private toastController: ToastController,
     private loadingController: LoadingController,
     private loadingController: LoadingController,
     private alertController: AlertController,
     private alertController: AlertController,
@@ -72,7 +75,7 @@ export class TestPageComponent implements OnInit {
     private router: Router,
     private router: Router,
     private navCtrl: NavController
     private navCtrl: NavController
   ) {
   ) {
-    addIcons({ personOutline, barbellOutline, alarmOutline, square, arrowBack });
+    addIcons({ fitness, personOutline, closeCircleOutline, barbellOutline, alarmOutline, square, arrowBack, checkmarkCircleOutline, });
   }
   }
   ngOnInit() { }
   ngOnInit() { }
 
 
@@ -123,15 +126,10 @@ export class TestPageComponent implements OnInit {
       await this.showToast('身高或体重为空,无法生成个人健身计划');
       await this.showToast('身高或体重为空,无法生成个人健身计划');
       return; // 退出函数,不继续生成健身计划
       return; // 退出函数,不继续生成健身计划
     }
     }
-    const loading = await this.loadingController.create({
-      message: '生成计划中...',
-      duration: 30000 // 加载时长可以根据实际需求调整
-    });
-    await loading.present();
     this.generatedPlan = '';
     this.generatedPlan = '';
     this.messageList = [];
     this.messageList = [];
     this.isGenerating = true;
     this.isGenerating = true;
-
+    this.isRevert = true
     console.log('生成健身计划', {
     console.log('生成健身计划', {
       tags: this.selectedTags,
       tags: this.selectedTags,
       exercisePreference: this.exercisePreference,
       exercisePreference: this.exercisePreference,
@@ -143,7 +141,7 @@ export class TestPageComponent implements OnInit {
     });
     });
 
 
     let prompt = `您作为一名专业的健身计划定制大师,请帮我根据以下情况制定健身计划(健身计划请给每天的运动标上序号)。关键词:${this.selectedTags.join(",")},目标描述:${this.goalDescription},运动偏好:${this.exercisePreference},
     let prompt = `您作为一名专业的健身计划定制大师,请帮我根据以下情况制定健身计划(健身计划请给每天的运动标上序号)。关键词:${this.selectedTags.join(",")},目标描述:${this.goalDescription},运动偏好:${this.exercisePreference},
-    健身频率每周:${this.workoutFrequency},身高:${this.height}cm,体重:${this.weight}kg,年龄:${this.age},注意:只需给出训练日计划,训练日只做四个运动`;
+    健身频率每周:${this.workoutFrequency},身高:${this.height}cm,体重:${this.weight}kg,年龄:${this.age},注意:训练部位给出具体部位(如胸部,腿部),具体次数,组数。一般一天一个部位。具体计划只需给出训练日计划,训练日只做四个运动`;
 
 
     let messageList = new FmodeChatCompletion([
     let messageList = new FmodeChatCompletion([
       { role: "system", content: '' },
       { role: "system", content: '' },
@@ -153,11 +151,9 @@ export class TestPageComponent implements OnInit {
     messageList.sendCompletion().subscribe((message: any) => {
     messageList.sendCompletion().subscribe((message: any) => {
       console.log(message.content);
       console.log(message.content);
       this.generatedPlan = message.content;
       this.generatedPlan = message.content;
-
       if (message?.complete) {
       if (message?.complete) {
         this.isGenerating = false;
         this.isGenerating = false;
         this.getJson()
         this.getJson()
-        loading.dismiss();
       }
       }
     });
     });
   }
   }
@@ -168,13 +164,14 @@ export class TestPageComponent implements OnInit {
   planArray: any
   planArray: any
   JSONcomplete: boolean = false
   JSONcomplete: boolean = false
   JSONdes = ""
   JSONdes = ""
+
   JSONobject: { [key: string]: string } = {}
   JSONobject: { [key: string]: string } = {}
   getJson() {
   getJson() {
     let promt = `请你以以下json格式分每天来整合文段内容:
     let promt = `请你以以下json格式分每天来整合文段内容:
     {
     {
     "date":"周几运动",
     "date":"周几运动",
     "srcId": "plan001等等",
     "srcId": "plan001等等",
-    "trainingPart":"训练部位",
+    "trainingPart":"训练部位如(胸部,腿部)",
     "trainingItems":"四个运动项目,以下面形式给出,形式如下"[
     "trainingItems":"四个运动项目,以下面形式给出,形式如下"[
   {
   {
     "item": "引体向上",
     "item": "引体向上",
@@ -213,8 +210,9 @@ export class TestPageComponent implements OnInit {
         console.log("json:", this.JSONdes);
         console.log("json:", this.JSONdes);
         this.generatedPlan = message.content;
         this.generatedPlan = message.content;
         this.planArray = extractAllJsonFromString(this.JSONdes);
         this.planArray = extractAllJsonFromString(this.JSONdes);
+        this.isRevert = false
+        this.planReady = true;
         console.log(this.planArray)
         console.log(this.planArray)
-        this.showConfirmationAlert();
         // planArray.forEach((plan: any) => {
         // planArray.forEach((plan: any) => {
         //   plan.detail = this.generatedPlan; // 添加额外的计划内容
         //   plan.detail = this.generatedPlan; // 添加额外的计划内容
         //   console.log(plan);
         //   console.log(plan);
@@ -243,63 +241,38 @@ export class TestPageComponent implements OnInit {
       }
       }
     });
     });
   }
   }
-  async showConfirmationAlert() {
-    const alert = await this.alertController.create({
-      header: '确认生成计划',
-      message: ` <div style="white-space: pre-wrap;">
-        <!-- 使用 fm-markdown-preview 渲染 Markdown 格式的内容 -->
-        <fm-markdown-preview class="content-style" [content]="generatedPlan"></fm-markdown-preview>
-      </div>`,
-      buttons: [
-        {
-          text: '放弃',
-          role: 'cancel',
-          handler: () => {
-            console.log('用户选择放弃');
-          }
-        },
-        {
-          text: '确认',
-          handler: () => {
-            // 这里可以调用 API 将数据存到数据库
-            console.log('用户确认', this.generatedPlan);
-            this.savePlanToDatabase(this.generatedPlan);
-          }
-        }
-      ]
-    });
-    await alert.present();
+  confirmPlan() {
+    this.savePlanToDatabase(this.generatedPlan);
+  }
+  discardPlan() {
+    this.generatedPlan = " "
   }
   }
   async savePlanToDatabase(plan: string) {
   async savePlanToDatabase(plan: string) {
 
 
-    let currentUser = new CloudUser().toPointer();  // 获取当前用户实例
+    let currentUser = new CloudUser().toPointer();
     console.log(currentUser)
     console.log(currentUser)
     console.log('计划保存到数据库', plan);
     console.log('计划保存到数据库', plan);
-
-    // 查询当前用户的所有计划
     const cloudQuery = new CloudQuery("fitPlan");
     const cloudQuery = new CloudQuery("fitPlan");
-    // 过滤出与当前用户关联的所有计划
     cloudQuery.equalTo("user", currentUser)
     cloudQuery.equalTo("user", currentUser)
     try {
     try {
-      const userPlans = await cloudQuery.find();  // 获取当前用户的所有计划
+      const userPlans = await cloudQuery.find();
       console.log("找到的计划数量:", userPlans.length);
       console.log("找到的计划数量:", userPlans.length);
 
 
       // 删除当前用户的所有计划
       // 删除当前用户的所有计划
       for (const planObj of userPlans) {
       for (const planObj of userPlans) {
-        await planObj.destroy();  // 删除每个计划
+        await planObj.destroy();
         console.log("已删除计划:", planObj);
         console.log("已删除计划:", planObj);
       }
       }
       this.planArray.forEach((plan: any) => {
       this.planArray.forEach((plan: any) => {
-        plan.detail = this.generatedPlan; // 添加额外的计划内容
+        plan.detail = this.generatedPlan;
         console.log(plan);
         console.log(plan);
-
         // 准备插入数据库的数据对象
         // 准备插入数据库的数据对象
         let newPlan = {
         let newPlan = {
           "date": plan['date'],
           "date": plan['date'],
           "srcId": plan['srcId'],
           "srcId": plan['srcId'],
           "trainingPart": plan['trainingPart'],
           "trainingPart": plan['trainingPart'],
           "trainingItems": plan['trainingItems'],
           "trainingItems": plan['trainingItems'],
-          "user": currentUser,  // 将当前用户指针关联到计划
+          "user": currentUser,
         };
         };
         // 创建新的 CloudObject 实例
         // 创建新的 CloudObject 实例
         let newObject = new CloudObject("fitPlan");
         let newObject = new CloudObject("fitPlan");
@@ -307,6 +280,7 @@ export class TestPageComponent implements OnInit {
         newObject.save()
         newObject.save()
           .then(() => {
           .then(() => {
             console.log("计划保存成功");
             console.log("计划保存成功");
+            this.goToPage("tab2")
           })
           })
           .catch((error: any) => {
           .catch((error: any) => {
             console.error("保存计划时发生错误", error);
             console.error("保存计划时发生错误", error);
@@ -316,7 +290,6 @@ export class TestPageComponent implements OnInit {
     } catch (error) {
     } catch (error) {
       console.error("查询或删除计划时发生错误", error);
       console.error("查询或删除计划时发生错误", error);
     }
     }
-    this.goToPage("tab2")
   }
   }
 
 
   goBack() {
   goBack() {