tab1.page.ts 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. import { Component } from '@angular/core';
  2. import { IonCardHeader, IonHeader, IonToolbar, IonTitle, IonContent, IonTabButton, IonSearchbar, IonLabel, IonItem, IonList, NavController, IonCard, IonCardTitle, IonCardSubtitle, IonCardContent, IonThumbnail } from '@ionic/angular/standalone';
  3. import { ExploreContainerComponent } from '../explore-container/explore-container.component';
  4. import { IonButton } from '@ionic/angular/standalone';
  5. import { IonIcon } from '@ionic/angular/standalone';
  6. import { Router } from '@angular/router';
  7. import { CommonModule } from '@angular/common';
  8. import { ModalController } from '@ionic/angular/standalone';
  9. import { HttpClient } from '@angular/common/http';
  10. import { addIcons } from 'ionicons';
  11. import { documentText, chatbubbles, person, calendar, newspaper,
  12. medkit,clipboard, podium, videocam, people } from 'ionicons/icons';
  13. import { CloudObject, CloudQuery, CloudUser } from 'src/lib/ncloud';
  14. import { ChatPanelOptions, FmodeChat, FmodeChatMessage, openChatPanelModal } from 'fmode-ng';
  15. import { openUserLoginModal } from 'src/lib/user/modal-user-login/modal-user-login.component';
  16. import { ArticleCardComponent } from '../component/article-card/article-card.component';
  17. addIcons({ documentText, chatbubbles, person, calendar, newspaper,
  18. medkit,clipboard, podium, videocam, people
  19. });
  20. @Component({
  21. selector: 'app-tab1',
  22. templateUrl: 'tab1.page.html',
  23. styleUrls: ['tab1.page.scss'],
  24. standalone: true,
  25. imports: [
  26. IonHeader, IonToolbar, IonTitle, IonContent, ExploreContainerComponent, IonTabButton, IonButton,
  27. IonIcon,IonSearchbar,IonLabel,IonItem,IonList,CommonModule,IonCard,IonCardHeader,IonCardTitle,IonCardSubtitle,
  28. IonCardContent, IonThumbnail,
  29. ],
  30. })
  31. export class Tab1Page {
  32. constructor(
  33. private router: Router,
  34. private modalCtrl: ModalController,
  35. // private navCtrl: NavController,
  36. private http: HttpClient // 注入 HttpClient
  37. ) {}
  38. /**
  39. * 轮播图
  40. */
  41. images = [
  42. 'https://picsum.photos/800/400?random=1',
  43. 'https://picsum.photos/800/400?random=2',
  44. 'https://picsum.photos/800/400?random=3'
  45. ];
  46. currentSlide = 0;
  47. intervalId: any;
  48. setSlidePosition() {
  49. // 这里不需要额外的逻辑,因为在 HTML 中已经通过绑定实现
  50. }
  51. nextSlide() {
  52. this.currentSlide = (this.currentSlide + 1) % this.images.length;
  53. }
  54. prevSlide() {
  55. this.currentSlide = (this.currentSlide - 1 + this.images.length) % this.images.length;
  56. }
  57. goToSlide(index: number) {
  58. this.currentSlide = index;
  59. }
  60. startAutoSlide() {
  61. this.intervalId = setInterval(() => this.nextSlide(), 3000);
  62. }
  63. ngOnDestroy() {
  64. if (this.intervalId) {
  65. clearInterval(this.intervalId);
  66. }
  67. }
  68. /**
  69. * Go to the ai page
  70. */
  71. goToPage1(){
  72. console.log(['route'])
  73. this.router.navigate(['/tabs/inquiry/ai'])
  74. }
  75. /**
  76. * Go to the human page
  77. */
  78. goToPage2(){
  79. this.router.navigate(['/tabs/inquiry/human'])
  80. }
  81. goToPicture(){
  82. console.log(['route'])
  83. this.router.navigate(['/tabs/picture'])
  84. }
  85. searchContent:string = ''; //搜索内容
  86. handleInput(ev:any) {
  87. console.log("ev.detail.value: ",ev.detail.value)
  88. this.searchContent = ev.detail.value;
  89. }
  90. search(){
  91. if (this.searchContent == ''){
  92. console.log("请输入搜索内容")
  93. }
  94. else {
  95. console.log("搜索内容: ",this.searchContent)
  96. this.searchContent = '';
  97. }
  98. }
  99. // 功能按钮数据
  100. functionItems1 = [
  101. { label: '我的健康', icon: 'document-text', route: '/tabs/my-health' },
  102. { label: '健康档案', icon: 'person', route: '/tabs/health-records' },
  103. { label: '电话问诊', icon: 'calendar', route: '/tabs/phone-inquiry' },
  104. { label: '购买药品', icon: 'medkit', route: '/tabs/drug-purchase' },
  105. ];
  106. functionItems2 = [
  107. { label: '专业男科', icon: 'clipboard', route: '/tabs/tab1' },
  108. { label: '权威专家', icon: 'podium', route: '/tabs/authority-experts' },
  109. { label: '健康资讯', icon: 'newspaper', route: '/tabs/health-information' },
  110. { label: '智慧社区', icon: 'people', route: '/tabs/smart-community' }
  111. ];
  112. doctors = [
  113. {
  114. name: '余海涛',
  115. age: 20,
  116. position: '主任医师',
  117. department: '中医草药科',
  118. hospital: '南昌市江西师范医院',
  119. desc:'中医大师,擅长用中药调养身体来根治病症',
  120. image: '../../assets/image/doctor5.png',
  121. },
  122. {
  123. name: '聂翼伏',
  124. age: 25,
  125. position: '副主任医师',
  126. department: '骨科',
  127. hospital: 'YY市人民医院',
  128. desc:'骨科专家,擅长治疗各种骨骼损伤症状',
  129. image: '../../assets/image/doctor7.png',
  130. },
  131. {
  132. name: '徐君豪',
  133. age: 28,
  134. position: '主治医师',
  135. department: '心理科',
  136. hospital: 'XX市第一医院',
  137. desc:'心理专家,擅长解决各类心理问题和疾病',
  138. image: '../../assets/image/doctor6.png',
  139. },
  140. ];
  141. // 导航到指定路由
  142. navigateTo(route: string) {
  143. this.router.navigate([route]);
  144. console.log("route: ",route)
  145. }
  146. ngOnInit() {
  147. this.loadDoctorList()
  148. this.startAutoSlide();
  149. }
  150. doctorList:Array<CloudObject> = []
  151. async loadDoctorList(){
  152. let query = new CloudQuery("Doctor");
  153. query.include("depart")
  154. this.doctorList = await query.find()
  155. }
  156. /** 示例:问诊根据doctor拼接提示词 */
  157. async openInquiry(doctor:any){
  158. // 验证用户登录
  159. let currentUser = new CloudUser();
  160. let userPrompt = ``
  161. if(!currentUser?.id){
  162. console.log("用户未登录,请登录后重试");
  163. let user = await openUserLoginModal(this.modalCtrl);
  164. if(!user?.id){
  165. return
  166. }
  167. currentUser = user;
  168. }
  169. if(currentUser?.get("realname")){
  170. userPrompt += `当前来访的患者,姓名:${currentUser?.get("realname")}`
  171. }
  172. if(currentUser?.get("gender")){
  173. userPrompt += `,性别:${currentUser?.get("gender")}`
  174. }
  175. if(currentUser?.get("age")){
  176. userPrompt += `,年龄:${currentUser?.get("age")}`
  177. }
  178. localStorage.setItem("company","E4KpGvTEto")
  179. let consult = new CloudObject("Consultation")
  180. let now = new Date();
  181. let dateStr = `${now.getFullYear()}-${now.getMonth()+1}-${now.getDate()}`
  182. // 对象权限的精确指定
  183. let ACL:any = {
  184. "*":{read:false,write:false}
  185. }
  186. if(currentUser?.id){
  187. ACL[currentUser?.id] = {read:true,write:true}
  188. }
  189. consult.set({
  190. title:`${doctor.get('depart')?.name || ""}门诊记录${dateStr}-${doctor?.get("name")}`,
  191. doctor:doctor.toPointer(),
  192. depart:{
  193. __type:"Pointer",
  194. className:"Department",
  195. objectId:doctor.get("depart")?.objectId
  196. },
  197. user:currentUser.toPointer(),
  198. ACL:ACL
  199. })
  200. let options:ChatPanelOptions = {
  201. roleId:"2DXJkRsjXK",
  202. onChatInit:(chat:FmodeChat)=>{
  203. console.log("onChatInit");
  204. console.log("预设角色",chat.role);
  205. chat.role.set("name",doctor?.get("name"));
  206. chat.role.set("title",doctor?.get("title"));
  207. chat.role.set("desc",doctor?.get("desc"));
  208. chat.role.set("tags",doctor?.get("qualifications"));
  209. chat.role.set("avatar",doctor?.get("avatar") || "../../assets/image/doctor7.png")
  210. chat.role.set("prompt",`
  211. # 角色设定
  212. 您是${doctor?.get("name")},${doctor?.get("desc")},年龄${doctor?.get("age")}岁,需要完成一次完整的门诊服务。
  213. # 对话环节
  214. 0.导诊(根据用户基本情况,引导挂号合适的科室)
  215. 1.预设的问询方式(根据不同症状来问询具体的情况)
  216. - 打招呼,以用户自述为主
  217. - 当信息充足时候,确认用户症状对应的科室,并进入下一个环节
  218. 2.拓展的问询细节
  219. 例如:用户反映呼吸不畅,拓展出:是否咳嗽;是否感觉痛或者痒等其他需要的问题。
  220. - 当问询细节补充完成后进入下一个环节
  221. 3.初步的诊断结果,并且同时列出检查检验项目
  222. 初步诊断:确定需要有哪些进一步检查
  223. 检查检验:获取医学客观数据
  224. - 等待用户提交客观数据,进入下一阶段
  225. 4.给出诊断方案并给出处方
  226. - 完成处方时,请在消息结尾附带: [处方完成]
  227. # 开始话语
  228. 当您准备好了,可以以一个医生的身份,先向来访的用户亲切地打招呼。
  229. ${userPrompt}
  230. `);
  231. },
  232. onMessage:(chat:FmodeChat,message:FmodeChatMessage)=>{
  233. console.log("onMessage",message)
  234. let content:any = message?.content
  235. if(typeof content == "string"){
  236. if(content?.indexOf("[处方完成]")>-1){
  237. console.log("门诊已完成")
  238. consult.set({
  239. content:content // 处方内容
  240. })
  241. consult.save();
  242. }
  243. }
  244. },
  245. onChatSaved:(chat:FmodeChat)=>{
  246. // chat?.chatSession?.id 本次会话的 chatId
  247. console.log("onChatSaved",chat,chat?.chatSession,chat?.chatSession?.id)
  248. }
  249. }
  250. openChatPanelModal(this.modalCtrl,options)
  251. }
  252. }