Browse Source

ai智能体

7 2 weeks ago
parent
commit
05991e7d08

+ 60 - 17
myapp/package-lock.json

@@ -22,6 +22,7 @@
         "@capacitor/keyboard": "7.0.1",
         "@capacitor/status-bar": "7.0.1",
         "@ionic/angular": "^8.0.0",
+        "axios": "^1.9.0",
         "ionicons": "^7.0.0",
         "rxjs": "~7.8.0",
         "tslib": "^2.3.0",
@@ -7109,6 +7110,12 @@
         "node": ">= 0.4"
       }
     },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+      "license": "MIT"
+    },
     "node_modules/at-least-node": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
@@ -7173,6 +7180,17 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/axios": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmmirror.com/axios/-/axios-1.9.0.tgz",
+      "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==",
+      "license": "MIT",
+      "dependencies": {
+        "follow-redirects": "^1.15.6",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
+      }
+    },
     "node_modules/axobject-query": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
@@ -7689,7 +7707,6 @@
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
       "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "es-errors": "^1.3.0",
@@ -8026,6 +8043,18 @@
         "node": ">=0.1.90"
       }
     },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "license": "MIT",
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
     "node_modules/commander": {
       "version": "2.20.3",
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -8588,6 +8617,15 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
     "node_modules/depd": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -8736,7 +8774,6 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
       "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "call-bind-apply-helpers": "^1.0.1",
@@ -9056,7 +9093,6 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
       "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">= 0.4"
@@ -9066,7 +9102,6 @@
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
       "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">= 0.4"
@@ -9083,7 +9118,6 @@
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
       "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "es-errors": "^1.3.0"
@@ -9096,7 +9130,6 @@
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
       "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "es-errors": "^1.3.0",
@@ -10055,7 +10088,6 @@
       "version": "1.15.9",
       "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
       "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
-      "dev": true,
       "funding": [
         {
           "type": "individual",
@@ -10105,6 +10137,21 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
+    "node_modules/form-data": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.2.tgz",
+      "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==",
+      "license": "MIT",
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "es-set-tostringtag": "^2.1.0",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/forwarded": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -10193,7 +10240,6 @@
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
       "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
-      "dev": true,
       "license": "MIT",
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
@@ -10267,7 +10313,6 @@
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
       "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "call-bind-apply-helpers": "^1.0.2",
@@ -10292,7 +10337,6 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
       "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "dunder-proto": "^1.0.1",
@@ -10438,7 +10482,6 @@
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
       "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">= 0.4"
@@ -10524,7 +10567,6 @@
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
       "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">= 0.4"
@@ -10537,7 +10579,6 @@
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
       "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "has-symbols": "^1.0.3"
@@ -10553,7 +10594,6 @@
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
       "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "function-bind": "^1.1.2"
@@ -12749,7 +12789,6 @@
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
       "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">= 0.4"
@@ -12866,7 +12905,6 @@
       "version": "1.52.0",
       "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
       "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">= 0.6"
@@ -12876,7 +12914,6 @@
       "version": "2.1.35",
       "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
       "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "mime-db": "1.52.0"
@@ -14668,6 +14705,12 @@
         "node": ">= 0.10"
       }
     },
+    "node_modules/proxy-from-env": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+      "license": "MIT"
+    },
     "node_modules/prr": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",

+ 1 - 0
myapp/package.json

@@ -27,6 +27,7 @@
     "@capacitor/keyboard": "7.0.1",
     "@capacitor/status-bar": "7.0.1",
     "@ionic/angular": "^8.0.0",
+    "axios": "^1.9.0",
     "ionicons": "^7.0.0",
     "rxjs": "~7.8.0",
     "tslib": "^2.3.0",

+ 43 - 0
myapp/src/app/ai-agent/ai-agent.page.html

@@ -0,0 +1,43 @@
+<ion-header [translucent]="true">
+  <ion-toolbar>
+    <ion-buttons slot="start">
+      <ion-back-button defaultHref="/tabs/tab1"></ion-back-button>
+    </ion-buttons>
+    <ion-title>智能助手</ion-title>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content [fullscreen]="true" class="ion-padding">
+  <!-- 聊天消息容器(添加滚动优化) -->
+  <div class="conversation-container">
+    <div class="message-list">
+      <!-- 用户消息 -->
+      <div *ngFor="let msg of conversation" 
+           [class.user-message]="msg.role === 'user'"
+           [class.assistant-message]="msg.role === 'assistant'"
+           class="message-item">
+        <div class="message-bubble">
+          {{ msg.content }}
+          <span class="message-time">{{ msg.time | date:'HH:mm' }}</span>
+        </div>
+      </div> <!-- 对应 *ngFor 的 message-item -->
+    </div> <!-- 对应 message-list -->
+  </div> <!-- 对应 conversation-container -->
+</ion-content>
+
+<!-- 输入区样式优化(固定底部) -->
+<ion-footer class="input-footer">
+  <ion-toolbar>
+    <ion-item class="input-item" lines="none">
+      <ion-input [(ngModel)]="userInput" 
+                 placeholder="输入您的需求,例如:'帮我总结今日新闻'" 
+                 class="input-field"
+                 (keyup.enter)="sendMessage()"></ion-input>
+      <ion-button class="send-button" 
+                  (click)="sendMessage()" 
+                  [disabled]="!userInput.trim()">
+        <ion-icon name="send" slot="icon-only"></ion-icon>
+      </ion-button>
+    </ion-item>
+  </ion-toolbar>
+</ion-footer>

