Browse Source

ai对话+tab3(我的)

CuddleNan 3 weeks ago
parent
commit
19b6e2859c

+ 15 - 0
.hintrc

@@ -0,0 +1,15 @@
+{
+  "extends": [
+    "development"
+  ],
+  "hints": {
+    "compat-api/css": [
+      "default",
+      {
+        "ignore": [
+          "backdrop-filter"
+        ]
+      }
+    ]
+  }
+}

+ 12 - 0
README.md

@@ -169,6 +169,18 @@ D --> D1(营养素缺口分析)
 | 薄荷健康 | 卡路里计算精准              | 食材库存管理功能薄弱 | 强化 “库存驱动型推荐”    |
 | 下厨房   | UGC 内容丰富                | 个性化推荐算法单一   | 多约束条件智能组合推荐   |
 
+<img src="E:\AGI\app_recipe\image\tab1.jpg" alt="tab1" style="zoom: 25%;" />
+
+
+
+<img src="E:\AGI\app_recipe\image\tab1.jpg" alt="tab1" style="zoom:25%;" />
+
+#### <img src="E:\AGI\app_recipe\image\tab1.jpg" alt="tab1" style="zoom:25%;" /
+
+<img src="E:\AGI\app_recipe\image\tab3.jpg" alt="tab3" style="zoom: 25%;" />
+
+<img src="E:\AGI\app_recipe\image\tab1.1.jpg" alt="tab1.1" style="zoom: 25%;" />
+
 #### 2. **潜在进入者**
 
 - **互联网巨头**:美团(本地生活入口优势)、字节(流量分发能力)可能通过 “外卖 + 食谱推荐” 场景切入,需构建 “设备数据 + 健康目标” 的深度绑定壁垒。

BIN
image/tab1.1.jpg


BIN
image/tab1.jpg


BIN
image/tab2.jpg


BIN
image/tab3.jpg


+ 2 - 1
myapp/angular.json

