Forráskód Böngészése

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

yuebuzu-creater 4 hónapja
szülő
commit
4c2364c7a3

+ 19 - 11
wisdom-app/src/app/page/inquiry-human/inquiry-human.component.html

@@ -62,9 +62,8 @@
       </ion-item>
     </ion-card>
   </div>
-  
 
-  <!-- 底部弹出模态 -->
+  <!-- 医生详情模态框 -->
   <ion-modal [isOpen]="isModalOpen" cssClass="bottom-modal">
     <ng-template>
       <ion-header>
@@ -72,7 +71,6 @@
           <ion-buttons slot="start">
             <ion-button (click)="closeDetailModal()">关闭</ion-button>
           </ion-buttons>
-          <!-- <ion-title>{{}}</ion-title> -->
           <ion-buttons slot="end">
             <ion-button>分享</ion-button>
           </ion-buttons>
@@ -80,8 +78,8 @@
       </ion-header>
 
       <ion-content class="ion-padding">
-        <div >
-          <ion-card class="first" >
+        <div>
+          <ion-card class="first">
             <div class="doctor-header1" style="display: flex; background-color: rgb(213, 205, 144); border-radius: 5px;">
               <div class="verification-badge" *ngIf="doctor.isVerified">
                 <ion-icon name="checkmark-circle"></ion-icon>
@@ -118,7 +116,6 @@
                     <span>接诊量 {{doctor.consultations}}</span>
                   </div>
                   <div class="service">
-                    <!-- <span>{{doctor.rating}}</span> -->
                     <span>服务态度好</span>
                   </div>
                 </div>
@@ -142,12 +139,12 @@
             </div>
           </ion-card>
         </div>
-        <div class="aa"  style="display: flex;">
+        <div class="aa" style="display: flex;">
           <p class="aaa">保证医生真实</p>
           <p class="aaa">未使用随时退</p>
           <p class="aaa">不满意可申诉</p>
         </div>
-        <div class="consult-options" >
+        <div class="consult-options">
           <div class="option-grid">
             <div class="option-item" 
                  *ngFor="let option of options"
@@ -179,10 +176,10 @@
         </div>
         <div class="info" style="margin:0 20px;box-shadow: 1px 1px 1px 0px rgba(0, 0, 0, 0.163), -1px -1px 1px 0px rgba(0, 0, 0, 0.148);">
           <div style="margin: 5px 10px;">
-            <h1 >擅长与简介</h1>
+            <h1>擅长与简介</h1>
           </div>
           <div style="margin: 5px 10px;">
-            <p style="color: grey;"> {{doctor.expertise}}</p>
+            <p style="color: grey;">{{doctor.expertise}}</p>
           </div>
         </div>
       </ion-content>
@@ -191,5 +188,16 @@
       </ion-footer>
     </ng-template>
   </ion-modal>
-</ion-content>>
 
+  <!-- 新增收款码模态框 -->
+  <ion-modal [isOpen]="isPaymentModalOpen" cssClass="payment-modal" (ionBackdropTap)="closePaymentModal()">
+    <ng-template>
+      <ion-content class="ion-padding payment-content">
+        <div class="payment-codes">
+          <img src="../../../assets/image/paya.png" alt="收款码A" class="payment-image">
+          <img src="../../../assets/image/payb.png" alt="收款码B" class="payment-image">
+        </div>
+      </ion-content>
+    </ng-template>
+  </ion-modal>
+</ion-content>

+ 257 - 241
wisdom-app/src/app/page/inquiry-human/inquiry-human.component.scss

