浏览代码

Merge branch 'master' of http://git.fmode.cn:3000/yuebuzu/s202226701018

惊鸿戏梦 4 月之前
父节点
当前提交
163fb2c5f3

二进制
MY-WEB/.DS_Store


+ 2 - 1
wisdom-app/src/app/page/page-create-agent/page-create-agent.component.ts

@@ -211,8 +211,9 @@ export class PageCreateAgentComponent  implements OnInit {
   
   agentList: Array<CloudObject> = [];
   async loadAgentData() {
-    let objectId = this.currentUser.get('objectId')
+    let user = new CloudUser();
     let query = new CloudQuery("DoctorAgent")
+    query.equalTo("user",user?.id)
     let agentlist = await query.find()
     // 将查询到的数据反向排序
     this.agentList = agentlist.reverse()

+ 53 - 17
wisdom-app/src/app/page/page-my-health/page-my-health.component.html

@@ -1,7 +1,18 @@
 <ion-header [translucent]="true">
   <ion-toolbar class="searchbar">
-      <ion-button slot="start" (click)="backHome()" color="primary">{{back}}</ion-button>
-      <ion-title slot="end">我的每次问询记录</ion-title>
+    <ion-button slot="start" (click)="backHome()" color="primary">{{back}}</ion-button>
+    <ion-title>
+      <div class="user-info">
+        <ion-avatar class="user-avatar">
+          <img [src]="avatar" (error)="handleImageError()" alt="用户头像" class="avatar" />
+        </ion-avatar>
+        <span class="user-name">欢迎,{{ userName }}!</span>
+      </div>
+      我的每次问询记录
+    </ion-title>
+    <ion-buttons slot="end">
+      <ion-icon name="menu-outline"></ion-icon>
+    </ion-buttons>
   </ion-toolbar>
 </ion-header>
 
@@ -9,19 +20,44 @@
   <ion-refresher slot="fixed" (ionRefresh)="handleRefresh($event)">
     <ion-refresher-content></ion-refresher-content>
   </ion-refresher>
-  <div>
-    <!-- <p>尊敬的用户:{{currentUser?.data[realname]}},您好!</p> -->
-     <ion-card *ngFor="let message of allMessage">
-       <ion-card-header>
-         <ion-card-title>就诊时间:{{message?.updatedAt}}</ion-card-title>
-       </ion-card-header>
-       <ion-card-content>
-        <p>就诊医生{{message.data["doctor"]?.name}}</p>
-        <p>就诊部门{{message.data["depart"]?.name}}</p>
-        <p>门诊名称{{message.data["title"]}}</p>
-        <p>就诊内容{{message.data["content"]}}</p>
-        <!-- <fm-markdown-preview class="content-style" [content]="responseMsg"></fm-markdown-preview> -->
-       </ion-card-content>
-     </ion-card>
+
+  <!-- 数据加载指示器 -->
+  <ion-spinner *ngIf="isLoading" name="crescent" class="loading-spinner"></ion-spinner>
+
+  <!-- 数据展示区域 -->
+
+  <div *ngIf="!isLoading && allMessage.length === 0" class="no-data">
+    <ion-icon name="folder-open-outline" style="font-size: 50px; color: #888;"></ion-icon>
+    <p>暂无问询记录,赶快去咨询医生吧!</p>
+  </div>
+
+  <ion-list *ngIf="!isLoading && allMessage.length > 0">
+    <ion-item *ngFor="let message of allMessage" lines="none">
+      <ion-card class="message-card">
+        <ion-card-header>
+          <ion-card-title>就诊时间: {{ message?.updatedAt | date:'short' }}</ion-card-title>
+        </ion-card-header>
+        <ion-card-content>
+          <ion-icon name="person-outline" slot="start"></ion-icon>
+          <p><strong>就诊医生:</strong> {{ message.data["doctor"]?.name }}</p>
+          <ion-icon name="business-outline" slot="start"></ion-icon>
+          <p><strong>就诊部门:</strong> {{ message.data["depart"]?.name }}</p>
+          <ion-icon name="medical-outline" slot="start"></ion-icon>
+          <p><strong>门诊名称:</strong> {{ message.data["title"] }}</p>
+          <ion-icon name="document-text-outline" slot="start"></ion-icon>
+          <p><strong>就诊内容:</strong> {{ message.data["content"] }}</p>
+        </ion-card-content>
+      </ion-card>
+    </ion-item>
+  </ion-list>
+
+  <!-- 无数据提示 -->
+  <div *ngIf="!isLoading && allMessage.length === 0" class="no-data">
+    <p>暂无问询记录。</p>
+  </div>
+
+  <!-- 错误提示 -->
+  <div *ngIf="!isLoading && errorMessage" class="error-message">
+    <p>{{ errorMessage }}</p>
   </div>
-</ion-content>
+</ion-content>

+ 97 - 0
wisdom-app/src/app/page/page-my-health/page-my-health.component.scss

@@ -0,0 +1,97 @@
+.searchbar {
+    --background: #ffffff;
+    --ion-color-primary: #3880ff;
+  }
+  
+  .user-info {
+    display: flex;
+    align-items: center;
+    background: linear-gradient(to right, #f8fafc, #58f083);
+    padding: 10px;
+    border-radius: 8px;
+  }
+  
+  .user-avatar {
+    width: 50px;
+    height: 50px;
+    margin-right: 10px;
+  }
+  
+  .user-avatar img.avatar {
+    width: 100%;
+    height: 100%;
+    border-radius: 50%;
+  }
+  
+  .user-name {
+    font-size: 20px;
+    font-weight: bold;
+    color: #3880ff;
+    margin-left: 10px;
+  }
+  
+  .user-details {
+    text-align: center;
+    margin: 10px 0;
+  }
+  
+  .loading-spinner {
+    display: block;
+    margin: 50px auto;
+  }
+  
+  .message-card {
+    margin: 15px;
+    border-radius: 10px;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
+    background: #f9f9f9;
+    transition: transform 0.2s;
+  }
+  .message-card:hover {
+    transform: scale(1.03);
+  }
+  .message-card ion-card-header {
+    background: #e7effb;
+    padding: 10px;
+    border-radius: 10px 10px 0 0;
+  }
+  
+  .message-card ion-card-title {
+    font-size: 16px;
+    font-weight: bold;
+  }
+  
+  .message-card ion-card-content p {
+    margin: 5px 0;
+    font-size: 14px;
+  }
+  
+  .no-data {
+    text-align: center;
+    margin-top: 50px;
+    color: gray;
+    font-size: 16px;
+  }
+  
+  .error-message {
+    text-align: center;
+    margin-top: 50px;
+    color: red;
+    font-size: 16px;
+  }
+
+  .ion-icon {
+    margin-right: 8px;
+    color: #3880ff;
+  }
+
+  .loading-spinner {
+    display: block;
+    margin: 50px auto;
+    animation: spin 2s linear infinite;
+  }
+  
+  @keyframes spin {
+    0% { transform: rotate(0deg); }
+    100% { transform: rotate(360deg); }
+  }

+ 129 - 41
wisdom-app/src/app/page/page-my-health/page-my-health.component.ts

@@ -1,68 +1,156 @@
-import { Component, NgModule, OnInit } from '@angular/core';
-import { ModalController, IonModal, IonHeader, IonToolbar, IonTitle, IonContent, IonList, IonItem, IonLabel, IonAvatar, IonButton, IonSegment, IonSegmentButton, IonSegmentContent, IonSegmentView, IonCardContent, IonCardTitle, IonCardHeader, IonCard, IonIcon, IonButtons, IonInput, IonRefresherContent, IonRefresher } from '@ionic/angular/standalone';
+import { Component, OnInit } from '@angular/core';
+import {
+  ModalController,
+  IonModal,
+  IonHeader,
+  IonToolbar,
+  IonTitle,
+  IonContent,
+  IonList,
+  IonItem,
+  IonLabel,
+  IonAvatar,
+  IonButton,
+  IonSegment,
+  IonSegmentButton,
+  IonSegmentContent,
+  IonSegmentView,
+  IonCardContent,
+  IonCardTitle,
+  IonCardHeader,
+  IonCard,
+  IonIcon,
+  IonButtons,
+  IonInput,
+  IonRefresherContent,
+  IonRefresher,
+  LoadingController,
+  IonSpinner,
+  IonGrid,        // 导入 IonGrid
+  IonRow,         // 导入 IonRow
+  IonCol          // 导入 IonCol
+} from '@ionic/angular/standalone'; // 确保导入自 '@ionic/angular/standalone'
+
 import { addIcons } from 'ionicons';
-import { airplane, bluetooth, call, wifi } from 'ionicons/icons';
+import { airplane, bluetooth, call, wifi, arrowBackOutline, menuOutline, personOutline, businessOutline, medicalOutline, documentTextOutline, folderOpenOutline } from 'ionicons/icons';
 import { CommonModule } from '@angular/common';
 import { CloudObject, CloudQuery, CloudUser } from 'src/lib/ncloud';
 // import { FmMarkdownPreview } from 'fmode-ng';
 import { Router } from '@angular/router';
 addIcons({ airplane, bluetooth, call, wifi });
+
 @Component({
   selector: 'page-my-health',
   templateUrl: './page-my-health.component.html',
   styleUrls: ['./page-my-health.component.scss'],
   standalone: true,
-    imports: [
-      IonHeader, IonToolbar, IonTitle, IonContent,
-      IonLabel,IonItem,IonList,IonAvatar,CommonModule,IonButton,
-      IonSegment, IonSegmentButton,
-      IonSegmentContent,IonSegmentView,IonCardContent, IonCardTitle, IonCardHeader,IonCard,
-      IonModal,IonIcon, IonButtons,IonInput,IonRefresher,IonRefresherContent
-      // FmMarkdownPreview,
-    ]
+  imports: [
+    IonHeader,
+    IonToolbar,
+    IonTitle,
+    IonContent,
+    IonLabel,
+    IonItem,
+    IonList,
+    IonAvatar,
+    CommonModule,
+    IonButton,
+    IonSegment,
+    IonSegmentButton,
+    IonSegmentContent,
+    IonSegmentView,
+    IonCardContent,
+    IonCardTitle,
+    IonCardHeader,
+    IonCard,
+    IonModal,
+    IonIcon,
+    IonButtons,
+    IonInput,
+    IonRefresher,
+    IonRefresherContent,
+    IonSpinner,
+    IonGrid,        // 添加 IonGrid 到 imports
+    IonRow,         // 添加 IonRow 到 imports
+    IonCol          // 添加 IonCol 到 imports
+    // FmMarkdownPreview,
+  ]
 })
-export class PageMyHealthComponent  implements OnInit {
-  handleRefresh(event:any) {
-    setTimeout(() => {
-      // Any calls to load data go here
-      this.loadData();
-      event.target.complete();
-    }, 2000);
-  }
+export class PageMyHealthComponent implements OnInit {
+  allMessage: Array<CloudObject> = [];
+  isLoading: boolean = false;
+  errorMessage: string = "";
 
-  avatar : string = "../assets/imgs/avatar.png";
-  currentUser : CloudUser | undefined ;
-  objectId : string = "";
+  avatar: string = "../assets/imgs/avatar.png"; // 默认头像
+  currentUser: CloudUser | undefined;
+  objectId: string = "";
+  userName: string = "";
+
+  back: string = "back";
+
+  // 备用头像 URL
+  fallbackAvatarUrl: string = 'https://app.fmode.cn/dev/jxnu/202226701019/头像示例.png';
 
   constructor(
-    private router: Router
+    private router: Router,
+    private loadingController: LoadingController
   ) {
     this.currentUser = new CloudUser();
-    this.avatar = this.currentUser.data["avatar"];
+    this.avatar = this.currentUser.data["avatar"] || this.fallbackAvatarUrl;
     this.objectId = this.currentUser.data['objectId'];
+    this.userName = this.currentUser.data["realname"] || "用户";
   }
-  allMessage : Array<CloudObject> = [];
 
-  async loadData(){
-    let user = new CloudUser();
-    console.log("objectId",this.objectId);
-    let query = new CloudQuery('Consultation');
-    query.include("doctor","depart");
-    query.equalTo("user",user?.id);
-    // 根据用户id查询, 其中用户id字段是指针,指向User表中的objectId
-    // query.equalTo("user",{ "__type": "Pointer", "className": "_User", "objectId": this.objectId });
-    this.allMessage = await query.find();
-    console.log("allMessage",this.allMessage);
-  }
-   
   ngOnInit() {
     this.loadData();
   }
-  back:string = "back"
-  backHome(){
+
+  async loadData() {
+    this.isLoading = true;
+    const loading = await this.loadingController.create({
+      message: '加载中...',
+    });
+    await loading.present();
+
+    try {
+      let user = new CloudUser();
+      console.log("objectId", this.objectId);
+      let query = new CloudQuery('Consultation');
+      query.include("doctor", "depart");
+      query.equalTo("user", { "__type": "Pointer", "className": "_User", "objectId": this.objectId });
+
+      const messages = await query.find();
+      console.log("allMessage", messages);
+
+      this.allMessage = messages;
+    } catch (error) {
+      console.error("加载数据失败:", error);
+      this.errorMessage = "数据加载失败,请稍后再试。";
+    } finally {
+      this.isLoading = false;
+      await loading.dismiss();
+    }
+  }
+
+  handleRefresh(event: any) {
+    setTimeout(() => {
+      this.allMessage = [];
+      this.loadData().then(() => {
+        event.target.complete();
+      });
+    }, 2000);
+  }
+
+  backHome() {
     this.router.navigate(['/tabs/tab1']);
   }
-  gotouser(){
 
+  gotouser() {
+    // 用户相关逻辑
+  }
+
+  // 处理图片加载错误,设置备用图片
+  handleImageError() {
+    this.avatar = this.fallbackAvatarUrl;
   }
-}
+}

+ 94 - 88
wisdom-app/src/app/tab3/tab3.page.html

@@ -1,5 +1,3 @@
-<!-- tab3.page.html -->
-
 <ion-header [translucent]="true">
   <ion-toolbar class="custom-toolbar">
     <ion-title class="custom-title">
@@ -11,103 +9,111 @@
 <ion-content [fullscreen]="true" class="content-background">
   <!-- 搜索栏 -->
   <ion-searchbar 
-  placeholder="搜索" 
-  class="custom-searchbar" 
-  (ionInput)="searchProducts($event)">
-</ion-searchbar>
+    placeholder="搜索" 
+    class="custom-searchbar" 
+    (ionInput)="searchProducts($event)">
+  </ion-searchbar>
 
- <!-- 分类区域(可横向滑动) -->
-<div class="category-scroll">
-  <div class="category-scroll-inner">
-    <ion-grid>
-      <ion-row class="category-row">
-        <ion-col 
-          size="3" 
-          size-sm="3" 
-          size-md="3" 
-          size-lg="3" 
-          size-xl="3" 
-          *ngFor="let category of categories" 
-          class="category-col">
-          <div class="category-item" (click)="onCategoryClick(category)">
-            <div class="category-image-wrapper">
-              <img [src]="category.image" alt="{{category.name}}" class="category-image">
+  <!-- 分类区域(可横向滑动) -->
+  <div class="category-scroll">
+    <div class="category-scroll-inner">
+      <ion-grid>
+        <ion-row class="category-row">
+          <ion-col 
+            size="3" 
+            size-sm="3" 
+            size-md="3" 
+            size-lg="3" 
+            size-xl="3" 
+            *ngFor="let category of categories" 
+            class="category-col">
+            <div class="category-item" (click)="onCategoryClick(category)">
+              <div class="category-image-wrapper">
+                <img [src]="category.image" alt="{{category.name}}" class="category-image">
+              </div>
+              <div class="category-text">{{ category.name }}</div>
             </div>
-            <div class="category-text">{{ category.name }}</div>
-          </div>
+          </ion-col>
+        </ion-row>
+      </ion-grid>
+    </div>
+  </div>
+
+  <!-- 热销模块 -->
+  <div class="marketing-section">
+    <h2>热销🔥🔥🔥</h2>
+    <ion-grid>
+      <ion-row>
+        <ion-col size="6" size-md="4" size-lg="3" *ngFor="let product of hotProducts | slice:0:4">
+          <ion-card class="product-card" (click)="openDetailModal(product)">
+            <ion-card-header class="product-card-header">
+              <div class="product-tag">{{ product.get('title') || '热销🔥🔥🔥' }}</div>
+            </ion-card-header>
+            <ion-card-content class="product-card-content">
+              <div class="product-image-wrapper">
+                <img [src]="product.get('image')" alt="{{product.get('name')}}" class="product-image">
+              </div>
+              <div class="product-info">
+                <h3 class="product-name">{{ product.get('name') }}</h3>
+                <div class="product-price">{{ product.get('price') }}</div>
+              </div>
+            </ion-card-content>
+          </ion-card>
         </ion-col>
       </ion-row>
     </ion-grid>
-  </div>
-</div>
-
-<!-- 热销模块 -->
-<div class="marketing-section">
-  <h2>热销🔥🔥🔥</h2>
-  <div class="product-container">
-    <ng-container *ngFor="let product of hotProducts | slice:0:2">
-      <ion-card class="product-card" (click)="openDetailModal(product)">
-        <ion-card-header class="product-card-header">
-          <div class="product-tag">{{ product.get('title') || '热销🔥🔥🔥' }}</div>
-        </ion-card-header>
-        <ion-card-content class="product-card-content">
-          <div class="product-image-wrapper">
-            <img [src]="product.get('image')" alt="{{product.get('name')}}" class="product-image">
-          </div>
-          <div class="product-info">
-            <h3 class="product-name">{{ product.get('name') }}</h3>
-            <div class="product-price">{{ product.get('price') }}</div>
-          </div>
-        </ion-card-content>
-      </ion-card>
-    </ng-container>
     <ion-button fill="clear" (click)="viewMore('hot')">查看更多</ion-button>
   </div>
-</div>
 
-<!-- 特价模块 -->
-<div class="marketing-section">
-  <h2>特价优惠💰💰💰</h2>
-  <div class="product-container">
-    <ng-container *ngFor="let product of specialProducts | slice:0:2">
-      <ion-card class="product-card" (click)="openDetailModal(product)">
-        <ion-card-header class="product-card-header">
-          <div class="product-tag">{{ product.get('title') || '特价优惠💰💰💰' }}</div>
-        </ion-card-header>
-        <ion-card-content class="product-card-content">
-          <div class="product-image-wrapper">
-            <img [src]="product.get('image')" alt="{{product.get('name')}}" class="product-image">
-          </div>
-          <div class="product-info">
-            <h3 class="product-name">{{ product.get('name') }}</h3>
-            <div class="product-price">{{ product.get('price') }}</div>
-          </div>
-        </ion-card-content>
-      </ion-card>
-    </ng-container>
+  <!-- 特价模块 -->
+  <div class="marketing-section">
+    <h2>特价优惠💰💰💰</h2>
+    <ion-grid>
+      <ion-row>
+        <ion-col size="6" size-md="4" size-lg="3" *ngFor="let product of specialProducts | slice:0:4">
+          <ion-card class="product-card" (click)="openDetailModal(product)">
+            <ion-card-header class="product-card-header">
+              <div class="product-tag">{{ product.get('title') || '特价优惠💰💰💰' }}</div>
+            </ion-card-header>
+            <ion-card-content class="product-card-content">
+              <div class="product-image-wrapper">
+                <img [src]="product.get('image')" alt="{{product.get('name')}}" class="product-image">
+              </div>
+              <div class="product-info">
+                <h3 class="product-name">{{ product.get('name') }}</h3>
+                <div class="product-price">{{ product.get('price') }}</div>
+              </div>
+            </ion-card-content>
+          </ion-card>
+        </ion-col>
+      </ion-row>
+    </ion-grid>
     <ion-button fill="clear" (click)="viewMore('special')">查看更多</ion-button>
   </div>
-</div>
 
-<!-- 商品卡片列表区域 -->
-<div class="product-container">
-  <ng-container *ngFor="let product of products">
-    <ion-card class="product-card" (click)="openDetailModal(product)">
-      <ion-card-header class="product-card-header">
-        <div class="product-tag">{{ product.get('title') || '药品详情' }}</div>
-      </ion-card-header>
-      <ion-card-content class="product-card-content">
-        <div class="product-image-wrapper">
-          <img [src]="product.get('image')" alt="{{product.get('name')}}" class="product-image">
-        </div>
-        <div class="product-info">
-          <h3 class="product-name">{{ product.get('name') }}</h3>
-          <div class="product-price">{{ product.get('price') }}</div>
-        </div>
-      </ion-card-content>
-    </ion-card>
-  </ng-container>
-</div>
+  <!-- 商品卡片列表区域 -->
+  <div class="product-container">
+    <ion-grid>
+      <ion-row>
+        <ion-col size="6" size-md="4" size-lg="3" *ngFor="let product of products">
+          <ion-card class="product-card" (click)="openDetailModal(product)">
+            <ion-card-header class="product-card-header">
+              <div class="product-tag">{{ product.get('title') || '药品详情' }}</div>
+            </ion-card-header>
+            <ion-card-content class="product-card-content">
+              <div class="product-image-wrapper">
+                <img [src]="product.get('image')" alt="{{product.get('name')}}" class="product-image">
+              </div>
+              <div class="product-info">
+                <h3 class="product-name">{{ product.get('name') }}</h3>
+                <div class="product-price">{{ product.get('price') }}</div>
+              </div>
+            </ion-card-content>
+          </ion-card>
+        </ion-col>
+      </ion-row>
+    </ion-grid>
+  </div>
 
   <!-- 底部弹出模态 -->
   <ion-modal [isOpen]="showDetailModal" cssClass="bottom-modal" backdropDismiss="true" (ionModalDidDismiss)="closeDetailModal()">

+ 10 - 11
wisdom-app/src/app/tab3/tab3.page.scss

@@ -98,11 +98,11 @@
 .product-card {
   border-radius: 12px;
   box-shadow: 0 2px 8px rgba(0,0,0,0.08);
-  margin-bottom: 16px;
+  margin: 8px 0; /* 调整上下间距 */
 }
 
 .product-card-header {
-  background: #ffeb3b;
+  background: #348ef5;
   border-top-left-radius: 12px;
   border-top-right-radius: 12px;
   display: flex;
@@ -118,29 +118,28 @@
 
 .product-card-content {
   display: flex;
-  align-items: center;
+  flex-direction: column; /* 竖直排列图片和信息 */
+  align-items: center; /* 居中对齐 */
   padding: 12px;
 }
 
 .product-image-wrapper {
-  width: 80px;
-  height: 80px;
+  width: 100%;
+  height: 120px; /* 增大图片高度以适应网格布局 */
   border-radius: 8px;
   overflow: hidden;
-  margin-right: 12px;
+  margin-bottom: 12px; /* 增加底部间距 */
 }
 
 .product-image {
   width: 100%;
   height: 100%;
-  /* object-fit: cover; */
+  object-fit: cover;
 }
 
 .product-info {
-  flex: 1;
-  display: flex;
-  flex-direction: column;
-  justify-content: center;
+  width: 100%;
+  text-align: center; /* 居中对齐文本 */
 }
 
 .product-name {

+ 1 - 1
wisdom-app/src/app/tab4/tab4.page.ts

@@ -67,7 +67,7 @@ export class Tab4Page {
     }
   }
   logout(){
-    this.pageNum=0;
+    // this.pageNum=0;
     this.currentUser?.logout();
   }