+ 86 - 0
myapp/src/app/ai-agent/ai-agent.page.scss

@@ -0,0 +1,86 @@
+/* 聊天消息容器 */
+.conversation-container {
+  height: calc(100vh - 140px); /* 调整高度计算 */
+  overflow-y: auto;
+  padding: 16px;  /* 增加内边距 */
+  -webkit-overflow-scrolling: touch;  /* 优化移动端滚动 */
+}
+
+/* 消息列表布局 */
+.message-list {
+  display: flex;
+  flex-direction: column;
+  gap: 18px;  /* 增加消息间距 */
+}
+
+/* 单条消息布局 */
+.message-item {
+  display: flex;
+  &.user-message {
+    justify-content: flex-end;
+  }
+  &.assistant-message {
+    justify-content: flex-start;
+  }
+}
+
+/* 消息气泡样式 */
+.message-bubble {
+  max-width: 75%;  /* 增大最大宽度 */
+  padding: 12px 18px;
+  border-radius: 18px;  /* 更圆润的边角 */
+  line-height: 1.6;
+  position: relative;
+  box-shadow: 0 2px 6px rgba(0,0,0,0.08);  /* 添加柔和阴影 */
+  
+  &.user-message {
+    background: #2196F3;  /* 蓝色调用户消息 */
+    color: white;
+    border-bottom-right-radius: 4px;  /* 右下直角设计 */
+  }
+  
+  &.assistant-message {
+    background: #ffffff;  /* 白色助手消息 */
+    color: #333;
+    border-bottom-left-radius: 4px;  /* 左下直角设计 */
+  }
+
+  /* 消息时间戳样式 */
+  .message-time {
+    display: block;
+    font-size: 12px;
+    opacity: 0.8;
+    margin-top: 4px;
+    text-align: right;  /* 用户消息时间右对齐 */
+  }
+  &.assistant-message .message-time {
+    text-align: left;  /* 助手消息时间左对齐 */
+  }
+}
+
+/* 输入区样式 */
+.input-footer {
+  --ion-toolbar-background: #f5f7fa;  /* 浅灰背景 */
+  border-top: 1px solid #e0e0e0;  /* 顶部分割线 */
+}
+
+.input-item {
+  --background: white;
+  border-radius: 28px;
+  margin: 12px 16px;
+  padding: 4px 16px;
+  box-shadow: 0 1px 3px rgba(0,0,0,0.05);  /* 输入框阴影 */
+}
+
+.send-button {
+  --padding-start: 12px;
+  --padding-end: 12px;
+  --border-radius: 24px;
+  --background: #2196F3;
+  color: white;
+  transition: transform 0.2s ease;
+  
+  &:hover {
+    transform: scale(1.08);  /* 悬停放大效果 */
+  }
+}

+ 84 - 0
myapp/src/app/ai-agent/ai-agent.page.ts

