test-chat-panel.component.ts 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. import { CommonModule } from '@angular/common';
  2. import { ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core';
  3. import { ActivatedRoute } from '@angular/router';
  4. import { ModalController } from '@ionic/angular/standalone';
  5. import { ChatPanelComponent } from 'fmode-ng'
  6. import Parse from "parse";
  7. import { combineLatest } from 'rxjs';
  8. // 添加Icons
  9. import { addIcons } from 'ionicons';
  10. import * as icons from 'ionicons/icons';
  11. addIcons(icons);
  12. @Component({
  13. selector: 'app-test-chat-panel',
  14. templateUrl: './test-chat-panel.component.html',
  15. styleUrls: ['./test-chat-panel.component.scss'],
  16. standalone: true,
  17. imports:[
  18. CommonModule,
  19. ChatPanelComponent,
  20. ]
  21. })
  22. export class TestChatPanelComponent implements OnInit {
  23. @ViewChild(ChatPanelComponent) chatComp:ChatPanelComponent|undefined
  24. leftButtons:any[]=[]
  25. modelList:any[]=[]
  26. isDirect:boolean=true;
  27. hideShare:boolean=true;
  28. hideModalSelect:boolean=true;
  29. hideInputPreview:boolean = true;
  30. chatId:string = ""
  31. roleId:string = ""
  32. pid:string = ""
  33. constructor(
  34. private route:ActivatedRoute,
  35. private cdRef:ChangeDetectorRef,
  36. private modalCtrl:ModalController
  37. ) {
  38. combineLatest([this.route.params,this.route.queryParams]).subscribe(async (data:any)=>{
  39. let params = data[0] || {}
  40. this.chatId = params['chatId'] || this.chatId || null;
  41. this.roleId = params['roleId'] || this.roleId || null;
  42. this.pid = params['pid'] || this.pid || null;
  43. console.log("this.pid",this.pid)
  44. // 异步加载的后续数据 操作按钮
  45. let bint = setInterval(() => {
  46. if(this.roleId){
  47. clearInterval(bint);
  48. return
  49. }
  50. this.initPanelConfig();
  51. }, 2000);
  52. })
  53. }
  54. ngOnInit() {
  55. this.initPanelConfig();
  56. // 异步加载的后续数据 提示词
  57. let pint = setInterval(() => {
  58. if(this.chatComp?.fmodeChat?.promptList?.length){
  59. clearInterval(pint);
  60. return
  61. }
  62. this.getChatPrompt();
  63. }, 2000);
  64. // 异步加载的后续数据 采访人物 ChatSession.person
  65. let personInt = setInterval(() => {
  66. if(this.chatComp?.fmodeChat?.chatSession?.get("person")){
  67. clearInterval(personInt)
  68. }
  69. if(!this.chatComp?.fmodeChat?.chatSession?.get("person")){
  70. if(this.pid){
  71. this.chatComp?.fmodeChat?.chatSession?.set("person",{type:"Pointer",className:"Person",objectId:this.pid})
  72. }
  73. }
  74. }, 2000);
  75. }
  76. // 初始化聊天面板的设置
  77. initPanelConfig(){
  78. this.roleId = this.chatComp?.fmodeChat?.chatSession?.get("role")?.id || this.roleId;
  79. // 按钮自定义
  80. this.leftButtons = [
  81. // 提示 当角色配置预设提示词时 显示
  82. {
  83. title:"话题灵感",
  84. showTitle:true,
  85. icon:"color-wand-outline",
  86. onClick:()=>{
  87. if(this.chatComp){
  88. this.chatComp.fmodeChat.isPromptModalOpen = true
  89. }
  90. },
  91. show:()=>{
  92. return this.chatComp?.fmodeChat?.promptList?.length
  93. }
  94. }
  95. ]
  96. this.leftButtons.push({ // 总结 结束并归档本次对话
  97. title:"AI总结对话",
  98. showTitle:true,
  99. icon:"archive-outline",
  100. onClick:()=>{
  101. if(this.chatComp){
  102. // this.chatComp.fmodeChat.isPromptModalOpen = true
  103. if(this.chatComp.fmodeChat){
  104. console.log(JSON.stringify(this.chatComp.fmodeChat.messageList))
  105. // alert("处理对话记录")
  106. }
  107. }
  108. },
  109. show:()=>{
  110. return !this.chatComp?.fmodeChat?.chatSession?.get("story")?.id
  111. }
  112. })
  113. this.leftButtons.push({ // 总结 结束并归档本次对话
  114. title:"聊天心理分析",
  115. showTitle:true,
  116. icon:"archive-outline",
  117. onClick:()=>{
  118. if(this.chatComp){
  119. // this.chatComp.fmodeChat.isPromptModalOpen = true
  120. if(this.chatComp.fmodeChat){
  121. let messageList = JSON.parse(JSON.stringify(this.chatComp.fmodeChat.messageList))
  122. messageList = messageList.filter((item:any)=>item.role!="system"&&item?.hidden!=true)
  123. let qaContent = messageList.map((item:any)=>{
  124. let roleName = "当前用户"
  125. if(item.role!="user"){
  126. if(this.chatComp&&this.chatComp.fmodeChat.role){
  127. roleName = this.chatComp.fmodeChat.role.get("name");
  128. }else{
  129. roleName = "AI助理"
  130. }
  131. }
  132. return `${roleName}:${item.content}`
  133. }
  134. ).join("\n")
  135. console.log(qaContent)
  136. // alert("处理对话记录")
  137. }
  138. }
  139. },
  140. show:()=>{
  141. return !this.chatComp?.fmodeChat?.chatSession?.get("story")?.id
  142. }
  143. })
  144. setTimeout(()=>{
  145. if(this.chatComp&&this.chatComp.fmodeChat){
  146. // 自定义左下角操作按钮
  147. console.log("左下角操作按钮",this.chatComp.fmodeChat.leftButtons);
  148. this.chatComp.fmodeChat.leftButtons = this.leftButtons;
  149. // 自定义角色名称
  150. console.log("自定义角色",this.chatComp.fmodeChat.role);
  151. this.chatComp.fmodeChat.role.set("name","晓晓");
  152. this.chatComp.fmodeChat.role.set("title","心理咨询师");
  153. this.chatComp.fmodeChat.role.set("desc","一名亲切和蔼的心理咨询师,晓晓,年龄36岁");
  154. this.chatComp.fmodeChat.role.set("tags",["焦虑","抑郁"]);
  155. this.chatComp.fmodeChat.role.set("avatar","https://nova-cloud.obs.cn-south-1.myhuaweicloud.com/storage/aigc/imagine/Q4Zif7fTbK-0.png")
  156. this.chatComp.fmodeChat.role.set("prompt",`
  157. # 角色设定
  158. 您是一名亲切和蔼的心理咨询师,晓晓,年龄36岁,需要完成陪来访者聊聊天,随意轻松一些。
  159. # 对话环节
  160. 0.破冰,互相了解,引导用户介绍自己
  161. 1.拓展话题,根据用户的介绍,拓展一些和其心理状态相关的话题
  162. - 引导,可深入的点,以用户自述为主
  163. - 当信息充足时候,确认用户心理状态,并进入下一个环节
  164. 2.引导收尾,委婉引导用户结束本次对话
  165. - 用户同意结束后,结束本次对话,如果依依不舍,可以再陪聊一会儿`);
  166. // this.chatComp.fmodeChat.role.set("name","晓晓");
  167. // this.chatComp.fmodeChat.role.set("title","主任医师");
  168. // this.chatComp.fmodeChat.role.set("desc","一名专业的全科医生,晓晓,年龄36岁");
  169. // this.chatComp.fmodeChat.role.set("tags",["呼吸道","感染科"]);
  170. // this.chatComp.fmodeChat.role.set("avatar","https://nova-cloud.obs.cn-south-1.myhuaweicloud.com/storage/aigc/imagine/Q4Zif7fTbK-0.png")
  171. // this.chatComp.fmodeChat.role.set("prompt",`
  172. // # 角色设定
  173. // 您是一名专业的全科医生,晓晓,年龄36岁,需要完成一次完整的门诊服务。
  174. // # 对话环节
  175. // 0.导诊(根据用户基本情况,引导挂号合适的科室)
  176. // 1.预设的问询方式(感冒问呼吸、肚子疼叩诊)
  177. // - 打招呼,以用户自述为主
  178. // - 当信息充足时候,确认用户症状对应的科室,并进入下一个环节
  179. // 2.拓展的问询细节
  180. // 例如:用户反映呼吸不畅,拓展出:是否咳嗽;是否感觉痛或者痒等其他需要的问题。
  181. // - 当问询细节补充完成后进入下一个环节
  182. // 3.初步的诊断结果,并且同时列出检查检验项目
  183. // 初步诊断:确定需要有哪些进一步检查
  184. // 检查检验:获取医学客观数据
  185. // - 等待用户提交客观数据,进入下一阶段
  186. // 4.给出诊断方案并给出处方
  187. // # 开始话语
  188. // 当您准备好了,可以以一个医生的身份,向来访的用户打招呼。
  189. // `);
  190. this.cdRef.detectChanges();
  191. }
  192. },1000)
  193. // 模型自定义
  194. let ChatModel = Parse.Object.extend("ChatModel");
  195. let model1 = new ChatModel();
  196. model1.set({
  197. name:"语伴4.5-128k",
  198. code:"fmode-4.5-128k",
  199. model:"gpt-4o-mini",
  200. credit:0.096,
  201. })
  202. this.modelList = [model1]
  203. console.log("initPanelConfig",this.leftButtons,this.modelList)
  204. }
  205. async getChatPrompt(){
  206. let query = new Parse.Query('ChatPrompt')
  207. query.notEqualTo('isDeleted', true)
  208. // query.equalTo('company', localStorage.getItem("company"))
  209. query.equalTo('role', this.chatComp?.fmodeChat?.role)
  210. query.include('role')
  211. let promptData = await query.find()
  212. if(this.chatComp&&this.chatComp.fmodeChat){
  213. this.chatComp.fmodeChat.promptList = promptData
  214. this.chatComp.fmodeChat.promptList.forEach((item:any)=>{
  215. let cate = item.get('role').get('promptCates').filter((cate:any) => cate.name == item.get('cate'))
  216. item.img = cate[0].img
  217. })
  218. }
  219. }
  220. }