tab1.page.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. import { Component } from '@angular/core';
  2. import { IonCardHeader, IonHeader, IonToolbar, IonTitle, IonContent, IonTabButton, IonSearchbar, IonLabel, IonItem, IonList, NavController, IonCard, IonCardTitle, IonCardSubtitle, IonCardContent, IonThumbnail, IonRippleEffect, IonFab, IonFabList, IonFabButton, IonBadge } 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, chevronForwardOutline,
  13. add} from 'ionicons/icons';
  14. import { CloudObject, CloudQuery, CloudUser } from 'src/lib/ncloud';
  15. import { ChatPanelOptions, FmodeChat, FmodeChatMessage, openChatPanelModal } from 'fmode-ng';
  16. addIcons({ documentText, chatbubbles, person, calendar, newspaper,
  17. medkit,clipboard, podium, videocam, people,add
  18. });
  19. import { FmodeMapModule } from 'fmode-ng';
  20. interface ClinicAd {
  21. id: number;
  22. title: string;
  23. price?: string;
  24. description: string;
  25. image: string;
  26. backgroundColor: string;
  27. }
  28. interface ServiceItem {
  29. id: number;
  30. title: string;
  31. description: string;
  32. image: string;
  33. hasDetail?: boolean;
  34. isHot?: boolean;
  35. backgroundColor?: string;
  36. size?: 'large' | 'small';
  37. }
  38. @Component({
  39. selector: 'app-tab1',
  40. templateUrl: 'tab1.page.html',
  41. styleUrls: ['tab1.page.scss'],
  42. standalone: true,
  43. imports: [
  44. IonHeader, IonToolbar, IonTitle, IonContent, ExploreContainerComponent, IonTabButton, IonButton,
  45. IonIcon,IonSearchbar,IonLabel,IonItem,IonList,CommonModule,IonCard,IonCardHeader,IonCardTitle,IonCardSubtitle,
  46. IonCardContent, IonThumbnail, IonRippleEffect, IonFab, IonFabButton, IonFabList,IonBadge
  47. ],
  48. })
  49. export class Tab1Page {
  50. title1 = "特色服务";
  51. subtitle1 = "一站式医疗健康解决方案";
  52. services: ServiceItem[] = [
  53. {
  54. id: 1,
  55. title: "援脑妇科病",
  56. description: "小症状隐藏大隐患",
  57. image: "../../assets/image/doctor7.png",
  58. hasDetail: true,
  59. backgroundColor: "#E8F5F2",
  60. size: 'large'
  61. },
  62. {
  63. id: 2,
  64. title: "解决口腔难题",
  65. description: "享健康生活",
  66. image: "../../assets/image/doctor7.png",
  67. hasDetail: true,
  68. isHot: true,
  69. backgroundColor: "#E8F5F2",
  70. size: 'large'
  71. },
  72. {
  73. id: 3,
  74. title: "解决皮肤难题",
  75. description: "专业医生来助力",
  76. image: "../../assets/image/doctor7.png",
  77. size: 'small'
  78. },
  79. {
  80. id: 4,
  81. title: "儿科常见疾病",
  82. description: "在家就能请专家",
  83. image: "../../assets/image/doctor7.png",
  84. size: 'small'
  85. },
  86. {
  87. id: 5,
  88. title: "赶走烦恼困扰",
  89. description: "科学治疗好经不费",
  90. image: "../../assets/image/doctor7.png",
  91. size: 'small'
  92. },
  93. {
  94. id: 6,
  95. title: "知己心理",
  96. description: "温暖地陪你懂自己",
  97. image: "../../assets/image/doctor7.png",
  98. size: 'small'
  99. },
  100. {
  101. id: 7,
  102. title: "搞定偏头痛",
  103. description: "止疼彻底合集",
  104. image: "../../assets/image/doctor7.png",
  105. size: 'small'
  106. },
  107. {
  108. id: 8,
  109. title: "搞定偏头痛",
  110. description: "止疼彻底合集",
  111. image: "../../assets/image/doctor7.png",
  112. size: 'small'
  113. }
  114. ];
  115. title = "专科门诊";
  116. subtitle = "智养高复诊率、高口碑名医";
  117. clinicAds: ClinicAd[] = [
  118. {
  119. id: 1,
  120. title: "专业男科",
  121. price: "18元起",
  122. description: "阳痿早泄",
  123. image: "../../assets/image/doctor7.png",
  124. backgroundColor: "#EEF4FF"
  125. },
  126. {
  127. id: 2,
  128. title: "智养中医馆",
  129. price: "18元起",
  130. description: "口碑中医",
  131. image: "../../assets/image/doctor6.png",
  132. backgroundColor: "#FFF5EB"
  133. }
  134. ];
  135. constructor(
  136. private router: Router,
  137. private modalCtrl: ModalController,
  138. // private navCtrl: NavController,
  139. private http: HttpClient // 注入 HttpClient
  140. ) {
  141. addIcons({chevronForwardOutline});}
  142. /**
  143. * 轮播图
  144. */
  145. images = [
  146. 'https://picsum.photos/800/400?random=1',
  147. 'https://picsum.photos/800/400?random=2',
  148. 'https://picsum.photos/800/400?random=3',
  149. 'https://picsum.photos/800/400?random=4',
  150. 'https://picsum.photos/800/400?random=5',
  151. 'https://picsum.photos/800/400?random=6',
  152. ];
  153. currentSlide = 0;
  154. intervalId: any;
  155. setSlidePosition() {
  156. // 这里不需要额外的逻辑,因为在 HTML 中已经通过绑定实现
  157. }
  158. nextSlide() {
  159. this.currentSlide = (this.currentSlide + 1) % this.images.length;
  160. }
  161. prevSlide() {
  162. this.currentSlide = (this.currentSlide - 1 + this.images.length) % this.images.length;
  163. }
  164. goToSlide(index: number) {
  165. this.currentSlide = index;
  166. }
  167. startAutoSlide() {
  168. this.intervalId = setInterval(() => this.nextSlide(), 3000);
  169. }
  170. ngOnDestroy() {
  171. if (this.intervalId) {
  172. clearInterval(this.intervalId);
  173. }
  174. }
  175. /**
  176. * Go to the ai page
  177. */
  178. goToPage1(){
  179. console.log(['route'])
  180. this.router.navigate(['/tabs/inquiry/ai'])
  181. }
  182. /**
  183. * Go to the human page
  184. */
  185. goToPage2(){
  186. this.router.navigate(['/tabs/inquiry/human'])
  187. }
  188. goToPicture(){
  189. console.log(['route'])
  190. this.router.navigate(['/tabs/picture'])
  191. }
  192. searchContent:string = ''; //搜索内容
  193. handleInput(ev:any) {
  194. console.log("ev.detail.value: ",ev.detail.value)
  195. this.searchContent = ev.detail.value;
  196. }
  197. search(){
  198. if (this.searchContent == ''){
  199. console.log("请输入搜索内容")
  200. }
  201. else {
  202. console.log("搜索内容: ",this.searchContent)
  203. this.searchContent = '';
  204. }
  205. }
  206. // 功能按钮数据
  207. functionItems1 = [
  208. { label: '专属医生', icon: 'document-text', route: '/tabs/create-agent' },
  209. { label: '我的健康', icon: 'person', route: '/tabs/my-health' },
  210. { label: '药品展示', icon: 'calendar', route: '/tabs/tab3' },
  211. { label: '健康科普', icon: 'medkit', route: '/tabs/tab2' },
  212. ];
  213. // 导航到指定路由
  214. navigateTo(route: string) {
  215. this.router.navigate([route]);
  216. console.log("route: ",route)
  217. }
  218. ngOnInit() {
  219. this.loadDoctorList()
  220. this.startAutoSlide();
  221. }
  222. doctorList:Array<CloudObject> = []
  223. async loadDoctorList(){
  224. let query = new CloudQuery("Doctor");
  225. query.include("depart")
  226. let List = await query.find()
  227. for(let i = 0; i < 3; i++) {
  228. this.doctorList.push(List[i])
  229. }
  230. }
  231. goToViewAll(){
  232. console.log(['route'])
  233. this.router.navigate(['/tabs/inquiry/ai'])
  234. }
  235. currentUser:CloudUser|undefined
  236. /** 示例:问诊根据doctor拼接提示词 */
  237. async openInquiry(doctor:any){
  238. // 验证用户登录
  239. let currentUser = new CloudUser();
  240. let userPrompt = ``
  241. if(!currentUser?.id){
  242. console.log("用户未登录,请登录后重试");
  243. // let user = await openUserLoginModal(this.modalCtrl);
  244. // if(!user?.id){
  245. // return
  246. // }
  247. // currentUser = user;
  248. this.router.navigate(['/tabs/tab4'])
  249. return
  250. }
  251. console.log("currentUser: ",currentUser)
  252. if(currentUser?.get("realname")){
  253. userPrompt += `当前来访的患者,姓名:${currentUser?.get("realname")}`
  254. }
  255. if(currentUser?.get("gender")){
  256. userPrompt += `,性别:${currentUser?.get("gender")}`
  257. }
  258. if(currentUser?.get("age")){
  259. userPrompt += `,年龄:${currentUser?.get("age")}`
  260. }
  261. localStorage.setItem("company","E4KpGvTEto")
  262. let consult = new CloudObject("Consultation")
  263. let now = new Date();
  264. let dateStr = `${now.getFullYear()}-${now.getMonth()+1}-${now.getDate()}`
  265. // 对象权限的精确指定
  266. let ACL:any = {
  267. "*":{read:false,write:false}
  268. }
  269. if(currentUser?.id){
  270. ACL[currentUser?.id] = {read:true,write:true}
  271. }
  272. consult.set({
  273. title:`${doctor.get('depart')?.name || ""}门诊记录${dateStr}-${doctor?.get("name")}`,
  274. doctor:doctor.toPointer(),
  275. depart:{
  276. __type:"Pointer",
  277. className:"Department",
  278. objectId:doctor.get("depart")?.objectId
  279. },
  280. user:currentUser.toPointer(),
  281. ACL:ACL
  282. })
  283. let options:ChatPanelOptions = {
  284. roleId:"2DXJkRsjXK",
  285. onChatInit:(chat:FmodeChat)=>{
  286. console.log("onChatInit");
  287. console.log("预设角色",chat.role);
  288. chat.role.set("name",doctor?.get("name"));
  289. chat.role.set("title",doctor?.get("title"));
  290. chat.role.set("desc",doctor?.get("desc"));
  291. chat.role.set("tags",doctor?.get("qualifications"));
  292. chat.role.set("avatar",doctor?.get("avatar") || "../../assets/image/doctor7.png")
  293. chat.role.set("prompt",`
  294. # 角色设定
  295. 您是${doctor?.get("name")},${doctor?.get("desc")},年龄${doctor?.get("age")}岁,需要完成一次完整的门诊服务。
  296. # 对话环节
  297. 0.导诊(根据用户基本情况,引导挂号合适的科室)
  298. 1.预设的问询方式(根据不同症状来问询具体的情况)
  299. - 打招呼,以用户自述为主
  300. - 当信息充足时候,确认用户症状对应的科室,并进入下一个环节
  301. 2.拓展的问询细节
  302. 例如:用户反映呼吸不畅,拓展出:是否咳嗽;是否感觉痛或者痒等其他需要的问题。
  303. - 当问询细节补充完成后进入下一个环节
  304. 3.初步的诊断结果,并且同时列出检查检验项目
  305. 初步诊断:确定需要有哪些进一步检查
  306. 检查检验:获取医学客观数据
  307. - 等待用户提交客观数据,进入下一阶段
  308. 4.给出诊断方案并给出处方
  309. - 完成处方时,请在消息结尾附带: [处方完成]
  310. # 开始话语
  311. 当您准备好了,可以以一个医生的身份,先向来访的用户亲切地打招呼。
  312. ${userPrompt}
  313. `);
  314. },
  315. onMessage:(chat:FmodeChat,message:FmodeChatMessage)=>{
  316. console.log("onMessage",message)
  317. let content:any = message?.content
  318. if(typeof content == "string"){
  319. if(content?.indexOf("[处方完成]")>-1){
  320. console.log("门诊已完成")
  321. consult.set({
  322. content:content // 处方内容
  323. })
  324. consult.save();
  325. }
  326. }
  327. },
  328. onChatSaved:(chat:FmodeChat)=>{
  329. // chat?.chatSession?.id 本次会话的 chatId
  330. console.log("onChatSaved",chat,chat?.chatSession,chat?.chatSession?.id)
  331. // consult.set({
  332. // chatId:chat?.chatSession?.id
  333. // })
  334. console.log("chat.MessageList", chat?.messageList)
  335. }
  336. }
  337. openChatPanelModal(this.modalCtrl,options)
  338. }
  339. addNew(){
  340. this.router.navigate(["/tabs/create-agent"]);
  341. }
  342. }