Browse Source

页面跳转

CuddleNan 2 days ago
parent
commit
4af08d5557

+ 54 - 4
myapp/src/app/tab1/import-recipe-data.ts → myapp/src/app/import-recipe-data.ts

@@ -1,6 +1,5 @@
 import { CloudObject } from "src/lib/ncloud";
 
-
 // 食谱分类数据生成
 async function seedRecipeCategories() {
   const categories = [
@@ -352,6 +351,52 @@ async function seedRecipes(categories: CloudObject[]) {
   return createdRecipes;
 }
 
+// 历史记录导入
+async function seedHistories(recipes: CloudObject[]) {
+  // 随机选择5-10个食谱作为历史记录
+  const shuffled = [...recipes].sort(() => 0.5 - Math.random());
+  const historyCount = 5 + Math.floor(Math.random() * 6); // 5-10条记录
+  const historyRecipes = shuffled.slice(0, historyCount);
+  
+  // 创建历史记录,时间分布在最近30天内
+  for (let i = 0; i < historyRecipes.length; i++) {
+    const history = new CloudObject('RecipeHistory');
+    const date = new Date();
+    date.setDate(date.getDate() - Math.floor(Math.random() * 30));
+    
+    history.set({
+      recipe: historyRecipes[i].toPointer(),
+      viewedAt: date.toISOString()
+    });
+    
+    await history.save();
+    console.log(`Created history record for recipe: ${historyRecipes[i].get('title')} at ${date.toLocaleDateString()}`);
+  }
+}
+
+// 收藏导入
+async function seedFavorites(recipes: CloudObject[]) {
+  // 随机选择3-8个食谱作为收藏
+  const shuffled = [...recipes].sort(() => 0.5 - Math.random());
+  const favoriteCount = 3 + Math.floor(Math.random() * 6); // 3-8条记录
+  const favoriteRecipes = shuffled.slice(0, favoriteCount);
+  
+  // 创建收藏记录
+  for (const recipe of favoriteRecipes) {
+    const favorite = new CloudObject('RecipeFavorite');
+    const date = new Date();
+    date.setDate(date.getDate() - Math.floor(Math.random() * 30));
+    
+    favorite.set({
+      recipe: recipe.toPointer(),
+      createdAt: date.toISOString()
+    });
+    
+    await favorite.save();
+    console.log(`Created favorite record for recipe: ${recipe.get('title')} at ${date.toLocaleDateString()}`);
+  }
+}
+
 // 每日推荐数据生成
 async function seedDailyRecommendations(recipes: CloudObject[]) {
   // 获取最近7天的日期
@@ -389,12 +434,17 @@ export async function importAllData() {
     // 2. 导入食谱数据
     const recipes = await seedRecipes(categories);
     
-    // 3. 生成每日推荐
+    // 3. 生成历史记录
+    await seedHistories(recipes);
+    
+    // 4. 生成收藏记录
+    await seedFavorites(recipes);
+    
+    // 5. 生成每日推荐
     await seedDailyRecommendations(recipes);
     
     console.log('Data import completed successfully!');
   } catch (error) {
     console.error('Error during data import:', error);
   }
-}
-
+}

+ 72 - 13
myapp/src/app/tab1/README.md

@@ -44,6 +44,7 @@ class Recipe {
   ingredients: JSON Array
   steps: JSON Array
   rating: Number
+  viewCount: Number
   category: Pointer<RecipeCategory>
   author: Pointer<_User>
 }
@@ -54,6 +55,7 @@ class RecipeCategory {
   updatedAt: Date
   name: String
   icon: String
+  sortOrder: Number
 }
 
 class DailyRecommendation {
@@ -62,12 +64,37 @@ class DailyRecommendation {
   updatedAt: Date
   date: Date
   recommendedRecipes: Array<Pointer<Recipe>>
+  algorithmVersion: String
 }
 
-' 关系定义
-RecipeCategory ||--o{ Recipe : "1个分类 → 多个食谱"
-DailyRecommendation }o--|| Recipe : "每日推荐 → 多个食谱"
-Recipe ||--o| _User : "作者关系"
+class RecipeHistory {
+  objectId: String
+  createdAt: Date
+  updatedAt: Date
+  user: Pointer<_User>
+  recipe: Pointer<Recipe>
+  viewCount: Number
+  lastViewedAt: Date
+}
+
+class RecipeFavorite {
+  objectId: String
+  createdAt: Date
+  updatedAt: Date
+  user: Pointer<_User>
+  recipe: Pointer<Recipe>
+  tags: Array<String>
+}
+
+class UserPreference {
+  objectId: String
+  createdAt: Date
+  updatedAt: Date
+  user: Pointer<_User>
+  preferredCategories: Array<Pointer<RecipeCategory>>
+  dietaryRestrictions: Array<String>
+  calorieRange: Object
+}
 
 ' 系统内置用户表
 class _User {
@@ -78,19 +105,51 @@ class _User {
   updatedAt: Date
 }
 
+' 关系定义
+RecipeCategory ||--o{ Recipe : "1个分类 → 多个食谱"
+DailyRecommendation }o--|| Recipe : "每日推荐 → 多个食谱"
+Recipe ||--o| _User : "作者关系"
+
+_User ||--o{ RecipeHistory : "浏览历史"
+_User ||--o{ RecipeFavorite : "收藏记录"
+_User ||--o| UserPreference : "用户偏好"
+Recipe ||--o{ RecipeHistory : "被浏览记录"
+Recipe ||--o{ RecipeFavorite : "被收藏记录"
+
 ' 样式调整
 note top of Recipe
-  **字段说明**
-  ingredients格式示例:
-  [{"name":"意大利面","amount":"400g"},...]
-  steps格式示例:
-  ["步骤1描述","步骤2描述",...]
+  **新增字段**
+  viewCount: 浏览量统计
+  **索引建议**
+  (category) 索引
+  (rating) 索引
+  (createdAt) 索引
+end note
+
+note left of RecipeHistory
+  **索引建议**
+  复合索引(user, recipe)
+  (lastViewedAt) 索引
+  **约束**
+  自动更新viewCount
+end note
+
+note right of RecipeFavorite
+  **索引建议**
+  复合唯一索引(user, recipe)
+  (createdAt) 索引
+  **功能**
+  支持标签分类收藏
 end note
 
-note right of DailyRecommendation
-  每日存储推荐记录
-  通过date字段实现历史推荐查询
-  推荐逻辑需通过云函数实现
+note bottom of UserPreference
+  **数据结构**
+  calorieRange: {
+    min: Number,
+    max: Number
+  }
+  **索引建议**
+  (user) 唯一索引
 end note
 @enduml
 ```

+ 13 - 2
myapp/src/app/tab1/page-detail/page-detail.page.ts

@@ -3,9 +3,10 @@ import { Component, OnInit } from '@angular/core';
 import { ActivatedRoute } from '@angular/router';
 import { IonBackButton, IonButton, IonButtons, IonCard, IonCardContent, IonCardHeader, IonCardTitle, IonChip, IonContent, IonHeader, IonIcon, IonItem, IonLabel, IonList, IonNote, IonThumbnail, IonTitle, IonToolbar } from '@ionic/angular/standalone';
 import { addIcons } from 'ionicons';
-import { basketOutline, restaurantOutline, timeOutline, flameOutline, peopleOutline } from 'ionicons/icons';
+import { basketOutline, restaurantOutline, timeOutline, flameOutline, peopleOutline, star, starOutline, bookmark, bookmarkOutline, shareSocialOutline } from 'ionicons/icons';
 import { CloudObject, CloudQuery } from 'src/lib/ncloud';
 
+
 interface Ingredient {
   name: string;
   amount: string;
@@ -30,6 +31,7 @@ interface Recipe {
   styleUrls: ['./page-detail.page.scss'],
   //imports:[CommonModule],
   standalone: false
+  
   // imports: [IonHeader, IonToolbar, IonTitle, IonContent, IonBackButton, IonButtons, IonButton, IonIcon, 
   //           IonCard, IonCardHeader, IonCardTitle, IonCardContent, IonList, IonItem, IonLabel, IonNote, IonChip]
 })
@@ -39,7 +41,16 @@ export class PageDetailPage implements OnInit {
   constructor(
     private route: ActivatedRoute
   ) {
-    addIcons({ basketOutline, restaurantOutline, timeOutline, flameOutline, peopleOutline });
+    addIcons({ timeOutline, 
+      flameOutline, 
+      peopleOutline, 
+      basketOutline, 
+      restaurantOutline,
+      star,
+      starOutline,
+      bookmark,
+      bookmarkOutline,
+      shareSocialOutline });
     this.route.params.subscribe(params => {
      console.log(params) ;
      this.loadRecipe(params['recipeId']);

+ 49 - 50
myapp/src/app/tab1/page-type/page-type.page.ts

@@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core';
 import { ActivatedRoute } from '@angular/router';
 import { NavController } from '@ionic/angular';
 import { IonBackButton, IonButtons, IonContent, IonHeader, IonItem, IonLabel, IonList, IonThumbnail, IonTitle, IonToolbar } from '@ionic/angular/standalone';
-import { importAllData } from '../import-recipe-data';
+import { importAllData } from '../../import-recipe-data';
 import { CloudObject, CloudQuery } from 'src/lib/ncloud';
 
 interface Recipe {
@@ -32,7 +32,7 @@ export class PageTypePage implements OnInit {
     this.categoryName = this.route.snapshot.paramMap.get('name') || '分类名称';
     
     // 加载该分类下的菜品数据
-    this.loadRecipes();
+    //this.loadRecipes();
     this.loadRecipeList();
   }
 
@@ -41,60 +41,59 @@ export class PageTypePage implements OnInit {
   }
   recipeList : Array<CloudObject> = [];
   recipeCategoryList : Array<CloudObject> = [];
-  DailyRecommendationList : Array<CloudObject> = [];
+
   async loadRecipeList(){
     let query1 = new CloudQuery("Recipe");
     this.recipeList = await query1.find(); 
     let query2 = new CloudQuery("RecipeCategory");
     this.recipeCategoryList = await query1.find(); 
-    let query3 = new CloudQuery("DailyRecommendation");
-    this.DailyRecommendationList = await query1.find(); 
-  }
-  loadRecipes() {
-    // 模拟数据 - 实际应用中应该从API获取
-    this.recipes = [
-      {
-        id: 1,
-        title: '经典意大利肉酱面',
-        imageUrl: 'https://images.unsplash.com/photo-1555949258-eb67b1ef0ceb',
-        description: '传统意大利风味肉酱面,酱汁浓郁,面条劲道',
-        cookTime: '45分钟',
-        rating: 4.5
-      },
-      {
-        id: 2,
-        title: '奶油蘑菇意面',
-        imageUrl: 'https://images.unsplash.com/photo-1611270629569',
-        description: '奶油香浓,蘑菇鲜美,意面口感绝佳',
-        cookTime: '30分钟',
-        rating: 4.8
-      },
-      {
-        id: 3,
-        title: '番茄罗勒意面',
-        imageUrl: 'https://images.unsplash.com/photo-1608755728476',
-        description: '新鲜番茄与罗勒的完美结合,清爽可口',
-        cookTime: '25分钟',
-        rating: 4.3
-      },
-      {
-        id: 4,
-        title: '海鲜意大利面',
-        imageUrl: 'https://images.unsplash.com/photo-1516100882582',
-        description: '多种海鲜搭配,鲜香浓郁',
-        cookTime: '35分钟',
-        rating: 4.7
-      },
-      {
-        id: 5,
-        title: '千层面',
-        imageUrl: 'https://images.unsplash.com/photo-1611273426858',
-        description: '层层美味,奶酪与肉酱的完美融合',
-        cookTime: '60分钟',
-        rating: 4.9
-      }
-    ];
+
   }
+  // loadRecipes() {
+  //   // 模拟数据 - 实际应用中应该从API获取
+  //   this.recipes = [
+  //     {
+  //       id: 1,
+  //       title: '经典意大利肉酱面',
+  //       imageUrl: 'https://images.unsplash.com/photo-1555949258-eb67b1ef0ceb',
+  //       description: '传统意大利风味肉酱面,酱汁浓郁,面条劲道',
+  //       cookTime: '45分钟',
+  //       rating: 4.5
+  //     },
+  //     {
+  //       id: 2,
+  //       title: '奶油蘑菇意面',
+  //       imageUrl: 'https://images.unsplash.com/photo-1611270629569',
+  //       description: '奶油香浓,蘑菇鲜美,意面口感绝佳',
+  //       cookTime: '30分钟',
+  //       rating: 4.8
+  //     },
+  //     {
+  //       id: 3,
+  //       title: '番茄罗勒意面',
+  //       imageUrl: 'https://images.unsplash.com/photo-1608755728476',
+  //       description: '新鲜番茄与罗勒的完美结合,清爽可口',
+  //       cookTime: '25分钟',
+  //       rating: 4.3
+  //     },
+  //     {
+  //       id: 4,
+  //       title: '海鲜意大利面',
+  //       imageUrl: 'https://images.unsplash.com/photo-1516100882582',
+  //       description: '多种海鲜搭配,鲜香浓郁',
+  //       cookTime: '35分钟',
+  //       rating: 4.7
+  //     },
+  //     {
+  //       id: 5,
+  //       title: '千层面',
+  //       imageUrl: 'https://images.unsplash.com/photo-1611273426858',
+  //       description: '层层美味,奶酪与肉酱的完美融合',
+  //       cookTime: '60分钟',
+  //       rating: 4.9
+  //     }
+  //   ];
+  // }
 
   goToDetail(recipe : CloudObject) {
     this.navCtrl.navigateForward(["tabs","tab1","page-detail",recipe.id]);

+ 7 - 7
myapp/src/app/tab1/tab1.page.html

@@ -74,15 +74,15 @@
           md="6" 
           lg="4" 
           class="recipe-card" 
-          *ngFor="let recipe of recommendedRecipes"
-          (click)="goToRecipeDetail(recipe.objectId)"
-        >
-          <ion-card class="recipe-card-hover" (click)="goToDetail()">
-            <ion-img [src]="recipe.image?.url || '/assets/images/default-food.jpg'"></ion-img>
+          *ngFor="let recipe of recipeGroup"
+          (click)="goToDetail(recipe)"
+        > 
+          <ion-card class="recipe-card-hover">
+            <ion-img [src]="recipe.imageUrl || '/assets/images/default-food.jpg'"></ion-img>
             <ion-card-content class="p-4">
-              <h3 class="recipe-title">{{ recipe.title }}</h3>
+              <h3 class="recipe-title">{{  recipe.title }}</h3>
               <div class="recipe-meta">
-                <ion-icon name="time" class="icon-md"></ion-icon> {{ recipe.cookingTime || 30 }}分钟
+                <ion-icon name="time" class="icon-md"></ion-icon> {{  recipe.cookingTime || 30 }}分钟
                 <ion-icon name="star" class="icon-md text-primary"></ion-icon> {{ recipe.rating || 4.5 }}评分
               </div>
             </ion-card-content>

+ 33 - 4
myapp/src/app/tab1/tab1.page.ts

@@ -1,6 +1,7 @@
 import { Component, OnInit, Renderer2 } from '@angular/core';
 import { Router } from '@angular/router';
 import { NavController } from '@ionic/angular';
+import { CloudObject, CloudQuery } from 'src/lib/ncloud';
 
 @Component({
   selector: 'app-tab1',
@@ -24,7 +25,7 @@ export class Tab1Page implements OnInit {
     { id: 3, title: '蔬菜鸡胸肉沙拉', image: '/assets/food/jxsl.jpg', time: 25, rating: 4.7 },
   ];
 
-  constructor(private router: Router, private renderer: Renderer2,private navCtrl: NavController) {}
+  constructor(private router: Router, private renderer: Renderer2, private navCtrl: NavController) { }
 
   ngOnInit() {
     setTimeout(() => {
@@ -34,8 +35,36 @@ export class Tab1Page implements OnInit {
         this.renderer.setStyle(card, 'transform', 'translateY(0)');
       });
     }, 1000);
+    this.loadDailyRecommendationList();
   }
 
+
+  DailyRecommendationList: Array<CloudObject> = []; // 存储原始每日推荐记录
+  filteredRecipes: Array<Array<CloudObject>> = []; // 二维数组:外层=DailyRecommendation,内层=对应的Recipe列表
+  recipeGroup: Array<CloudObject> = [];
+
+  async loadDailyRecommendationList() {
+    // 1. 查询 DailyRecommendation 表并关联 Recipe 数据
+    let query = new CloudQuery("DailyRecommendation");
+    query.include("recommendedRecipes"); // 关键:联查 Recipe 表
+    this.DailyRecommendationList = await query.find();
+
+    // 2. 构建二维数组
+    for (let dailyRec of this.DailyRecommendationList) {
+      // 获取当前 DailyRecommendation 的 recommendedRecipes 数组
+      const recipes = dailyRec.data['recommendedRecipes'] || []; // 防止undefined
+      // 将当前 DailyRecommendation 的所有关联 Recipe 存入内层数组
+      this.filteredRecipes.push(recipes);
+    }
+    console.log("完整的二维数组结构:", this.filteredRecipes);
+    const randomGroupIndex = Math.floor(Math.random() * this.filteredRecipes.length);
+    console.log("随机选择的组索引:", randomGroupIndex);
+    this.recipeGroup = this.filteredRecipes[randomGroupIndex];
+    console.log("随机选择的组内容:", this.recipeGroup);
+
+  }
+
+
   login() {
     this.router.navigate(['/login']);
   }
@@ -60,12 +89,12 @@ export class Tab1Page implements OnInit {
   }
 
   goToTypeList() {
-    this.navCtrl.navigateForward(["tabs","tab1","page-type"]);
+    this.navCtrl.navigateForward(["tabs", "tab1", "page-type"]);
     console.log('Navigating to page-type');
   }
 
-  goToDetail() {
-    this.navCtrl.navigateForward(["tabs","tab1","page-detail"]);
+  goToDetail(recipe: CloudObject) {
+    this.navCtrl.navigateForward(["tabs", "tab1", "page-detail", recipe.objectId]);
     console.log('Navigating to page-detail');
   }
 }

+ 1 - 1
myapp/src/app/tab2/tab2.page.scss

@@ -55,7 +55,7 @@
 }
 
 .credentials {
-  display: flex;
+  //display: flex;
   align-items: center;
   flex-wrap: wrap;
   gap: 12px;

+ 9 - 9
myapp/src/app/tab3/page-collections/page-collections.page.html

@@ -10,29 +10,29 @@
 <ion-content [fullscreen]="true">
   <!-- 收藏列表 -->
   <ion-list>
-    <ion-item-sliding *ngFor="let item of collections">
-      <ion-item [routerLink]="['/recipe-detail', item.id]">
+    <ion-item-sliding *ngFor="let item of recipeFavoriteList">
+      <ion-item  (click)="goToDetail(item.id)">
         <ion-thumbnail slot="start">
-          <img [src]="item.image" [alt]="item.name">
+          <img [src]="item.get('imageUrl')" [alt]="item.get('title')">
         </ion-thumbnail>
         <ion-label>
-          <h2>{{ item.name }}</h2>
-          <p *ngIf="item.time">收藏时间: {{ item.time | date:'yyyy-MM-dd' }}</p>
+          <h2>{{ item.get('title') }}</h2>
+          <p *ngIf="item.get('favoriteTime')">收藏时间: {{ item.get('favoriteTime') | date:'yyyy-MM-dd' }}</p>
         </ion-label>
         <ion-icon name="heart" slot="end" color="danger"></ion-icon>
       </ion-item>
       <ion-item-options side="end">
-        <ion-item-option color="danger" (click)="removeCollection(item.id)">
+        <!-- <ion-item-option color="danger" (click)="removeCollection(item.id)">
           <ion-icon name="trash" slot="icon-only"></ion-icon>
-        </ion-item-option>
+        </ion-item-option> -->
       </ion-item-options>
     </ion-item-sliding>
   </ion-list>
 
   <!-- 空状态提示 -->
-  <div class="empty-state" *ngIf="collections.length === 0">
+  <div class="empty-state" *ngIf="recipeFavoriteList.length === 0">
     <ion-icon name="heart-outline"></ion-icon>
     <h3>暂无收藏记录</h3>
     <p>您收藏的菜品将会显示在这里</p>
   </div>
-</ion-content>
+</ion-content>

+ 52 - 25
myapp/src/app/tab3/page-collections/page-collections.page.ts

@@ -1,7 +1,11 @@
 import { Component, OnInit } from '@angular/core';
 import { IonBackButton, IonButtons, IonContent, IonHeader, IonIcon, IonItem, IonItemOption, IonItemOptions, IonItemSliding, IonLabel, IonList, IonThumbnail, IonTitle, IonToolbar } from '@ionic/angular/standalone';
 import { addIcons } from 'ionicons';
-import { heart, heartOutline, trash } from 'ionicons/icons';
+import { codeDownloadSharp, heart, heartOutline, trash } from 'ionicons/icons';
+import { importAllData } from 'src/app/import-recipe-data';
+import { CloudObject, CloudQuery } from 'src/lib/ncloud';
+import { NavController } from '@ionic/angular';
+import { Router } from '@angular/router';
 
 interface CollectionItem {
   id: number;
@@ -20,40 +24,63 @@ interface CollectionItem {
 export class PageCollectionsPage implements OnInit {
   collections: CollectionItem[] = [];
 
-  constructor() {
+  constructor(private navCtrl: NavController,private router:Router) { 
     addIcons({ heart, heartOutline, trash });
   }
 
   ngOnInit() {
-    this.loadCollections();
+    //this.loadCollections();
+    this.loadRecipeFavoriteList();
   }
 
-  loadCollections() {
-    // 模拟数据 - 实际应该从本地存储或API获取
-    this.collections = [
-      {
-        id: 1,
-        name: '意大利肉酱面',
-        image: 'https://images.unsplash.com/photo-1555949258-eb67b1ef0ceb',
-        time: new Date('2023-05-15')
-      },
-      {
-        id: 2,
-        name: '奶油蘑菇汤',
-        image: 'https://images.unsplash.com/photo-1547592180-85f173990554',
-        time: new Date('2023-05-10')
-      },
-      {
-        id: 3,
-        name: '番茄炒蛋',
-        image: 'https://images.unsplash.com/photo-1582456891920-7a6a13cc5c4a',
-        time: new Date('2023-05-05')
-      }
-    ];
+  recipeFavoriteList: CloudObject[] = []; // 存储RecipeFavorite的CloudObject
+  recipeDataList: any[] = []; // 存储Recipe表的完整data数据
+  
+  async loadRecipeFavoriteList() {
+    const query = new CloudQuery("RecipeFavorite");
+    query.include("recipe"); // 联查Recipe表
+    const favorites = await query.find();
+
+    console.log('favorites',favorites);
+    
+    
+    this.recipeFavoriteList = favorites.map(fav => fav.get("recipe"));
+    // this.recipeDataList = this.recipeFavoriteList.map(recipe => recipe.data);
+    
+    console.log("Recipe数据列表:", this.recipeFavoriteList);
   }
 
+  // loadCollections() {
+  //   // 模拟数据 - 实际应该从本地存储或API获取
+  //   this.collections = [
+  //     {
+  //       id: 1,
+  //       name: '意大利肉酱面',
+  //       image: 'https://images.unsplash.com/photo-1555949258-eb67b1ef0ceb',
+  //       time: new Date('2023-05-15')
+  //     },
+  //     {
+  //       id: 2,
+  //       name: '奶油蘑菇汤',
+  //       image: 'https://images.unsplash.com/photo-1547592180-85f173990554',
+  //       time: new Date('2023-05-10')
+  //     },
+  //     {
+  //       id: 3,
+  //       name: '番茄炒蛋',
+  //       image: 'https://images.unsplash.com/photo-1582456891920-7a6a13cc5c4a',
+  //       time: new Date('2023-05-05')
+  //     }
+  //   ];
+  // }
+
   removeCollection(id: number) {
     // 模拟删除操作 - 实际应该更新本地存储或API
     this.collections = this.collections.filter(item => item.id !== id);
   }
+  goToDetail(recipeId: any) {
+    // this.navCtrl.navigateForward(["tabs", "tab1", "page-detail", recipe.objectId]);
+    this.navCtrl.navigateForward(`/tabs/tab1/page-detail/${recipeId}`);
+    console.log('Navigating to page-detail');
+  }
 }

+ 3 - 3
myapp/src/app/tab3/page-records/page-records.page.html

@@ -10,11 +10,11 @@
 <ion-content [fullscreen]="true">
   <!-- 浏览记录列表 -->
   <ion-list>
-    <ion-item *ngFor="let item of historyList" [routerLink]="['/recipe-detail', item.id]">
+    <ion-item *ngFor="let item of recipeRecordList" (click)="goToDetail(item.id)">
       <ion-thumbnail slot="start">
-        <img [src]="item.image" [alt]="item.name">
+        <img [src]="item.get('imageUrl')" [alt]="item.get('title')">
       </ion-thumbnail>
-      <ion-label>{{ item.name }}</ion-label>
+      <ion-label>{{ item.get('title') }}</ion-label>
     </ion-item>
   </ion-list>
 

+ 49 - 20
myapp/src/app/tab3/page-records/page-records.page.ts

@@ -1,7 +1,9 @@
 import { Component, OnInit } from '@angular/core';
-import { IonBackButton, IonButtons, IonContent, IonHeader, IonIcon, IonItem, IonLabel, IonList, IonThumbnail, IonTitle, IonToolbar } from '@ionic/angular/standalone';
+import { Router } from '@angular/router';
+import { IonBackButton, IonButtons, IonContent, IonHeader, IonIcon, IonItem, IonLabel, IonList, IonThumbnail, IonTitle, IonToolbar, NavController } from '@ionic/angular/standalone';
 import { addIcons } from 'ionicons';
-import { timeOutline } from 'ionicons/icons';
+import { heart, heartOutline, timeOutline, trash } from 'ionicons/icons';
+import { CloudObject, CloudQuery } from 'src/lib/ncloud';
 
 interface HistoryItem {
   id: number;
@@ -20,24 +22,51 @@ interface HistoryItem {
 export class PageRecordsPage implements OnInit {
   historyList: HistoryItem[] = [];
 
+  constructor(private navCtrl: NavController,private router:Router) { 
+    addIcons({ heart, heartOutline, trash });
+  }
   ngOnInit() {
-    // 模拟数据 - 实际应该从本地存储获取
-    this.historyList = [
-      {
-        id: 1,
-        name: '意大利肉酱面',
-        image: 'https://images.unsplash.com/photo-1555949258-eb67b1ef0ceb'
-      },
-      {
-        id: 2,
-        name: '奶油蘑菇汤',
-        image: 'https://images.unsplash.com/photo-1547592180-85f173990554'
-      },
-      {
-        id: 3,
-        name: '番茄炒蛋',
-        image: 'https://images.unsplash.com/photo-1582456891920-7a6a13cc5c4a'
-      }
-    ];
+    // // 模拟数据 - 实际应该从本地存储获取
+    // this.historyList = [
+    //   {
+    //     id: 1,
+    //     name: '意大利肉酱面',
+    //     image: 'https://images.unsplash.com/photo-1555949258-eb67b1ef0ceb'
+    //   },
+    //   {
+    //     id: 2,
+    //     name: '奶油蘑菇汤',
+    //     image: 'https://images.unsplash.com/photo-1547592180-85f173990554'
+    //   },
+    //   {
+    //     id: 3,
+    //     name: '番茄炒蛋',
+    //     image: 'https://images.unsplash.com/photo-1582456891920-7a6a13cc5c4a'
+    //   }
+    // ];
+    this.loadRecipeFavoriteList();
+  }
+
+  recipeRecordList: CloudObject[] = []; // 存储RecipeFavorite的CloudObject
+  recipeDataList: any[] = []; // 存储Recipe表的完整data数据
+  
+  async loadRecipeFavoriteList() {
+    const query = new CloudQuery("RecipeHistory");
+    query.include("recipe"); // 联查Recipe表
+    const favorites = await query.find();
+
+    console.log('favorites',favorites);
+    
+    
+    this.recipeRecordList = favorites.map(fav => fav.get("recipe"));
+    // this.recipeDataList = this.recipeFavoriteList.map(recipe => recipe.data);
+    
+    console.log("Recipe数据列表:", this.recipeRecordList);
+  }
+
+  goToDetail(recipeId: any) {
+    // this.navCtrl.navigateForward(["tabs", "tab1", "page-detail", recipe.objectId]);
+    this.navCtrl.navigateForward(`/tabs/tab1/page-detail/${recipeId}`);
+    console.log('Navigating to page-detail');
   }
 }

+ 5 - 0
myapp/src/app/tab3/tab3.page.ts

@@ -33,5 +33,10 @@ export class Tab3Page {
     this.navCtrl.navigateForward(["tabs","tab3","page-collections"]);
     console.log('Navigating to page-collections');
   }
+  goToDetail(recipeId: any) {
+    // this.navCtrl.navigateForward(["tabs", "tab1", "page-detail", recipe.objectId]);
+    this.navCtrl.navigateForward(`/tabs/tab1/page-detail/${recipeId}`);
+    console.log('Navigating to page-detail');
+  }
 
 }

+ 14 - 0
myapp/src/lib/ncloud.ts

@@ -11,6 +11,12 @@ export class CloudObject {
     createdAt: any;
     updatedAt: any;
     data: Record<string, any> = {};
+    recipe: any;
+    imageUrl: any;
+    title: any;
+    cookingTime: any;
+    rating: any;
+    objectId: any;
 
     constructor(className: string) {
         this.className = className;
@@ -87,6 +93,14 @@ export class CloudObject {
 
 // CloudQuery.ts
 export class CloudQuery {
+    containedIn(arg0: string, recipeIds: any[]) {
+        throw new Error('Method not implemented.');
+    }
+    // containedIn(key: string, values: any[]) {
+    //     if (!this.queryParams["where"]) this.queryParams["where"] = {};
+    //     this.queryParams["where"][key] = { $in: values };  // 使用 $in 操作符
+    //     return this;
+    //   }
     className: string;
     queryParams: Record<string, any> = { where: {} };