Browse Source

保存、展示历史对话

yf 3 months ago
parent
commit
ee20a3b041

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

@@ -27,35 +27,44 @@
   <!-- 数据展示区域 -->
 
   <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)">
         <ion-card-header>
-          <ion-card-title>就诊时间: {{ message?.updatedAt | date:'short' }}</ion-card-title>
+          <ion-card-title>
+            就诊时间: {{ consultation?.updatedAt | date:'short' }}
+          </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'}">
+              <ion-icon [name]="getIcon(msg.role)" slot="start" class="consultation-icon"></ion-icon>
+              <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>

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

@@ -1,97 +1,128 @@
 .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;
+}
+
+.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: 32px; /* 设置更大的字体大小 */
+  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);
+  }
 }