@@ -1,287 +1,303 @@
 .ioncard {
-    margin: 16px;
-    box-shadow: none;
-    border: 1px solid #eee;
+  margin: 16px;
+  box-shadow: none;
+  border: 1px solid #eee;
+}
+
+.doctor-header {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  
+  h2 {
+    margin: 0;
+    font-size: 18px;
+    font-weight: bold;
   }
+}
+
+.hospital-info {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  font-size: 14px;
+  color: #666;
+}
+
+.expertise {
+  font-size: 14px;
+  display: -webkit-box;
+  -webkit-box-orient: vertical;
+  overflow: hidden;
+}
+
+.stats {
+  display: flex;
+  gap: 16px;
+  font-size: 14px;
   
-  .doctor-header {
+  div {
     display: flex;
     align-items: center;
-    gap: 8px;
-    
-    h2 {
-      margin: 0;
-      font-size: 18px;
-      font-weight: bold;
-    }
+    gap: 4px;
   }
-  
-  .doctor-info {
-    margin: 4px 0;
+}
+
+.consultation-types {
+  display: flex;
+  gap: 8px;
+  overflow-x: auto;
+  
+  ion-button {
+    --padding-start: 16px;
+    --padding-end: 16px;
+    height: 32px;
     font-size: 14px;
-    color: #666;
-    
-    span {
-      margin-right: 8px;
-    }
   }
-  
-  .hospital-info {
+}
+
+.first {
+  margin: 5px 16px;
+  padding: 12px;
+  box-shadow: none;
+  border: 1px solid #eee;
+}
+
+.doctor-header1 {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 12px;
+  font-size: 12px;
+  color: #666;
+
+  .verification-badge {
     display: flex;
     align-items: center;
-    gap: 8px;
-    font-size: 14px;
-    color: #666;
-  }
-  
-  .expertise {
-    font-size: 14px;
-    display: -webkit-box;
-    // -webkit-line-clamp: 2;
-    -webkit-box-orient: vertical;
-    overflow: hidden;
-  }
-  
-  .stats {
-    display: flex;
-    gap: 16px;
-    font-size: 14px;
+    gap: 4px;
     
-    div {
-      display: flex;
-      align-items: center;
-      gap: 4px;
+    ion-icon {
+      color: #52c41a;
     }
   }
+}
+
+.doctor-info1 {
+  display: flex;
+  justify-content: space-between;
   
-  .consultation-types {
-    display: flex;
-    gap: 8px;
-    overflow-x: auto;
+  .left-section {
+    flex: 1;
     
-    ion-button {
-      --padding-start: 16px;
-      --padding-end: 16px;
-      height: 32px;
-      font-size: 14px;
-    }
-  }
-
+    .name-title {
+      display: flex;
+      align-items: center;
+      gap: 8px;
+      margin-bottom: 8px;
 
+      h2 {
+        margin: 0;
+        font-size: 16px;
+        font-weight: 500;
+      }
 
+      ion-badge {
+        --padding-start: 4px;
+        --padding-end: 4px;
+      }
+    }
 
-  .first {
-    margin: 5px 16px;
-    padding: 12px;
-    box-shadow: none;
-    border: 1px solid #eee;
-  }
-  
-  .doctor-header1 {
-    display: flex;
-    justify-content: space-between;
-    margin-bottom: 12px;
-    font-size: 12px;
-    color: #666;
-  
-    .verification-badge {
+    .position, .hospital {
       display: flex;
       align-items: center;
-      gap: 4px;
-      
-      ion-icon {
-        color: #52c41a;
-      }
+      gap: 8px;
+      margin-bottom: 6px;
+      color: #666;
+      font-size: 14px;
     }
-  }
-  
-  .doctor-info1 {
-    display: flex;
-    justify-content: space-between;
-    
-    .left-section {
-      flex: 1;
-      
-      .name-title {
-        display: flex;
-        align-items: center;
-        gap: 8px;
-        margin-bottom: 8px;
-  
-        h2 {
-          margin: 0;
-          font-size: 16px;
-          font-weight: 500;
-        }
-  
-        ion-badge {
-          --padding-start: 4px;
-          --padding-end: 4px;
-        }
-      }
-  
-      .position, .hospital {
-        display: flex;
-        align-items: center;
-        gap: 8px;
-        margin-bottom: 6px;
-        color: #666;
-        font-size: 14px;
-      }
-  
-      .stats {
+
+    .stats {
+      display: flex;
+      align-items: center;
+      gap: 16px;
+      margin: 8px 0;
+      font-size: 14px;
+
+      .rating {
         display: flex;
         align-items: center;
-        gap: 16px;
-        margin: 8px 0;
-        font-size: 14px;
-  
-        .rating {
-          display: flex;
-          align-items: center;
-          gap: 4px;
-          
-          .number {
-            color: #f90;
-            font-weight: 500;
-          }
-        }
-      }
-  
-      .tags {
-        color: blue;
-        display: flex;
-        flex-wrap: wrap;
-        gap: 8px;
+        gap: 4px;
         
-        ion-chip {
-          margin: 0;
-          height: 24px;
-          --background: rgb(0, 255, 0);
-          --color: #666;
+        .number {
+          color: #f90;
+          font-weight: 500;
         }
       }
     }
-  
-    .right-section {
+
+    .tags {
+      color: blue;
       display: flex;
-      flex-direction: column;
-      align-items: center;
+      flex-wrap: wrap;
       gap: 8px;
-      margin-left: 16px;
-  
-      ion-avatar {
-        width: 64px;
-        height: 64px;
-      }
-  
-      ion-button {
-        --border-color: #666;
+      
+      ion-chip {
+        margin: 0;
+        height: 24px;
+        --background: rgb(0, 255, 0);
         --color: #666;
-        font-size: 12px;
       }
     }
   }
-  .aa{
-    margin: 2px auto;
-    padding: 0;
-  }
-  .aaa{
-    font-size: 12px;
-    color: gray;
-    margin-top: 0px;
-    margin-right: 15px;
-    margin-left: 35px;
-  }
 
-  .consult-options {
-    padding: 16px;
-    background: #fff;
-    margin: 0 10px
-  }
-  
-  .option-grid {
-    display: grid;
-    grid-template-columns: repeat(5, 1fr);
-    gap: 12px;
+  .right-section {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    gap: 8px;
+    margin-left: 16px;
+
+    ion-avatar {
+      width: 64px;
+      height: 64px;
+    }
+
+    ion-button {
+      --border-color: #666;
+      --color: #666;
+      font-size: 12px;
+    }
   }
-  
-  .option-item {
-    position: relative;
-    border: 1px solid #e8e8e8;
-    border-radius: 8px;
-    padding: 12px;
-    cursor: pointer;
-    transition: all 0.3s;
-  
-    &.selected {
-      border-color: var(--ion-color-primary);
-      background-color: var(--ion-color-primary-tint);
-  
-      .icon-wrapper {
-        ion-icon {
-          color: var(--ion-color-primary);
-        }
-      }
-  
-      .title {
+}
+
+.aa{
+  margin: 2px auto;
+  padding: 0;
+}
+.aaa{
+  font-size: 12px;
+  color: gray;
+  margin-top: 0px;
+  margin-right: 15px;
+  margin-left: 35px;
+}
+
+.consult-options {
+  padding: 16px;
+  background: #fff;
+  margin: 0 10px;
+}
+
+.option-grid {
+  display: grid;
+  grid-template-columns: repeat(5, 1fr);
+  gap: 12px;
+}
+
+.option-item {
+  position: relative;
+  border: 1px solid #e8e8e8;
+  border-radius: 8px;
+  padding: 12px;
+  cursor: pointer;
+  transition: all 0.3s;
+
+  &.selected {
+    border-color: var(--ion-color-primary);
+    background-color: var(--ion-color-primary-tint);
+
+    .icon-wrapper {
+      ion-icon {
         color: var(--ion-color-primary);
       }
     }
-  
-    &.disabled {
-      opacity: 0.6;
-      cursor: not-allowed;
-  
-      .icon-wrapper ion-icon {
-        color: #999;
-      }
-  
-      .title {
-        color: #999;
-      }
+
+    .title1 {
+      color: var(--ion-color-primary);
     }
   }
-  
-  .option-content {
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-    text-align: center;
-  }
-  
-  .icon-wrapper {
-    position: relative;
-    margin-bottom: 8px;
-  
-    ion-icon {
-      font-size: 24px;
-      color: #666;
+
+  &.disabled {
+    opacity: 0.6;
+    cursor: not-allowed;
+
+    .icon-wrapper ion-icon {
+      color: #999;
     }
-  
-    .check-icon {
-      position: absolute;
-      top: -4px;
-      right: -4px;
-      font-size: 16px;
-      color: var(--ion-color-primary);
-      background: #fff;
-      border-radius: 50%;
+
+    .title1 {
+      color: #999;
     }
   }
-  
-  .title1 {
-    font-size: 14px;
-    color: #333;
-    margin-bottom: 4px;
+}
+
+.option-content {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  text-align: center;
+}
+
+.icon-wrapper {
+  position: relative;
+  margin-bottom: 8px;
+
+  ion-icon {
+    font-size: 24px;
+    color: #666;
   }
-  
-  .price {
-    font-size: 12px;
+
+  .check-icon {
+    position: absolute;
+    top: -4px;
+    right: -4px;
+    font-size: 16px;
     color: var(--ion-color-primary);
+    background: #fff;
+    border-radius: 50%;
   }
-  
-  .status {
-    font-size: 12px;
-    color: #999;
-  }
+}
+
+.title1 {
+  font-size: 14px;
+  color: #333;
+  margin-bottom: 4px;
+}
+
+.price {
+  font-size: 12px;
+  color: var(--ion-color-primary);
+}
+
+.status {
+  font-size: 12px;
+  color: #999;
+}
+
+/* 新增收款码模态框样式 */
+.payment-modal {
+  --width: 80%;
+  --max-width: 400px;
+  --height: auto;
+  --border-radius: 12px;
+}
+
+.payment-content {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  flex-direction: column;
+}
+
+.payment-codes {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  gap: 16px;
+}
+
+.payment-image {
+  width: 200px; // 根据实际需要调整尺寸
+  height: auto;
+  border: 1px solid #ddd;
+  border-radius: 8px;
+}

+ 44 - 28
wisdom-app/src/app/page/inquiry-human/inquiry-human.component.ts

@@ -1,13 +1,14 @@
 import { Component, OnInit } from '@angular/core';
-import { IonModal, IonHeader, IonToolbar, IonTitle, IonContent, IonList, IonItem, IonLabel, IonAvatar, IonButton, IonChip, IonIcon, IonBadge, IonText, IonCard, IonSegmentButton, IonSegment, IonCol, IonRow, IonGrid, IonButtons, IonFooter } from '@ionic/angular/standalone';
+import { IonModal, IonHeader, IonToolbar, IonTitle, IonContent, IonList, IonItem, IonLabel, IonAvatar, IonButton, IonChip, IonIcon, IonBadge, IonText, IonCard, IonSegmentButton, IonSegment, IonCol, IonRow, IonGrid, IonButtons, IonFooter, ToastController } from '@ionic/angular/standalone';
 import { ExploreContainerComponent } from '../../explore-container/explore-container.component';
 import { addIcons } from 'ionicons';
-import { airplane, bluetooth, call, wifi } from 'ionicons/icons';
+import { airplane, bluetooth, call, wifi, star, checkmarkCircle } from 'ionicons/icons';
 import { Router } from '@angular/router';
 import { CommonModule } from '@angular/common';
 import { FormsModule } from '@angular/forms';
 
 addIcons({ airplane, bluetooth, call, wifi });
+
 interface Doctor {
   avatar: string;
   name: string;
@@ -29,6 +30,7 @@ interface Doctor {
   isVerified?: boolean;
   isExpert?: boolean;
 }
+
 interface ConsultOption {
   id: number;
   title: string;
@@ -45,13 +47,13 @@ interface ConsultOption {
   styleUrls: ['./inquiry-human.component.scss'],
   standalone: true,
   imports: [
-    IonHeader, IonToolbar, IonTitle, IonContent, ExploreContainerComponent,CommonModule,
-    IonLabel,IonItem,IonList,IonAvatar,IonLabel,IonButton,IonChip,IonIcon,IonBadge,
-    IonText,IonCard,IonSegment,IonSegmentButton, FormsModule,IonCol,IonRow,IonGrid,
-    IonModal,IonButtons,IonFooter
+    IonHeader, IonToolbar, IonTitle, IonContent, ExploreContainerComponent, CommonModule,
+    IonLabel, IonItem, IonList, IonAvatar, IonButton, IonChip, IonIcon, IonBadge,
+    IonText, IonCard, IonSegment, IonSegmentButton, FormsModule, IonCol, IonRow, IonGrid,
+    IonModal, IonButtons, IonFooter
   ]
 })
-export class InquiryHumanComponent  implements OnInit {
+export class InquiryHumanComponent implements OnInit {
   options: ConsultOption[] = [
     {
       id: 1,
@@ -95,38 +97,31 @@ export class InquiryHumanComponent  implements OnInit {
       isAvailable: false
     }
   ];
+
   selectOption(option: ConsultOption) {
     if (!option.isAvailable) return;
-    
     this.options.forEach(opt => opt.isSelected = false);
     option.isSelected = true;
   }
 
-
-
   isModalOpen = false;
-  doctor: any;    
-
-  openDetailModal(doctor?: any) {
-    this.isModalOpen = true;
-    this.doctor = doctor;
-  }
-  closeDetailModal() {
-    this.isModalOpen = false;
-    this.doctor = null;
-  }
+  isPaymentModalOpen = false; // 新增状态变量
+  doctor: any;
 
   constructor(
-    private router: Router
-  ) { }
+    private router: Router,
+    private toastController: ToastController // 注入 ToastController
+  ) {
+      addIcons({star,checkmarkCircle}); }
 
-  ngOnInit() {}
-  back:string = "<";
+  ngOnInit() { }
+
+  back: string = "<";
   backhome(){
     this.router.navigate(['/tabs/tab1']);
   }
   selectedSegment = '全部';
-  segments = ['全部', '妇科', '儿科', '科', '内科',];
+  segments = ['全部', '妇科', '儿科', '皮肤性病科', '内科',];
   
   doctors: Doctor[] = [
     {
@@ -219,7 +214,28 @@ export class InquiryHumanComponent  implements OnInit {
     this.selectedSegment = event.detail.value;
     console.log(this.selectedSegment);
   }
-  openConsult(){
-    console.log("openConsult");
+
+  async openConsult(){
+    const selectedOption = this.options.find(option => option.isSelected);
+    if (!selectedOption) {
+      // 显示 Toast 提示用户选择咨询方式
+      const toast = await this.toastController.create({
+        message: '请先选择咨询方式',
+        duration: 2000,
+        position: 'bottom'
+      });
+      toast.present();
+      return;
+    }
+
+    if (selectedOption.title === '图文咨询' || selectedOption.title === '电话咨询') {
+      this.isPaymentModalOpen = true;
+    } else {
+      // 处理其他选项(如需要)
+    }
+  }
+
+  closePaymentModal() {
+    this.isPaymentModalOpen = false;
   }
-}
+}

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

@@ -27,35 +27,48 @@
   <!-- 数据展示区域 -->
 
   <div *ngIf="!isLoading && allMessage.length === 0" class="no-data">
-    <ion-icon name="folder-open-outline" style="font-size: 50px; color: #888;"></ion-icon>
+    <ion-icon name="folder-open-outline" class="no-data-icon"></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-item *ngFor="let consultation of allMessage" lines="none">
+      <ion-card class="message-card" (click)="toggleConsultation(consultation.id)" [attr.aria-expanded]="isConsultationExpanded(consultation.id)">
         <ion-card-header>
-          <ion-card-title>就诊时间: {{ message?.updatedAt | date:'short' }}</ion-card-title>
+          <ion-card-title>
+            就诊时间: {{ consultation?.updatedAt | date:'short' }}
+            <ion-icon 
+              [name]="isConsultationExpanded(consultation.id) ? 'chevron-up-outline' : 'chevron-down-outline'" 
+              class="toggle-icon">
+            </ion-icon>
+          </ion-card-title>
+          <p><strong>问诊编号:</strong> {{ consultation.id }}</p> <!-- 显示编号 -->
         </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-icon name="person-outline" slot="start" class="consultation-icon"></ion-icon>
+          <p class="card-text"><strong>就诊医生:</strong> {{ consultation.data["doctor"]?.name }}</p>
+          <ion-icon name="business-outline" slot="start" class="consultation-icon"></ion-icon>
+          <p class="card-text"><strong>就诊部门:</strong> {{ consultation.data["depart"]?.name }}</p>
+          <ion-icon name="medical-outline" slot="start" class="consultation-icon"></ion-icon>
+          <p class="card-text"><strong>门诊名称:</strong> {{ consultation.data["title"] }}</p>
+          <ion-icon name="document-text-outline" slot="start" class="consultation-icon"></ion-icon>
+          <p class="card-text"><strong>对话记录:</strong></p>
+          
+          <!-- 根据展开状态显示对话内容 -->
+          <div *ngIf="isConsultationExpanded(consultation.id)">
+            <!-- 遍历 allContent,跳过前两个系统消息 -->
+            <div *ngFor="let msg of consultation.data['allContent'] | slice:2" 
+                 class="conversation-message" 
+                 [ngClass]="{'user-message': msg.role === 'user', 'assistant-message': msg.role === 'assistant'}">
+              <!-- 移除对话中的图标 -->
+              <p class="message-text"><strong>{{ getRoleLabel(msg.role) }}:</strong> {{ msg.content }}</p>
+            </div>
+          </div>
         </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>

+ 134 - 96
wisdom-app/src/app/page/page-my-health/page-my-health.component.scss

@@ -1,97 +1,135 @@
 .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); }
-  }
+  --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: 24px; /* 增大字体 */
+  font-weight: bold;
+  color: #3880ff;
+  margin-left: 10px;
+}
+
+.loading-spinner {
+  display: block;
+  margin: 50px auto;
+  animation: spin 2s linear infinite;
+}
+
+.message-card {
+  margin: 15px;
+  border-radius: 10px;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
+  background: #f9f9f9;
+  transition: transform 0.2s;
+  cursor: pointer; /* 添加鼠标指针样式 */
+  width: 100%; /* 确保卡片宽度一致 */
+}
+
+.message-card:hover {
+  transform: scale(1.03);
+}
+
+.message-card ion-card-header {
+  background: #e7effb;
+  padding: 15px; /* 增大内边距 */
+  border-radius: 10px 10px 0 0;
+}
+
+.message-card ion-card-title {
+  font-size: 20px; /* 增大字体 */
+  font-weight: bold;
+  display: flex;
+  align-items: center;
+}
+
+.toggle-icon {
+  margin-left: auto;
+  font-size: 24px; /* 增大切换图标 */
+}
+
+.message-card ion-card-content p {
+  margin: 10px 0; /* 增大间距 */
+  font-size: 16px; /* 增大字体 */
+}
+
+.card-text {
+  font-size: 16px; /* 增大字体 */
+}
+
+.message-text {
+  font-size: 16px; /* 增大字体 */
+}
+
+.no-data {
+  text-align: center;
+  margin-top: 50px;
+  color: gray;
+  font-size: 18px; /* 增大字体 */
+}
+
+.no-data-icon {
+  font-size: 60px; /* 增大图标 */
+  color: #888;
+}
+
+.error-message {
+  text-align: center;
+  margin-top: 50px;
+  color: red;
+  font-size: 18px; /* 增大字体 */
+}
+
+/* 放大所有咨询相关图标,并保持相同大小 */
+.consultation-icon {
+  font-size: 40px; /* 设置更大的字体大小 */
+  margin-right: 12px; /* 增大图标间距 */
+  color: #3880ff;
+}
+
+/* 对话消息样式 */
+.conversation-message {
+  display: flex;
+  align-items: center;
+  margin-top: 10px; /* 增大间距 */
+}
+
+.conversation-message p {
+  margin: 0;
+  padding: 8px 12px; /* 增大内边距 */
+  border-radius: 5px;
+  font-size: 16px; /* 增大字体 */
+}
+
+.user-message p {
+  background-color: #e1f5fe; /* 病人消息背景色 */
+}
+
+.assistant-message p {
+  background-color: #ffe0b2; /* 医生消息背景色 */
+}
+
+@keyframes spin {
+  0% { transform: rotate(0deg); }
+  100% { transform: rotate(360deg); }
+}

+ 120 - 13
wisdom-app/src/app/page/page-my-health/page-my-health.component.ts

@@ -26,19 +26,56 @@ import {
   IonRefresher,
   LoadingController,
   IonSpinner,
-  IonGrid,        // 导入 IonGrid
-  IonRow,         // 导入 IonRow
-  IonCol          // 导入 IonCol
+  IonGrid,
+  IonRow,
+  IonCol
 } from '@ionic/angular/standalone'; // 确保导入自 '@ionic/angular/standalone'
 
 import { addIcons } from 'ionicons';
 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 });
 
+// 定义对话消息的接口
+interface Message {
+  role: 'user' | 'assistant' | string;
+  content: string;
+}
+
+// 定义医生信息的接口
+interface Doctor {
+  name: string;
+  // 根据实际情况添加其他属性,例如:
+  // title: string;
+  // desc: string;
+  // qualifications: string[];
+  // avatar?: string;
+}
+
+// 定义部门信息的接口
+interface Depart {
+  name: string;
+  // 根据实际情况添加其他属性,例如:
+  // description: string;
+}
+
+// 定义 Consultation 数据的接口
+interface ConsultationData {
+  doctor: Doctor;
+  depart: Depart;
+  title: string;
+  allContent: Message[];
+}
+
+// 定义 Consultation 对象的接口
+interface Consultation {
+  id: string; // 确保为 string 类型
+  updatedAt: Date;
+  data: ConsultationData;
+}
+
 @Component({
   selector: 'page-my-health',
   templateUrl: './page-my-health.component.html',
@@ -70,14 +107,15 @@ addIcons({ airplane, bluetooth, call, wifi });
     IonRefresher,
     IonRefresherContent,
     IonSpinner,
-    IonGrid,        // 添加 IonGrid 到 imports
-    IonRow,         // 添加 IonRow 到 imports
-    IonCol          // 添加 IonCol 到 imports
+    IonGrid,
+    IonRow,
+    IonCol
+    // 如果需要,可以取消注释以下行
     // FmMarkdownPreview,
   ]
 })
 export class PageMyHealthComponent implements OnInit {
-  allMessage: Array<CloudObject> = [];
+  allMessage: Consultation[] = []; // 使用 Consultation 接口
   isLoading: boolean = false;
   errorMessage: string = "";
 
@@ -91,13 +129,16 @@ export class PageMyHealthComponent implements OnInit {
   // 备用头像 URL
   fallbackAvatarUrl: string = 'https://app.fmode.cn/dev/jxnu/202226701019/头像示例.png';
 
+  // 用于跟踪展开的问诊记录 ID
+  expandedConsultations: Set<string> = new Set<string>();
+
   constructor(
     private router: Router,
     private loadingController: LoadingController
   ) {
     this.currentUser = new CloudUser();
     this.avatar = this.currentUser.data["avatar"] || this.fallbackAvatarUrl;
-    this.objectId = this.currentUser.data['objectId'];
+    this.objectId = this.currentUser.data['objectId'] ?? ''; // 使用空字符串作为默认值
     this.userName = this.currentUser.data["realname"] || "用户";
   }
 
@@ -105,6 +146,9 @@ export class PageMyHealthComponent implements OnInit {
     this.loadData();
   }
 
+  /**
+   * 加载问诊数据
+   */
   async loadData() {
     this.isLoading = true;
     const loading = await this.loadingController.create({
@@ -113,8 +157,6 @@ export class PageMyHealthComponent implements OnInit {
     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 });
@@ -122,7 +164,17 @@ export class PageMyHealthComponent implements OnInit {
       const messages = await query.find();
       console.log("allMessage", messages);
 
-      this.allMessage = messages;
+      // 映射数据到 Consultation 接口,确保 id 为 string
+      this.allMessage = messages.map(message => ({
+        id: message.id ?? 'unknown', // 如果 id 为 null 或 undefined,则使用 'unknown'
+        updatedAt: new Date(message.updatedAt), // 确保 updatedAt 为 Date 类型
+        data: {
+          doctor: message.data["doctor"],
+          depart: message.data["depart"],
+          title: message.data["title"],
+          allContent: Array.isArray(message.data["allContent"]) ? message.data["allContent"] : []
+        }
+      }));
     } catch (error) {
       console.error("加载数据失败:", error);
       this.errorMessage = "数据加载失败,请稍后再试。";
@@ -132,6 +184,10 @@ export class PageMyHealthComponent implements OnInit {
     }
   }
 
+  /**
+   * 处理下拉刷新
+   * @param event 下拉刷新事件
+   */
   handleRefresh(event: any) {
     setTimeout(() => {
       this.allMessage = [];
@@ -141,16 +197,67 @@ export class PageMyHealthComponent implements OnInit {
     }, 2000);
   }
 
+  /**
+   * 返回首页
+   */
   backHome() {
     this.router.navigate(['/tabs/tab1']);
   }
 
+  /**
+   * 跳转到用户页面
+   */
   gotouser() {
     // 用户相关逻辑
   }
 
-  // 处理图片加载错误,设置备用图片
+  /**
+   * 处理图片加载错误,设置备用图片
+   */
   handleImageError() {
     this.avatar = this.fallbackAvatarUrl;
   }
+
+  /**
+   * 根据角色获取标签
+   * @param role 角色标识
+   * @returns 角色标签
+   */
+  getRoleLabel(role: string): string {
+    if (role === 'user') return '病人';
+    if (role === 'assistant') return '医生';
+    return role;
+  }
+
+  /**
+   * 根据角色获取图标名称
+   * @param role 角色标识
+   * @returns 图标名称
+   */
+  getIcon(role: string): string {
+    if (role === 'user') return 'person-outline';
+    if (role === 'assistant') return 'medkit';
+    return 'person-outline';
+  }
+
+  /**
+   * 切换问诊记录的展开状态
+   * @param consultationId 问诊记录的 ID
+   */
+  toggleConsultation(consultationId: string) {
+    if (this.expandedConsultations.has(consultationId)) {
+      this.expandedConsultations.delete(consultationId);
+    } else {
+      this.expandedConsultations.add(consultationId);
+    }
+  }
+
+  /**
+   * 检查问诊记录是否展开
+   * @param consultationId 问诊记录的 ID
+   * @returns 是否展开
+   */
+  isConsultationExpanded(consultationId: string): boolean {
+    return this.expandedConsultations.has(consultationId);
+  }
 }

BIN
wisdom-app/src/assets/image/paya.png


BIN
wisdom-app/src/assets/image/payb.png