Gollum il y a 7 mois
Parent
commit
762a45dea1

+ 46 - 15
smarteat-app/src/app/tab1/tab1.page.html

@@ -35,34 +35,64 @@
   </div>
 </div>
 
-<!-- 推荐健康建议 -->
-<ion-card>
-  <ion-card-header>
-    <ion-card-title>
-      <ion-icon slot="start" name="leaf-outline"></ion-icon>
-      健康建议
+
+<ion-card class="diet-card">
+  <ion-card-header class="diet-card-header">
+    <ion-card-title class="diet-card-title">
+      <ion-icon  name="leaf-outline"></ion-icon>
+      今日饮食内容
     </ion-card-title>
   </ion-card-header>
-
-  <ion-card-content>
-    <div>
-     @if(currentUser?.id){
-      @if(!responseMsg){
+  <ion-card-content class="diet-card-content">
+    
+    @if(currentUser?.id && result && plan){
+    <ion-card-content class="diet-card-content">
+    
+    <div><h4 class="meal-title">早餐</h4>
+    <div class="meal-details" [innerHTML]="breakfast"><!-- 今日饮食计划 --></div></div>
+    <div><h4 class="meal-title">午餐</h4>
+    <div class="meal-details" [innerHTML]="lunch"><!-- 今日饮食计划 --></div></div>
+    <div><h4 class="meal-title">晚餐</h4>
+    <div class="meal-details" [innerHTML]="dinner"><!-- 今日饮食计划 --></div></div>
+    @if(!mark0){
+      <ion-button class="green-button" (click)="check()">点击打卡</ion-button>
+    }
+    @if(mark0){
+      <ion-button><ion-icon name="checkmark-circle-outline"></ion-icon>打卡成功
+        <ion-progress-bar [value]="progress" color="primary"></ion-progress-bar>
+        <p>{{ currentDay }} / {{ planDays }} 天</p>
+      </ion-button>
+    }
+    </ion-card-content>
+    }
+    @if(currentUser?.id &&  !plan ){
+      <div class="no-plan">您还未导入饮食规划</div>
+    }
+    @if(currentUser?.id &&  plan && !result){
+      <div class="no-plan">今日无饮食规划</div>
+    }
+  </ion-card-content>
+  <ion-card-content class="diet-card-footer">
+    <div class="loading-msg">
+     @if(currentUser?.id && plan && result){
+      <h4 class="meal-title">健康建议</h4>
+      @if(!isComplete && responseMsg){
         <p>加载中...</p>
       }
-      <p>{{ responseMsg }}</p>
+      @if(isComplete){
+        <p>{{ responseMsg }}</p>
+      }
      }
     </div>
     <!-- 如果用户未登录,显示登录按钮 -->
     @if(!currentUser?.id){
-      <ion-button (click)="login()" fill="outline" color="primary">
-        请登录后使用该功能
+      <ion-button (click)="login()" fill="outline" color="primary" class="login-btn">
+        请登录后可见
       </ion-button>
     }
   </ion-card-content>
 </ion-card>
 
-
   <!-- 快速入口 -->
   <ion-grid>
     <ion-row>
@@ -98,4 +128,5 @@
       </ion-button>
     </ion-card-content>
   </ion-card>
+
 </ion-content>

+ 435 - 67
smarteat-app/src/app/tab1/tab1.page.scss

@@ -1,4 +1,303 @@
-//   /* 设置轮播图区域 */
+// //   /* 设置轮播图区域 */
+// .carousel-container {
+//   position: relative;
+//   overflow: hidden;
+//   width: 100%;
+//   max-width: 600px; /* 可根据需要调整宽度 */
+//   margin: 0 auto;
+// }
+
+// //轮播图描述样式
+// .description.active {
+//   color: black;
+//   font-weight: bold;
+//   /* 确保不会隐藏描述内容 */
+//   display: block;
+//   opacity: 1; 
+//   text-align: center;
+//   display: flex;
+//   justify-content: center;
+//   align-items: center;
+//   flex-direction: column;
+// }
+
+// .carousel {
+//   display: flex;
+//   transition: transform 0.5s ease;
+// }
+
+// .slide {
+//   min-width: 100%;
+//   max-width: 100%;
+// }
+
+// .slide img {
+//   width: 100%;
+//   height: auto;
+//   border-radius: 15px;
+// }
+
+// button {
+//   position: absolute;
+//   top: 50%;
+//   transform: translateY(-50%);
+//   background: rgba(0, 0, 0, 0.5);
+//   color: #fff;
+//   border: none;
+//   padding: 10px;
+//   cursor: pointer;
+//   z-index: 10;
+// }
+
+// button.prev {
+//   left: 10px;
+// }
+
+// button.next {
+//   right: 10px;
+// }
+
+// .dots {
+//   position: absolute;
+//   bottom: 10px;
+//   left: 50%;
+//   transform: translateX(-50%);
+//   display: flex;
+//   justify-content: center;
+// }
+
+// .dot {
+//   width: 10px;
+//   height: 10px;
+//   margin: 0 5px;
+//   background-color: rgba(255, 255, 255, 0.5);
+//   border-radius: 50%;
+//   cursor: pointer;
+// }
+
+// .dot.active {
+//   background-color: #fff;
+// }
+
+
+// /* 设置所有矩形框为圆角矩形 */
+// ion-card {
+//     border-radius: 12px; /* 卡片圆角 */
+//     overflow: hidden; /* 防止内容溢出圆角边界 */
+//     box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 轻微的阴影效果 */
+//     margin-bottom: 16px; /* 卡片之间的间距 */
+//   }
+  
+//   .custom-searchbar {
+//     --background: #f8f8f8;
+//     --border-radius: 10px; // 可选:调整边角圆滑度
+//     --box-shadow: none; // 可选:去掉阴影
+//   }
+
+//   ion-card-header {
+//     // background: linear-gradient(to bottom, #ccffcc, #00ffcc);
+//     // background-color: #f8f8f8; /* 设置卡片头部背景颜色 */
+//     background: linear-gradient(to right, #ccffcc, #00ffcc), linear-gradient(to bottom, #33ffcc, white);
+//     background-blend-mode: multiply; /* 混合模式,确保两个渐变效果结合 */
+//     border-top-left-radius: 12px; /* 圆角效果 */
+//     border-top-right-radius: 12px; /* 圆角效果 */
+//   }
+  
+//   ion-card-title {
+//     font-weight: bold; /* 标题加粗 */
+//     font-size: 18px;
+//     color: #333; /* 字体颜色 */
+//   }
+  
+//   ion-card-content {
+//     padding: 16px; /* 内容的内边距 */
+//     color: #555; /* 内容字体颜色 */
+//   }
+  
+//   ion-button:hover {
+//     transform: scale(1.05); /* 按钮悬停效果 */
+//   }
+
+
+//   /* 设置所有按钮的样式 */
+//   ion-button {
+//     border-radius: 12px; /* 按钮圆角 */
+//     color: #333; /* 按钮中文字的颜色 */
+//     font-weight: bold; /* 按钮字体加粗 */
+//     text-align: center; /* 确保按钮文字水平居中 */
+//     display: flex; /* 使用 flexbox 布局 */
+//     justify-content: center; /* 水平居中 */
+//     align-items: center; /* 垂直居中 */
+//   }
+  
+  
+//   /* 设置图标的间距 */
+//   ion-icon {
+//     margin-right: 8px; /* 图标与文字之间的间距 */
+//   }
+  
+//   /* 设置搜索框的样式 */
+//   ion-searchbar {
+//     border-radius: 20px; /* 搜索框圆角 */
+//     margin: 10px 0; /* 上下间距 */
+//   }
+  
+//   /* 设置页面布局 */
+//   ion-grid {
+//     padding: 0 16px; /* 网格的内边距 */
+//   }
+  
+//   ion-row {
+//     margin-bottom: 16px; /* 行间距 */
+//   }
+  
+//   ion-col {
+//     padding: 0; /* 去掉每列的默认内边距 */
+//   }
+  
+
+// /* 卡片样式 */
+// .diet-card {
+//   border-radius: 12px; /* 卡片圆角 */
+//   box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 轻微的阴影效果 */
+//   margin: 20px auto; /* 设置上下外边距 */
+//   max-width: 700px; /* 限制最大宽度 */
+//   background-color: #fff; /* 卡片背景颜色 */
+//   transition: box-shadow 0.3s ease-in-out; /* 平滑的阴影变化 */
+// }
+
+// /* 卡片头部样式 */
+// .diet-card-header {
+//   background-color: #e6f7e6; /* 淡绿色背景 */
+//   padding: 16px 20px; /* 上下和左右内边距 */
+//   border-top-left-radius: 12px;
+//   border-top-right-radius: 12px;
+//   display: flex;
+//   align-items: center; /* 图标与文字垂直居中 */
+//   border-bottom: 2px solid #4caf50; /* 添加底部分隔线 */
+// }
+
+// /* 卡片标题样式 */
+// .diet-card-title {
+//   font-size: 20px;
+//   font-weight: bold;
+//   color: #2c6e4f; /* 深绿色 */
+//   display: flex;
+//   align-items: center; /* 图标与文字垂直居中 */
+//   gap: 8px; /* 图标与文字之间的间距 */
+// }
+
+// /* 卡片内容区域样式 */
+// .diet-card-content {
+//   padding: 16px; /* 内边距 */
+//   color: #555; /* 内容文字颜色 */
+// }
+
+// /* 外层框,包裹整个饮食规划内容 */
+// .diet-plan-container {
+//   border: 2px solid #4caf50; /* 边框颜色 */
+//   padding: 16px;
+//   border-radius: 8px;
+//   margin-bottom: 16px;
+// }
+
+// /* 每餐的框 */
+// .meal-box {
+//   border: 1px solid #4caf50; /* 每餐框的边框颜色 */
+//   padding: 12px;
+//   border-radius: 8px;
+//   margin-bottom: 12px; /* 每餐之间的间距 */
+// }
+
+// /* 早餐、午餐、晚餐的标题 */
+// .meal-title {
+//   font-size: 18px;
+//   font-weight: bold;
+//   margin-top: 10px; /* 减小顶部间距 */
+//   margin-bottom: 5px; /* 减小底部间距 */
+//   color: #4caf50; /* 绿色 */
+// }
+
+// /* 每餐的饮食内容 */
+// .meal-details {
+//   font-size: 16px;
+//   color: #333; /* 内容颜色 */
+//   line-height: 1.6; /* 增加行间距,使内容更易读 */
+//   margin-bottom: 20px; /* 每段内容的间距 */
+// }
+
+// /* 没有饮食规划的提示 */
+// .no-plan {
+//   font-size: 16px;
+//   color: #f44336; /* 红色 */
+//   text-align: center;
+//   padding: 8px;
+//   background-color: #f8d7da;
+//   border-radius: 8px;
+//   margin-bottom: 16px;
+// }
+
+// /* 底部内容区域 */
+// .diet-card-footer {
+//   padding: 16px;
+// }
+
+// /* 加载中消息的样式 */
+// .loading-msg p {
+//   font-size: 16px;
+//   color: #888; /* 灰色文字 */
+//   text-align: center; /* 文字居中 */
+//   margin-top: 10px;
+// }
+
+// /* 登录按钮的样式 */
+// .login-btn {
+//   margin-top: 20px; /* 与上一部分的间距 */
+//   display: block;
+//   width: 100%; /* 按钮宽度占满容器 */
+//   font-size: 16px; /* 按钮文字大小 */
+//   padding: 10px 0; /* 按钮上下内边距 */
+//   border-radius: 12px; /* 按钮圆角 */
+//   transition: background-color 0.3s ease, color 0.3s ease; /* 按钮的平滑过渡效果 */
+// }
+
+// /* 登录按钮的 hover 效果 */
+// .login-btn:hover {
+//   background-color: #3880ff; /* 蓝色背景 */
+//   color: white; /* 按钮文字变为白色 */
+// }
+
+// /* 小屏设备上的样式调整 */
+// @media (max-width: 768px) {
+//   .diet-card {
+//     max-width: 90%; /* 调整卡片最大宽度 */
+//   }
+
+//   .diet-card-header {
+//     padding: 12px 16px; /* 缩小内边距 */
+//   }
+
+//   .diet-card-content,
+//   .diet-card-footer {
+//     padding: 12px; /* 减少内边距 */
+//   }
+
+//   .meal-title {
+//     font-size: 16px; /* 调整字体大小 */
+//   }
+
+//   .meal-details {
+//     font-size: 14px; /* 调整字体大小 */
+//   }
+
+//   .login-btn {
+//     font-size: 14px; /* 调整按钮文字大小 */
+//     padding: 8px 0; /* 减小按钮内边距 */
+//   }
+// }
+
+
+/* 保持轮播图相关的样式不变 */
 .carousel-container {
   position: relative;
   overflow: hidden;
@@ -7,11 +306,9 @@
   margin: 0 auto;
 }
 
-//轮播图描述样式
 .description.active {
   color: black;
   font-weight: bold;
-  /* 确保不会隐藏描述内容 */
   display: block;
   opacity: 1; 
   text-align: center;
@@ -79,79 +376,150 @@ button.next {
   background-color: #fff;
 }
 
+/* 以下是饮食卡片部分的新增样式 */
 
 /* 设置所有矩形框为圆角矩形 */
 ion-card {
-    border-radius: 12px; /* 卡片圆角 */
-    overflow: hidden; /* 防止内容溢出圆角边界 */
-    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 轻微的阴影效果 */
-    margin-bottom: 16px; /* 卡片之间的间距 */
-  }
-  
-  .custom-searchbar {
-    --background: #f8f8f8;
-    --border-radius: 10px; // 可选:调整边角圆滑度
-    --box-shadow: none; // 可选:去掉阴影
-  }
+  border-radius: 12px; /* 卡片圆角 */
+  overflow: hidden; /* 防止内容溢出圆角边界 */
+  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 轻微的阴影效果 */
+  margin-bottom: 16px; /* 卡片之间的间距 */
+}
 
-  ion-card-header {
-    // background: linear-gradient(to bottom, #ccffcc, #00ffcc);
-    // background-color: #f8f8f8; /* 设置卡片头部背景颜色 */
-    background: linear-gradient(to right, #ccffcc, #00ffcc), linear-gradient(to bottom, #33ffcc, white);
-    background-blend-mode: multiply; /* 混合模式,确保两个渐变效果结合 */
-    border-top-left-radius: 12px; /* 圆角效果 */
-    border-top-right-radius: 12px; /* 圆角效果 */
-  }
-  
-  ion-card-title {
-    font-weight: bold; /* 标题加粗 */
-    font-size: 18px;
-    color: #333; /* 字体颜色 */
-  }
-  
-  ion-card-content {
-    padding: 16px; /* 内容的内边距 */
-    color: #555; /* 内容字体颜色 */
-  }
-  
-  ion-button:hover {
-    transform: scale(1.05); /* 按钮悬停效果 */
-  }
+ion-card-header {
+  background-color: #e6f7e6; /* 淡绿色背景 */
+  padding: 16px 20px; /* 上下和左右内边距 */
+  border-top-left-radius: 12px; /* 圆角效果 */
+  border-top-right-radius: 12px; /* 圆角效果 */
+  display: flex;
+  align-items: center; /* 图标与文字垂直居中 */
+  border-bottom: 2px solid #4caf50; /* 添加底部分隔线 */
+}
+
+ion-card-title {
+  font-size: 20px;
+  font-weight: bold;
+  color: #2c6e4f; /* 深绿色 */
+  display: flex;
+  align-items: center; /* 图标与文字垂直居中 */
+  gap: 8px; /* 图标与文字之间的间距 */
+}
 
+ion-card-content {
+  padding: 16px; /* 内容的内边距 */
+  color: #555; /* 内容字体颜色 */
+}
+
+/* 卡片悬停效果 */
+.diet-card:hover {
+  box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15); /* 增强的阴影效果 */
+  transform: translateY(-4px); /* 向上漂浮的效果 */
+  transition: box-shadow 0.3s ease, transform 0.3s ease; /* 平滑的过渡效果 */
+}
+
+/* 设置每餐的框样式 */
+.meal-box {
+  background-color: #f7fff7; /* 淡绿色背景 */
+  border: 1px solid #4caf50; /* 每餐框的边框颜色 */
+  padding: 16px;
+  border-radius: 8px;
+  margin-bottom: 16px; /* 每餐之间的间距 */
+  transition: background-color 0.3s ease; /* 背景颜色过渡 */
+}
+
+/* 每餐框的悬停效果 */
+.meal-box:hover {
+  background-color: #e1f7e1; /* 悬停时变为更亮的绿色 */
+}
 
-  /* 设置所有按钮的样式 */
-  ion-button {
-    border-radius: 12px; /* 按钮圆角 */
-    color: #333; /* 按钮中文字的颜色 */
-    font-weight: bold; /* 按钮字体加粗 */
-    text-align: center; /* 确保按钮文字水平居中 */
-    display: flex; /* 使用 flexbox 布局 */
-    justify-content: center; /* 水平居中 */
-    align-items: center; /* 垂直居中 */
+/* 早餐、午餐、晚餐的标题 */
+.meal-title {
+  font-size: 18px;
+  font-weight: bold;
+  margin-top: 10px; /* 减小顶部间距 */
+  margin-bottom: 5px; /* 减小底部间距 */
+  color: #4caf50; /* 绿色 */
+}
+
+/* 每餐的饮食内容 */
+.meal-details {
+  font-size: 16px;
+  color: #333; /* 内容颜色 */
+  line-height: 1.6; /* 增加行间距,使内容更易读 */
+  margin-bottom: 20px; /* 每段内容的间距 */
+}
+
+/* 没有饮食规划的提示 */
+.no-plan {
+  font-size: 16px;
+  color: #f44336; /* 红色 */
+  text-align: center;
+  padding: 8px;
+  background-color: #f8d7da;
+  border-radius: 8px;
+  margin-bottom: 16px;
+}
+
+/* 底部内容区域 */
+.diet-card-footer {
+  padding: 16px;
+  background-color: #f0f9f0; /* 淡绿色背景 */
+  border-bottom-left-radius: 12px;
+  border-bottom-right-radius: 12px;
+  border-top: 1px solid #4caf50;
+}
+
+/* 加载中消息的样式 */
+.loading-msg p {
+  font-size: 18px;
+  color: #555;
+  font-weight: bold;
+  text-align: center;
+  margin-top: 20px;
+}
+
+/* 登录按钮的样式 */
+.login-btn {
+  margin-top: 20px; /* 与上一部分的间距 */
+  display: block;
+  width: 100%; /* 按钮宽度占满容器 */
+  font-size: 16px; /* 按钮文字大小 */
+  padding: 10px 0; /* 按钮上下内边距 */
+  border-radius: 12px; /* 按钮圆角 */
+  transition: background-color 0.3s ease, color 0.3s ease; /* 按钮的平滑过渡效果 */
+}
+
+/* 登录按钮的 hover 效果 */
+.login-btn:hover {
+  background-color: #3880ff; /* 蓝色背景 */
+  color: white; /* 按钮文字变为白色 */
+}
+
+/* 小屏设备上的样式调整 */
+@media (max-width: 768px) {
+  .diet-card {
+    max-width: 90%; /* 调整卡片最大宽度 */
   }
-  
-  
-  /* 设置图标的间距 */
-  ion-icon {
-    margin-right: 8px; /* 图标与文字之间的间距 */
+
+  .diet-card-header {
+    padding: 12px 16px; /* 缩小内边距 */
   }
-  
-  /* 设置搜索框的样式 */
-  ion-searchbar {
-    border-radius: 20px; /* 搜索框圆角 */
-    margin: 10px 0; /* 上下间距 */
+
+  .diet-card-content,
+  .diet-card-footer {
+    padding: 12px; /* 减少内边距 */
   }
-  
-  /* 设置页面布局 */
-  ion-grid {
-    padding: 0 16px; /* 网格的内边距 */
+
+  .meal-title {
+    font-size: 16px; /* 调整字体大小 */
   }
-  
-  ion-row {
-    margin-bottom: 16px; /* 行间距 */
+
+  .meal-details {
+    font-size: 14px; /* 调整字体大小 */
   }
-  
-  ion-col {
-    padding: 0; /* 去掉每列的默认内边距 */
+
+  .login-btn {
+    font-size: 14px; /* 调整按钮文字大小 */
+    padding: 8px 0; /* 减小按钮内边距 */
   }
-  
+}

+ 128 - 59
smarteat-app/src/app/tab1/tab1.page.ts

@@ -3,8 +3,8 @@ import { Router } from '@angular/router';
 import { CloudSeUser } from 'src/lib/cloudSeuser'; // 引入 CloudSeUser 类
 import { FmodeChatCompletion } from 'fmode-ng'; // 引入 FmodeChatCompletion
 import { addIcons } from 'ionicons';
-import { albumsOutline, documentOutline, leafOutline, scanOutline, storefrontOutline } from 'ionicons/icons';
-import { IonButton, IonCard, IonCardContent, IonCardHeader, IonCol, IonContent, IonHeader, IonIcon, IonInput, IonRow, IonTextarea, IonTitle, IonToolbar, IonGrid, IonCardTitle, IonSearchbar, IonButtons } from '@ionic/angular/standalone'; // 导入 Ionic 组件
+import { albumsOutline, checkmarkCircleOutline, documentOutline, leafOutline, scanOutline, storefrontOutline } from 'ionicons/icons';
+import { IonButton, IonCard, IonCardContent, IonCardHeader, IonCol, IonContent, IonHeader, IonIcon, IonInput, IonRow, IonTextarea, IonTitle, IonToolbar, IonGrid, IonCardTitle, IonSearchbar, IonProgressBar,  } from '@ionic/angular/standalone'; // 导入 Ionic 组件
 import { CommonModule } from '@angular/common'; // 导入 CommonModule
 import { ImagePopupComponent } from '../image-popup/image-popup.component'; // 导入弹窗组件
 import { ModalController, NavController } from '@ionic/angular/standalone';
@@ -13,10 +13,8 @@ import { Image2PopupComponent } from '../image-popup/image2-popup/image2-popup.c
 import { Image3PopupComponent } from '../image-popup/image3-popup/image3-popup.component';
 import { Image4PopupComponent } from '../image-popup/image4-popup/image4-popup.component';
 import { openUserLoginModal } from 'src/lib/user/modal-user-login/modal-user-login.component';
-import { CloudUser } from 'src/lib/ncloud';
-import { MealService } from '../meal/meal.service';
-import { MealSearchComponent } from '../meal-search/meal-search/meal-search.component';
-
+import { CloudQuery, CloudUser } from 'src/lib/ncloud';
+import { CloudSeMealPlan } from 'src/lib/cloudplans';
 
 @Component({
   selector: 'app-tab1',
@@ -26,18 +24,38 @@ import { MealSearchComponent } from '../meal-search/meal-search/meal-search.comp
   imports: [
     CommonModule, IonContent, IonHeader, IonTitle, IonToolbar, 
     IonButton, IonTextarea, IonInput, IonCard, IonCardContent, IonGrid, IonRow, IonCol, IonIcon,
-    IonCardHeader, IonCardTitle, IonSearchbar,IonButtons
+    IonCardHeader, IonCardTitle, IonSearchbar, IonProgressBar
   ],
 })
 export class Tab1Page implements OnInit {
   private cloudSeUser: CloudSeUser; // 引入 CloudSeUser 实例
-  searchQuery: string = '';
+  private cloudSeMealPlan: CloudSeMealPlan; // 引入 CloudSeMealPlan 实例
+
   userInfo: any = null; // 用户信息
   responseMsg: string = ""; // 用于存储 AI 生成的饮食建议
   recipeMsg: string = ""; // 用于存储 AI 生成的推荐食谱
   isLoading: boolean = false; 
   dishName:string="";//用于存储菜品名
   dishPhoto:string="";
+  breakfast: string = "";  // 用于存储早餐
+  lunch: string = "";  // 用于存储午餐
+  dinner: string = "";  // 用于存储晚餐
+  notes: string = "";  //用于存储饮食建议
+  today:string = "";//判定日期
+  currentDate = new Date();
+  plan: boolean = false;  // 用户是否有饮食计划
+  result: boolean = true;  // 是否成功匹配到饮食计划
+  mark0:boolean=false;
+  isComplete:boolean = false;
+
+  // 当前显示的幻灯片索引
+  currentSlide: number = 0;
+  currentUser:CloudUser|undefined
+
+  currentDay: number = 0;  // 当前饮食计划是第几天
+  planDays: number = 0;  // 总饮食计划天数
+  progress: number = 0;  // 饮食计划进度
+  // currentUser: CloudUser | undefined;
 
   // 存储图片的数组
   images = [
@@ -54,47 +72,21 @@ export class Tab1Page implements OnInit {
       '<p><strong>三伏天“烤”验 孩子饮食如何搭配</strong></p>',
       '<p><strong>[辟谣]锻炼补水,喝运动饮料比喝白开水更好?</strong></p>'
   ];
-  // 当前显示的幻灯片索引
-  currentSlide: number = 0;
-  currentUser:CloudUser|undefined
+  
 
-  constructor(private router: Router, private modalCtrl: ModalController, private mealService: MealService,) {
-    addIcons({ scanOutline, documentOutline, storefrontOutline, albumsOutline, leafOutline });
+  constructor(private router: Router, private modalCtrl: ModalController,) {
+    addIcons({ scanOutline, documentOutline, storefrontOutline, albumsOutline, leafOutline, checkmarkCircleOutline});
     this.cloudSeUser = new CloudSeUser();
+    this.cloudSeMealPlan = new CloudSeMealPlan();
     this.currentUser=new CloudUser()
   }
 
-  //搜索框功能实现
-  // 当输入发生变化时触发
-  setSearchQuery(query: string) {
-    this.searchQuery = query;
-  }
-
-  // 点击搜索按钮时触发的搜索方法
-  async search() {
-    if (this.searchQuery.trim()) {
-      await this.openMealSearchModal();
-    }
-  }
-
-  // 打开弹窗并展示搜索结果
-  async openMealSearchModal() {
-    const modal = await this.modalCtrl.create({
-      component: MealSearchComponent,
-      componentProps: {
-        searchQuery: this.searchQuery,
-      },
-    });
-
-    await modal.present();
-  }
-//搜索框功能实现
-
   async ngOnInit(): Promise<void> {
     await this.loadUserData(); // 页面初始化时加载用户数据
     if (this.currentUser?.id) {
       this.goHealthTips();  // 用户已登录,立即调用生成健康建议的方法
       console.log(this.responseMsg)
+      this.getTodayDietPlan(); // 获取今日饮食计划
     }
   }
 
@@ -117,7 +109,12 @@ export class Tab1Page implements OnInit {
                 dietGroup: userData.get('dietGroup') || '',
                 avatar: userData.get('avatar') || null,
                 allergies: userData.get('allergies') || '',
+                planDays: userData.get('planDays') || null, // 获取 planDays 字段
             };
+            
+            // 检查用户是否有饮食计划
+            this.plan = this.userInfo.planDays != null && this.userInfo.planDays > 0;
+            this.planDays = this.userInfo.planDays || 0;  // 设置 planDays
         }
     } catch (error) {
         console.error('加载用户数据失败', error);
@@ -126,16 +123,16 @@ export class Tab1Page implements OnInit {
 
   // 获取健康建议
   async goHealthTips() {
+    this.isComplete = false;
     if (!this.userInfo) return;
 
-    const { height, weight, activityLevel, dietPreference, dietGroup } = this.userInfo;
+    const { height, weight, activityLevel, dietGroup ,gender} = this.userInfo;
     const newPrompt = `
-      你是一名专业的养生健康专家。根据以下用户信息,请提供今日的健康建议,字数大概在100-150字,分条列举,偏向与运动,睡眠与生活习惯等建议:
-      身高:${height} cm
-      体重:${weight} kg
-      活动水平:${activityLevel}
-      饮食偏好:${dietPreference}
-      饮食类型:${dietGroup}
+      你是一名专业的养生健康有关的专家,,专门为用户提供每日健康建议。
+      现在有一个身高${height} cm、体重${weight} kg的${gender}性用户向你咨询今日的健康建议。
+      重点是该用户是${dietGroup}饮食群体,活动水平${activityLevel}。
+      并且该用户今日的饮食规划为早餐:${this.breakfast}、午餐${this.lunch}、晚餐${this.dinner},参考饮食规划中的建议:${this.notes}。
+      请根据以上内容为该用户提供今日的健康建议。不需要再复述用户的信息,并且不需要提供饮食有关的建议,提供有关日常活动的,字数大概在100字以内。
     `;
 
     const completion = new FmodeChatCompletion([
@@ -146,9 +143,60 @@ export class Tab1Page implements OnInit {
     completion.sendCompletion().subscribe((message: any) => {
       console.log(message.content);
       this.responseMsg = message.content; // 更新健康建议
+      if (message?.complete){
+        this.isComplete = true;
+      }
     });
   }
 
+  async getTodayDietPlan() {
+    if (!this.userInfo || !this.currentUser?.id || !this.plan) {
+      this.result = false;
+      console.log("用户没有饮食计划");
+      return null;
+    }
+  
+    const currentDateStr = new Date().toISOString().split('T')[0]; // 获取今日日期(例如:2024-12-24)
+  
+    const cloudSeMealPlan = new CloudSeMealPlan();
+  
+    try {
+      // 获取当前用户的饮食计划(通过 user 外键和 day 日期进行匹配)
+      const query = new CloudQuery("seMealPlans");
+      query.equalTo("user", { "__type": "Pointer", "className": "_User", "objectId": this.currentUser.id });
+      query.equalTo("day", currentDateStr);  // 使用 today 变量匹配日期
+  
+      // 执行查询并获取第一个匹配的结果
+      const mealPlan = await query.first(); // 如果有多个匹配的计划,可以使用 `query.find()` 获取所有
+  
+      // 检查是否找到了匹配的饮食计划
+      if (mealPlan) {
+        this.breakfast = mealPlan.get("breakfast") || '暂无早餐信息';
+        this.lunch = mealPlan.get("lunch") || '暂无午餐信息';
+        this.dinner = mealPlan.get("dinner") || '暂无晚餐信息';
+        this.notes = mealPlan.get("notes") || '暂无饮食建议信息';
+        this.mark0 = mealPlan.get("mark") || false;  // 获取当前的打卡状态
+        this.currentDay = mealPlan.get("No") || 0;  // 获取当前是第几天
+        this.result = true;  // 标记成功
+
+        // 计算进度
+        this.progress = this.planDays ? this.currentDay / this.planDays : 0;
+
+        console.log("今日饮食计划: ", this.breakfast, this.lunch, this.dinner);
+        console.log("mealPlan objectId:", mealPlan.id);  // 调试:确保返回了 objectId
+        return mealPlan;  // 返回 mealPlan,以便后续更新
+      } else {
+        // 如果没有找到今日饮食计划
+        this.result = false;
+        console.log('未找到今日饮食计划');
+        return null;
+      }
+    } catch (error) {
+      console.error("获取今日饮食计划失败", error);
+      this.result = false;
+      return null;
+    }
+  }
 
   // 打开弹窗
   async openImagePopup(imageUrl: string, description: string) {
@@ -215,18 +263,6 @@ export class Tab1Page implements OnInit {
       this.router.navigate([`/tabs/tips`]);
     }
 
-    goToasy() {
-      this.router.navigate([`/tabs/asy`]);
-    }
-
-    goToasf(){
-      this.router.navigate([`/tabs/asf`]);
-    }
-
-    goToasx(){
-      this.router.navigate([`/tabs/asx`]);
-    }
-
     async login(){
       // 弹出登录窗口
       let user = await openUserLoginModal(this.modalCtrl);
@@ -235,4 +271,37 @@ export class Tab1Page implements OnInit {
         await this.loadUserData();// 登录后加载用户信息
       }
     }
-  }
+
+    // setToday() {
+    //   const nextDay = new Date(this.currentDate);
+    //   this.today = nextDay.toISOString().split('T')[0];
+    //   }
+
+    async check() {
+    
+      // 获取当前日期
+      const currentDateStr = new Date().toISOString().split('T')[0]; // 获取今日日期(例如:2024-12-24)
+    
+      // 获取今日饮食计划
+      const mealPlan = await this.getTodayDietPlan(); // 获取当前饮食计划
+      console.log('当前 mealPlan:', mealPlan);  // 调试:检查 mealPlan 是否存在
+      if (mealPlan && mealPlan.id) {
+        // 使用 get 方法获取 objectId
+        const mealPlanId = mealPlan.id;
+        console.log('准备更新 mealPlan objectId:', mealPlanId);  // 打印 objectId
+    
+        // 更新数据库中的 mark 字段
+        try {
+          // 调用后端接口更新饮食计划
+          await this.cloudSeMealPlan.updateMealPlan({ mark: true }, mealPlanId); 
+          this.mark0 = true;
+          console.log('打卡状态已更新:', );
+        } catch (error) {
+          console.error('更新打卡状态失败', error);
+        }
+      } else {
+        console.log('未找到今日饮食规划,无法打卡');
+      }
+    }
+    
+}

+ 7 - 1
smarteat-app/src/app/tab2/tab2.page.html

@@ -41,8 +41,14 @@
   </div>
 
   <!-- 按钮:执行消息生成函数 -->
+  @if(!currentUser?.id){
+    <ion-button (click)="login()" fill="outline" color="primary">
+      登录
+    </ion-button>
+  }
+  @if(currentUser?.id){
   <ion-button (click)="sendMessage()" expand="block">饮食方案生成</ion-button>
-
+ }
   <!-- 展示:返回消息内容 -->
   @if(!isComplete && responseMsg!="" && !isNew){
     <!-- <div class="response-container">{{responseMsg}}</div> -->

+ 21 - 7
smarteat-app/src/app/tab2/tab2.page.ts

@@ -3,8 +3,9 @@ import { CloudSeMealPlan } from 'src/lib/cloudplans'; // 引入封装好的 Clou
 import { FmodeChatCompletion, MarkdownPreviewModule } from 'fmode-ng';
 import { CloudSeUser } from 'src/lib/cloudSeuser'; // 引入 CloudSeUser 类
 
-import { IonButton, IonContent, IonHeader, IonInput, IonSelect, IonSelectOption, IonTextarea, IonTitle, IonToolbar } from '@ionic/angular/standalone';
+import { IonButton, IonContent, IonHeader, IonInput, IonSelect, IonSelectOption, IonTextarea, IonTitle, IonToolbar, ModalController } from '@ionic/angular/standalone';
 import { CloudUser } from 'src/lib/ncloud';
+import { openUserLoginModal } from 'src/lib/user/modal-user-login/modal-user-login.component';
 @Component({
 selector: 'app-tab2',
 templateUrl: 'tab2.page.html',
@@ -18,7 +19,9 @@ MarkdownPreviewModule,
 })
 export class Tab2Page {
 
-constructor() {}
+constructor(private modalCtrl: ModalController) {
+  this.currentUser=new CloudUser();
+}
 
 ngOnInit() {
 this.loadUserData();
@@ -29,7 +32,7 @@ planningDays: string = "";
 userPrompt: string = "";
 currentDate = new Date();
 dateOnlyString: string = '';
-
+currentUser:CloudUser|undefined
 // 用户信息
 age: number | null = null;
 gender: string = '';
@@ -95,7 +98,7 @@ if(this.responseMsg1==""){
   现在告诉你用户描述:该用户是一个年龄为${this.age}岁,身高和体重分别为${this.height}cm,${this.weight}kg的${this.gender}性。
   他的活动水平${this.activityLevel},饮食偏好${this.dietPreference},并且他的过敏信息为${this.allergies}。
   重点是他希望作为一位${this.dietGroup}群体的人,希望你为他或她规划以为${this.dateOnlyString}开始${this.planningDays}天的详细的饮食规划(食物内容以日常生活常见食物为主,每次规划尽量不同,要多样化)。
-  生成的结果不需要再复述用户的信息,直接以形式输出格式为(day(date类型)、breakfast(string类型)、lunch(string类型)、dinner(string类型)、notes(string类型))结构化JSON格式输出
+  生成的结果不需要再复述用户的信息,直接以形式输出格式为(day(date类型)、breakfast(string类型)、lunch(string类型)、dinner(string类型)、notes(string类型)、No(number类型,第几天))结构化JSON格式输出
   (结果不需要用\`\`\`json和\`\`\`将结果包裹,当天数大于一时,用[]括起多天的规划、并且之间用,隔开)
   `;
 }else{
@@ -106,7 +109,7 @@ if(this.responseMsg1==""){
   他的活动水平${this.activityLevel},饮食偏好${this.dietPreference},并且他的过敏信息为${this.allergies}。
   重点是他希望作为一位${this.dietGroup}群体的人,希望你为他或她规划以为${this.dateOnlyString}开始${this.planningDays}天的详细的饮食规划(食物内容以日常生活常见食物为主)。
   你可以在该${this.responseMsg1}饮食规划的基础上,再根据该需求${this.userPrompt},生成新的饮食规划,以下格式不变。
-  生成的结果不需要再复述用户的信息,直接以形式输出格式为(day(date类型)、breakfast(string类型)、lunch(string类型)、dinner(string类型)、notes(string类型))结构化JSON格式输出
+  生成的结果不需要再复述用户的信息,直接以形式输出格式为(day(date类型,日期)、breakfast(string类型)、lunch(string类型)、dinner(string类型)、notes(string类型)、No(number类型,第几天))结构化JSON格式输出
   (结果不需要用\`\`\`json和\`\`\`将结果包裹,当天数大于一时,用[]括起多天的规划、并且之间用,隔开)
   `;
 
@@ -164,7 +167,8 @@ try {
       breakfast: plan.breakfast,
       lunch: plan.lunch,
       dinner: plan.dinner,
-      notes: plan.notes
+      notes: plan.notes,
+      No: Number(plan.No)
     };
   });
 
@@ -224,7 +228,8 @@ async exportMealPlan() {
           breakfast: plan.breakfast,
           lunch: plan.lunch,
           dinner: plan.dinner,
-          notes: plan.notes
+          notes: plan.notes,
+          No: Number(plan.No)
         };
       });
 
@@ -271,4 +276,13 @@ async exportMealPlan() {
   }
 }
 
+async login(){
+  // 弹出登录窗口
+  let user = await openUserLoginModal(this.modalCtrl);
+  if(user?.id){
+    this.currentUser = user
+    await this.loadUserData();// 登录后加载用户信息
+  }
+}
+
 }

+ 3 - 3
smarteat-app/src/app/tab3/tab3.page.html

@@ -41,11 +41,11 @@
   <!-- 我的饮食计划 -->
     <ion-card>
       <ion-card-header>
-        <ion-card-title>我的饮食划</ion-card-title>
+        <ion-card-title>我的饮食划</ion-card-title>
       </ion-card-header>
       <ion-card-content>
         <ion-item>
-          <ion-label>今天的计划</ion-label>
+          <ion-label></ion-label>
           <ion-button expand="block" color="secondary">
             查看详情
           </ion-button>
@@ -61,7 +61,7 @@
       </ion-card-header>
       <ion-card-content>
         <ion-item>
-          <ion-label>最近三天记录</ion-label>
+          <ion-label></ion-label>
           <ion-button expand="block" color="tertiary">
             查看详情
           </ion-button>

+ 1 - 1
smarteat-app/src/theme/variables.scss

@@ -3,7 +3,7 @@
 
   ion-button {
     border-radius: 12px; /* 按钮圆角 */
-    --background: #33ffcc;   /* 设置背景色为 #33ffcc */
+    --background: #99ffcc;   /* 设置背景色为 #99ffcc */
     color: #333; /* 按钮中文字的颜色 */
     font-weight: bold; /* 按钮字体加粗 */
     text-align: center; /* 确保按钮文字水平居中 */