123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368 |
- import { Component, OnInit } from '@angular/core';
- import { Router } from '@angular/router';
- import { CloudObject, CloudQuery, CloudUser } from 'src/lib/ncloud';
- import { LoadingController,IonHeader, IonToolbar, IonTitle, IonContent, IonButton,IonIcon, ModalController, IonTextarea, IonInput, IonCard, IonCardHeader, IonCardTitle, IonThumbnail, IonCardContent, IonCardSubtitle, IonItem, IonList, IonLabel, IonAvatar, IonSelect, IonSelectOption, AlertController, IonButtons, IonProgressBar, IonText, IonRefresherContent, IonRefresher, ToastController, IonToast, IonFooter, IonBackButton } from '@ionic/angular/standalone';
- import { CommonModule } from '@angular/common';
- import { AvatarModule, ChatPanelOptions, DalleOptions, FmodeChat, FmodeChatCompletion, FmodeChatMessage, ImagineWork, openChatPanelModal } from 'fmode-ng';
- import { FormsModule } from '@angular/forms';
- import { IonicModule } from '@ionic/angular';
- @Component({
- selector: 'app-page-create-agent',
- templateUrl: './page-create-agent.component.html',
- styleUrls: ['./page-create-agent.component.scss'],
- standalone: true,
- imports: [
- IonFooter,
- IonBackButton,
- IonHeader,
- IonToolbar,
- IonTitle,
- IonContent,
- IonButton,
- IonTextarea,
- IonInput,
- IonIcon,
- IonCard,
- IonCardHeader,
- IonCardTitle,
- IonCardSubtitle,
- IonCardContent,
- IonThumbnail,
- IonItem,
- IonList,
- CommonModule,
- IonLabel,
- IonAvatar,
- IonSelect,
- IonSelectOption,
- IonButtons,
- IonProgressBar,
- IonText,
- IonCardHeader,
- IonCardSubtitle,
- IonRefresher,
- IonRefresherContent,
- IonToast,FormsModule
- ],
- })
- export class PageCreateAgentComponent implements OnInit {
- public buffer = 0.05;
- public progress = 0;
- // async presentToast(position: 'top' | 'middle' | 'bottom') {
- // const toast = await this.toastController.create({
- // message: '正在创建智能体,请耐心等待!',
- // duration: 1500,
- // position: position,
- // });
- // await toast.present();
- // }
- handleRefresh(event:any) {
- setTimeout(() => {
- // Any calls to load data go here
- this.loadAgentData()
- event.target.complete();
- }, 2000);
- }
- currentUser: CloudUser;
- constructor(
- private toastController: ToastController,
- private modalCtrl:ModalController,
- private router:Router,
- private alertController: AlertController,
- private loadingController: LoadingController,
- ) {
- this.currentUser = new CloudUser();
- // 示例任务,自己生成图片后请存储新的ID
- this.imagineWork = new ImagineWork("");
- this.imagineWork.fetchTask().then(work=>{
- if(work){
- this.imagineWork.id = work.id
- }
- this.images = this.imagineWork?.images || '../../assets/image/头像示例.png';
- })
- this.loadAgentData()
- }
- images:Array<string> = []
- ngOnInit() {
- }
- name: string = ''
- nameInput(e:any) {
- this.name = e.detail.value;
- console.log(this.name);
- }
- age: number = 18;
- ageInput(e:any) {
- this.age = e.detail.value;
- console.log(this.age);
- }
- gender: string = "男";
- genderChange(e:any) {
- console.log('ionChange fired with value: ' + e.detail.value);
- this.gender = e.detail.value;
- }
- genderCancel(){
- }
- genderDismiss(){
- }
- // 描述
- desc: string = ''
- descInput(e:any) {
- this.desc = e.detail.value;
- console.log(this.desc);
- }
- imagineWork:ImagineWork
- PictureDescResult:string = `` // 画面描述结果
- loading: HTMLIonLoadingElement | null = null;
- // 创建医生
- async createAgent() {
- let alert1 = await this.alertController.create({
- header: '温馨提示',
- subHeader: 'Tips',
- message: '把信息填写完整哦~',
- buttons: ['好的'],
- });
- let alert2 = await this.alertController.create({
- header: '温馨提示',
- subHeader: 'Tips',
- message: '智能体已经创建成功!',
- buttons: ['好的'],
- });
- let alert4 = await this.alertController.create({
- header: '温馨提示',
- subHeader: 'Tips',
- message: '智能体创建失败,请重新创建!',
- buttons: ['好的'],
- });
- if (this.name == '' || this.age == 0 || this.gender == '' || this.desc == '') {
- await alert1.present();
- return;
- }
- this.loading = await this.loadingController.create({
- message: '智能体生成中...',
- });
- await this.loading.present();
- localStorage.setItem("company","E4KpGvTEto")
- let consult = new CloudObject("DoctorAgent")
- let now = new Date();
- let dateStr = `${now.getFullYear()}-${now.getMonth()+1}-${now.getDate()}`
- // 对象权限的精确指定
- let ACL:any = {
- "*":{read:true,write:true}
- }
- if(this.currentUser?.id){
- ACL[this.currentUser?.id] = {read:true,write:true}
- }
- this.imagineWork = new ImagineWork();
- // 文本生成
- let PromptTemplate = `您是一名专业的美术画家,擅长画各类型头像图,请您根据下面提供的需求内容,将其描述的画面、场景、人物、物品等用最简短的语言表达,直接写出画面,
- 需求如下:
- ${this.name},${this.age}岁,${this.gender},描述:${this.desc}
- `
- let completion = new FmodeChatCompletion([
- {role:"system",content:""},
- {role:"user",content:PromptTemplate}
- ])
- let avatar = ""
- if (!this.name || !this.desc){
- this.progress = 0; // 进度条重置
-
- await alert4.present();
- }
- completion.sendCompletion().subscribe((message:any)=>{
- // 打印消息体
- console.log(message.content)
- // 赋值消息内容给组件内属性
- this.PictureDescResult = message.content
- if(this.progress<0.97){
- if(this.progress<0.5){
- this.progress+=0.002
- }
- if(this.progress>=0.8){
- this.progress+=0.001
- }
- }
- if(message?.complete){ // 判断message为完成状态,则设置isComplete为完成
- // 图片生成
- let PicturePrompt = `${this.PictureDescResult}\n风格:画面不带任何文字。人物为主体,人物要在图片的正中央。其中人物必须帅气,符合现代中国人审美。`
- let options:DalleOptions = {prompt:PicturePrompt}
- this.imagineWork?.draw(options).subscribe(async work=>{
- if(this.progress<0.5){
- this.progress+=0.01
- }
- if(this.progress>=0.8){
- this.progress+=0.001
- }
- if(work?.get("images")?.length){
- if (this.loading) {
- await this.loading.dismiss();
- this.loading = null; // 清空 loading 实例
- }
- avatar = work?.get("images")[0];
- consult.set({
- avatar:`${avatar}`,
- name:`${this.name}`,
- age:`${this.age}`,
- gender:`${this.gender}`,
- desc:`${this.desc}`,
- user:this.currentUser.toPointer(),
- ACL:ACL,
- })
- this.progress=0
- consult.save();
- // this.progress = 1;
- console.log("consult",consult);
- alert2.present();
- this.loadAgentData();
- this.name = ''
- this.desc = ''
- }
- })
- }
- })
- }
-
- agentList: Array<CloudObject> = [];
- async loadAgentData() {
- let user = new CloudUser();
- let query = new CloudQuery("DoctorAgent")
- query.equalTo("user",user?.id)
- let agentlist = await query.find()
- // 将查询到的数据反向排序
- this.agentList = agentlist.reverse()
- console.log(this.agentList);
- }
- openInquiry(doctor:CloudObject){
- // 验证用户登录
- let currentUser = new CloudUser();
- let userPrompt = ``
- if(currentUser?.get("realname")){
- userPrompt += `当前来访的患者,姓名:${currentUser?.get("realname")}`
- }
- if(currentUser?.get("gender")){
- userPrompt += `,性别:${currentUser?.get("gender")}`
- }
- if(currentUser?.get("age")){
- userPrompt += `,年龄:${currentUser?.get("age")}`
- }
-
- localStorage.setItem("company","E4KpGvTEto")
- let consult = new CloudObject("Consultation")
- let now = new Date();
- let dateStr = `${now.getFullYear()}-${now.getMonth()+1}-${now.getDate()}`
- // 对象权限的精确指定
- let ACL:any = {
- "*":{read:true,write:true}
- }
- if(currentUser?.id){
- ACL[currentUser?.id] = {read:true,write:true}
- }
- consult.set({
- title:`门诊记录${dateStr}-${doctor?.get("name")}`,
- doctor:doctor.toPointer(),
- user:currentUser.toPointer(),
- ACL:ACL
- })
- let options:ChatPanelOptions = {
- roleId:"2DXJkRsjXK",
- onChatInit:(chat:FmodeChat)=>{
- console.log("onChatInit");
- console.log("预设角色",chat.role);
- chat.role.set("name",doctor?.get("name"));
- chat.role.set("desc",doctor?.get("desc"));
- chat.role.set("avatar",doctor?.get("avatar") || "../../assets/image/doctor7.png")
- chat.role.set("prompt",`
- # 角色设定
- 您是${doctor?.get("name")},${doctor?.get("desc")},年龄${doctor?.get("age")}岁,需要完成一次完整的门诊服务。
- # 对话环节
- 0.直接和用户打招呼(如:你好,XXX,我是···)
- - 注意:如果用户问的问题和你的${doctor?.get("desc")}的不符,请直接引导用户去其他的地方
- 1.预设的问询方式(根据不同症状来问询具体的情况)
- - 打招呼,以用户自述为主
- - 当信息充足时候,确认用户症状对应的科室,并进入下一个环节
- 2.拓展的问询细节
- 例如:用户反映呼吸不畅,拓展出:是否咳嗽;是否感觉痛或者痒等其他需要的问题。
- - 当问询细节补充完成后进入下一个环节
- 3.初步的诊断结果,并且同时列出检查检验项目
- 初步诊断:确定需要有哪些进一步检查
- 检查检验:获取医学客观数据
- - 等待用户提交客观数据,进入下一阶段
- 4.给出诊断方案并给出处方
- - 完成处方时,请在消息结尾附带: [处方完成]
- # 开始话语
- 当您准备好了,可以以一个医生的身份,向来访的用户打招呼。
- ${userPrompt}
- `);
- },
- onMessage:(chat:FmodeChat,message:FmodeChatMessage)=>{
- console.log("onMessage",message)
- let content:any = message?.content
- if(typeof content == "string"){
- if(content?.indexOf("[处方完成]")>-1){
- console.log("门诊已完成")
- let list = chat?.messageList
- console.log("门诊已完成")
- consult.set({
- allContent:list,
- content:content // 处方内容
- })
- consult.save();
- }
- }
- },
- onChatSaved:(chat:FmodeChat)=>{
- // chat?.chatSession?.id 本次会话的 chatId
- console.log("onChatSaved",chat,chat?.chatSession,chat?.chatSession?.id)
- }
- }
- openChatPanelModal(this.modalCtrl,options)
- }
- async deleteAgent(agent:CloudObject){
- const alert = await this.alertController.create({
- header: '确认删除',
- message: `确定要删除 ${agent.get('name')} 吗?`,
- buttons: [
- {
- text: '取消',
- role: 'cancel',
- },
- {
- text: '确认',
- handler: () => {
- this.agentList = this.agentList.filter(a => a.id !== agent.id);
- this.presentToast('智能体已删除。');
- },
- },
- ],
- });
-
- await alert.present();
- console.log("删除了",agent);
- agent.destroy();
- this.loadAgentData();
- }
- async presentToast(message: string) {
- const toast = await this.toastController.create({
- message,
- duration: 2000,
- position: 'bottom',
- });
- toast.present();
- }
- }
|