sqj 2 maanden geleden
bovenliggende
commit
c8c4d1c9f7

+ 6 - 2
FitMind-app/src/app/page-bmi/page-bmi.component.html

@@ -28,8 +28,8 @@
     </div>
   </div>
 
-  <!-- BMI输出框 -->
-  <div class="info-section">
+  <!-- BMI 输出框 -->
+  <div class="info-section" *ngIf="bmi !== null">
     <div class="input-row">
       <div class="input-group">
         <label>BMI:</label>
@@ -37,6 +37,10 @@
         <span class="unit">KG/M<sup>2</sup></span>
       </div>
     </div>
+    <!-- BMI 分类提示 -->
+    <div *ngIf="bmiStatus" class="status-box">
+      <p>{{ bmiStatus }}</p>
+    </div>
   </div>
 
   <!-- 按钮区 -->

+ 42 - 23
FitMind-app/src/app/page-bmi/page-bmi.component.ts

@@ -1,33 +1,41 @@
 import { Component, OnInit } from '@angular/core';
 import { Router } from '@angular/router';
-import { AlertController, IonButton, IonButtons, IonContent, IonHeader, IonIcon, IonInput, IonItem, IonLabel, IonTitle, IonToolbar } from '@ionic/angular/standalone';
+import { AlertController } from '@ionic/angular';
 import { FormsModule } from '@angular/forms'; // 导入 FormsModule
 import { CommonModule } from '@angular/common'; // 导入 CommonModule
-import { chevronBackOutline } from 'ionicons/icons';
-import { addIcons } from 'ionicons';
-addIcons({chevronBackOutline});
+import { IonicModule } from '@ionic/angular';
+
 @Component({
   selector: 'app-page-bmi',
   templateUrl: './page-bmi.component.html',
   styleUrls: ['./page-bmi.component.scss'],
   standalone: true,
-  imports:[IonHeader,IonToolbar,IonTitle,IonButton,IonButtons,IonContent,IonItem,IonLabel,IonInput,FormsModule,CommonModule,IonIcon]
+  imports: [FormsModule, CommonModule, IonicModule], // 导入相关模块
 })
