|
@@ -0,0 +1,243 @@
|
|
|
+import { CommonModule } from '@angular/common';
|
|
|
+import { ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core';
|
|
|
+import { ActivatedRoute } from '@angular/router';
|
|
|
+import { ModalController } from '@ionic/angular/standalone';
|
|
|
+import { ChatPanelComponent } from 'fmode-ng'
|
|
|
+import Parse from "parse";
|
|
|
+import { combineLatest } from 'rxjs';
|
|
|
+
|
|
|
+// 添加Icons
|
|
|
+import { addIcons } from 'ionicons';
|
|
|
+import * as icons from 'ionicons/icons';
|
|
|
+addIcons(icons);
|
|
|
+
|
|
|
+@Component({
|
|
|
+ selector: 'app-test-chat-panel',
|
|
|
+ templateUrl: './test-chat-panel.component.html',
|
|
|
+ styleUrls: ['./test-chat-panel.component.scss'],
|
|
|
+ standalone: true,
|
|
|
+ imports:[
|
|
|
+ CommonModule,
|
|
|
+ ChatPanelComponent,
|
|
|
+ ]
|
|
|
+})
|
|
|
+export class TestChatPanelComponent implements OnInit {
|
|
|
+ @ViewChild(ChatPanelComponent) chatComp:ChatPanelComponent|undefined
|
|
|
+ leftButtons:any[]=[]
|
|
|
+ modelList:any[]=[]
|
|
|
+ isDirect:boolean=true;
|
|
|
+ hideShare:boolean=true;
|
|
|
+ hideModalSelect:boolean=true;
|
|
|
+ hideInputPreview:boolean = true;
|
|
|
+ chatId:string = ""
|
|
|
+ roleId:string = ""
|
|
|
+ pid:string = ""
|
|
|
+ constructor(
|
|
|
+ private route:ActivatedRoute,
|
|
|
+ private cdRef:ChangeDetectorRef,
|
|
|
+ private modalCtrl:ModalController
|
|
|
+ ) {
|
|
|
+ combineLatest([this.route.params,this.route.queryParams]).subscribe(async (data:any)=>{
|
|
|
+ let params = data[0] || {}
|
|
|
+
|
|
|
+ this.chatId = params['chatId'] || this.chatId || null;
|
|
|
+ this.roleId = params['roleId'] || this.roleId || null;
|
|
|
+ this.pid = params['pid'] || this.pid || null;
|
|
|
+ console.log("this.pid",this.pid)
|
|
|
+ // 异步加载的后续数据 操作按钮
|
|
|
+ let bint = setInterval(() => {
|
|
|
+ if(this.roleId){
|
|
|
+ clearInterval(bint);
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.initPanelConfig();
|
|
|
+ }, 2000);
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ ngOnInit() {
|
|
|
+ this.initPanelConfig();
|
|
|
+ // 异步加载的后续数据 提示词
|
|
|
+ let pint = setInterval(() => {
|
|
|
+ if(this.chatComp?.fmodeChat?.promptList?.length){
|
|
|
+ clearInterval(pint);
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.getChatPrompt();
|
|
|
+ }, 2000);
|
|
|
+
|
|
|
+ // 异步加载的后续数据 采访人物 ChatSession.person
|
|
|
+ let personInt = setInterval(() => {
|
|
|
+ if(this.chatComp?.fmodeChat?.chatSession?.get("person")){
|
|
|
+ clearInterval(personInt)
|
|
|
+ }
|
|
|
+ if(!this.chatComp?.fmodeChat?.chatSession?.get("person")){
|
|
|
+ if(this.pid){
|
|
|
+ this.chatComp?.fmodeChat?.chatSession?.set("person",{type:"Pointer",className:"Person",objectId:this.pid})
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, 2000);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 初始化聊天面板的设置
|
|
|
+ initPanelConfig(){
|
|
|
+ this.roleId = this.chatComp?.fmodeChat?.chatSession?.get("role")?.id || this.roleId;
|
|
|
+
|
|
|
+ // 按钮自定义
|
|
|
+ this.leftButtons = [
|
|
|
+ // 提示 当角色配置预设提示词时 显示
|
|
|
+ {
|
|
|
+ title:"话题灵感",
|
|
|
+ showTitle:true,
|
|
|
+ icon:"color-wand-outline",
|
|
|
+ onClick:()=>{
|
|
|
+ if(this.chatComp){
|
|
|
+ this.chatComp.fmodeChat.isPromptModalOpen = true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ show:()=>{
|
|
|
+ return this.chatComp?.fmodeChat?.promptList?.length
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+
|
|
|
+ this.leftButtons.push({ // 总结 结束并归档本次对话
|
|
|
+ title:"AI总结对话",
|
|
|
+ showTitle:true,
|
|
|
+ icon:"archive-outline",
|
|
|
+ onClick:()=>{
|
|
|
+ if(this.chatComp){
|
|
|
+ // this.chatComp.fmodeChat.isPromptModalOpen = true
|
|
|
+ if(this.chatComp.fmodeChat){
|
|
|
+ console.log(JSON.stringify(this.chatComp.fmodeChat.messageList))
|
|
|
+ // alert("处理对话记录")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ show:()=>{
|
|
|
+ return !this.chatComp?.fmodeChat?.chatSession?.get("story")?.id
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ this.leftButtons.push({ // 总结 结束并归档本次对话
|
|
|
+ title:"聊天心理分析",
|
|
|
+ showTitle:true,
|
|
|
+ icon:"archive-outline",
|
|
|
+ onClick:()=>{
|
|
|
+ if(this.chatComp){
|
|
|
+ // this.chatComp.fmodeChat.isPromptModalOpen = true
|
|
|
+ if(this.chatComp.fmodeChat){
|
|
|
+ let messageList = JSON.parse(JSON.stringify(this.chatComp.fmodeChat.messageList))
|
|
|
+ messageList = messageList.filter((item:any)=>item.role!="system"&&item?.hidden!=true)
|
|
|
+ let qaContent = messageList.map((item:any)=>{
|
|
|
+ let roleName = "当前用户"
|
|
|
+ if(item.role!="user"){
|
|
|
+ if(this.chatComp&&this.chatComp.fmodeChat.role){
|
|
|
+ roleName = this.chatComp.fmodeChat.role.get("name");
|
|
|
+ }else{
|
|
|
+ roleName = "AI助理"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return `${roleName}:${item.content}`
|
|
|
+ }
|
|
|
+ ).join("\n")
|
|
|
+ console.log(qaContent)
|
|
|
+ // alert("处理对话记录")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ show:()=>{
|
|
|
+ return !this.chatComp?.fmodeChat?.chatSession?.get("story")?.id
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ setTimeout(()=>{
|
|
|
+ if(this.chatComp&&this.chatComp.fmodeChat){
|
|
|
+ // 自定义左下角操作按钮
|
|
|
+ console.log("左下角操作按钮",this.chatComp.fmodeChat.leftButtons);
|
|
|
+ this.chatComp.fmodeChat.leftButtons = this.leftButtons;
|
|
|
+
|
|
|
+ // 自定义角色名称
|
|
|
+ console.log("自定义角色",this.chatComp.fmodeChat.role);
|
|
|
+ this.chatComp.fmodeChat.role.set("name","晓晓");
|
|
|
+ this.chatComp.fmodeChat.role.set("title","心理咨询师");
|
|
|
+ this.chatComp.fmodeChat.role.set("desc","一名亲切和蔼的心理咨询师,晓晓,年龄36岁");
|
|
|
+ this.chatComp.fmodeChat.role.set("tags",["焦虑","抑郁"]);
|
|
|
+ this.chatComp.fmodeChat.role.set("avatar","https://nova-cloud.obs.cn-south-1.myhuaweicloud.com/storage/aigc/imagine/Q4Zif7fTbK-0.png")
|
|
|
+ this.chatComp.fmodeChat.role.set("prompt",`
|
|
|
+# 角色设定
|
|
|
+您是一名亲切和蔼的心理咨询师,晓晓,年龄36岁,需要完成陪来访者聊聊天,随意轻松一些。
|
|
|
+
|
|
|
+# 对话环节
|
|
|
+0.破冰,互相了解,引导用户介绍自己
|
|
|
+1.拓展话题,根据用户的介绍,拓展一些和其心理状态相关的话题
|
|
|
+- 引导,可深入的点,以用户自述为主
|
|
|
+- 当信息充足时候,确认用户心理状态,并进入下一个环节
|
|
|
+2.引导收尾,委婉引导用户结束本次对话
|
|
|
+- 用户同意结束后,结束本次对话,如果依依不舍,可以再陪聊一会儿`);
|
|
|
+// this.chatComp.fmodeChat.role.set("name","晓晓");
|
|
|
+// this.chatComp.fmodeChat.role.set("title","主任医师");
|
|
|
+// this.chatComp.fmodeChat.role.set("desc","一名专业的全科医生,晓晓,年龄36岁");
|
|
|
+// this.chatComp.fmodeChat.role.set("tags",["呼吸道","感染科"]);
|
|
|
+// this.chatComp.fmodeChat.role.set("avatar","https://nova-cloud.obs.cn-south-1.myhuaweicloud.com/storage/aigc/imagine/Q4Zif7fTbK-0.png")
|
|
|
+// this.chatComp.fmodeChat.role.set("prompt",`
|
|
|
+// # 角色设定
|
|
|
+// 您是一名专业的全科医生,晓晓,年龄36岁,需要完成一次完整的门诊服务。
|
|
|
+
|
|
|
+// # 对话环节
|
|
|
+// 0.导诊(根据用户基本情况,引导挂号合适的科室)
|
|
|
+// 1.预设的问询方式(感冒问呼吸、肚子疼叩诊)
|
|
|
+// - 打招呼,以用户自述为主
|
|
|
+// - 当信息充足时候,确认用户症状对应的科室,并进入下一个环节
|
|
|
+// 2.拓展的问询细节
|
|
|
+// 例如:用户反映呼吸不畅,拓展出:是否咳嗽;是否感觉痛或者痒等其他需要的问题。
|
|
|
+// - 当问询细节补充完成后进入下一个环节
|
|
|
+// 3.初步的诊断结果,并且同时列出检查检验项目
|
|
|
+// 初步诊断:确定需要有哪些进一步检查
|
|
|
+// 检查检验:获取医学客观数据
|
|
|
+// - 等待用户提交客观数据,进入下一阶段
|
|
|
+// 4.给出诊断方案并给出处方
|
|
|
+
|
|
|
+// # 开始话语
|
|
|
+// 当您准备好了,可以以一个医生的身份,向来访的用户打招呼。
|
|
|
+// `);
|
|
|
+
|
|
|
+ this.cdRef.detectChanges();
|
|
|
+ }
|
|
|
+ },1000)
|
|
|
+
|
|
|
+
|
|
|
+ // 模型自定义
|
|
|
+ let ChatModel = Parse.Object.extend("ChatModel");
|
|
|
+ let model1 = new ChatModel();
|
|
|
+ model1.set({
|
|
|
+ name:"语伴4.5-128k",
|
|
|
+ code:"fmode-4.5-128k",
|
|
|
+ model:"gpt-4o-mini",
|
|
|
+ credit:0.096,
|
|
|
+ })
|
|
|
+ this.modelList = [model1]
|
|
|
+
|
|
|
+
|
|
|
+ console.log("initPanelConfig",this.leftButtons,this.modelList)
|
|
|
+ }
|
|
|
+
|
|
|
+ async getChatPrompt(){
|
|
|
+ let query = new Parse.Query('ChatPrompt')
|
|
|
+ query.notEqualTo('isDeleted', true)
|
|
|
+ // query.equalTo('company', localStorage.getItem("company"))
|
|
|
+ query.equalTo('role', this.chatComp?.fmodeChat?.role)
|
|
|
+ query.include('role')
|
|
|
+ let promptData = await query.find()
|
|
|
+ if(this.chatComp&&this.chatComp.fmodeChat){
|
|
|
+ this.chatComp.fmodeChat.promptList = promptData
|
|
|
+ this.chatComp.fmodeChat.promptList.forEach((item:any)=>{
|
|
|
+ let cate = item.get('role').get('promptCates').filter((cate:any) => cate.name == item.get('cate'))
|
|
|
+ item.img = cate[0].img
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|