2 lines
17 KiB
JavaScript
2 lines
17 KiB
JavaScript
import{d as e,a as l,r as a,c as s,o as t,b as n,e as o,f as i,w as c,i as u,E as r,j as d,t as m,l as p,m as f,F as g,n as _,k as h,g as v,G as b,y as k,z as y,x,S as C,u as V,I as $,M as w}from"./index-CpNRQgjE.js";import{_ as F}from"./config-doctor.TgARj_nM.js";import{r as I}from"./cases.BlouN7SM.js";import{c as D,a as j,b as A}from"./navigation.CsipbD6y.js";import{b as P,d as T,u as U,s as E,e as N}from"./session.Cc2HEzjU.js";import{_ as q}from"./_plugin-vue_export-helper.BCo6x5W8.js";const O={id:"case-1006004",title:"持续胸痛3小时",patientName:"陈先生",gender:"男",age:60,department:"心血管内科",scene:"住院部",caseNo:"1006004",tone:"orange",mode:"training"};const S=q(e({__name:"chat",props:{caseItem:{}},emits:["open-settings","open-profile","go-home"],setup(e,{emit:q}){const S=e,M=q,H=D(M),X=j(M),z=A(M),B=l({patient:{name:"陈先生",gender:"男",age:60,department:"心血管内科",chiefComplaint:"持续胸痛3小时"},stages:[{key:"history",label:"病史采集",active:!0},{key:"diagnosis",label:"初步诊断",active:!1},{key:"treatment",label:"治疗方案",active:!1}],messages:[]}),G=a(""),Q=a(!1),R=a(!1),J=a(!1),K=a(0),L=a(""),W=a(!1),Y=a(!1),Z=a(!1),ee=a(null),le=a(null);let ae=null,se=null,te=null;const ne=[{name:"心电图",result:"检查结果:床边12导联心电图提示窦性心律,II、III、aVF 导联 ST 段抬高,提示下壁急性心肌梗死可能。"},{name:"胸部X线",result:"检查结果:胸部X线未见明显气胸或纵隔明显增宽,心影大小基本正常,不能排除急性冠脉综合征。"},{name:"心脏超声",result:"检查结果:心脏超声提示左室下壁节段性运动减低,未见大量心包积液,需结合心电图及心肌标志物判断。"},{name:"冠脉CTA",result:"检查结果:冠脉CTA提示右冠状动脉近段重度狭窄/闭塞可能,建议结合急诊介入评估。"}],oe=l({temperature:"",pulse:"",respiration:"",bloodPressure:"",spo2:"",complexion:"",examFinding:"",otherFinding:""}),ie=s((()=>S.caseItem||le.value)),ce=s((()=>B.patient.chiefComplaint.includes("胸痛")?"胸痛":B.patient.chiefComplaint.slice(0,6)));function ue(){(function(e){const l=e||O,a="毕波涛"===l.patientName?"陈先生":l.patientName;return Promise.resolve({patient:{name:a,gender:l.gender,age:l.age,department:l.department,chiefComplaint:l.title},stages:[{key:"history",label:"病史采集",active:!0},{key:"diagnosis",label:"初步诊断",active:!1},{key:"treatment",label:"治疗方案",active:!1}],messages:[{id:"patient-initial",role:"patient",content:"心血管内科"===l.department?"医生,我心口这儿针扎一样疼了两个小时了,现在感觉喘气都费劲。":`医生,我这次主要是${l.title},有点担心。`,label:"患者"},{id:"mentor-initial",role:"mentor",content:"观察患者的面部表情和生命体征。你的第一个问题应该如何询问,以明确疼痛的性质?",label:"王主任"}]})})(ie.value).then((e=>{var l;Object.assign(B.patient,e.patient),B.stages=e.stages;const a=P();if(null==(l=null==a?void 0:a.session)?void 0:l.session_id)return ee.value=a.session.session_id,B.messages=a.session.patient_opening?[{id:`patient-opening-${a.session.session_id}`,role:"patient",content:a.session.patient_opening,label:"患者"}]:[],ve(),void _e("开始问诊");B.messages=e.messages,ve()}))}async function re(){if(J.value)return;if(Q.value||R.value)return void be("请等待当前回复完成");const e=ee.value;if(e){J.value=!0;try{const l=await T(e);U(l.status),b({url:"/pages/diagnosis/diagnosis"})}catch(l){be(l instanceof Error?l.message:"完成采集失败")}finally{J.value=!1}}else be("未找到当前会话,请先生成模拟场景")}function de(){Z.value=!1,Y.value=!0}function me(){Y.value=!1,Z.value=!0}function pe(){const e=[oe.temperature.trim()?`体温 ${oe.temperature.trim()}℃`:"",oe.pulse.trim()?`心率 ${oe.pulse.trim()}次/分`:"",oe.respiration.trim()?`呼吸 ${oe.respiration.trim()}次/分`:"",oe.bloodPressure.trim()?`血压 ${oe.bloodPressure.trim()}mmHg`:"",oe.spo2.trim()?`血氧 ${oe.spo2.trim()}%`:"",oe.complexion.trim()?`意识/面色:${oe.complexion.trim()}`:"",oe.examFinding.trim()?`心肺/腹部查体:${oe.examFinding.trim()}`:"",oe.otherFinding.trim()?`其他发现:${oe.otherFinding.trim()}`:""].filter(Boolean);if(0===e.length)return void be("请至少录入一项体格检查");const l=Date.now(),a=[{id:`doctor-physical-${l}`,role:"doctor",content:`录入体格检查:${e.join(";")}`,label:"我"},{id:`mentor-physical-${l+1}`,role:"mentor",content:fe(),label:"AI助手"}];B.messages.push(...a),Z.value=!1,oe.temperature="",oe.pulse="",oe.respiration="",oe.bloodPressure="",oe.spo2="",oe.complexion="",oe.examFinding="",oe.otherFinding="",ve()}function fe(){const e=Number(oe.pulse),l=Number(oe.respiration),a=Number(oe.spo2),s=Number(oe.temperature),t=[];e>=100&&t.push("心率偏快"),l>=22&&t.push("呼吸频率偏快"),a>0&&a<95&&t.push("血氧偏低"),s>=37.3&&t.push("体温偏高"),(oe.complexion.includes("苍白")||oe.complexion.includes("出汗"))&&t.push("面色/出汗提示急性病容"),(oe.otherFinding.includes("血压差")||oe.otherFinding.includes("双侧"))&&t.push("双侧血压或脉搏差异需警惕主动脉夹层");return`${t.length?`已记录体格检查。当前提示:${t.join("、")}。`:"已记录体格检查,暂未见明确异常体征。"}建议结合胸痛性质、心电图及心肌标志物进一步判断,并持续监测生命体征变化。`}function ge(){const e=G.value.trim();if(e&&!Q.value){if(G.value="",ee.value)return B.messages.push({id:`doctor-${Date.now()}`,role:"doctor",content:e,label:"我"}),ve(),void _e(e);Q.value=!0,function(e){const l=e.trim(),a=l.includes("出冷汗")||l.includes("恶心")?"有,刚才疼得厉害的时候出了一身冷汗,还有点恶心,但没有吐。":l.includes("体格检查")?"患者面色苍白,额部出汗,心率偏快,血压较入院时略低。":l.includes("辅助检查")?"心电图提示下壁导联 ST 段抬高,肌钙蛋白待回报。":"疼痛主要在胸骨后,像压榨一样,休息后也没有明显缓解。";return Promise.resolve([{id:`doctor-${Date.now()}`,role:"doctor",content:l,label:"我"},{id:`patient-${Date.now()+1}`,role:"patient",content:a,label:"患者"},{id:`mentor-${Date.now()+2}`,role:"mentor",content:"很好,继续围绕 OPQRST 思路追问疼痛诱因、部位、性质、放射、持续时间和缓解因素,同时关注危险信号。",label:"王主任"}])}(e).then((e=>{B.messages.push(...e),ve()})).finally((()=>{Q.value=!1}))}}async function _e(e){const l=ee.value;if(!l)return;Q.value=!0,null==se||se.abort(),se=new AbortController;const a=B.messages.length;B.messages.push({id:`patient-stream-${Date.now()}`,role:"patient",content:"",label:"患者"}),ve();try{await E(l,e,{onDelta(e){B.messages[a].content+=e,ve()}},se.signal)}catch(s){if(s instanceof DOMException&&"AbortError"===s.name)return;B.messages[a].content.trim()||(B.messages[a].content="AI 病人回复失败,请重试。"),be(s instanceof Error?s.message:"AI 流式回复异常")}finally{Q.value=!1,se=null,ve()}}async function he(){const e=ee.value;if(!e)return void be("请先生成模拟场景");if(R.value)return;R.value=!0,null==te||te.abort(),te=new AbortController;const l=B.messages.length;B.messages.push({id:`mentor-hint-${Date.now()}`,role:"mentor",content:"王主任正在生成提示...",label:"王主任"}),ve();try{let a=!1;await N(e,function(){const e=[...B.messages].reverse().find((e=>"doctor"===e.role));return(null==e?void 0:e.content)||"开始问诊"}(),{onDelta(e){a||(B.messages[l].content="",a=!0),B.messages[l].content+=e,ve()}},te.signal)}catch(a){if(a instanceof DOMException&&"AbortError"===a.name)return;B.messages[l].content.trim()&&"王主任正在生成提示..."!==B.messages[l].content||(B.messages[l].content="练习提示生成失败,请稍后重试。"),be(a instanceof Error?a.message:"练习提示生成失败,请稍后重试")}finally{R.value=!1,te=null,ve()}}function ve(){setTimeout((()=>{K.value+=1e3}),60)}function be(e){ae&&clearTimeout(ae),L.value=e,W.value=!0,ae=setTimeout((()=>{W.value=!1}),2200)}return t((()=>{le.value=I(),ue()})),n((()=>{null==se||se.abort(),null==te||te.abort(),ae&&clearTimeout(ae)})),(e,l)=>{const a=k,s=y,t=x,n=C,b=V,I=$,D=w;return o(),i(a,{class:"chat-page"},{default:c((()=>[u(a,{class:"chat-shell"},{default:c((()=>[u(a,{class:"top-nav"},{default:c((()=>[u(s,{class:"icon-button","aria-label":"设置",onClick:r(X)},{default:c((()=>[u(a,{class:"settings-icon"})])),_:1},8,["onClick"]),u(s,{class:"icon-button home-button","aria-label":"首页",onClick:r(z)},{default:c((()=>[u(a,{class:"home-icon"})])),_:1},8,["onClick"]),u(a,{class:"nav-spacer"}),u(s,{class:"icon-button","aria-label":"个人中心",onClick:r(H)},{default:c((()=>[u(a,{class:"account-icon"})])),_:1},8,["onClick"])])),_:1}),u(a,{class:"case-header"},{default:c((()=>[u(a,{class:"case-title-row"},{default:c((()=>[u(t,{class:"case-heading"},{default:c((()=>[d("患者:"+m(B.patient.name)+" ("+m(ce.value)+")",1)])),_:1}),u(s,{class:"finish-button",disabled:J.value,onClick:re},{default:c((()=>[u(a,{class:"check-icon"}),u(t,null,{default:c((()=>[d(m(J.value?"提交中":"完成采集"),1)])),_:1})])),_:1},8,["disabled"])])),_:1}),u(a,{class:"patient-meta"},{default:c((()=>[u(t,null,{default:c((()=>[d("姓名:"+m(B.patient.name),1)])),_:1}),u(t,null,{default:c((()=>[d("性别:"+m(B.patient.gender),1)])),_:1}),u(t,null,{default:c((()=>[d("年龄:"+m(B.patient.age)+"岁",1)])),_:1}),u(t,null,{default:c((()=>[d("科室:"+m(B.patient.department),1)])),_:1})])),_:1})])),_:1}),u(a,{class:"stage-bar"},{default:c((()=>[u(a,{class:"stage-line"}),u(a,{class:"stage-line-active"}),(o(!0),p(g,null,f(B.stages,(e=>(o(),i(a,{key:e.key,class:_(["stage-item",{active:e.active}])},{default:c((()=>[u(a,{class:"stage-dot"},{default:c((()=>[u(a,{class:_(["stage-icon",`stage-icon-${e.key}`])},null,8,["class"])])),_:2},1024),u(t,null,{default:c((()=>[d(m(e.label),1)])),_:2},1024)])),_:2},1032,["class"])))),128))])),_:1}),u(n,{class:"chat-body","scroll-y":"","scroll-top":K.value},{default:c((()=>[u(a,{class:"message-list"},{default:c((()=>[(o(!0),p(g,null,f(B.messages,(e=>(o(),i(a,{key:e.id,class:_(["message-row",[`role-${e.role}`]])},{default:c((()=>["patient"===e.role?(o(),i(a,{key:0,class:"avatar patient-avatar"},{default:c((()=>[u(t,null,{default:c((()=>[d(m(B.patient.name.slice(0,1)),1)])),_:1})])),_:1})):v("",!0),u(a,{class:_(["message-bubble",`${e.role}-bubble`])},{default:c((()=>[u(t,{class:"message-content"},{default:c((()=>[d('"'+m(e.content)+'"',1)])),_:2},1024),u(a,{class:_(["message-label",{mentor:"mentor"===e.role}])},{default:c((()=>["mentor"===e.role?(o(),i(a,{key:0,class:"star-icon"})):v("",!0),u(t,null,{default:c((()=>[d(m(e.label),1)])),_:2},1024)])),_:2},1032,["class"])])),_:2},1032,["class"]),"doctor"===e.role?(o(),i(a,{key:1,class:"avatar doctor-avatar"},{default:c((()=>[u(a,{class:"person-icon"})])),_:1})):v("",!0)])),_:2},1032,["class"])))),128))])),_:1})])),_:1},8,["scroll-top"]),u(a,{class:_(["mentor-float",{loading:R.value}]),onClick:[h(he,["stop"]),h(he,["stop"])]},{default:c((()=>[u(t,{class:"mentor-badge"},{default:c((()=>[d("王主任")])),_:1}),u(a,{class:"mentor-avatar",onClick:[h(he,["stop"]),h(he,["stop"])]},{default:c((()=>[u(b,{src:F,mode:"aspectFill"})])),_:1})])),_:1},8,["class"]),u(a,{class:"input-panel"},{default:c((()=>[u(n,{class:"quick-actions","scroll-x":""},{default:c((()=>[u(a,{class:"quick-row"},{default:c((()=>[u(s,{class:"quick-chip",onClick:me},{default:c((()=>[d("体格检查")])),_:1}),u(s,{class:"quick-chip",onClick:de},{default:c((()=>[d("辅助检查")])),_:1})])),_:1})])),_:1}),u(a,{class:"input-row"},{default:c((()=>[u(I,{class:"chat-input",modelValue:G.value,"onUpdate:modelValue":l[0]||(l[0]=e=>G.value=e),type:"text",placeholder:"输入你对患者的提问...","placeholder-class":"input-placeholder",onConfirm:ge},null,8,["modelValue"]),u(s,{class:"send-button",disabled:Q.value,onClick:ge},{default:c((()=>[u(a,{class:"send-icon"})])),_:1},8,["disabled"])])),_:1})])),_:1})])),_:1}),Z.value?(o(),i(a,{key:0,class:"exam-mask",onClick:l[12]||(l[12]=e=>Z.value=!1)},{default:c((()=>[u(a,{class:"physical-panel",onClick:l[11]||(l[11]=h((()=>{}),["stop"]))},{default:c((()=>[u(a,{class:"exam-header"},{default:c((()=>[u(t,{class:"exam-title"},{default:c((()=>[d("录入体格检查")])),_:1}),u(s,{class:"exam-close","aria-label":"关闭",onClick:l[1]||(l[1]=e=>Z.value=!1)},{default:c((()=>[u(a,{class:"close-icon"})])),_:1})])),_:1}),u(n,{class:"physical-form","scroll-y":""},{default:c((()=>[u(a,{class:"vital-grid"},{default:c((()=>[u(a,{class:"form-field"},{default:c((()=>[u(t,{class:"field-label"},{default:c((()=>[d("体温")])),_:1}),u(I,{class:"field-input",modelValue:oe.temperature,"onUpdate:modelValue":l[2]||(l[2]=e=>oe.temperature=e),type:"digit",placeholder:"36.8","placeholder-class":"field-placeholder"},null,8,["modelValue"]),u(t,{class:"field-unit"},{default:c((()=>[d("℃")])),_:1})])),_:1}),u(a,{class:"form-field"},{default:c((()=>[u(t,{class:"field-label"},{default:c((()=>[d("心率")])),_:1}),u(I,{class:"field-input",modelValue:oe.pulse,"onUpdate:modelValue":l[3]||(l[3]=e=>oe.pulse=e),type:"number",placeholder:"98","placeholder-class":"field-placeholder"},null,8,["modelValue"]),u(t,{class:"field-unit"},{default:c((()=>[d("次/分")])),_:1})])),_:1}),u(a,{class:"form-field"},{default:c((()=>[u(t,{class:"field-label"},{default:c((()=>[d("呼吸")])),_:1}),u(I,{class:"field-input",modelValue:oe.respiration,"onUpdate:modelValue":l[4]||(l[4]=e=>oe.respiration=e),type:"number",placeholder:"22","placeholder-class":"field-placeholder"},null,8,["modelValue"]),u(t,{class:"field-unit"},{default:c((()=>[d("次/分")])),_:1})])),_:1}),u(a,{class:"form-field"},{default:c((()=>[u(t,{class:"field-label"},{default:c((()=>[d("血氧")])),_:1}),u(I,{class:"field-input",modelValue:oe.spo2,"onUpdate:modelValue":l[5]||(l[5]=e=>oe.spo2=e),type:"number",placeholder:"96","placeholder-class":"field-placeholder"},null,8,["modelValue"]),u(t,{class:"field-unit"},{default:c((()=>[d("%")])),_:1})])),_:1})])),_:1}),u(a,{class:"form-field full"},{default:c((()=>[u(t,{class:"field-label"},{default:c((()=>[d("血压")])),_:1}),u(I,{class:"field-input",modelValue:oe.bloodPressure,"onUpdate:modelValue":l[6]||(l[6]=e=>oe.bloodPressure=e),type:"text",placeholder:"138/86","placeholder-class":"field-placeholder"},null,8,["modelValue"]),u(t,{class:"field-unit"},{default:c((()=>[d("mmHg")])),_:1})])),_:1}),u(a,{class:"form-field full"},{default:c((()=>[u(t,{class:"field-label"},{default:c((()=>[d("意识/面色")])),_:1}),u(I,{class:"field-input",modelValue:oe.complexion,"onUpdate:modelValue":l[7]||(l[7]=e=>oe.complexion=e),type:"text",placeholder:"清醒,面色苍白,出汗","placeholder-class":"field-placeholder"},null,8,["modelValue"])])),_:1}),u(a,{class:"form-field textarea-field"},{default:c((()=>[u(t,{class:"field-label"},{default:c((()=>[d("心肺/腹部查体")])),_:1}),u(D,{class:"field-textarea",modelValue:oe.examFinding,"onUpdate:modelValue":l[8]||(l[8]=e=>oe.examFinding=e),placeholder:"心音、肺部啰音、腹部压痛等","placeholder-class":"field-placeholder"},null,8,["modelValue"])])),_:1}),u(a,{class:"form-field textarea-field"},{default:c((()=>[u(t,{class:"field-label"},{default:c((()=>[d("其他发现")])),_:1}),u(D,{class:"field-textarea",modelValue:oe.otherFinding,"onUpdate:modelValue":l[9]||(l[9]=e=>oe.otherFinding=e),placeholder:"如双侧血压差、下肢水肿、神经系统体征等","placeholder-class":"field-placeholder"},null,8,["modelValue"])])),_:1})])),_:1}),u(a,{class:"physical-actions"},{default:c((()=>[u(s,{class:"physical-cancel",onClick:l[10]||(l[10]=e=>Z.value=!1)},{default:c((()=>[d("取消")])),_:1}),u(s,{class:"physical-submit",onClick:pe},{default:c((()=>[d("提交检查结果")])),_:1})])),_:1})])),_:1})])),_:1})):v("",!0),Y.value?(o(),i(a,{key:1,class:"exam-mask",onClick:l[15]||(l[15]=e=>Y.value=!1)},{default:c((()=>[u(a,{class:"exam-panel",onClick:l[14]||(l[14]=h((()=>{}),["stop"]))},{default:c((()=>[u(a,{class:"exam-header"},{default:c((()=>[u(t,{class:"exam-title"},{default:c((()=>[d("选择辅助检查")])),_:1}),u(s,{class:"exam-close","aria-label":"关闭",onClick:l[13]||(l[13]=e=>Y.value=!1)},{default:c((()=>[u(a,{class:"close-icon"})])),_:1})])),_:1}),u(a,{class:"exam-list"},{default:c((()=>[(o(),p(g,null,f(ne,(e=>u(s,{key:e.name,class:"exam-item",onClick:l=>function(e){Y.value=!1;const l=Date.now(),a=[{id:`doctor-exam-${l}`,role:"doctor",content:`选择辅助检查:${e.name}`,label:"我"},{id:`mentor-exam-${l+1}`,role:"mentor",content:e.result,label:"AI助手"}];B.messages.push(...a),ve()}(e)},{default:c((()=>[u(t,{class:"exam-name"},{default:c((()=>[d(m(e.name),1)])),_:2},1024),u(a,{class:"chevron-icon"})])),_:2},1032,["onClick"]))),64))])),_:1})])),_:1})])),_:1})):v("",!0),u(a,{class:_(["toast",{visible:W.value}])},{default:c((()=>[d(m(L.value),1)])),_:1},8,["class"])])),_:1})}}}),[["__scopeId","data-v-5cbdbcc3"]]);export{S as default};
|