-export class PageBmiComponent  implements OnInit {
+export class PageBmiComponent implements OnInit {
 
-  ngOnInit() {this.resetForm();} // 页面加载时清空数据
-  height: number|null =null; // 身高
-  weight: number|null =null; // 体重
-  bmi: number|null=null; // BMI 值
+  height: number | null = null; // 身高
+  weight: number | null = null; // 体重
+  bmi: number | null = null; // BMI 值
+  bmiStatus: string | null = null; // BMI 状态提示
 
-  constructor(private router: Router,private alertController: AlertController) {this.resetForm();}
+  constructor(private router: Router, private alertController: AlertController) {
+    this.resetForm(); // 初始化时清空数据
+  }
+
+  ngOnInit() {
+    this.resetForm(); // 页面加载时清空数据
+  }
 
   // 计算 BMI
   async calculateBMI() {
-    if (this.height !=null && this.weight !=null) {
-      if(this.height >0 && this.weight >0) {
-      const heightInMeters = this.height / 100; // 将身高转换为米
-      this.bmi = this.weight / (heightInMeters * heightInMeters); // 计算 BMI
+    if (this.height != null && this.weight != null) {
+      if (this.height > 0 && this.weight > 0) {
+        const heightInMeters = this.height / 100; // 将身高转换为米
+        this.bmi = this.weight / (heightInMeters * heightInMeters); // 计算 BMI
+
+        // 检查 BMI 并显示相应的提示
+        this.checkBmiStatus(this.bmi);
       } else {
         const alert = await this.alertController.create({
           header: '身高体重不能为0!',
@@ -41,21 +49,32 @@ export class PageBmiComponent  implements OnInit {
         buttons: ['确定']
       });
       await alert.present(); // 显示弹出框
-      
     }
   }
 
-  //清空数据
-    // 清空输入数据
-    resetForm() {
-      this.height = null;
-      this.weight = null;
-      this.bmi = null;
+  // 检查 BMI 并给出分类提示
+  checkBmiStatus(bmi: number) {
+    if (bmi < 18.5) {
+      this.bmiStatus = '低体重:BMI 小于 18.5,建议增加体重';
+    } else if (bmi >= 18.5 && bmi < 24.9) {
+      this.bmiStatus = '正常体重:BMI 在 18.5 到 24.9 之间,保持健康';
+    } else if (bmi >= 25 && bmi < 29.9) {
+      this.bmiStatus = '超重:BMI 在 25 到 29.9 之间,建议控制体重';
+    } else {
+      this.bmiStatus = '肥胖:BMI 大于或等于 30,建议减肥';
     }
+  }
+
+  // 清空数据
+  resetForm() {
+    this.height = null;
+    this.weight = null;
+    this.bmi = null;
+    this.bmiStatus = null; // 清空 BMI 状态提示
+  }
 
   // 返回上一个页面
   goBack() {
     this.router.navigate(['/tabs/tab2'], { replaceUrl: true }); // 使用 replaceUrl 强制重载页面
   }
 }
-

+ 68 - 64
FitMind-app/src/app/page-test/page-test.component.html

@@ -1,68 +1,72 @@
 <ion-header>
-    <ion-toolbar>
-      <ion-buttons slot="start">
-        <ion-button (click)="goBack()" fill="clear">
-          <ion-icon aria-hidden="true" name="chevron-back-outline" style="color: black; font-size: 24px;"></ion-icon>
-        </ion-button>
-      </ion-buttons>
-      <ion-title>体脂率测试</ion-title>
-    </ion-toolbar>
-  </ion-header>
-  
-  <ion-content>
-    <!-- 身高体重输入框 -->
-    <div class="info-section">
-      <div class="input-row">
-        <div class="input-group">
-          <label>身高:</label>
-          <input type="number" [(ngModel)]="height" placeholder="请输入身高" class="input-box" />
-          <span class="unit">CM</span>
-        </div>
-      </div>
-      <div class="input-row">
-        <div class="input-group">
-          <label>体重:</label>
-          <input type="number" [(ngModel)]="weight" placeholder="请输入体重" class="input-box" />
-          <span class="unit">KG</span>
-        </div>
-      </div>
-      <div class="input-row">
-        <div class="input-group">
-          <label>年龄:</label>
-          <input type="number" [(ngModel)]="age" placeholder="请输入年龄" class="input-box" />
-        </div>
-      </div>
-      <div class="input-row">
-        <div class="input-group">
-          <label>性别:</label>
-          <ion-select [(ngModel)]="gender">
-            <ion-select-option value="male">男性</ion-select-option>
-            <ion-select-option value="female">女性</ion-select-option>
-          </ion-select>
-        </div>
-      </div>
-      <!-- 腰围输入框 -->
-      <div class="input-row">
-        <div class="input-group">
-          <label>腰围:</label>
-          <input type="number" [(ngModel)]="waist" placeholder="请输入腰围" class="input-box" />
-          <span class="unit">CM</span>
-        </div>
-      </div>
+  <ion-toolbar>
+    <ion-buttons slot="start">
+      <ion-button (click)="goBack()" fill="clear">
+        <ion-icon aria-hidden="true" name="chevron-back-outline" style="color: black; font-size: 24px;"></ion-icon>
+      </ion-button>
+    </ion-buttons>
+    <ion-title>体脂率测试</ion-title>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content>
+<!-- 身高体重输入框 -->
+<div class="info-section">
+  <div class="input-row">
+    <div class="input-group">
+      <label>身高:</label>
+      <input type="number" [(ngModel)]="height" placeholder="请输入身高" class="input-box" />
+      <span class="unit">CM</span>
     </div>
-  
-    <!-- 体脂率输出框 -->
-    <div class="info-section" *ngIf="bodyFatPercentage !== null">
-      <div class="output-box">
-        <h3>体脂率</h3>
-        <p>{{ bodyFatPercentage | number: '1.1-1' }}%</p>
-      </div>
+  </div>
+  <div class="input-row">
+    <div class="input-group">
+      <label>体重:</label>
+      <input type="number" [(ngModel)]="weight" placeholder="请输入体重" class="input-box" />
+      <span class="unit">KG</span>
     </div>
-  
-    <!-- 按钮区 -->
-    <div class="center-button">
-      <ion-button fill="clear" class="analysis-button" (click)="calculateBodyFat()">计算体脂率</ion-button>
-      <ion-button fill="clear" class="analysis-button" (click)="resetForm()">清空</ion-button>
+  </div>
+  <div class="input-row">
+    <div class="input-group">
+      <label>年龄:</label>
+      <input type="number" [(ngModel)]="age" placeholder="请输入年龄" class="input-box" />
     </div>
-  </ion-content>
-  
+  </div>
+  <div class="input-row">
+    <div class="input-group">
+      <label>性别:</label>
+      <ion-select [(ngModel)]="gender">
+        <ion-select-option value="male">男性</ion-select-option>
+        <ion-select-option value="female">女性</ion-select-option>
+      </ion-select>
+    </div>
+  </div>
+  <!-- 腰围输入框 -->
+  <div class="input-row">
+    <div class="input-group">
+      <label>腰围:</label>
+      <input type="number" [(ngModel)]="waist" placeholder="请输入腰围" class="input-box" />
+      <span class="unit">CM</span>
+    </div>
+  </div>
+</div>
+
+<!-- 体脂率输出框 -->
+<div class="info-section" *ngIf="bodyFatPercentage !== null">
+  <div class="output-box">
+    <h3>体脂率</h3>
+    <p>{{ bodyFatPercentage | number: '1.1-1' }}%</p>
+  </div>
+
+  <!-- 体脂率分类提示 -->
+  <div *ngIf="bodyFatStatus" class="status-box">
+    <p>{{ bodyFatStatus }}</p>
+  </div>
+</div>
+
+<!-- 按钮区 -->
+<div class="center-button">
+  <ion-button fill="clear" class="analysis-button" (click)="calculateBodyFat()">计算体脂率</ion-button>
+  <ion-button fill="clear" class="analysis-button" (click)="resetForm()">清空</ion-button>
+</div>
+</ion-content>

+ 31 - 3
FitMind-app/src/app/page-test/page-test.component.ts

@@ -20,6 +20,7 @@ export class PageBodyFatComponent implements OnInit {
   gender: string = 'male'; // 性别
   waist: number | null = null; // 腰围
   bodyFatPercentage: number | null = null; // 体脂率
+  bodyFatStatus: string | null = null; // 体脂率状态提示
 
   constructor(private router: Router, private alertController: AlertController) { }
 
@@ -40,13 +41,14 @@ export class PageBodyFatComponent implements OnInit {
         
         if (this.gender === 'female') {
           // 女性的体脂率估算公式
-          bodyFatPercentage = 0.1 * this.waist + 0.23 * bmi + 0.15 * this.age ;
+          bodyFatPercentage = 0.1 * this.waist + 0.23 * bmi + 0.15 * this.age;
         } else {
           // 男性的体脂率估算公式
-          bodyFatPercentage = 0.1 * this.waist + 0.23 * bmi + 0.15 * this.age ;
+          bodyFatPercentage = 0.1 * this.waist + 0.23 * bmi + 0.15 * this.age;
         }
 
         this.bodyFatPercentage = bodyFatPercentage;
+        this.checkBodyFatStatus(this.bodyFatPercentage);
 
       } else {
         const alert = await this.alertController.create({
@@ -64,14 +66,40 @@ export class PageBodyFatComponent implements OnInit {
     }
   }
 
+  // 检查体脂率并给出分类提示
+  checkBodyFatStatus(bodyFatPercentage: number) {
+    if (this.gender === 'female') {
+      if (bodyFatPercentage < 18) {
+        this.bodyFatStatus = '低体脂:体脂率小于18%,建议增加体脂';
+      } else if (bodyFatPercentage >= 18 && bodyFatPercentage < 28) {
+        this.bodyFatStatus = '正常体脂:体脂率在18%-28%之间,保持健康';
+      } else if (bodyFatPercentage >= 28 && bodyFatPercentage < 33) {
+        this.bodyFatStatus = '超重:体脂率在28%-33%之间,建议控制体脂';
+      } else {
+        this.bodyFatStatus = '肥胖:体脂率大于33%,建议减脂';
+      }
+    } else {
+      if (bodyFatPercentage < 10) {
+        this.bodyFatStatus = '低体脂:体脂率小于10%,建议增加体脂';
+      } else if (bodyFatPercentage >= 10 && bodyFatPercentage < 20) {
+        this.bodyFatStatus = '正常体脂:体脂率在10%-20%之间,保持健康';
+      } else if (bodyFatPercentage >= 20 && bodyFatPercentage < 25) {
+        this.bodyFatStatus = '超重:体脂率在20%-25%之间,建议控制体脂';
+      } else {
+        this.bodyFatStatus = '肥胖:体脂率大于25%,建议减脂';
+      }
+    }
+  }
+
   // 清空数据
   resetForm() {
     this.height = null;
     this.weight = null;
     this.age = null;
     this.gender = 'male';
-    this.waist = null; // 清空腰围
+    this.waist = null;
     this.bodyFatPercentage = null;
+    this.bodyFatStatus = null; // 清空体脂率状态
   }
 
   // 返回上一个页面

+ 55 - 0
FitMind-app/src/app/page-ytb/page-ytb.component.html

@@ -0,0 +1,55 @@
+<ion-header>
+  <ion-toolbar>
+    <ion-buttons slot="start">
+      <ion-button (click)="goBack()" fill="clear">
+        <ion-icon aria-hidden="true" name="chevron-back-outline" style="color: black; font-size: 24px;"></ion-icon>
+      </ion-button>
+    </ion-buttons>
+    <ion-title>腰臀比测试</ion-title>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content>
+  <!-- 身高和腰围输入框 -->
+  <div class="info-section">
+    <div class="input-row">
+      <div class="input-group">
+        <label>身高:</label>
+        <input type="number" [(ngModel)]="height" placeholder="请输入身高" class="input-box" />
+        <span class="unit">CM</span>
+      </div>
+    </div>
+    <div class="input-row">
+      <div class="input-group">
+        <label>臀围:</label>
+        <input type="number" [(ngModel)]="hip" placeholder="请输入臀围" class="input-box" />
+        <span class="unit">CM</span>
+      </div>
+    </div>
+    <div class="input-row">
+      <div class="input-group">
+        <label>腰围:</label>
+        <input type="number" [(ngModel)]="waist" placeholder="请输入腰围" class="input-box" />
+        <span class="unit">CM</span>
+      </div>
+    </div>
+  </div>
+
+  <!-- 腰臀比输出框 -->
+  <div class="info-section" *ngIf="whr !== null">
+    <div class="output-box">
+      <h3>腰臀比</h3>
+      <p>{{ whr | number: '1.2-2' }}</p>
+    </div>
+    <!-- 弹出腰臀比提示 -->
+    <div *ngIf="whrStatus" class="status-box">
+      <p>{{ whrStatus }}</p>
+    </div>
+  </div>
+
+  <!-- 按钮区 -->
+  <div class="center-button">
+    <ion-button fill="clear" class="analysis-button" (click)="calculateWhr()">计算腰臀比</ion-button>
+    <ion-button fill="clear" class="analysis-button" (click)="resetForm()">清空</ion-button>
+  </div>
+</ion-content>

+ 91 - 0
FitMind-app/src/app/page-ytb/page-ytb.component.scss

@@ -0,0 +1,91 @@
+$primary-color: #3880ff;  // 设置主色调
+$secondary-color: #f4f4f4; // 设置次要颜色
+
+/* 继承之前的样式 */
+ion-header {
+  background-color: $primary-color;
+  color: white;
+
+  ion-toolbar {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+
+    ion-title {
+      font-size: 24px;
+      font-weight: bold;
+    }
+  }
+}
+
+ion-content {
+  padding: 16px;
+  background-color: $secondary-color;
+
+  /* 输入框和显示区域 */
+  .info-section {
+    background-color: white;
+    border-radius: 8px;
+    padding: 16px;
+    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+    margin-bottom: 16px;
+
+    .input-row {
+      display: flex;
+      justify-content: center;
+      margin-bottom: 16px;
+
+      .input-group {
+        width: 60%;
+        max-width: 300px;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+
+        label {
+          font-weight: bold;
+          margin-bottom: 4px;
+          display: block;
+          text-align: center;
+        }
+
+        .input-box {
+          width: 100%;
+          padding: 8px;
+          border: 1px solid #ccc;
+          border-radius: 4px;
+        }
+
+        .unit {
+          font-size: 14px;
+          margin-top: 4px;
+        }
+      }
+    }
+  }
+
+  .center-button {
+    display: flex;
+    justify-content: center;
+    align-items: flex-start;
+    width: 100%;
+    height: 100%;
+    text-align: center;
+    padding-top: 40px;
+  }
+
+  .analysis-button {
+    width: 100%;
+    margin-top: 16px;
+    background-color: $primary-color;
+    color: white;
+    padding: 12px;
+    border-radius: 4px;
+    font-size: 16px;
+    transition: background-color 0.3s;
+
+    &:hover {
+      background-color: darken($primary-color, 10%);
+    }
+  }
+}

+ 37 - 0
FitMind-app/src/app/page-ytb/page-ytb.component.spec.ts

@@ -0,0 +1,37 @@
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+import { PageWhrTestComponent } from './page-ytb.component';
+
+describe('PageWhrTestComponent', () => {
+  let component: PageWhrTestComponent;
+  let fixture: ComponentFixture<PageWhrTestComponent>;
+
+  beforeEach(waitForAsync(() => {
+    TestBed.configureTestingModule({
+      imports: [PageWhrTestComponent],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(PageWhrTestComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  }));
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  it('should calculate waist-to-hip ratio correctly', () => {
+    component.height = 170;
+    component.waist = 70;
+    component.hip = 90;
+    component.calculateWhr();
+    expect(component.whr).toBeCloseTo(0.777, 2);
+  });
+
+  it('should show alert if input is invalid', async () => {
+    component.height = null;
+    component.waist = 0;
+    component.hip = 90;
+    await component.calculateWhr();
+    expect(component.whr).toBeNull();
+  });
+});

+ 80 - 0
FitMind-app/src/app/page-ytb/page-ytb.component.ts

@@ -0,0 +1,80 @@
+import { Component, OnInit } from '@angular/core';
+import { Router } from '@angular/router';
+import { AlertController } from '@ionic/angular';
+import { FormsModule } from '@angular/forms';
+import { CommonModule } from '@angular/common';
+import { IonicModule } from '@ionic/angular';
+
+@Component({
+  selector: 'app-page-ytb',
+  templateUrl: './page-ytb.component.html',
+  styleUrls: ['./page-ytb.component.scss'],
+  standalone: true,
+  imports: [FormsModule, CommonModule, IonicModule],
+})
+export class PageYtbComponent implements OnInit {
+  height: number | null = null; // 身高
+  waist: number | null = null;  // 腰围
+  hip: number | null = null;    // 臀围
+  whr: number | null = null;    // 腰臀比
+  whrStatus: string | null = null; // 腰臀比状态信息
+
+  constructor(private router: Router, private alertController: AlertController) {}
+
+  ngOnInit() {
+    this.resetForm(); // 页面加载时清空数据
+  }
+
+  // 计算腰臀比
+  async calculateWhr() {
+    if (this.height && this.waist && this.hip) {
+      if (this.height > 0 && this.waist > 0 && this.hip > 0) {
+        // 计算腰臀比
+        const whr = this.waist / this.hip;
+        this.whr = whr;
+
+        // 检查腰臀比是否正常
+        this.checkWhrStatus(whr);
+      } else {
+        const alert = await this.alertController.create({
+          header: '身高、腰围和臀围不能为零!',
+          buttons: ['确定'],
+        });
+        await alert.present(); // 显示弹出框
+      }
+    } else {
+      const alert = await this.alertController.create({
+        header: '请确保输入完整的身高、腰围和臀围!',
+        buttons: ['确定'],
+      });
+      await alert.present(); // 显示弹出框
+    }
+  }
+
+  // 检查腰臀比是否正常
+  checkWhrStatus(whr: number) {
+    if (whr <= 0) {
+      this.whrStatus = '腰臀比不正常,请检查输入数据';
+    } else if (whr > 0 && whr <= 0.9) {
+      this.whrStatus = '腰臀比正常';
+    } else if (whr > 0.9 && whr <= 1.0) {
+      this.whrStatus = '腰臀比偏高,需注意';
+    } else {
+      this.whrStatus = '腰臀比不正常,建议调整';
+    }
+  }
+
+  // 清空数据
+  resetForm() {
+    this.height = null;
+    this.waist = null;
+    this.hip = null;
+    this.whr = null;
+    this.whrStatus = null; // 清空状态信息
+  }
+
+  // 返回上一个页面
+  goBack() {
+    this.router.navigate(['/tabs/tab2'], { replaceUrl: true });
+  }
+}

+ 12 - 8
FitMind-app/src/app/tab2/tab2.page.html

@@ -102,16 +102,20 @@
 
   </div>
   
-  <!--测试-->
-  <div *ngIf="selectedSegment === 'test'" class="center-button">
-    <ion-button (click)="goBmipage()">测测你的BMI</ion-button>
-  </div>
-  
-  <div *ngIf="selectedSegment === 'test'" class="center-button">
-    <ion-button (click)="goTestpage()">测测你的体脂率</ion-button>
+  <div *ngIf="selectedSegment === 'test'" class="center-buttons">
+    <div class="center-button">
+      <ion-button (click)="goBmipage()">测测你的BMI</ion-button>
+    </div>
+    
+    <div class="center-button">
+      <ion-button (click)="goTestpage()">测测你的体脂率</ion-button>
+    </div>
+      
+  <div class="center-button">
+    <ion-button (click)="goYtbpage()">测测你的腰臀比</ion-button>
   </div>
 
-
+  </div>
 
   
 </ion-content>

+ 4 - 1
FitMind-app/src/app/tab2/tab2.page.ts

@@ -12,7 +12,7 @@ import { PageAiChatComponent } from '../page-ai-chat/page-ai-chat.component';
 
 import { CloudUser } from 'src/lib/ncloud';
 import { openUserLoginModal } from 'src/lib/user/modal-user-login/modal-user-login.component';
-import { CloudfearlessPlan } from 'src/app/lib/cloudPlans'; // 引入封装好的 CloudfearlessPlan 类
+// import { CloudfearlessPlan } from 'src/app/lib/cloudPlans'; // 引入封装好的 CloudfearlessPlan 类
 
 
 @Component({
@@ -223,6 +223,9 @@ goTestpage() {
   this.router.navigate(['/tabs/test']); // 跳转到测试BMI页面
 }
 
+goYtbpage() {
+  this.router.navigate(['/tabs/ytb']); // 跳转到测试BMI页面
+}
 
 
 alertButtons = ['退出'];

+ 5 - 0
FitMind-app/src/app/tabs/tabs.routes.ts

@@ -43,6 +43,11 @@ export const routes: Routes = [
         path: 'test',
         loadComponent: () =>
           import('../page-test/page-test.component').then((m) => m.PageBodyFatComponent),
+      },  
+      {
+        path: 'ytb',
+        loadComponent: () =>
+          import('../page-ytb/page-ytb.component').then((m) => m.PageYtbComponent),
       },
       {
         path: 'chat',