@@ -136,7 +136,8 @@
   "cli": {
     "schematicCollections": [
       "@ionic/angular-toolkit"
-    ]
+    ],
+    "analytics": false
   },
   "schematics": {
     "@ionic/angular-toolkit:component": {

+ 17 - 0
myapp/src/app/tab1/page-aichat/page-aichat-routing.module.ts

@@ -0,0 +1,17 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { PageAichatPage } from './page-aichat.page';
+
+const routes: Routes = [
+  {
+    path: '',
+    component: PageAichatPage
+  }
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
+})
+export class PageAichatPageRoutingModule {}

+ 20 - 0
myapp/src/app/tab1/page-aichat/page-aichat.module.ts

@@ -0,0 +1,20 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+
+import { IonicModule } from '@ionic/angular';
+
+import { PageAichatPageRoutingModule } from './page-aichat-routing.module';
+
+import { PageAichatPage } from './page-aichat.page';
+
+@NgModule({
+  imports: [
+    CommonModule,
+    FormsModule,
+    IonicModule,
+    PageAichatPageRoutingModule
+  ],
+  declarations: [PageAichatPage]
+})
+export class PageAichatPageModule {}

+ 57 - 0
myapp/src/app/tab1/page-aichat/page-aichat.page.html

@@ -0,0 +1,57 @@
+<!-- page-aichat.page.html -->
+<ion-header [translucent]="true">
+  <ion-toolbar class="header-bar">
+    <ion-title class="app-title">AI助手</ion-title>
+    <ion-icon name="sparkles" slot="end" class="header-icon"></ion-icon>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content [fullscreen]="true" class="chat-content">
+  <!-- 消息容器 -->
+  <div #messagesContainer class="messages-container">
+    <div 
+      *ngFor="let message of messages"
+      class="message-wrapper"
+      [class.user]="!message.isAI"
+      [@messageAnim]>
+      <div class="message-bubble">
+        <div class="message-text">{{ message.content }}</div>
+        <div class="message-time">{{ message.time }}</div>
+      </div>
+      <div class="message-status" *ngIf="!message.isAI">
+        <ion-icon 
+          [name]="message.status === 'sending' ? 'time' : 
+                  message.status === 'sent' ? 'checkmark' : 
+                  'alert-circle'" 
+          class="status-icon"></ion-icon>
+      </div>
+    </div>
+  </div>
+
+  <!-- 输入区域 -->
+  <div class="input-wrapper">
+    <div class="input-box">
+      <ion-textarea 
+        #messageInput
+        [(ngModel)]="newMessage"
+        (keyup.enter)="sendMessage()"
+        placeholder="输入消息..."
+        autoGrow
+        rows="1"
+        class="message-input"
+        [class.focused]="isInputFocused"
+        (ionFocus)="isInputFocused = true"
+        (ionBlur)="isInputFocused = false">
+      </ion-textarea>
+      <ion-button 
+        class="send-button"
+        (click)="sendMessage()"
+        [disabled]="!canSend"
+        shape="round">
+        <ion-icon 
+          [name]="canSend ? 'paper-plane' : 'send-outline'" 
+          class="send-icon"></ion-icon>
+      </ion-button>
+    </div>
+  </div>
+</ion-content>

+ 177 - 0
myapp/src/app/tab1/page-aichat/page-aichat.page.scss

@@ -0,0 +1,177 @@
+/* recipe-chat.page.scss */
+.header-bar {
+  --background: linear-gradient(135deg, #48BB78 0%, #38B2AC 100%);
+  --color: white;
+  
+  .app-title {
+    font-family: 'PingFang SC', sans-serif;
+    font-weight: 500;
+    letter-spacing: 1px;
+  }
+  
+  .header-icon {
+    font-size: 1.8em;
+    margin-right: 12px;
+    color: rgba(255,255,255,0.9);
+  }
+}
+
+.chat-content {
+  --background: #f7fafc;
+}
+
+.messages-container {
+  padding: 16px;
+  padding-bottom: 100px;
+  display: flex;
+  flex-direction: column;
+  gap: 20px;
+}
+
+.message-wrapper {
+  &.user {
+    align-self: flex-end;
+    max-width: 75%;
+    
+    .message-bubble {
+      background: white;
+      border-radius: 18px 4px 18px 18px;
+      box-shadow: 0 2px 8px rgba(0,0,0,0.1);
+      padding: 12px 16px;
+      
+      .message-text {
+        color: #2d3748;
+        font-weight: 500;
+      }
+      
+      .message-time {
+        color: #718096;
+        font-size: 12px;
+        margin-top: 4px;
+      }
+    }
+  }
+}
+
+.recipe-card {
+  background: white;
+  border-radius: 16px;
+  box-shadow: 0 4px 12px rgba(0,0,0,0.08);
+  margin: 8px 0;
+  
+  .recipe-image {
+    height: 200px;
+    object-fit: cover;
+    border-radius: 16px 16px 0 0;
+  }
+
+  .recipe-title {
+    font-size: 1.2em;
+    color: #2d3748;
+    font-weight: 600;
+  }
+
+  .section-title {
+    color: #48BB78;
+    font-weight: 500;
+    margin: 16px 0 8px;
+    font-size: 1.1em;
+  }
+
+  ion-item {
+    --padding-start: 0;
+    --inner-padding-end: 0;
+    --min-height: 40px;
+  }
+
+  .step-badge {
+    --background: #48BB78;
+    --color: white;
+    width: 24px;
+    height: 24px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+
+  .nutrition-grid {
+    display: grid;
+    grid-template-columns: repeat(3, 1fr);
+    gap: 12px;
+    margin-top: 16px;
+    
+    .nutrition-item {
+      background: #f7fafc;
+      padding: 12px;
+      border-radius: 8px;
+      text-align: center;
+      
+      ion-icon {
+        font-size: 24px;
+        color: #48BB78;
+        margin-bottom: 8px;
+      }
+      
+      div {
+        font-size: 12px;
+        color: #4a5568;
+      }
+    }
+  }
+}
+
+.input-wrapper {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  background: rgba(255,255,255,0.95);
+  backdrop-filter: blur(8px);
+  padding: 16px;
+  box-shadow: 0 -4px 20px rgba(0,0,0,0.05);
+}
+
+.input-box {
+  display: flex;
+  gap: 12px;
+  align-items: center;
+}
+
+.custom-searchbar {
+  --background: #edf2f7;
+  --border-radius: 24px;
+  --box-shadow: none;
+  flex: 1;
+  
+  &.searchbar-has-focus {
+    --background: white;
+    --box-shadow: 0 0 0 2px #48BB7833;
+  }
+}
+
+.search-button {
+  --border-radius: 50%;
+  --padding-start: 0;
+  --padding-end: 0;
+  width: 48px;
+  height: 48px;
+  --background: linear-gradient(135deg, #48BB78 0%, #38B2AC 100%);
+  
+  &:disabled {
+    opacity: 0.6;
+  }
+  
+  ion-icon {
+    color: white;
+  }
+}
+
+/* 动画 */
+@keyframes fadeIn {
+  from { opacity: 0; transform: translateY(10px); }
+  to { opacity: 1; transform: translateY(0); }
+}
+
+.recipe-card {
+  animation: fadeIn 0.5s ease-out;
+}

+ 17 - 0
myapp/src/app/tab1/page-aichat/page-aichat.page.spec.ts

@@ -0,0 +1,17 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { PageAichatPage } from './page-aichat.page';
+
+describe('PageAichatPage', () => {
+  let component: PageAichatPage;
+  let fixture: ComponentFixture<PageAichatPage>;
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(PageAichatPage);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 139 - 0
myapp/src/app/tab1/page-aichat/page-aichat.page.ts

@@ -0,0 +1,139 @@
+import { Component, OnInit, ViewChild, ElementRef, AfterViewChecked } from '@angular/core';
+import { trigger, transition, style, animate } from '@angular/animations';
+
+interface ChatMessage {
+  content: string;
+  isAI: boolean;
+  time: string;
+  status?: 'sending' | 'sent' | 'error';
+}
+
+@Component({
+  selector: 'app-page-aichat',
+  templateUrl: './page-aichat.page.html',
+  styleUrls: ['./page-aichat.page.scss'],
+  standalone: false,
+  animations: [
+    trigger('messageAnim', [
+      transition(':enter', [
+        style({ opacity: 0, transform: 'translateY(20px)' }),
+        animate('300ms cubic-bezier(0.4, 0, 0.2, 1)', 
+          style({ opacity: 1, transform: 'translateY(0)' }))
+      ])
+    ])
+  ]
+})
+export class PageAichatPage implements OnInit, AfterViewChecked {
+  @ViewChild('messagesContainer') private messagesContainer!: ElementRef;
+  @ViewChild('messageInput') messageInput!: ElementRef;
+
+  messages: ChatMessage[] = [];
+  newMessage = '';
+  isInputFocused = false;
+
+  get canSend(): boolean {
+    return this.newMessage.trim().length > 0;
+  }
+
+  ngOnInit() {
+    this.addAIMessage('您好!我是您的智能食谱助手,您可以输入食材名称,我会为您推荐相关食谱。例如:"番茄"、"鸡肉"');
+  }
+
+  ngAfterViewChecked() {
+    this.scrollToBottom();
+  }
+
+  async sendMessage() {
+    if (!this.canSend) return;
+
+    const userMessage = this.newMessage.trim();
+    this.addUserMessage(userMessage);
+    
+    // 模拟发送过程
+    await this.simulateSendDelay();
+    
+    // 添加AI回复
+    this.addAIMessage(await this.generateAIReply(userMessage));
+    
+    this.newMessage = '';
+    this.messageInput.nativeElement.focus();
+  }
+
+  private addUserMessage(content: string) {
+    this.messages.push({
+      content,
+      isAI: false,
+      time: this.getCurrentTime(),
+      status: 'sending'
+    });
+
+    // 更新发送状态
+    setTimeout(() => {
+      const index = this.messages.length - 1;
+      this.messages[index].status = Math.random() > 0.1 ? 'sent' : 'error';
+    }, 1000);
+  }
+
+  private addAIMessage(content: string) {
+    this.messages.push({
+      content,
+      isAI: true,
+      time: this.getCurrentTime()
+    });
+  }
+
+  private scrollToBottom() {
+    try {
+      setTimeout(() => {
+        this.messagesContainer.nativeElement.scrollTop = 
+          this.messagesContainer.nativeElement.scrollHeight;
+      }, 100);
+    } catch(err) { /* 处理滚动错误 */ }
+  }
+
+  private getCurrentTime(): string {
+    return new Date().toLocaleTimeString([], { 
+      hour: '2-digit', 
+      minute: '2-digit' 
+    });
+  }
+
+  private async simulateSendDelay(): Promise<void> {
+    return new Promise(resolve => setTimeout(resolve, 500));
+  }
+
+  private async generateAIReply(input: string): Promise<string> {
+    // 模拟AI回复逻辑
+    await new Promise(resolve => setTimeout(resolve, 800));
+    return this.getRecipeRecommendations(input);
+  }
+
+  private getRecipeRecommendations(input: string): string {
+    const recipes: { [key: string]: string[] } = {
+      番茄: [
+        "番茄炒蛋:将番茄切块,鸡蛋炒熟后加入番茄一起翻炒,调味即可。",
+        "番茄汤:番茄去皮切块,加水煮开后调味,可加入鸡蛋液做成番茄蛋汤。",
+        "番茄意大利面:番茄炒成酱,加入煮好的意大利面拌匀。"
+      ],
+      鸡肉: [
+        "宫保鸡丁:鸡肉切丁,与花生米、青椒等一起炒制。",
+        "香煎鸡胸肉:鸡胸肉用调料腌制后,放入锅中煎至两面金黄。",
+        "鸡汤:鸡肉加水炖煮,加入姜片、葱段等调料。"
+      ],
+      土豆: [
+        "土豆丝:土豆切成丝,清炒或酸辣口味都很不错。",
+        "土豆炖牛肉:土豆与牛肉一起炖煮,口感软糯。",
+        "薯条:土豆切成条,炸至金黄,可搭配番茄酱食用。"
+      ]
+    };
+
+    for (const [ingredient, recipeList] of Object.entries(recipes)) {
+      if (input.includes(ingredient)) {
+        const randomIndex = Math.floor(Math.random() * recipeList.length);
+        return `为您推荐使用 ${ingredient} 的食谱:${recipeList[randomIndex]}`;
+      }
+    }
+    
+    return `很抱歉,暂时没有找到与 "${input}" 相关的食谱。您可以尝试输入其他食材。`;
+  }
+}

+ 5 - 1
myapp/src/app/tab1/tab1-routing.module.ts

@@ -6,7 +6,11 @@ const routes: Routes = [
   {
     path: '',
     component: Tab1Page,
-  }
+  },
+  {
+    path: 'page-aichat',
+    loadChildren: () => import('./page-aichat/page-aichat.module').then( m => m.PageAichatPageModule)
+  },
 ];
 
 @NgModule({

+ 1 - 1
myapp/src/app/tab1/tab1.module.ts

@@ -17,4 +17,4 @@ import { Tab1PageRoutingModule } from './tab1-routing.module';
   ],
   declarations: [Tab1Page]
 })
-export class Tab1PageModule {}
+export class Tab1PageModule {}

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

@@ -13,8 +13,8 @@
 <ion-content [fullscreen]="true" class="bg-light">
   <!-- 搜索栏 -->
   <ion-card class="search-card">
-    <ion-row class="relative">
-      <ion-col size="12">
+    <ion-row class="search-row">
+      <ion-col size="10">
         <ion-input 
           class="search-input" 
           type="text" 
@@ -25,7 +25,7 @@
           aria-label="食谱搜索"
         ></ion-input>
       </ion-col>
-      <ion-col size="auto" class="absolute right-4 top-1/2 transform -translate-y-1/2">
+      <ion-col size="2">
         <ion-button 
           class="search-btn" 
           shape="round" 
@@ -101,7 +101,7 @@
         </p>
       </ion-col>
       <ion-col size="auto">
-        <ion-avatar class="user-avatar">
+        <ion-avatar class="user-avatar" (click)="goToAIChat()">
           <ion-label>M</ion-label>
         </ion-avatar>
       </ion-col>

+ 143 - 77
myapp/src/app/tab1/tab1.page.scss

@@ -1,78 +1,144 @@
-:host {
-    --ion-color-primary: #2ecc71;
-    --ion-color-primary-rgb: 46, 204, 113;
-    --ion-color-secondary: #27ae60;
-    --ion-color-secondary-rgb: 39, 174, 96;
-    --ion-color-tertiary: #f39c12;
-    --ion-color-tertiary-rgb: 243, 156, 18;
-  
-    .bg-gray-50 {
-      background-color: #f9fafb;
-    }
-  
-    .custom-header {
-      background: linear-gradient(135deg, var(--ion-color-primary) 20%, var(--ion-color-secondary) 80%);
-      box-shadow: 0 4px 12px rgba(46, 204, 113, 0.15);
-    }
-  
-    .nav-btn {
-      border: 2px solid transparent;
-      &:first-child {
-        color: white;
-        border-color: rgba(255, 255, 255, 0.2);
-      }
-      &:last-child {
-        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-      }
-    }
-  
-    .search-input {
-      background-color: white;
-      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
-      &::placeholder {
-        color: #9ca3af;
-      }
-    }
-  
-    .category-icon {
-      animation: pulse 2s infinite;
-    }
-  
-    .recipe-card-hover ion-img {
-      transition: transform 0.3s ease, opacity 0.3s ease;
-      &:hover {
-        transform: scale(1.02);
-      }
-    }
-  
-    .user-info-card {
-      box-shadow: 0 8px 24px rgba(46, 204, 113, 0.2);
-      .user-avatar {
-        box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
-      }
-    }
-  
-    @media (min-width: 768px) {
-      .search-card {
-        margin: 2rem 8rem;
-      }
-  
-      .category-grid {
-        margin: 2rem 8rem;
-      }
-  
-      .recommend-card {
-        margin: 4rem 8rem;
-      }
-  
-      .user-info-card {
-        margin: 2rem 8rem;
-      }
-    }
-  
-    @keyframes pulse {
-      0% { box-shadow: 0 0 0 0 rgba(46, 204, 113, 0.4); }
-      70% { box-shadow: 0 0 0 10px rgba(46, 204, 113, 0); }
-      100% { box-shadow: 0 0 0 0 rgba(46, 204, 113, 0); }
-    }
+/* tab1.page.scss */
+
+/* 自定义头部样式 */
+.custom-header {
+    --background: #ffffff;
+    --color: #333;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+  }
+  
+  .logo {
+    font-size: 1.5rem;
+    font-weight: bold;
+    display: flex;
+    align-items: center;
+  }
+  
+  .logo span {
+    margin-left: 0.5rem;
+  }
+  
+  .nav-btn {
+    margin-left: 0.5rem;
+    color: #333;
+  }
+  
+  /* 搜索栏样式 */
+  .search-card {
+    margin: 1rem;
+    border-radius: 0.5rem;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+  }
+  
+  .search-row {
+    align-items: center;
+  }
+  
+  .search-input {
+    border: 1px solid #ccc;
+    border-radius: 0.5rem;
+    padding: 0.5rem;
+  }
+  
+  .search-btn {
+    --background: #ff6b6b;
+    --color: white;
+  }
+  
+  /* 分类网格样式 */
+  .category-grid {
+    margin: 1rem;
+  }
+  
+  .category-card {
+    margin-bottom: 1rem;
+  }
+  
+  .card-hover {
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+    transition: box-shadow 0.3s ease;
+  }
+  
+  .card-hover:hover {
+    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
+  }
+  
+  .category-icon {
+    font-size: 2rem;
+    color: #ff6b6b;
+    margin-bottom: 0.5rem;
+  }
+  
+  .category-title {
+    font-size: 1rem;
+    font-weight: bold;
+  }
+  
+  /* 推荐食谱样式 */
+  .recommend-card {
+    margin: 1rem;
+    border-radius: 0.5rem;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+  }
+  
+  .section-title {
+    font-size: 1.2rem;
+    font-weight: bold;
+    margin-bottom: 0.5rem;
+  }
+  
+  .recipe-card {
+    margin-bottom: 1rem;
+    opacity: 0;
+    transform: translateY(20px);
+    transition: opacity 0.5s ease, transform 0.5s ease;
+  }
+  
+  .recipe-card-hover {
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+    transition: box-shadow 0.3s ease;
+  }
+  
+  .recipe-card-hover:hover {
+    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
+  }
+  
+  .recipe-title {
+    font-size: 1rem;
+    font-weight: bold;
+    margin-bottom: 0.25rem;
+  }
+  
+  .recipe-meta {
+    font-size: 0.8rem;
+    color: #666;
+  }
+  
+  /* 用户信息样式 */
+  .user-info-card {
+    margin: 1rem;
+    border-radius: 0.5rem;
+    background-color: #ff6b6b;
+    color: white;
+  }
+  
+  .greeting {
+    font-size: 1rem;
+  }
+  
+  .username {
+    font-weight: bold;
+  }
+  
+  .user-avatar {
+    width: 3rem;
+    height: 3rem;
+    background-color: white;
+    color: #ff6b6b;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    border-radius: 50%;
+    font-size: 1.5rem;
+    cursor: pointer;
   }

+ 9 - 3
myapp/src/app/tab1/tab1.page.ts

@@ -1,11 +1,12 @@
 import { Component, OnInit, Renderer2 } from '@angular/core';
 import { Router } from '@angular/router';
+import { NavController } from '@ionic/angular';
 
 @Component({
   selector: 'app-tab1',
   templateUrl: 'tab1.page.html',
   styleUrls: ['tab1.page.scss'],
-  standalone: false, // 重要:明确关闭独立组件(默认值为 false,若被误设为 true 需修正)
+  standalone: false,
 })
 export class Tab1Page implements OnInit {
   searchQuery: string = '';
@@ -23,7 +24,7 @@ export class Tab1Page implements OnInit {
     { id: 3, title: '蔬菜鸡胸肉沙拉', image: 'https://picsum.photos/300/240?random=3', time: 25, rating: 4.7 },
   ];
 
-  constructor(private router: Router, private renderer: Renderer2) {}
+  constructor(private router: Router, private renderer: Renderer2,private navCtrl: NavController) {}
 
   ngOnInit() {
     setTimeout(() => {
@@ -57,4 +58,9 @@ export class Tab1Page implements OnInit {
       this.router.navigate(['/search-results'], { queryParams: { q: query } });
     }
   }
-}
+
+  goToAIChat() {
+    this.navCtrl.navigateForward(["tabs","tab1","page-aichat"]);
+    console.log('Navigating to AI Chat');
+  }
+}

+ 65 - 8
myapp/src/app/tab3/tab3.page.html

@@ -1,17 +1,74 @@
+<!-- tab3.page.html -->
 <ion-header [translucent]="true">
-  <ion-toolbar>
-    <ion-title>
-      Tab 3
-    </ion-title>
+  <ion-toolbar class="header-bar">
+    <ion-title class="app-title">我的</ion-title>
+    <ion-icon name="leaf" slot="end" class="header-icon"></ion-icon>
   </ion-toolbar>
 </ion-header>
 
-<ion-content [fullscreen]="true">
+<ion-content [fullscreen]="true" class="profile-content">
   <ion-header collapse="condense">
     <ion-toolbar>
-      <ion-title size="large">Tab 3</ion-title>
+      <ion-title size="large">我的空间</ion-title>
     </ion-toolbar>
   </ion-header>
 
-  <app-explore-container name="Tab 3 page"></app-explore-container>
-</ion-content>
+  <!-- 用户信息 -->
+  <div class="user-section">
+    <div class="avatar-container">
+      <ion-avatar class="glow-avatar">
+        <img src="assets/avatar.png" alt="用户头像">
+      </ion-avatar>
+      <ion-badge color="success" class="id-badge">VIP3</ion-badge>
+    </div>
+    <div class="user-info">
+      <h2 class="username">美食探险家</h2>
+      <p class="user-id">ID: foodie_9527</p>
+    </div>
+  </div>
+
+  <!-- 数据卡片,使用普通 div 代替 ion-grid 和 ion-col -->
+  <div class="stats-grid">
+    <div class="stat-card history" style="display: inline-block; width: 48%;">
+      <ion-icon name="time" class="stat-icon"></ion-icon>
+      <div class="stat-content">
+        <h3>156</h3>
+        <p>历史浏览</p>
+      </div>
+    </div>
+    <div class="stat-card favorite" style="display: inline-block; width: 48%;">
+      <ion-icon name="heart" class="stat-icon"></ion-icon>
+      <div class="stat-content">
+        <h3>89</h3>
+        <p>我的收藏</p>
+      </div>
+    </div>
+  </div>
+
+  <!-- 功能菜单 -->
+  <ion-list lines="none" class="menu-list">
+    <ion-item class="menu-item" button detail (click)="handleAction('feedback')">
+      <ion-icon name="chatbubble-ellipses" slot="start" color="success"></ion-icon>
+      <ion-label>意见反馈</ion-label>
+      <ion-note>及时沟通</ion-note>
+    </ion-item>
+
+    <ion-item class="menu-item" button detail (click)="handleAction('privacy')">
+      <ion-icon name="shield-checkmark" slot="start" color="success"></ion-icon>
+      <ion-label>隐私政策</ion-label>
+      <ion-note>v2.1</ion-note>
+    </ion-item>
+
+    <ion-item class="menu-item" button detail (click)="handleAction('agreement')">
+      <ion-icon name="document-text" slot="start" color="success"></ion-icon>
+      <ion-label>用户协议</ion-label>
+      <ion-note>2024版</ion-note>
+    </ion-item>
+  </ion-list>
+
+  <!-- 版本信息 -->
+  <div class="version-section">
+    <ion-text color="medium">当前版本 2.1.0</ion-text>
+    <ion-text color="medium">© 2024 美食助手</ion-text>
+  </div>
+</ion-content>

+ 179 - 0
myapp/src/app/tab3/tab3.page.scss

@@ -0,0 +1,179 @@
+/* tab3.page.scss */
+:host {
+    --primary-green: #2ecc71;
+    --secondary-green: #27ae60;
+    --light-green: #d4efdf;
+    --text-dark: #2c3e50;
+  }
+  
+  .header-bar {
+    --background: linear-gradient(135deg, var(--primary-green) 0%, var(--secondary-green) 100%);
+    --color: white;
+  
+    .app-title {
+      font-weight: 500;
+      letter-spacing: 1px;
+    }
+  
+    .header-icon {
+      font-size: 1.8rem;
+      margin-right: 12px;
+    }
+  }
+  
+  .profile-content {
+    background: linear-gradient(var(--light-green) 30%, #ffffff 70%);
+  }
+  
+  .user-section {
+    padding: 2rem 1rem;
+    text-align: center;
+  
+    .avatar-container {
+      position: relative;
+      display: inline-block;
+  
+      .glow-avatar {
+        width: 100px;
+        height: 100px;
+        border: 3px solid white;
+        box-shadow: 0 0 20px rgba(46, 204, 113, 0.3);
+        transition: transform 0.3s ease;
+  
+        &:active {
+          transform: scale(0.95);
+        }
+      }
+  
+      .id-badge {
+        position: absolute;
+        bottom: -10px;
+        right: -10px;
+        border-radius: 15px;
+        font-size: 0.8rem;
+      }
+    }
+  
+    .user-info {
+      margin-top: 1.5rem;
+  
+      .username {
+        color: var(--text-dark);
+        margin: 0;
+        font-size: 1.4rem;
+        font-weight: 600;
+      }
+  
+      .user-id {
+        color: #7f8c8d;
+        margin: 0.3rem 0;
+        font-size: 0.9rem;
+      }
+    }
+  }
+  
+  .stats-grid {
+    padding: 0 1rem;
+  
+    .stat-card {
+      background: white;
+      border-radius: 15px;
+      //margin: 0.5rem;
+      padding: 1.2rem;
+      box-shadow: 0 4px 12px rgba(46, 204, 113, 0.1);
+      transition: all 0.3s ease;
+  
+      &:active {
+        transform: scale(0.98);
+      }
+  
+      &.history {
+        border-left: 4px solid var(--primary-green);
+        // 添加 flex 相关属性为初始值
+        flex: initial;
+        flex-grow: initial;
+        flex-shrink: initial;
+        flex-basis: initial;
+      }
+  
+      &.favorite {
+        border-left: 4px solid #e74c3c;
+        // 添加 flex 相关属性为初始值
+        flex: initial;
+        flex-grow: initial;
+        flex-shrink: initial;
+        flex-basis: initial;
+      }
+    }
+  
+    .stat-icon {
+      font-size: 2.2rem;
+      color: var(--primary-green);
+      margin-bottom: 0.8rem;
+    }
+  
+    .stat-content {
+      h3 {
+        color: var(--text-dark);
+        margin: 0;
+        font-size: 1.6rem;
+      }
+  
+      p {
+        color: #7f8c8d;
+        margin: 0.3rem 0 0;
+        font-size: 0.9rem;
+      }
+    }
+  }
+  
+  .menu-list {
+    background: transparent;
+    margin: 1.5rem 0;
+  
+    .menu-item {
+      --background-hover: #e8f8f1;
+      --border-radius: 12px;
+      margin: 0.5rem 1rem;
+      transition: transform 0.3s ease;
+  
+      ion-icon {
+        transition: transform 0.3s ease;
+      }
+  
+      &:active {
+        transform: scale(0.98);
+      }
+  
+      ion-label {
+        color: var(--text-dark);
+        font-weight: 500;
+      }
+  
+      ion-note {
+        font-size: 0.85rem;
+      }
+    }
+  }
+  
+  .version-section {
+    text-align: center;
+    padding: 2rem 1rem;
+  
+    ion-text {
+      display: block;
+      margin: 0.3rem 0;
+      font-size: 0.85rem;
+    }
+  }
+  
+  /* 动画效果 */
+  @keyframes avatarGlow {
+    0% { box-shadow: 0 0 10px rgba(46, 204, 113, 0.3); }
+    50% { box-shadow: 0 0 20px rgba(46, 204, 113, 0.5); }
+    100% { box-shadow: 0 0 10px rgba(46, 204, 113, 0.3); }
+  }
+  
+  .glow-avatar {
+    animation: avatarGlow 2s ease-in-out infinite;
+  }

+ 16 - 2
myapp/src/app/tab3/tab3.page.ts

@@ -1,3 +1,4 @@
+// tab3.page.ts
 import { Component } from '@angular/core';
 
 @Component({
@@ -8,6 +9,19 @@ import { Component } from '@angular/core';
 })
 export class Tab3Page {
 
-  constructor() {}
+  constructor() { }
 
-}
+  handleAction(type: string) {
+    switch(type) {
+      case 'feedback':
+        console.log('打开意见反馈');
+        break;
+      case 'privacy':
+        console.log('打开隐私政策');
+        break;
+      case 'agreement':
+        console.log('打开用户协议');
+        break;
+    }
+  }
+}