Files
zyt/server/public/admin/assets/PrescriptionAiReportDialog-Bv2IvMg2.js
T

17 lines
18 KiB
JavaScript

import{K as Me,a3 as We,W as He,i as Ke,T as Qe,m as Xe,l as Ye,s as Ze,C as et,L as tt,V as rt}from"./element-plus-CWHdHlgZ.js";import{c as st,d as at,b as ot}from"./tcm-CdJxXEws.js";import{u as it,j as B,_ as nt}from"./index-dDVfDL1w.js";import{f as $e,ak as i,G as f,aN as n,I as k,J as o,a as g,H as b,O as y,F as Ie,ap as lt,aP as pt,i as re,A as U}from"./@vue/runtime-core-C6bnekPw.js";import{Q as _,o as ut}from"./@vue/shared-mAAVTE9n.js";import{y as K,n as R,r as dt}from"./@vue/reactivity-DiY1c2vO.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-CbYn5zW9.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const ct={class:"dialog-heading"},ft=["id"],mt={key:0,class:"report-shell"},vt={class:"prescription-snapshot"},yt={class:"snapshot-content"},_t={key:1,class:"report-loading"},gt={key:2,class:"report-error"},bt={class:"error-message"},kt={key:3,class:"report-error"},Et={class:"model-tab-label"},ht={class:"model-name"},Rt={class:"report-pane","element-loading-text":"正在重新生成整个诊断报告…"},wt={key:0,class:"report-error"},At={class:"error-message"},Ct={class:"report-document"},St={class:"report-meta"},xt={class:"report-meta-main"},$t={class:"report-title-line"},It={class:"report-times"},Tt={key:0},Vt={key:1,class:"report-editor"},Bt={class:"editor-actions"},zt={key:0,class:"report-summary"},Nt={class:"report-grid"},Lt={class:"report-section"},Pt={class:"report-section"},Ft={class:"report-section"},Ot={class:"report-section"},Dt={key:1,class:"report-section report-section-wide"},jt={class:"report-cautions"},Ut={class:"report-disclaimer"},qt={key:3,class:"report-section report-section-wide"},Gt={class:"raw-content"},Jt=$e({__name:"PrescriptionAiReportDialog",setup(Mt,{expose:Te}){const q=$e({name:"PrescriptionAiReportList",props:{items:{type:Array,default:()=>[]},emptyText:{type:String,default:"暂无"}},setup(t){return()=>t.items.length?re("ul",{class:"report-list"},t.items.map(e=>re("li",{key:e},e))):re("p",{class:"report-empty-text"},t.emptyText)}}),x=[{profile:"qwen",label:"千问",name:"qwen3.6-35b"},{profile:"openai",label:"OpenAI",name:"gpt-5.6-sol"}],Ve=["tcm.prescriptionLibrary/editAiReport","wcf.prescription/editAiReport"],Q=()=>({error:"",data:null,editing:!1,structuredEdit:!1,saving:!1,draft:"",originalContent:"",editError:""}),Be=it(),z=R(!1),E=R(null),N=R("qwen"),I=R(0),L=R(0),T=R(!1),$=R(""),h=R(!1),A=R(""),S=R(!1),P=R(!1),s=dt({qwen:Q(),openai:Q()}),ze=U(()=>{var e;const t=((e=E.value)==null?void 0:e.herbs)||[];return t.length?t.map(a=>`${a.name||"未命名药材"} ${a.dosage??"-"}g`).join("、"):"暂无药材"}),X=U(()=>x.some(({profile:t})=>!!(s[t].data||s[t].error))),F=U(()=>x.some(({profile:t})=>s[t].saving)),O=U(()=>x.some(({profile:t})=>s[t].editing)),Ne=U(()=>{const t=Be.perms||[];return t.includes("*")||Ve.some(e=>t.includes(e))}),Y=()=>{x.forEach(({profile:t})=>Object.assign(s[t],Q()))},G=t=>{if(typeof t=="string"&&t.trim())return t;if(t&&typeof t=="object"){const e=t,a=e.msg||e.message||e.error;if(typeof a=="string"&&a.trim())return a}return"模型服务暂时不可用,请稍后重试"},C=t=>t===I.value&&z.value&&!!E.value,se=t=>{var l,v;Y(),S.value=t.can_refresh===!0||((l=t.capabilities)==null?void 0:l.can_refresh)===!0,P.value=t.can_edit===!0||((v=t.capabilities)==null?void 0:v.can_edit)===!0,(Array.isArray(t.reports)?t.reports:[]).forEach(c=>{const m=s[c.model_key];m&&(m.data=c)}),(Array.isArray(t.results)?t.results:[]).forEach(c=>{const m=s[c.model_key];!m||c.status!=="error"||(m.error=c.error_message||"该模型报告生成失败,请重新生成整个报告")});const p=s[N.value];if(!p.data&&!p.error){const c=x.find(({profile:m})=>s[m].data||s[m].error);c&&(N.value=c.profile)}},Z=async(t=I.value,e={})=>{const a=E.value;if(!a)return;const p=++L.value;e.silent||(T.value=!0,$.value="");try{const l=await st({id:a.id});if(!C(t)||p!==L.value)return;se(l),$.value=""}catch(l){if(!C(t)||p!==L.value)return;e.silent?A.value=`报告已保存,但刷新最新内容失败:${G(l)}`:$.value=G(l)}finally{C(t)&&p===L.value&&!e.silent&&(T.value=!1)}},Le=async()=>{const t=E.value;if(!t||h.value)return;if(O.value){B.msgWarning("请先保存或取消正在编辑的报告");return}const e=I.value;h.value=!0,A.value="";try{const a=await ot({id:t.id});if(!C(e))return;se(a),a.status==="partial"?(A.value="部分模型重新生成失败;成功结果已保存,失败模型仍显示上一次保存版本。",B.msgWarning("诊断报告部分生成成功")):a.status==="error"?(A.value="全部模型重新生成失败,已保留原有报告。",B.msgError("诊断报告生成失败")):B.msgSuccess("诊断报告已生成并保存")}catch(a){if(!C(e))return;A.value=G(a)}finally{C(e)&&(h.value=!1)}},J=async()=>{if(X.value)try{await B.confirm("重新生成会再次调用全部模型,并以新结果覆盖当前诊断报告。确定继续吗?")}catch{return}await Le()},ae=t=>x.find(e=>e.profile===t),oe=t=>{var e;return((e=s[t].data)==null?void 0:e.model_label)||ae(t).label},ie=t=>{var e;return((e=s[t].data)==null?void 0:e.model_name)||ae(t).name},Pe=t=>{const e=s[t].data;return(e==null?void 0:e.generated_at)||"—"},ne=t=>{const e=s[t].data;return(e==null?void 0:e.edited_at)||""},Fe=t=>{const e=s[t].data;return(e==null?void 0:e.is_edited)===!0},Oe=t=>{var e;return!!((e=s[t].data)!=null&&e.report)},M=["核心判断","可能症状与证候","主治方向","主要功效","可能适用人群","配伍分析","用药与复核提醒","免责声明"],le=t=>{const e=t.replace(/^\uFEFF/,"").replace(/\r\n?/g,`
`).split(`
`),a=[];for(const u of M){const d=e.reduce((w,V,te)=>(V.trim()===u&&w.push(te),w),[]);if(!d.length)return{ok:!1,error:`缺少章节标题“${u}”。请保留全部八个中文章节标题后再保存。`};if(d.length>1)return{ok:!1,error:`章节标题“${u}”出现了多次,请仅保留一个标题。`};a.push(d[0])}for(let u=1;u<a.length;u++)if(a[u]<=a[u-1])return{ok:!1,error:`章节顺序不正确,请依次保留:${M.join("、")}。`};const p=u=>{const d=a[u]+1,w=a[u+1]??e.length;return e.slice(d,w).join(`
`).trim()},l=M.map((u,d)=>p(d)),v=l.findIndex(u=>!u);if(v>=0)return{ok:!1,error:`章节“${M[v]}”内容不能为空;如无内容请填写“暂无”。`};const c=u=>u==="暂无"?"":u,m=u=>u==="暂无"?[]:u.split(`
`).map(d=>d.trim()).filter(Boolean).map(d=>d.replace(/^(?:[-*•]\s+|\d+[.)、]\s*)/,"").trim()).filter(Boolean);return{ok:!0,report:{summary:c(l[0]),possible_symptoms:m(l[1]),main_indications:c(l[2]),efficacy:m(l[3]),suitable_people:m(l[4]),compatibility_analysis:c(l[5]),cautions:m(l[6]),disclaimer:c(l[7])}}},pe=t=>{if(!t)return"";const e=a=>a.length?a.map(p=>`- ${p}`).join(`
`):"暂无";return[`核心判断
${t.summary||"暂无"}`,`可能症状与证候
${e(t.possible_symptoms||[])}`,`主治方向
${t.main_indications||"暂无"}`,`主要功效
${e(t.efficacy||[])}`,`可能适用人群
${e(t.suitable_people||[])}`,`配伍分析
${t.compatibility_analysis||"暂无"}`,`用药与复核提醒
${e(t.cautions||[])}`,`免责声明
${t.disclaimer||"仅供专业人员辅助审方,不替代辨证、诊断和处方审核。"}`].join(`
`)},ee=t=>!!s[t].data&&P.value&&Ne.value,De=t=>{const e=s[t];if(!e.data||!ee(t))return;let a=e.data.report;if(!a&&e.data.content){const l=le(e.data.content);l.ok&&(a=l.report)}e.structuredEdit=!!a;const p=a?pe(a):e.data.content;e.originalContent=p,e.draft=p,e.editError="",e.editing=!0},je=t=>{const e=s[t];e.draft=e.originalContent,e.editError="",e.editing=!1,e.structuredEdit=!1},Ue=t=>t.report,qe=async t=>{var u;const e=s[t],a=e.data;if(!a||e.saving||!ee(t))return;if(!e.draft.trim()){e.editError="报告内容不能为空";return}let p=null,l=e.draft;if(e.structuredEdit){const d=le(e.draft);if(!d.ok){e.editError=d.error;return}p=d.report,l=JSON.stringify(d.report)}if(l.length>12e3){e.editError="报告保存内容不能超过 12000 个字符,请精简后再保存";return}const v=Number(a.report_id||a.id||0);if(!v){e.editError="报告标识缺失,请重新加载后再试";return}const c=Number(((u=E.value)==null?void 0:u.id)||0);if(!c){e.editError="处方标识缺失,请关闭窗口后重试";return}const m=I.value;e.saving=!0,e.editError="";try{const d=await at({id:c,report_id:v,content:l});if(!C(m))return;const w=Ue(d),V=p&&!w.report?{...w,report:p}:w;e.data=V,e.error="",P.value=d.can_edit===!0,S.value=d.can_refresh===!0,e.originalContent=p?pe(p):V.content||e.draft,e.draft=e.originalContent,e.editing=!1,e.structuredEdit=!1,B.msgSuccess("报告修改已保存"),await Z(m,{silent:!0})}catch(d){if(!C(m))return;e.editError=G(d)}finally{C(m)&&(e.saving=!1)}},Ge=t=>{E.value={id:t.id,prescription_name:t.prescription_name,formula_type:t.formula_type,herbs:t.herbs?JSON.parse(JSON.stringify(t.herbs)):[]},N.value="qwen",Y(),$.value="",A.value="",S.value=!1,P.value=!1,T.value=!1,h.value=!1;const e=++I.value;z.value=!0,Z(e)},Je=()=>{I.value++,L.value++,E.value=null,T.value=!1,h.value=!1,$.value="",A.value="",S.value=!1,P.value=!1,Y()};return Te({open:Ge}),(t,e)=>{const a=Qe,p=Me,l=We,v=Ke,c=He,m=et,u=Ze,d=Ye,w=Xe,V=rt,te=tt;return i(),f(V,{modelValue:z.value,"onUpdate:modelValue":e[3]||(e[3]=r=>z.value=r),class:"prescription-ai-dialog",width:"min(920px, calc(100vw - 32px))",top:"5vh",title:"AI 处方解释","close-on-click-modal":!1,"destroy-on-close":"",onClosed:Je},{header:n(({titleId:r,titleClass:W})=>{var D,j;return[o("div",ct,[o("div",null,[o("h2",{id:r,class:ut(W)},"AI 处方解释",10,ft),o("p",null,_(((D=E.value)==null?void 0:D.prescription_name)||"未选择处方"),1)]),(j=E.value)!=null&&j.formula_type?(i(),f(a,{key:0,type:"info",effect:"plain"},{default:n(()=>[y(_(E.value.formula_type),1)]),_:1})):b("",!0)])]}),footer:n(()=>[g(v,{onClick:e[2]||(e[2]=r=>z.value=!1)},{default:n(()=>[...e[28]||(e[28]=[y("关闭",-1)])]),_:1}),S.value?(i(),f(v,{key:0,type:"primary",loading:h.value,disabled:!E.value||T.value||F.value||O.value,onClick:J},{default:n(()=>[y(_(X.value?"重新生成整个诊断报告":"生成诊断报告"),1)]),_:1},8,["loading","disabled"])):b("",!0)]),default:n(()=>[E.value?(i(),k("div",mt,[o("div",vt,[e[4]||(e[4]=o("span",{class:"snapshot-label"},"药材组合",-1)),o("span",yt,_(ze.value),1)]),g(p,{class:"medical-notice",type:"warning",closable:!1,"show-icon":"",title:"AI 仅依据药材组合推测可能证候与主治方向,不能替代四诊、辨证和处方审核。"}),A.value?(i(),f(p,{key:0,class:"operation-error",type:"error",closable:!1,"show-icon":"",title:A.value},null,8,["title"])):b("",!0),T.value?(i(),k("div",_t,[g(l,{rows:9,animated:""})])):$.value?(i(),k("div",gt,[g(c,{description:"已保存报告加载失败","image-size":72},{default:n(()=>[o("p",bt,_($.value),1),g(v,{type:"primary",plain:"",onClick:e[0]||(e[0]=r=>Z())},{default:n(()=>[...e[5]||(e[5]=[y(" 重新加载 ",-1)])]),_:1})]),_:1})])):X.value?(i(),f(w,{key:4,modelValue:N.value,"onUpdate:modelValue":e[1]||(e[1]=r=>N.value=r),class:"model-tabs"},{default:n(()=>[(i(),k(Ie,null,lt(x,r=>g(d,{key:r.profile,name:r.profile},{label:n(()=>[o("span",Et,[o("span",null,_(oe(r.profile)),1),o("span",ht,_(ie(r.profile)),1),h.value?(i(),f(a,{key:0,size:"small",type:"info",effect:"plain"},{default:n(()=>[...e[9]||(e[9]=[y(" 更新中 ",-1)])]),_:1})):s[r.profile].error?(i(),f(a,{key:1,size:"small",type:"danger",effect:"plain"},{default:n(()=>[...e[10]||(e[10]=[y(" 更新失败 ",-1)])]),_:1})):s[r.profile].data?(i(),f(a,{key:2,size:"small",type:"success",effect:"plain"},{default:n(()=>[...e[11]||(e[11]=[y(" 已保存 ",-1)])]),_:1})):(i(),f(a,{key:3,size:"small",type:"info",effect:"plain"},{default:n(()=>[...e[12]||(e[12]=[y(" 未生成 ",-1)])]),_:1}))])]),default:n(()=>[pt((i(),k("div",Rt,[s[r.profile].error&&!s[r.profile].data?(i(),k("div",wt,[g(c,{description:"这份模型报告生成失败","image-size":72},{default:n(()=>[o("p",At,_(s[r.profile].error),1),S.value?(i(),f(v,{key:0,type:"primary",plain:"",loading:h.value,disabled:F.value||O.value,onClick:J},{default:n(()=>[...e[13]||(e[13]=[y(" 重新生成整个报告 ",-1)])]),_:1},8,["loading","disabled"])):b("",!0)]),_:2},1024)])):s[r.profile].data?(i(),f(u,{key:1,"max-height":"56vh"},{default:n(()=>{var W,D,j,ue,de,ce,fe,me,ve,ye,_e,ge,be,ke,Ee,he,Re,we,Ae,Ce,Se,xe;return[o("article",Ct,[o("header",St,[o("div",xt,[o("div",$t,[o("strong",null,_(oe(r.profile))+"建议报告",1),o("span",null,_(ie(r.profile)),1),(W=s[r.profile].data)!=null&&W.is_stale?(i(),f(a,{key:0,size:"small",type:"warning",effect:"plain"},{default:n(()=>[...e[14]||(e[14]=[y(" 处方已变更 ",-1)])]),_:1})):b("",!0),Fe(r.profile)?(i(),f(a,{key:1,size:"small",type:"info",effect:"plain"},{default:n(()=>[...e[15]||(e[15]=[y(" 已人工编辑 ",-1)])]),_:1})):b("",!0)]),o("div",It,[o("span",null,"生成时间:"+_(Pe(r.profile)),1),ne(r.profile)?(i(),k("span",Tt," 编辑时间:"+_(ne(r.profile)),1)):b("",!0)])]),ee(r.profile)&&!s[r.profile].editing?(i(),f(v,{key:0,type:"primary",link:"",disabled:h.value||F.value,onClick:H=>De(r.profile)},{default:n(()=>[...e[16]||(e[16]=[y(" 编辑报告 ",-1)])]),_:1},8,["disabled","onClick"])):b("",!0)]),s[r.profile].error?(i(),f(p,{key:0,class:"saved-version-warning",type:"warning",closable:!1,"show-icon":"",title:`本次重新生成失败,当前展示上一次保存的版本:${s[r.profile].error}`},null,8,["title"])):b("",!0),s[r.profile].editing?(i(),k("div",Vt,[s[r.profile].structuredEdit?(i(),f(p,{key:0,class:"editor-format-notice",type:"info",closable:!1,"show-icon":"",title:"结构化报告会按下方八个中文章节保存;请勿删除、重命名或调整章节标题顺序。"})):b("",!0),g(m,{modelValue:s[r.profile].draft,"onUpdate:modelValue":H=>s[r.profile].draft=H,type:"textarea",rows:18,resize:"vertical",maxlength:"12000","show-word-limit":"",placeholder:"请输入报告内容"},null,8,["modelValue","onUpdate:modelValue"]),s[r.profile].editError?(i(),f(p,{key:1,class:"editor-error",type:"error",closable:!1,"show-icon":"",title:s[r.profile].editError},null,8,["title"])):b("",!0),o("div",Bt,[g(v,{disabled:s[r.profile].saving,onClick:H=>je(r.profile)},{default:n(()=>[...e[17]||(e[17]=[y(" 取消 ",-1)])]),_:1},8,["disabled","onClick"]),g(v,{type:"primary",loading:s[r.profile].saving,onClick:H=>qe(r.profile)},{default:n(()=>[...e[18]||(e[18]=[y(" 保存修改 ",-1)])]),_:1},8,["loading","onClick"])])])):Oe(r.profile)?(i(),k(Ie,{key:2},[(j=(D=s[r.profile].data)==null?void 0:D.report)!=null&&j.summary?(i(),k("section",zt,[e[19]||(e[19]=o("h3",null,"核心判断",-1)),o("p",null,_((de=(ue=s[r.profile].data)==null?void 0:ue.report)==null?void 0:de.summary),1)])):b("",!0),o("div",Nt,[o("section",Lt,[e[20]||(e[20]=o("h3",null,"可能症状与证候",-1)),g(K(q),{items:((fe=(ce=s[r.profile].data)==null?void 0:ce.report)==null?void 0:fe.possible_symptoms)||[],"empty-text":"模型未给出明确症状推测"},null,8,["items"])]),o("section",Pt,[e[21]||(e[21]=o("h3",null,"主治方向",-1)),o("p",null,_(((ve=(me=s[r.profile].data)==null?void 0:me.report)==null?void 0:ve.main_indications)||"暂无"),1)]),o("section",Ft,[e[22]||(e[22]=o("h3",null,"主要功效",-1)),g(K(q),{items:((_e=(ye=s[r.profile].data)==null?void 0:ye.report)==null?void 0:_e.efficacy)||[],"empty-text":"暂无"},null,8,["items"])]),o("section",Ot,[e[23]||(e[23]=o("h3",null,"可能适用人群",-1)),g(K(q),{items:((be=(ge=s[r.profile].data)==null?void 0:ge.report)==null?void 0:be.suitable_people)||[],"empty-text":"暂无"},null,8,["items"])])]),(Ee=(ke=s[r.profile].data)==null?void 0:ke.report)!=null&&Ee.compatibility_analysis?(i(),k("section",Dt,[e[24]||(e[24]=o("h3",null,"配伍分析",-1)),o("p",null,_((Re=(he=s[r.profile].data)==null?void 0:he.report)==null?void 0:Re.compatibility_analysis),1)])):b("",!0),o("section",jt,[e[25]||(e[25]=o("h3",null,"用药与复核提醒",-1)),g(K(q),{items:((Ae=(we=s[r.profile].data)==null?void 0:we.report)==null?void 0:Ae.cautions)||[],"empty-text":"仍需结合患者情况完成禁忌与相互作用复核"},null,8,["items"])]),o("p",Ut,_(((Se=(Ce=s[r.profile].data)==null?void 0:Ce.report)==null?void 0:Se.disclaimer)||"仅供专业人员辅助审方,不替代辨证、诊断和处方审核。"),1)],64)):(i(),k("section",qt,[e[26]||(e[26]=o("h3",null,"报告正文",-1)),o("pre",Gt,_(((xe=s[r.profile].data)==null?void 0:xe.content)||"暂无报告正文"),1)]))])]}),_:2},1024)):(i(),f(c,{key:2,description:"该模型暂无已保存报告","image-size":72},{default:n(()=>[S.value?(i(),f(v,{key:0,type:"primary",plain:"",loading:h.value,disabled:F.value||O.value,onClick:J},{default:n(()=>[...e[27]||(e[27]=[y(" 重新生成整个报告 ",-1)])]),_:1},8,["loading","disabled"])):b("",!0)]),_:1}))])),[[te,h.value&&!!s[r.profile].data]])]),_:2},1032,["name"])),64))]),_:1},8,["modelValue"])):(i(),k("div",kt,[g(c,{description:"暂无已保存的 AI 诊断报告","image-size":76},{default:n(()=>[e[8]||(e[8]=o("p",{class:"empty-message"},"打开窗口不会自动调用模型;需要时请手动生成。",-1)),S.value?(i(),f(v,{key:0,type:"primary",loading:h.value,disabled:F.value||O.value,onClick:J},{default:n(()=>[...e[6]||(e[6]=[y(" 生成报告 ",-1)])]),_:1},8,["loading","disabled"])):(i(),f(a,{key:1,type:"info",effect:"plain"},{default:n(()=>[...e[7]||(e[7]=[y("当前账号无生成权限",-1)])]),_:1}))]),_:1})]))])):b("",!0)]),_:1},8,["modelValue"])}}}),Tr=nt(Jt,[["__scopeId","data-v-5a75a47c"]]);export{Tr as default};