4 lines
16 KiB
JavaScript
4 lines
16 KiB
JavaScript
![]() |
import{_ as he,r as h,N as be,u as we,o as xe,m as b,f as e,w as t,b as ke,l as Ee,a as q,E as x,d as i,e as Ce,c as y,M as S,A as Me,y as De,z as Ve,B as Fe,C as Ae,F as Pe,D as Te,G as Ne,O as Se,H as ze,j as Ie,k as r,P as Re,I as _,Q as Ue,R as $,n as o,q as Z,h as Le,i as Ye,J as $e,K as n,S as Be,T as Oe,p as je,v as qe,U as Ke,V as Ge,W as B,X as He,Y as Je,Z as Qe,$ as We,a0 as Xe,a1 as Ze,a2 as et,a3 as tt,a4 as at,a5 as lt}from"./index-CtyWzmh7.js";/* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css */const st={class:"prediction-view"},ot={class:"card-header"},dt={style:{"margin-left":"8px"}},nt={class:"metrics-display"},rt={class:"metric-item"},it={class:"metric-value"},ut={class:"metric-item"},_t={class:"metric-value"},ct={class:"metric-item"},pt={class:"metric-value"},ft={class:"metric-item"},mt={class:"metric-value"},vt={class:"pagination-container"},yt={key:1,class:"loading-container"},gt={key:2,class:"result-container"},ht={class:"chart-container"},bt={class:"chart-container"},wt={key:1,class:"chart-placeholder",style:{height:"300px"}},xt={key:0,class:"prediction-dialog-content"},kt={class:"prediction-summary"},Et={class:"prediction-chart-container"},Ct={key:1,class:"chart-placeholder",style:{height:"400px"}},Mt={class:"prediction-chart-container"},Dt={key:1,class:"chart-placeholder",style:{height:"400px"}},Vt={class:"stat-cards"},Ft={class:"stat-value"},At={class:"stat-value"},Pt={class:"stat-value"},Tt={key:0},Nt={key:1},St={class:"dialog-footer"},zt={__name:"PredictionView",setup(It){const O=h([]),M=h(!1),z=h(!1),k=h(!1),D=h([]),d=h(null),K=h(""),j=h(""),I=h(""),V=h(1),T=h(10),ee=be(()=>{const s=(V.value-1)*T.value,a=s+T.value;return D.value.slice(s,a)}),c=we({product_id:"",model_type:"",start_date:new Date().toISOString().split("T")[0],future_days:7}),te=async()=>{try{const s=await q.get("/api/products");s.data.status==="success"&&(O.value=s.data.data)}catch(s){x.error("获取产品列表失败"),console.error(s)}},G=async()=>{z.value=!0,D.value=[],V.value=1;try{const s={};c.product_id&&(s.product_id=c.product_id),c.model_type&&(s.model_type=c.model_type);const a=await q.get("/api/models",{params:s});a.data.status==="success"&&(D.value=a.data.data,D.value.length===0&&x.info("没有找到符合条件的模型,请先训练模型或修改筛选条件"))}catch(s){x.error("获取可用模型列表失败"),console.error(s)}finally{z.value=!1}},ae=()=>{d.value=null},le=()=>{d.value=null},se=s=>{T.value=s,V.value=1},oe=s=>{V.value=s},de=async s=>{var a,f;K.value=s.model_id,j.value=s.model_type,I.value=s.product_id,M.value=!0,d.value=null;try{console.log(`开始预测,起始日期: ${c.start_date}`);const p=await q.post("/api/prediction",{product_id:s.product_id,model_type:s.model_type,future_days:c.future_days,start_date:c.start_date,include_visualization:!0});p.data.status==="success"?(d.value=p.data,x.success("预测成功!"),k.value=!0):x.error(p.data.error||"预测失败")}catch(p){x.error(((f=(a=p.response)==null?void 0:a.data)==null?void 0:f.error)||"预测请求失败"),console.error(p)}finally{M.value=!1}},ne=()=>{k.value=!1},H=s=>s?new Date(s).toLocaleString():"N/A",F=s=>s?new Date(s).toLocaleDateString():"N/A",J=s=>({mlstm:"primary",transformer:"success",kan:"warning"})[s]||"info",Q=s=>{const a=O.value.find(f=>f.product_id===s);return a?a.product_name:s},re=s=>!s||s.length===0?0:s.reduce((a,f)=>a+f.sales,0)/s.length,ie=s=>!s||s.length===0?0:Math.max(...s.map(a=>a.sales)),ue=s=>!s||s.length===0?0:Math.min(...s.map(a=>a.sales)),_e=()=>{if(d.value)try{let s=`日期,销量,数据类型
|
|||
|
`;d.value.data.forEach(w=>{s+=`${new Date(w.date).toLocaleDateString()},${w.sales.toFixed(2)},${w.data_type}
|
|||
|
`});const a=new Blob([s],{type:"text/csv;charset=utf-8;"}),f=URL.createObjectURL(a),p=document.createElement("a");p.href=f;const A=c.start_date.replace(/-/g,""),R=c.future_days;p.setAttribute("download",`预测结果_${I.value}_${A}_days${R}.csv`),document.body.appendChild(p),p.click(),document.body.removeChild(p),x.success("预测结果已导出")}catch(s){console.error("导出预测结果失败",s),x.error("导出预测结果失败")}};return xe(()=>{te(),G()}),(s,a)=>{const f=Re,p=Be,A=Ne,R=Ae,w=Fe,v=Ve,ce=Se,pe=ze,N=Ie,E=De,fe=Me,U=$e,u=Ye,C=Le,me=je,W=He,P=Qe,X=Je,L=ke,Y=Ze,ve=Xe,ye=Ee,ge=qe;return i(),b("div",st,[e(L,null,{header:t(()=>[o("div",ot,[a[9]||(a[9]=o("span",null,"模型预测",-1)),e(p,{content:"在这里可以使用已训练好的模型进行销售预测"},{default:t(()=>[e(f,null,{default:t(()=>[e(_(We))]),_:1})]),_:1})])]),default:t(()=>[e(fe,{model:c,class:"prediction-form","label-width":"120px"},{default:t(()=>[e(E,{gutter:20},{default:t(()=>[e(v,{sm:24,md:12,lg:8},{default:t(()=>[e(w,{label:"产品"},{default:t(()=>[e(R,{modelValue:c.product_id,"onUpdate:modelValue":a[0]||(a[0]=l=>c.product_id=l),placeholder:"选择产品",filterable:"",onChange:ae,style:{width:"100%"}},{default:t(()=>[(i(!0),b(Pe,null,Te(O.value,l=>(i(),y(A,{key:l.product_id,label:l.product_name,value:l.product_id},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1})]),_:1}),e(v,{sm:24,md:12,lg:8},{default:t(()=>[e(w,{label:"模型类型"},{default:t(()=>[e(R,{modelValue:c.model_type,"onUpdate:modelValue":a[1]||(a[1]=l=>c.model_type=l),placeholder:"选择模型类型",onChange:le,style:{width:"100%"}},{default:t(()=>[e(A,{label:"mLSTM",value:"mlstm"}),e(A,{label:"Transformer",value:"transformer"}),e(A,{label:"KAN",value:"kan"})]),_:1},8,["modelValue"])]),_:1})]),_:1}),e(v,{sm:24,md:12,lg:8},{default:t(()=>[e(w,{label:"预测起始日期"},{default:t(()=>[e(ce,{modelValue:c.start_date,"onUpdate:modelValue":a[2]||(a[2]=l=>c.start_date=l),type:"date",placeholder:"选择日期",format:"YYYY-MM-DD","value-format":"YYYY-MM-DD",style:{width:"100%"},clearable:!1},null,8,["modelValue"])]),_:1})]),_:1}),e(v,{sm:24,md:12,lg:8},{default:t(()=>[e(w,{label:"预测天数"},{default:t(()=>[e(pe,{modelValue:c.future_days,"onUpdate:modelValue":a[3]||(a[3]=l=>c.future_days=l),min:1,max:30,size:"default"},null,8,["modelValue"])]),_:1})]),_:1}),e(v,{sm:24,md:12,lg:8},{default:t(()=>[e(w,null,{default:t(()=>[e(N,{type:"primary",onClick:G},{default:t(()=>[e(f,null,{default:t(()=>[e(_(Ue))]),_:1}),a[10]||(a[10]=r(" 查询可用模型 "))]),_:1,__:[10]})]),_:1})]),_:1})]),_:1})]),_:1},8,["model"]),e(_($),{"content-position":"left"},{default:t(()=>a[11]||(a[11]=[r("可用模型列表")])),_:1,__:[11]}),Ce((i(),b("div",null,[D.value.length===0&&!z.value?(i(),y(_(Z),{key:0,description:"没有找到可用的模型,请先训练模型或修改筛选条件"})):(i(),y(C,{key:1,data:ee.value,border:"",stripe:"",style:{width:"100%"},"highlight-current-row":!0},{default:t(()=>[e(u,{prop:"model_id",label:"模型ID","min-width":"120"},{default:t(({row:l})=>[e(U,{size:"small",type:J(l.model_type)},{default:t(()=>[r(n(l.model_type),1)]),_:2},1032,["type"]),o("span",dt,n(l.model_id),1)]),_:1}),e(u,{prop:"product_id",label:"产品","min-width":"100"},{default:t(({row:l})=>[r(n(Q(l.product_id)),1)]),_:1}),e(u,{prop:"created_at",label:"创建时间","min-width":"160"},{default:t(({row:l})=>[r(n(H(l.created_at)),1)]),_:1}),e(u,{label:"评估指标","min-width":"200"},{default:t(({row:l})=>[o("div",nt,[e(p,{effect:"dark",content:"R平方值,越接近1表示模型越好",placement:"top"},{default:t(()=>{var m,g;return[o("div",rt,[a[12]||(a[12]=o("span",{class:"metric-label"},"R²:",-1)),o("span",it,n(((g=(m=l.metrics)==null?void 0:m.R2)==null?void 0:g.toFixed(4))||"N/A"),1)])]}),_:2},1024),e(p,{effect:"dark",content:"均方根误差,越小表示模型越准确",placement:"top"},{default:t(()=>{var m,g;return[o("div",ut,[a[13]||(a[13]=o("span",{class:"metric-label"},"RMSE:",-1)),o("span",_t,n(((g=(m=l.metrics)==null?void 0:m.RMSE)==null?void 0:g.toFixed(4)
|