@@ -0,0 +1,84 @@
+import { Component, ViewChild, ElementRef } from '@angular/core';  /* 新增ViewChild */
+import { IonicModule } from '@ionic/angular';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+
+@Component({
+  selector: 'app-ai-agent',
+  templateUrl: './ai-agent.page.html',
+  styleUrls: ['./ai-agent.page.scss'],
+  standalone: true,
+  imports: [IonicModule, CommonModule, FormsModule]
+})
+export class AiAgentPage {
+  userInput: string = '';
+  conversation: { role: 'user' | 'assistant'; content: string; time: Date }[] = [];  /* 新增time字段 */
+  @ViewChild('conversationContainer') conversationContainer!: ElementRef;  /* 获取消息容器引用 */
+
+  async sendMessage() {
+    if (!this.userInput.trim()) return;
+
+    // 添加用户消息(包含时间戳)
+    const currentTime = new Date();
+    this.conversation.push({ 
+      role: 'user', 
+      content: this.userInput, 
+      time: currentTime 
+    });
+    this.userInput = '';
+    this.scrollToBottom();  /* 滚动到最新消息 */
+
+    // 调用大模型API(示例,需替换为实际接口)
+    try {
+      // 请替换为正确的 DeepSeek API 地址和模型名称
+      const response = await fetch('https://api.deepseek.com/chat/completions', {
+        method: 'POST',
+        headers: {
+          'Content-Type': 'application/json',
+          // 修改授权头部格式,添加 Bearer 前缀
+          'Authorization': `Bearer sk-433e23f9bfcc4d6989987a177e33dfad`
+        },
+        body: JSON.stringify({
+          // 请替换为 DeepSeek 支持的模型名称
+          model: 'deepseek-chat', 
+          messages: this.conversation.map(msg => ({
+            role: msg.role,
+            content: msg.content
+          }))
+        })
+      });
+
+      // 检查响应状态
+      if (!response.ok) {
+        const errorText = await response.text();
+        throw new Error(`API 请求失败,状态码: ${response.status}, 错误信息: ${errorText}`);
+      }
+
+      const data = await response.json();
+      if (data.choices?.[0]?.message) {
+        // 添加当前时间戳
+        this.conversation.push({
+          role: 'assistant',
+          content: data.choices[0].message.content,
+          time: new Date()
+        });
+      }
+    } catch (error) {
+      console.error('大模型请求失败:', error);
+      // 添加当前时间戳
+      this.conversation.push({
+        role: 'assistant',
+        content: '抱歉,当前无法为您提供服务。',
+        time: new Date()
+      });
+    }
+  }
+
+  // 自动滚动到聊天底部
+  private scrollToBottom(): void {
+    setTimeout(() => {
+      const container = this.conversationContainer.nativeElement;
+      container.scrollTop = container.scrollHeight;
+    }, 100);  /* 延迟确保DOM更新完成 */
+  }
+}

+ 4 - 3
myapp/src/app/app-routing.module.ts

@@ -1,5 +1,6 @@
 import { NgModule } from '@angular/core';
 import { PreloadAllModules, RouterModule, Routes } from '@angular/router';
