注意:消息列表测试期间,保留关键字:FmodeAiTest测试问题,减少实际接口调用消耗,减少开发阶段的tokens支出。
// 引用FmodeChatCompletion类
import { FmodeChatCompletion } from 'fmode-ng/core/agent/chat/completion';
class CompChatPage{
responseMessage:string = ""
createNewCompletion(){
// 创建上下文提示词消息列表
let messageList = [
{role:"user",content:"填写你发送过的历史消息:可用于Prompt定义AI扮演的角色细节"},
{role:"assistant",content:"填写AI回复的历史消息"},
{role:"user",content:"FmodeAiTest测试问题"}, // 填写你要发送的消息
]
let options = {
model:"fmode-1.6-cn",
}
// 创建并发起一条新的消息补全
let completion = new FmodeChatCompletion(messageList,options)
completion.model = "fmode-1.6-cn"
// 持续更新事件推送的消息体内容绑定至消息变量
let send$ = completion.sendCompletion({
isDirect:true, // 直接返回不限速
temperature: 0.5,
presence_penalty: 0,
frequency_penalty: 0
}).subscribe(message=>{
if(typeof message?.content =="string"){
this.responseMessage = message?.content
}
if(message.complete){
// 完成消息推送,可执行其他业务逻辑
// 结束订阅
send$.unsubscribe();
}
})
}
}
import { completionJSON } from 'fmode-ng/core/agent/chat/completion';
// 定义 JSON 结构描述
const clothingSchema = `{
"character": "string", // 角色名称
"outfit": {
"head": {
"item": "string", // 头部装饰名称
"color": "string" // 颜色色号,格式为 #RRGGBB
},
"top": {
"item": "string", // 上衣名称
"color": "string" // 颜色色号
},
"bottom": {
"item": "string", // 下装名称
"color": "string" // 颜色色号
},
"shoes": {
"item": "string", // 鞋子名称
"color": "string" // 颜色色号
},
"accessories": [
{
"item": "string", // 配饰名称
"color": "string" // 颜色色号
}
]
}
}`;
// 使用函数生成哪吒主题的服装搭配
async function generateNezhaOutfit() {
try {
const prompt = `
请为哪吒这个经典的中国神话角色设计一套现代服装搭配。
要求:
1. 保持哪吒的经典特色(红色为主色调,活泼动感)
2. 融入现代时尚元素
3. 适合年轻人穿着
4. 颜色搭配要协调
5. 每个部位都要指定具体的颜色色号
`;
const result = await completionJSON(
prompt,
clothingSchema,
(content) => {
// 实时显示生成过程
console.log('正在生成:', content);
}
);
console.log('生成的服装搭配:', result);
return result;
} catch (error) {
console.error('生成失败:', error);
}
}
// medical-consultation.component.ts
import { CommonModule } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import {
IonHeader,
IonToolbar,
IonTitle,
IonContent,
IonCard,
IonCardHeader,
IonCardTitle,
IonCardSubtitle,
IonCardContent,
IonAvatar,
IonList,
IonItem,
IonLabel,
IonNote,
IonButton,
IonIcon,
IonBadge,
IonListHeader,
ModalController,
InfiniteScrollCustomEvent,
IonInfiniteScroll,
IonInfiniteScrollContent,
IonSpinner,
IonGrid,
IonRow,
IonCol,
IonRefresher,
IonRefresherContent
} from '@ionic/angular/standalone';
import { addIcons } from 'ionicons';
import {
medicalOutline,
medkitOutline,
chatbubbleOutline,
timeOutline,
refreshOutline,
arrowForwardOutline
} from 'ionicons/icons';
import { ChatPanelOptions, FmodeChat, FmodeChatMessage, openChatPanelModal } from 'fmode-ng';
import {FmodeParse,FmodeObject,FmodeQuery,FmodeUser} from "../../../../core/parse";const Parse = FmodeParse.with("nova");
@Component({
selector: 'fm-test-fmode-chat-panel-lifecycle',
templateUrl: './test-fmode-chat-panel-lifecycle.component.html',
styleUrl: './test-fmode-chat-panel-lifecycle.component.scss',
standalone: true,
providers:[ModalController],
imports: [
CommonModule,
IonHeader,
IonToolbar,
IonTitle,
IonContent,
IonCard,
IonCardHeader,
IonCardTitle,
IonCardSubtitle,
IonCardContent,
IonAvatar,
IonList,
IonItem,
IonLabel,
IonNote,
IonButton,
IonIcon,
IonBadge,
IonListHeader,
IonInfiniteScroll,
IonInfiniteScrollContent,
IonSpinner,
IonGrid,
IonRow,
IonCol,
IonRefresher,
IonRefresherContent
]
})
export class TestFmodeChatPanelLifecycleComponent implements OnInit {
doctors:FmodeObject[] = [];
consultations:FmodeObject[] = [];
isLoading = false;
isRefreshing = false;
constructor(private modalCtrl: ModalController) {
addIcons({
medicalOutline,
medkitOutline,
chatbubbleOutline,
timeOutline,
refreshOutline,
arrowForwardOutline
});
}
async ngOnInit() {
await this.loadDoctors();
await this.loadConsultations();
}
// 加载医生列表
async loadDoctors() {
this.isLoading = true;
try {
const query = new Parse.Query('Doctor');
query.include('depart');
query.equalTo('available', true);
query.descending('createdAt');
this.doctors = await query.find();
} catch (error) {
console.error('加载医生列表失败:', error);
} finally {
this.isLoading = false;
}
}
// 加载咨询记录
async loadConsultations(event?: InfiniteScrollCustomEvent) {
if (!event) {
this.isRefreshing = true;
}
try {
const query = new Parse.Query('DoctorConsult');
query.include(['doctor', 'department']);
query.equalTo('patient', Parse.User.current());
query.descending('updatedAt');
query.limit(10);
if (event) {
query.skip(this.consultations.length);
}
const results = await query.find();
if (event) {
this.consultations = [...this.consultations, ...results];
event.target.complete();
if (results.length < 10) {
event.target.disabled = true;
}
} else {
this.consultations = results;
}
} catch (error) {
console.error('加载咨询记录失败:', error);
} finally {
this.isRefreshing = false;
}
}
// 刷新数据
async handleRefresh(event: any) {
await this.loadDoctors();
await this.loadConsultations();
event.target.complete();
}
// 处理问诊(新建或恢复)
async handleConsultation(doctor:FmodeObject, consultation?:FmodeObject) {
localStorage.setItem("company", "E4KpGvTEto");
// 如果是新建咨询,创建记录
if (!consultation) {
consultation = new Parse.Object('DoctorConsult');
consultation.set('title', `${doctor.get('depart')?.get('name') || '未知科室'}问诊`);
consultation.set('doctor', doctor);
consultation.set('department', doctor.get('depart'));
consultation.set('patient', Parse.User.current());
consultation.set('status', '进行中');
consultation.set('consultationTime', new Date());
// await consultation.save();
}
const options: ChatPanelOptions = {
roleId: "2DXJkRsjXK",
chatId: consultation?.get('chatId'),
onChatInit: (chat: FmodeChat) => {
const currentDoctor = consultation?.get('doctor') || doctor;
// 设置医生角色信息
chat.role.set("name", currentDoctor.get('name'));
chat.role.set("title", currentDoctor.get('title'));
chat.role.set("desc", `${currentDoctor.get('title')} ${currentDoctor.get('name')}`);
chat.role.set("tags", [
consultation?.get('department')?.get('name') || currentDoctor.get('depart')?.get('name'),
currentDoctor.get('expertise')
]);
chat.role.set("avatar", currentDoctor.get('avatar') || "assets/images/default-doctor.png");
// 完整的角色提示词
chat.role.set("prompt", `
# 角色设定
您是一名亲切和蔼的专业的全科医生,${currentDoctor.get('name')},需要完成一次完整的门诊服务。
# 对话环节
## 1. 导诊环节:欢迎用户,请用户描述症状
用户回答后,引导合适科室,开始问诊
## 2. 问诊环节:询问症状细节、询问病史等关键信息
用户回答后进入下阶段
## 3. 检查环节:开检查单,并提醒用户检查后反馈结果
用户反馈后进入下阶段
## 4. 处方环节:给出处方内容,同时结尾携带[处方完成]"
# 开始话语
当您准备好了,可以以一个医生的身份,向来访的用户打招呼。并且每个阶段,主动一些。`);
// 对话灵感分类
const promptCates = [
{
"img": "https://file-cloud.fmode.cn/UP2cStyjuk/20231211/r1ltv1023812146.png",
"name": "外科"
},
{
"img": "https://file-cloud.fmode.cn/UP2cStyjuk/20231211/fo81fg034154259.png",
"name": "内科"
},
{
"img": "https://file-cloud.fmode.cn/UP2cStyjuk/20231211/fc1nqi034201098.png",
"name": "心理"
}
];
// 对话灵感列表
const promptList = [
{
cate: "外科",
img: "https://file-cloud.fmode.cn/UP2cStyjuk/20231211/r1ltv1023812146.png",
messageList: [
"局部疼痛或肿胀", "伤口出血或感染", "关节活动受限",
"体表肿块或结节", "外伤后活动障碍", "皮肤溃疡不愈合",
"异物刺入或嵌顿", "术后并发症复查", "肢体麻木或无力",
"运动损伤疼痛"
]
},
{
cate: "内科",
img: "https://file-cloud.fmode.cn/UP2cStyjuk/20231211/fo81fg034154259.png",
messageList: [
"反复发热或低热", "持续咳嗽咳痰", "胸闷气短心悸",
"慢性腹痛腹泻", "头晕头痛乏力", "体重骤增或骤减",
"食欲异常或消化不良", "尿频尿急尿痛", "睡眠障碍易醒",
"异常出汗或怕冷"
]
},
{
cate: "心理",
img: "https://file-cloud.fmode.cn/UP2cStyjuk/20231211/fc1nqi034201098.png",
messageList: [
"持续情绪低落", "焦虑紧张不安", "失眠或睡眠过多",
"注意力难以集中", "社交恐惧回避", "强迫思维或行为",
"记忆减退疑虑", "躯体无器质性疼痛", "自杀倾向念头",
"现实感丧失体验"
]
},
];
setTimeout(() => {
chat.role.set("promptCates", promptCates);
const ChatPrompt = Parse.Object.extend("ChatPrompt");
chat.promptList = promptList.map(item => {
const prompt = new ChatPrompt();
prompt.set(item);
prompt.img = item.img;
return prompt;
});
}, 500);
// 功能按钮区域预设
chat.leftButtons = [
{
title: "话题灵感",
showTitle: true,
icon: "color-wand-outline",
onClick: () => {
chat.isPromptModalOpen = true;
},
show: () => {
return chat?.promptList?.length;
}
},
{
title: "门诊归档",
showTitle: true,
icon: "archive-outline",
onClick: () => {
console.log(chat?.chatSession);
},
show: () => true
}
];
},
onMessage: (chat: FmodeChat, message: FmodeChatMessage) => {
const content = message?.content;
if (typeof content === 'string' && content.includes('[处方完成]')) {
console.log('处方完成,保存咨询记录');
consultation?.set('content', content);
consultation?.set('status', '已完成');
consultation?.save();
}
},
onChatSaved: (chat: FmodeChat) => {
console.log('咨询会话保存', chat?.chatSession?.id);
consultation?.set('chatId', chat?.chatSession?.id);
consultation?.save();
}
};
openChatPanelModal(this.modalCtrl, options);
}
// 格式化时间
}