Files
xuetang/server/public/admin/assets/PrescriptionAiBatchGenerateDialog-B0omE4jY.js
2026-09-08 11:40:15 +08:00

2 lines
11 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import{K as pe,a3 as de,W as ce,i as me,T as ve,a1 as fe,M as ge,N as _e,V as ye}from"./element-plus-Bm2jcHo4.js";import{a as he,b as ke}from"./tcm-B2NgAvC0.js";import{i as V,_ as be}from"./index-CJJeyIXM.js";import{f as we,ak as r,G as g,aN as u,J as l,a as d,I as h,O as m,F as Ce,H as C,A as X}from"./@vue/runtime-core-C6bnekPw.js";import{y as t,a as Ee,n as p,q as Me}from"./@vue/reactivity-DiY1c2vO.js";import{Q as i}from"./@vue/shared-mAAVTE9n.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-8Um_rfcd.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 $e={class:"batch-dialog-body"},xe={key:0,class:"loading-state"},Ae={key:1,class:"load-error-state"},Ie={class:"state-description"},Be={class:"overview-panel"},Ne={class:"overview-meta"},Re={key:0,class:"refresh-error"},Se={key:2,class:"progress-panel"},Te={class:"progress-heading"},ze={key:0,class:"current-prescription"},Ge={class:"counter-grid"},Ve={class:"counter-item counter-processed"},qe={class:"counter-item counter-success"},Le={class:"counter-item counter-partial"},Fe={class:"counter-item counter-failed"},Pe={key:3,class:"issues-panel"},De={class:"section-heading"},We={class:"issue-name"},je={class:"state-description"},He={key:5,class:"pending-panel"},Je={class:"section-heading"},Ke={class:"pending-count"},Oe={class:"dialog-footer"},Qe={key:0,class:"footer-tip"},Ue={key:1},I=500,Xe=we({__name:"PrescriptionAiBatchGenerateDialog",emits:["changed"],setup(Ye,{expose:Y,emit:Z}){const ee=Z,E=p(!1),T=p(0),B=p(0),z=p(!1),N=p(""),R=p(""),v=p([]),M=p(0),q=p(I),D=p(!1),c=p(!1),_=p(!1),W=p("idle"),y=p(0),w=p(0),j=p(0),L=p(0),G=p(0),k=p(null),$=p([]),F=Me(null),te=X(()=>y.value?Math.min(100,Math.round(w.value/y.value*100)):0),se=X(()=>{const s=Math.max(0,M.value-v.value.length);return s>0?`待生成数量超过单次上限,本次最多处理 ${v.value.length} 份;完成后可再次继续处理其余约 ${s} 份。`:`后端标记清单已截断,本次最多处理 ${q.value} 份;完成后可再次继续。`}),J=()=>{_.value=!1,W.value="idle",y.value=0,w.value=0,j.value=0,L.value=0,G.value=0,k.value=null,$.value=[]},K=()=>{z.value=!1,N.value="",R.value="",v.value=[],M.value=0,q.value=I,D.value=!1,J()},H=s=>{if(typeof s=="string"&&s.trim())return s;if(s&&typeof s=="object"){const e=s,n=e.response,a=n==null?void 0:n.data,o=e.msg||e.message||e.error||(a==null?void 0:a.msg)||(a==null?void 0:a.message);if(typeof o=="string"&&o.trim())return o}return"请求失败,请稍后重试"},b=s=>s===T.value&&E.value,P=async(s=T.value,e={})=>{const n=++B.value;e.silent||(z.value=!0,N.value="");try{const a=await he({limit:I});if(!b(s)||n!==B.value)return;const o=Array.isArray(a.items)?a.items.slice(0,I):[];v.value=o,M.value=Math.max(o.length,Number(a.total||0)),q.value=Math.min(I,Math.max(1,Number(a.limit||I))),D.value=a.truncated===!0||M.value>o.length,R.value=""}catch(a){if(!b(s)||n!==B.value)return;e.silent?R.value=`本轮已结束,但最新待生成清单读取失败:${H(a)}`:N.value=H(a)}finally{b(s)&&n===B.value&&(z.value=!1)}},O=s=>(s.results||[]).filter(n=>n.status==="error").map(n=>`${n.model_label||n.model_name}: ${n.error_message||"生成失败"}`).join("")||"模型未返回完整报告",le=(s,e)=>{const n=Number(e.success_count||0),a=Number(e.failure_count||0),o=e.status==="partial"||e.partial===!0||n>0&&a>0,S=e.status==="error"||a>0&&n===0;return o?(L.value+=1,$.value.push({id:s.id,prescription_name:s.prescription_name||`处方 #${s.id}`,status:"partial",message:O(e)}),!0):S?(G.value+=1,$.value.push({id:s.id,prescription_name:s.prescription_name||`处方 #${s.id}`,status:"failed",message:O(e)}),!1):(j.value+=1,!0)},ae=(s,e)=>{G.value+=1,$.value.push({id:s.id,prescription_name:s.prescription_name||`处方 #${s.id}`,status:"failed",message:H(e)})},Q=()=>{!c.value||_.value||(_.value=!0)},ne=async()=>{if(c.value||!v.value.length)return;const s=T.value,e=v.value.slice(0,I);try{await V.confirm(`确定按顺序为 ${e.length} 份处方生成 AI 报告吗?每份会调用双模型,过程中可请求停止。`)}catch{return}if(!b(s)||c.value)return;J(),y.value=e.length,c.value=!0,R.value="";const n=new Set;try{for(const a of e){if(!b(s)||_.value)break;k.value=a;try{const o=await ke({id:a.id});if(!b(s))return;le(a,o)&&n.add(a.id)}catch(o){if(!b(s))return;ae(a,o)}w.value+=1,k.value=null}}finally{if(!b(s))return;const a=_.value&&w.value<y.value;W.value=a?"stopped":"completed",c.value=!1,k.value=null,n.size&&(v.value=v.value.filter(S=>!n.has(S.id)),M.value=Math.max(0,M.value-n.size)),w.value>0&&ee("changed");const o=F.value;if(F.value=null,o){o();return}if(await P(s,{silent:!0}),!b(s))return;a?V.msgWarning(`已停止,本轮共处理 ${w.value} 份处方`):G.value>0||L.value>0?V.msgWarning("批量生成已完成,请查看失败与部分成功明细"):V.msgSuccess("批量生成报告完成")}},oe=s=>{if(!c.value){s();return}Q(),F.value=s,V.msgWarning("已请求停止,当前处方完成后将关闭窗口")},ie=()=>{++T.value,++B.value,F.value=null,c.value=!1,K()};return Y({open:()=>{if(c.value){E.value=!0;return}const s=++T.value;++B.value,K(),E.value=!0,P(s)}}),(s,e)=>{const n=pe,a=de,o=me,S=ce,x=ve,re=fe,A=_e,U=ge,ue=ye;return r(),g(ue,{modelValue:t(E),"onUpdate:modelValue":e[3]||(e[3]=f=>Ee(E)?E.value=f:null),class:"prescription-ai-batch-dialog",width:"min(820px, calc(100vw - 32px))",top:"6vh",title:"批量生成处方 AI 报告","close-on-click-modal":!1,"destroy-on-close":"","before-close":oe,onClosed:ie},{footer:u(()=>[l("div",Oe,[t(c)?(r(),h("span",Qe,"生成请求不会自动重试,也不会并发执行。")):(r(),h("span",Ue)),l("div",null,[t(c)?C("",!0):(r(),g(o,{key:0,onClick:e[2]||(e[2]=f=>E.value=!1)},{default:u(()=>[...e[20]||(e[20]=[m("关闭",-1)])]),_:1})),t(c)?(r(),g(o,{key:1,type:"warning",plain:"",disabled:t(_),onClick:Q},{default:u(()=>[m(i(t(_)?"正在停止…":"停止"),1)]),_:1},8,["disabled"])):(r(),g(o,{key:2,type:"primary",disabled:t(z)||!!t(N)||!t(v).length,onClick:ne},{default:u(()=>[m(i(t(y)>0?"继续生成剩余报告":"开始批量生成"),1)]),_:1},8,["disabled"]))])])]),default:u(()=>[l("div",$e,[d(n,{type:"info",closable:!1,"show-icon":"",title:"仅统计完全没有任何 AI 报告的处方;已有报告不会被本批次覆盖。"}),t(z)?(r(),h("div",xe,[d(a,{rows:5,animated:""})])):t(N)?(r(),h("div",Ae,[d(S,{description:"待生成清单加载失败","image-size":72},{default:u(()=>[l("p",Ie,i(t(N)),1),d(o,{type:"primary",plain:"",onClick:e[0]||(e[0]=f=>P())},{default:u(()=>[...e[4]||(e[4]=[m("重新加载",-1)])]),_:1})]),_:1})])):(r(),h(Ce,{key:2},[l("section",Be,[l("div",null,[e[5]||(e[5]=l("span",{class:"overview-label"},"当前完全缺失报告",-1)),l("strong",null,i(t(M)),1),e[6]||(e[6]=l("span",{class:"overview-unit"},"份处方",-1))]),l("div",Ne,[m(" 本次载入 "+i(t(v).length)+" 份 ",1),d(x,{size:"small",type:"info",effect:"plain"},{default:u(()=>[m("上限 "+i(t(q)),1)]),_:1})])]),t(R)?(r(),h("div",Re,[d(n,{type:"error",closable:!1,"show-icon":"",title:t(R)},null,8,["title"]),d(o,{type:"primary",plain:"",onClick:e[1]||(e[1]=f=>P())},{default:u(()=>[...e[7]||(e[7]=[m("重新读取清单",-1)])]),_:1})])):C("",!0),t(D)?(r(),g(n,{key:1,class:"truncated-alert",type:"warning",closable:!1,"show-icon":"",title:t(se)},null,8,["title"])):C("",!0),t(c)||t(y)>0?(r(),h("section",Se,[l("div",Te,[l("div",null,[e[8]||(e[8]=l("span",{class:"section-kicker"},"本轮进度",-1)),l("strong",null,i(t(w))+" / "+i(t(y)),1)]),t(c)&&!t(_)?(r(),g(x,{key:0,type:"primary"},{default:u(()=>[...e[9]||(e[9]=[m("顺序生成中",-1)])]),_:1})):t(c)&&t(_)?(r(),g(x,{key:1,type:"warning"},{default:u(()=>[...e[10]||(e[10]=[m("等待当前请求完成",-1)])]),_:1})):t(W)==="stopped"?(r(),g(x,{key:2,type:"warning"},{default:u(()=>[...e[11]||(e[11]=[m("已停止",-1)])]),_:1})):(r(),g(x,{key:3,type:"success"},{default:u(()=>[...e[12]||(e[12]=[m("本轮完成",-1)])]),_:1}))]),d(re,{percentage:t(te),"stroke-width":10},null,8,["percentage"]),t(k)?(r(),h("div",ze,[e[13]||(e[13]=l("span",null,"当前处方",-1)),l("strong",null,i(t(k).prescription_name||`处方 #${t(k).id}`),1),l("small",null,"#"+i(t(k).id)+" · "+i(t(k).formula_type||"未分类"),1)])):C("",!0),l("div",Ge,[l("div",Ve,[e[14]||(e[14]=l("span",null,"已处理",-1)),l("strong",null,i(t(w)),1)]),l("div",qe,[e[15]||(e[15]=l("span",null,"成功",-1)),l("strong",null,i(t(j)),1)]),l("div",Le,[e[16]||(e[16]=l("span",null,"部分成功",-1)),l("strong",null,i(t(L)),1)]),l("div",Fe,[e[17]||(e[17]=l("span",null,"失败",-1)),l("strong",null,i(t(G)),1)])]),t(_)&&t(c)?(r(),g(n,{key:1,class:"stop-alert",type:"warning",closable:!1,"show-icon":"",title:"已请求停止;当前处方生成完成后,不会继续发起下一条请求。"})):C("",!0)])):C("",!0),t($).length?(r(),h("section",Pe,[l("div",De,[e[18]||(e[18]=l("div",null,[l("span",{class:"section-kicker"},"失败清单"),l("strong",null,"失败与部分成功明细")],-1)),d(x,{type:"danger",effect:"plain"},{default:u(()=>[m(i(t($).length)+" 条",1)]),_:1})]),d(U,{data:t($),"max-height":"240",size:"small"},{default:u(()=>[d(A,{label:"处方","min-width":"180"},{default:u(({row:f})=>[l("div",We,i(f.prescription_name),1),l("small",null,"#"+i(f.id),1)]),_:1}),d(A,{label:"结果",width:"100"},{default:u(({row:f})=>[d(x,{size:"small",type:f.status==="partial"?"warning":"danger"},{default:u(()=>[m(i(f.status==="partial"?"部分成功":"失败"),1)]),_:2},1032,["type"])]),_:1}),d(A,{label:"原因","min-width":"300","show-overflow-tooltip":"",prop:"message"})]),_:1},8,["data"])])):C("",!0),!t(v).length&&!t(c)?(r(),g(S,{key:4,description:t(y)>0?"当前范围已无待生成处方":"暂无完全缺失 AI 报告的处方","image-size":76},{default:u(()=>[l("p",je,i(t(y)>0?"已重新读取数据库中的最新待生成清单。":"所有可见处方均已有至少一份持久化报告。"),1)]),_:1},8,["description"])):t(c)?C("",!0):(r(),h("section",He,[l("div",Je,[e[19]||(e[19]=l("div",null,[l("span",{class:"section-kicker"},"待生成清单"),l("strong",null,"本次将按以下顺序逐条处理")],-1)),l("span",Ke,i(t(v).length)+" 份",1)]),d(U,{data:t(v),"max-height":"280",size:"small"},{default:u(()=>[d(A,{label:"ID",prop:"id",width:"80"}),d(A,{label:"处方名称",prop:"prescription_name","min-width":"220","show-overflow-tooltip":""}),d(A,{label:"类型",prop:"formula_type",width:"100"}),d(A,{label:"药材数",width:"100",align:"right"},{default:u(({row:f})=>[m(i(f.herb_count)+" 味",1)]),_:1})]),_:1},8,["data"])]))],64))])]),_:1},8,["modelValue"])}}}),qt=be(Xe,[["__scopeId","data-v-e1699253"]]);export{qt as default};