+import { AiAgentPage } from './ai-agent/ai-agent.page';
 
 const routes: Routes = [
   {
@@ -14,8 +15,7 @@ const routes: Routes = [
     path: 'tab5',
     loadChildren: () => import('./tab5/tab5.module').then( m => m.Tab5PageModule)
   },
-  
-  
+  { path: 'ai-agent', component: AiAgentPage }
 ];
 @NgModule({
   imports: [
@@ -23,4 +23,5 @@ const routes: Routes = [
   ],
   exports: [RouterModule]
 })
-export class AppRoutingModule {}
+export class AppRoutingModule { }
+

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

@@ -38,17 +38,20 @@
     </ion-card>
   </div>
 
+
   <!-- 服务九宫格 -->
   <div class="services-grid">
     <ion-grid>
       <ion-row>
-        <ion-col size="6" *ngFor="let service of services">  <!-- 修改为每行2个服务 -->
-          <div class="service-card">
+        <ion-col *ngFor="let service of services" size="4" class="service-item">
+          <!-- 添加data-service-id属性用于样式区分 -->
+          <ion-button (click)="handleServiceClick(service.id)" fill="clear" [attr.data-service-id]="service.id">
             <div class="icon-container">
-              <ion-icon [name]="service.icon" size="large"></ion-icon>  <!-- 增大图标 -->
+              <ion-icon [name]="service.icon"></ion-icon>
             </div>
             <ion-label>{{ service.name }}</ion-label>
-          </div>
+            <ion-badge *ngIf="service.badge > 0">{{ service.badge }}</ion-badge>
+          </ion-button>
         </ion-col>
       </ion-row>
     </ion-grid>
@@ -93,3 +96,4 @@
     <div class="assistant-mouth"></div>
   </div>
 </div>
+

+ 94 - 3
myapp/src/app/tab1/tab1.page.scss

@@ -93,10 +93,102 @@ ion-content {
     }
   }
   
+  /* 服务九宫格 */
   /* 服务九宫格 */
   .services-grid {
-    padding: 16px 8px;
+    padding: 16px 12px;
     
+    ion-grid {
+      gap: 12px; /* 增加格子间距 */
+    }
+  
+    .service-item {
+      ion-button {
+        --padding-top: 12px;
+        --padding-bottom: 12px;
+        border-radius: 14px; /* 更圆润的边角 */
+        background: #ffffff;
+        box-shadow: 0 3px 8px rgba(0, 0, 0, 0.08); /* 更柔和的阴影 */
+        transition: all 0.2s ease;
+        min-height: 100px; /* 统一高度 */
+        width: 100%; /* 占满列宽度 */
+  
+        &:hover {
+          transform: translateY(-2px); /* 悬停上移效果 */
+          box-shadow: 0 5px 12px rgba(0, 0, 0, 0.12);
+        }
+  
+        // 已有的紧急求助和代买药品颜色
+        &[data-service-id="emergency"] {
+          background: linear-gradient(135deg, #ff6b6b, #ff9a9a);
+          ion-icon { color: #ffffff; }
+          ion-label { 
+            color: #ffffff;
+            white-space: normal; /* 允许文字换行 */
+            line-height: 1.3; /* 调整行高让文字两行显示 */
+          }
+        }
+        &[data-service-id="medicine"] {
+          background: linear-gradient(135deg, #42a5f5, #64b5f6);
+          ion-icon { color: #ffffff; }
+          ion-label { color: #ffffff; }
+        }
+        // 新增积分商城之后的颜色
+        &[data-service-id="shop"] {
+          background: linear-gradient(135deg, #ffb74d, #ffcc80); /* 橙色渐变 */
+          ion-icon { color: #ffffff; }
+          ion-label { 
+            color: #ffffff;
+            white-space: normal; /* 保持原有换行效果 */
+            line-height: 1.3;
+          }
+        }
+        // 新增工具借用、老人陪聊、AI管家颜色
+&[data-service-id="tools"] {
+  background: linear-gradient(135deg, #458cee, #2951d2); /* 蓝色渐变 */
+  ion-icon { color: #ffffff; }
+  ion-label { 
+    color: #ffffff;
+    white-space: normal; /* 允许文字换行 */
+    line-height: 1.3;
+  }
+}
+&[data-service-id="chat"] {
+  background: linear-gradient(135deg, #ff69b4, #ff80ab); /* 粉色渐变 */
+  ion-icon { color: #ffffff; }
+  ion-label { 
+    color: #ffffff;
+    white-space: normal; 
+    line-height: 1.3;
+  }
+}
+&[data-service-id="ai"] {
+  background: linear-gradient(135deg, #4dd0e1, #80deea); /* 青色渐变 */
+  ion-icon { color: #ffffff; }
+  ion-label { 
+    color: #ffffff;
+    white-space: normal; 
+    line-height: 1.3;
+  }
+}
+        &[data-service-id="events"] {
+          background: linear-gradient(135deg, #66bb6a, #81c784); /* 绿色渐变 */
+          ion-icon { color: #ffffff; }
+          ion-label { color: #ffffff; }
+        }
+        &[data-service-id="skills"] {
+          background: linear-gradient(135deg, #ba68c8, #ce93d8); /* 紫色渐变 */
+          ion-icon { color: #ffffff; }
+          ion-label { color: #ffffff; }
+        }
+        &[data-service-id="my"] {
+          background: linear-gradient(135deg, #90a4ae, #b0bec5); /* 灰色渐变 */
+          ion-icon { color: #ffffff; }
+          ion-label { color: #ffffff; }
+        }
+      }
+    }
+  }
     .service-card {
       display: flex;
       flex-direction: column;
@@ -162,8 +254,7 @@ ion-content {
       ion-label {
         font-size: 12px;
         text-align: center;
-      }
-    }
+      }  // 此处为正确闭合的大括号,若第227行是额外的`}`需删除
   }
   
   /* 社区动态信息流 */

+ 25 - 2
myapp/src/app/tab1/tab1.page.ts

@@ -1,6 +1,7 @@
 import { Component, OnInit, Renderer2, ElementRef, Input } from '@angular/core';
 import { ModalController, AnimationController, NavController } from '@ionic/angular';
 import { IonicModule } from '@ionic/angular';
+import { Router } from '@angular/router'; // 新增Router导入
 
 // 独立的紧急模态组件
 @Component({
@@ -154,7 +155,8 @@ export class Tab1Page implements OnInit {
     private renderer: Renderer2,
     private el: ElementRef,
     private animationCtrl: AnimationController,
-    private navCtrl: NavController
+    private navCtrl: NavController,
+    private router: Router // 新增Router依赖注入
   ) {}
 
   ngOnInit() {
@@ -273,4 +275,25 @@ export class Tab1Page implements OnInit {
   goDynamic(dynamic?: string) {
     this.navCtrl.navigateForward(["tab1", "dynamic"]);
   }
-}
+
+  // 处理服务项点击
+  handleServiceClick(serviceId: string) {
+    switch (serviceId) {
+      case 'ai':
+        this.navigateToAiAgent(); // AI管家导航
+        break;
+      case 'emergency':
+        this.openEmergencyModal(); // 紧急求助模态框
+        break;
+      // 其他服务可补充对应逻辑
+    }
+  }
+
+  // 跳转到AI管家页面方法
+  navigateToAiAgent() {
+    this.router.navigate(['/ai-agent']); // 使用Router进行导航
+  }
+} // 此处为 Tab1Page 类的正确闭合
+
+// 原错误代码块已删除(错误的 @Component 装饰器及内部方法)
+