3 lines
54 KiB
JavaScript
3 lines
54 KiB
JavaScript
import{aN as he,bs as f,aG as b,aD as n,bL as p,aK as l,R as Ke,a4 as ot,c8 as i,ai as J,bE as ce,Z as rt,bk as me,ad as je,aJ as q,$ as ct,aF as ye,bC as C,ay as A,ak as ke,b4 as Pe,bp as Xe,br as Je,u as Qe,aa as et,ab as tt,c9 as We,c0 as qe,cb as ve,bl as nt,Y as De,X as T,c7 as Fe,aE as fe,a3 as ut,r as Ae,F as at,bV as lt,Q as Ge,bS as H,bc as dt,bo as st,av as ft,o as vt,I as mt,bt as pt,an as Ee,K as gt,bw as yt,aX as _t,J as ht,aV as kt,c5 as He,c3 as bt,c2 as wt,au as $t,c4 as St,aQ as Ct,al as It,ag as Nt,bA as xt,L as Lt,a2 as Tt,bW as Mt,bX as Vt,w as Et,a6 as At,t as Ft,ac as Pt,a9 as Dt}from"./index-D5GfLbIx.js";/* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css */import{W as Rt}from"./Workspace3D-B9mv4VWE.js";/* empty css *//* empty css *//* empty css *//* empty css *//* empty css *//* empty css */import"./el-tooltip-l0sNRNKZ.js";/* empty css *//* empty css *//* empty css */import{r as pe}from"./reflection-BwOBPyb9.js";import{m as Ot}from"./mapEdit-BXIATxCI.js";import{O as zt}from"./ops-BCeFEEjY.js";import{e as Bt}from"./ops-C48uBBTk.js";import{f as it,i as Ut}from"./monitorConfigCache-DXn96T8F.js";/* empty css *//* empty css *//* empty css */import{w as re}from"./workspaceToolbar-abOZ7a24.js";import{l as Wt,a as qt}from"./projection-BHFE6Meg.js";import{u as Kt}from"./useProjectionStream-ayb6RvWW.js";const jt={class:"vehicle-monitor"},Xt={class:"overview-row"},Gt={class:"overview-item"},Ht={class:"overview-num"},Yt={class:"overview-item"},Zt={class:"overview-num online"},Jt={class:"overview-item"},Qt={class:"overview-num running"},en={class:"overview-item"},tn={class:"overview-num charging"},nn={class:"overview-item"},an={class:"overview-num fault"},ln={class:"toolbar"},sn={class:"vehicle-list"},on=["onClick"],rn={class:"vehicle-head"},cn={class:"vid"},un=["title"],dn={class:"vehicle-sub"},fn=["title"],vn={class:"mission-mini"},mn=["title"],pn={key:1,class:"mission-name muted"},gn={key:0,class:"empty muted"},yn=he({__name:"VehicleMonitorPanel",props:{cars:{},missions:{},selectedId:{}},emits:["select"],setup(g,{emit:E}){const c=g,P=E,D=C(""),s=C(""),y=[{value:"idle",label:"空闲"},{value:"running",label:"运行中"},{value:"charging",label:"充电中"},{value:"paused",label:"已暂停"},{value:"fault",label:"故障"},{value:"offline",label:"离线"}],x=y.reduce((h,L)=>(h[L.value]=L.label,h),{});function U(h){return x[h]??h}function N(h){switch(h){case"running":return"success";case"charging":return"primary";case"paused":return"warning";case"fault":return"danger";case"offline":return"info";case"idle":default:return"info"}}const X={queued:"排队",assigned:"已分配",running:"执行中",paused:"暂停",completed:"已完成",cancelled:"已取消",failed:"失败"};function G(h){return X[h]??h}function O(h){switch(h){case"running":return"success";case"assigned":return"primary";case"queued":return"info";case"paused":return"warning";case"completed":return"success";case"cancelled":return"info";case"failed":return"danger";default:return"info"}}const F=A(()=>c.cars.filter(h=>h.state!=="offline").length),w=A(()=>c.cars.filter(h=>h.state==="running").length),Y=A(()=>c.cars.filter(h=>h.state==="charging").length),Z=A(()=>c.cars.filter(h=>h.state==="fault").length),K=A(()=>{const h=r=>r==="running"?0:r==="paused"?1:r==="assigned"?2:3,L=new Map;for(const r of c.missions){if(!r.carId||r.status!=="running"&&r.status!=="paused"&&r.status!=="assigned")continue;const m=L.get(r.carId);(!m||h(r.status)<h(m.status))&&L.set(r.carId,r)}return L});function z(h){if(h.missionId){const L=c.missions.find(r=>r.id===h.missionId);if(L)return L}return K.value.get(h.id)}function R(h){const L=h.batterySoc??0,r=L>1?L:L*100;return Math.max(0,Math.min(100,Math.round(r)))}function ae(h){return h<20?"#f56c6c":h<50?"#e6a23c":"#67c23a"}function ue(h){return h<20?"low":h<50?"mid":"high"}const W=A(()=>{const h=D.value.trim().toLowerCase(),L=h?h.split(/\s+/).filter(Boolean):[];return c.cars.filter(r=>{if(s.value&&r.state!==s.value)return!1;if(!L.length)return!0;const m=z(r),B=[r.id,r.name,r.typeName??"",r.group??"",r.ip??"",U(r.state),m?.name??"",m?G(m.status):""].join(" ").toLowerCase();return L.every(u=>B.includes(u))})});function j(h){P("select",{kind:"vehicle",id:le(h),name:h.name})}function le(h){return h.rawId!=null?String(h.rawId):h.id.replace(/^C/i,"").replace(/^0+/,"")||h.id}return(h,L)=>{const r=Ke,m=rt,B=ot,u=je,o=ct;return f(),b("div",jt,[n("div",Xt,[n("div",Gt,[n("div",Ht,p(g.cars.length),1),L[2]||(L[2]=n("div",{class:"overview-label"},"总数",-1))]),n("div",Yt,[n("div",Zt,p(F.value),1),L[3]||(L[3]=n("div",{class:"overview-label"},"在线",-1))]),n("div",Jt,[n("div",Qt,p(w.value),1),L[4]||(L[4]=n("div",{class:"overview-label"},"运行",-1))]),n("div",en,[n("div",tn,p(Y.value),1),L[5]||(L[5]=n("div",{class:"overview-label"},"充电",-1))]),n("div",nn,[n("div",an,p(Z.value),1),L[6]||(L[6]=n("div",{class:"overview-label"},"故障",-1))])]),n("div",ln,[l(r,{modelValue:D.value,"onUpdate:modelValue":L[0]||(L[0]=_=>D.value=_),size:"small",clearable:"",placeholder:"搜索 ID / 名称 / 任务",class:"search"},null,8,["modelValue"]),l(B,{modelValue:s.value,"onUpdate:modelValue":L[1]||(L[1]=_=>s.value=_),size:"small",placeholder:"状态",clearable:"",class:"filter"},{default:i(()=>[(f(),b(J,null,ce(y,_=>l(m,{key:_.value,label:_.label,value:_.value},null,8,["label","value"])),64))]),_:1},8,["modelValue"])]),n("div",sn,[(f(!0),b(J,null,ce(W.value,_=>(f(),b("div",{key:_.id,class:me(["vehicle-row",{"is-selected":_.id===g.selectedId}]),onClick:I=>j(_)},[n("div",rn,[n("span",cn,p(_.id),1),n("span",{class:"vname",title:_.name},p(_.name),9,un),l(u,{size:"small",type:N(_.state),class:"state-tag",effect:"dark"},{default:i(()=>[n("span",{class:me(["dot",`dot-${_.state}`])},null,2),q(" "+p(U(_.state)),1)]),_:2},1032,["type"])]),n("div",dn,[n("div",{class:"battery-mini",title:`电量 ${R(_)}%`},[l(o,{percentage:R(_),"stroke-width":6,"show-text":!1,color:ae(R(_)),class:"battery-bar"},null,8,["percentage","color"]),n("span",{class:me(["battery-text",ue(R(_))])},p(R(_))+"% ",3)],8,fn),n("div",vn,[z(_)?(f(),b(J,{key:0},[l(u,{size:"small",type:O(z(_).status),effect:"plain",class:"mission-tag"},{default:i(()=>[q(p(G(z(_).status)),1)]),_:2},1032,["type"]),n("span",{class:"mission-name",title:z(_).name},p(z(_).name),9,mn)],64)):(f(),b("span",pn,"空闲"))])])],10,on))),128)),W.value.length?ye("",!0):(f(),b("div",gn," 无匹配车辆 "))])])}}}),_n=ke(yn,[["__scopeId","data-v-c1cc74ad"]]),Re="/sl/projection/deliveries";async function hn(g){const E={};g?.includeFinished===!1&&(E.includeFinished="false"),g?.includeAborted===!1&&(E.includeAborted="false");const{data:c}=await Pe.get(Re,{params:E});return Array.isArray(c)?c:[]}async function kn(g){await Pe.post(`${Re}/${g}/cancel`)}async function bn(g){await Pe.post(`${Re}/${g}/resend`)}async function wn(g){await Pe.post(`${Re}/${g}/force-complete`)}const $n={class:"mission-list-panel"},Sn={class:"toolbar"},Cn=["title"],In=["title"],Nn=["title"],xn=["title"],Ln={key:1,class:"muted"},Tn={key:0,class:"empty muted"},Mn=["disabled"],Vn=["disabled"],En=he({__name:"MissionListPanel",props:{deliveries:{},selectedId:{},loading:{type:Boolean}},emits:["select","refresh","actionDone"],setup(g,{emit:E}){const c=g,P=E,D=C(""),s=C(!0),y=C(!0),x=C(!1),U=C(0),N=C(0),X=C(null),G=A(()=>{const r=D.value.trim().toLowerCase(),m=r?r.split(/\s+/).filter(Boolean):[];return c.deliveries.filter(B=>{if(!m.length)return!0;const u=[String(B.id),B.srcLabel,B.dstLabel,B.status,B.carName??"",B.missionName].join(" ").toLowerCase();return m.every(o=>u.includes(o))})});function O(r,m=9){const B=r.indexOf("-"),u=B>=0?r.slice(B+1):r;return u.length<=m?u:`${u.slice(0,m)}…`}function F(r){return{已下发:"待发",执行中:"执行",已完成:"完成",已取消:"取消",强制结束:"强结",任务异常:"异常"}[r]??(r.length>4?`${r.slice(0,3)}…`:r)}function w(r,m=6){return r.length<=m?r:`${r.slice(0,m)}…`}function Y(r){switch(r){case"Fetching":case"Putting":return"success";case"Waiting":return"primary";case"Finished":return"info";case"Canceled":case"Terminated":return"warning";case"Error":return"danger";default:return"info"}}function Z({row:r}){const m=[];return r.id===c.selectedId&&m.push("is-selected-row"),r.overdue&&m.push("is-overdue-row"),m.join(" ")}function K(r){return["Finished","Canceled","Terminated","Error"].includes(r)}function z(r){return r!=null&&!K(r.statusCode)}function R(r){return r!=null&&!K(r.statusCode)}function ae(){P("refresh",{includeFinished:s.value,includeAborted:y.value})}function ue(r){j(),P("select",r)}function W(r,m,B){B.preventDefault(),X.value=r,U.value=B.clientX,N.value=B.clientY,x.value=!0}function j(){x.value=!1,X.value=null}const le={cancel:"取消任务",resend:"重发任务","force-complete":"强制完成"};async function h(r){const m=X.value;if(j(),!!m&&!(r==="cancel"&&!z(m))&&!(r==="force-complete"&&!R(m))){try{await De.confirm(`确定对任务 #${m.id}(${m.srcLabel} → ${m.dstLabel})执行「${le[r]}」?`,"确认操作",{type:"warning",confirmButtonText:"确定",cancelButtonText:"取消"})}catch{return}try{r==="cancel"?await kn(m.id):r==="resend"?await bn(m.id):await wn(m.id),T.success(`${le[r]} 已提交`),P("actionDone")}catch(B){T.error(`${le[r]} 失败:${B.message}`)}}}function L(){j()}return Xe(()=>document.addEventListener("click",L)),Je(()=>document.removeEventListener("click",L)),(r,m)=>{const B=Ke,u=Qe,o=tt,_=et;return f(),b("div",$n,[n("div",Sn,[l(B,{modelValue:D.value,"onUpdate:modelValue":m[0]||(m[0]=I=>D.value=I),size:"small",clearable:"",placeholder:"搜索任务 ID / 站点 / 车辆",class:"search"},null,8,["modelValue"]),l(u,{modelValue:s.value,"onUpdate:modelValue":m[1]||(m[1]=I=>s.value=I),size:"small",onChange:ae},{default:i(()=>[...m[7]||(m[7]=[q(" 含已完成 ",-1)])]),_:1},8,["modelValue"]),l(u,{modelValue:y.value,"onUpdate:modelValue":m[2]||(m[2]=I=>y.value=I),size:"small",onChange:ae},{default:i(()=>[...m[8]||(m[8]=[q(" 含取消/异常 ",-1)])]),_:1},8,["modelValue"])]),l(_,{data:G.value,size:"small",stripe:"","highlight-current-row":"","row-class-name":Z,height:"100%",class:"delivery-table","table-layout":"fixed",onRowClick:ue,onRowContextmenu:W},{default:i(()=>[l(o,{prop:"id",label:"ID",width:"40",align:"center"}),l(o,{label:"起点","show-overflow-tooltip":""},{default:i(({row:I})=>[n("span",{class:"cell-ellipsis",title:I.srcLabel},p(O(I.srcLabel)),9,Cn)]),_:1}),l(o,{label:"终点","show-overflow-tooltip":""},{default:i(({row:I})=>[n("span",{class:"cell-ellipsis",title:I.dstLabel},p(O(I.dstLabel)),9,In)]),_:1}),l(o,{label:"状态",width:"52",align:"center"},{default:i(({row:I})=>[n("span",{class:me(["status-pill",`status-pill--${Y(I.statusCode)}`]),title:I.status},p(F(I.status)),11,Nn)]),_:1}),l(o,{label:"车辆",width:"56","show-overflow-tooltip":""},{default:i(({row:I})=>[I.carName?(f(),b("span",{key:0,class:"cell-ellipsis",title:I.carName},p(w(I.carName)),9,xn)):(f(),b("span",Ln,"—"))]),_:1})]),_:1},8,["data"]),G.value.length?ye("",!0):(f(),b("div",Tn,"暂无搬运任务")),We(n("div",{class:"ctx-menu",style:nt({left:`${U.value}px`,top:`${N.value}px`}),onClick:m[6]||(m[6]=ve(()=>{},["stop"]))},[n("button",{type:"button",class:"ctx-item",disabled:!z(X.value),onClick:m[3]||(m[3]=I=>h("cancel"))}," 取消任务 ",8,Mn),n("button",{type:"button",class:"ctx-item",onClick:m[4]||(m[4]=I=>h("resend"))}," 重发任务 "),n("button",{type:"button",class:"ctx-item",disabled:!R(X.value),onClick:m[5]||(m[5]=I=>h("force-complete"))}," 强制完成 ",8,Vn)],4),[[qe,x.value]])])}}}),An=ke(En,[["__scopeId","data-v-38e00e9c"]]),Fn=["onClick"],Pn={class:"sid"},Dn={class:"sname"},Rn={key:0,class:"empty"},On=he({__name:"SitePickDialog",props:{modelValue:{type:Boolean},title:{},sites:{}},emits:["update:modelValue","confirm","pickOnMap"],setup(g,{expose:E,emit:c}){const P=g,D=c,s=A({get:()=>P.modelValue,set:F=>D("update:modelValue",F)}),y=C(""),x=C(null),U=C(!1),N=A(()=>{const F=y.value.trim().toLowerCase();return F?P.sites.filter(w=>String(w.id).includes(F)||w.name.toLowerCase().includes(F)||w.label.toLowerCase().includes(F)):P.sites});Fe(()=>P.modelValue,F=>{F&&(y.value="",x.value=P.sites[0]?.id??null)});function X(){x.value!=null&&(D("confirm",x.value),s.value=!1)}function G(){U.value=!0,D("pickOnMap")}function O(){U.value=!1}return E({close:()=>{s.value=!1},endMapPick:()=>{U.value=!1}}),(F,w)=>{const Y=Ke,Z=ut,K=Ae,z=at;return f(),fe(z,{modelValue:s.value,"onUpdate:modelValue":w[2]||(w[2]=R=>s.value=R),title:g.title,width:"420px","destroy-on-close":"","append-to-body":"",class:"site-pick-dialog",onClosed:O},{footer:i(()=>[l(K,{onClick:w[1]||(w[1]=R=>s.value=!1)},{default:i(()=>[...w[3]||(w[3]=[q("取消",-1)])]),_:1}),l(K,{loading:U.value,onClick:G},{default:i(()=>[...w[4]||(w[4]=[q("在地图上拾取",-1)])]),_:1},8,["loading"]),l(K,{type:"primary",disabled:x.value==null,onClick:X},{default:i(()=>[...w[5]||(w[5]=[q("确认前往",-1)])]),_:1},8,["disabled"])]),default:i(()=>[w[6]||(w[6]=n("p",{class:"hint"},"请选择车辆要前往的目标站点。",-1)),l(Y,{modelValue:y.value,"onUpdate:modelValue":w[0]||(w[0]=R=>y.value=R),clearable:"",placeholder:"搜索站点 ID / 名称",class:"filter-input"},null,8,["modelValue"]),l(Z,{"max-height":"280px",class:"site-scroll"},{default:i(()=>[(f(!0),b(J,null,ce(N.value,R=>(f(),b("button",{key:R.id,type:"button",class:me(["site-row",{active:x.value===R.id}]),onClick:ae=>x.value=R.id},[n("span",Pn,"#"+p(R.id),1),n("span",Dn,p(R.name||"未命名"),1)],10,Fn))),128)),N.value.length?ye("",!0):(f(),b("div",Rn,"无匹配站点"))]),_:1})]),_:1},8,["modelValue","title"])}}}),zn=ke(On,[["__scopeId","data-v-1e1b7025"]]),Bn=new Set(["Goto","GotoSite"]),Un=["去某地","前往站点"];function Ye(g){if(g.params?.length)return!1;if(Bn.has(g.methodName))return!0;const E=g.label??"";return Un.some(c=>E.includes(c))}async function Wn(){return(await pe.listObjects("site")).map(E=>({id:E.id,name:E.name,label:`#${E.id} ${E.name||"站点"}`})).sort((E,c)=>E.id-c.id)}async function Ze(){try{T.info({message:"请在 3D 地图上点击目标站点附近",duration:4e3});const g=await Ot.pick();return g.siteId==null||g.siteId<0?(T.warning("未识别到附近站点,请靠近站点再点击"),null):g.siteId}catch(g){return g instanceof Error&&/取消|cancel|499/i.test(g.message)||T.error(`地图拾取失败:${g instanceof Error?g.message:String(g)}`),null}}function qn(g){if(g&&typeof g=="object"&&"response"in g&&g.response?.status===404)return!0;const E=g instanceof Error?g.message:String(g);return/status code 404/i.test(E)}async function Kn(g,E){try{const c=await pe.gotoCarSite(g,E);return T.success(c.message||`已下发前往站点 #${E}`),!0}catch(c){if(!qn(c))return T.error(`前往站点失败:${c instanceof Error?c.message:String(c)}`),!1;try{const P=await pe.execute("car",g,"WebGotoSite",{siteId:E});return T.success(P.returnValue?`已执行:${P.returnValue}`:`已下发前往站点 #${E}`),!0}catch(P){const D=P instanceof Error?P.message:String(P),s=/WebGotoSite|goto-site|不存在可调用方法/i.test(D);return T.error(s?`${D}。当前 SimpleLite 仍是旧版 DLL:请先完全关闭 SimpleLite 窗口,再在 PowerShell 执行 Migu2.0/scripts/redeploy-simplelite.ps1,然后重新登录;或调用 POST /api/health/simplelite/restart-for-update`:`前往站点失败:${D}`),!1}}}async function jn(g,E,c){const P=c.label||c.methodName,D={};for(const s of c.params)try{const{value:y}=await De.prompt(`参数 ${s.name}(${s.typeName})`,P,{inputValue:s.defaultValue??"",confirmButtonText:"确定",cancelButtonText:"取消"});D[s.name]=y??""}catch{return!1}try{const s=await pe.execute(g,E,c.methodName,D);return T.success(s.returnValue?`已执行:${s.returnValue}`:`已执行 ${P}`),!0}catch(s){return T.error(`执行失败:${s instanceof Error?s.message:String(s)}`),!1}}const Xn={class:"monitor-selection"},Gn={key:0,class:"empty-hint"},Hn={key:1,class:"pane"},Yn={key:0,class:"pane-loading"},Zn={class:"card card--header"},Jn={class:"title-row"},Qn={class:"id-tag"},ea={class:"name-line"},ta={class:"card"},na={class:"kv-grid"},aa={class:"kv"},la={class:"v mono"},sa={class:"kv"},ia={class:"v mono"},oa={class:"kv"},ra={class:"v mono"},ca={key:0,class:"card"},ua={class:"card-hd"},da={class:"meta"},fa={class:"kv-list"},va={class:"k"},ma=["title"],pa={key:1,class:"card card--actions"},ga={class:"action-grid"},ya=["disabled","onClick"],_a={class:"card card--header"},ha={class:"title-row"},ka={class:"id-tag"},ba={class:"name-line"},wa={class:"card"},$a={class:"kv-list"},Sa={class:"kv-row"},Ca=["title"],Ia={class:"kv-row"},Na={class:"v"},xa=["title"],La={class:"kv-row"},Ta={class:"kv-row"},Ma=["title"],Va={class:"card card--actions"},Ea={class:"card-hd"},Aa={key:0,class:"meta"},Fa={key:1,class:"meta"},Pa={key:0,class:"muted-line"},Da={key:1,class:"action-grid action-grid--vehicle"},Ra=["disabled","title","onClick"],Oa={key:0,class:"muted-line"},za={key:1,class:"muted-line"},Ba={key:2,class:"action-grid action-grid--vehicle"},Ua=["disabled","onClick"],Wa={class:"card card--header"},qa={class:"title-row"},Ka={class:"id-tag"},ja={class:"name-line"},Xa={key:0,class:"card"},Ga={class:"kv-list"},Ha={class:"k"},Ya={class:"v"},Za={class:"k"},Ja={class:"v"},Qa={key:1,class:"card card--actions"},el={class:"action-grid"},tl=["disabled","onClick"],nl={key:4,class:"muted-line"},al=he({__name:"MonitorSelectionPanel",props:{selection:{},refreshKey:{},cars:{},missions:{},readOnly:{type:Boolean}},setup(g){const E=new Set(["AllowLock","PreventLock"]),c=g,P=lt(),D=C(!1),s=C(!1),y=C(!1),x=C(null),U=C(null),N=C(""),X=C(""),G=C(""),O=C({}),F=C([]),w=C([]),Y=C({}),Z=C([]),K=C([]),z=C(!1),R=C(!1),ae=C([]),ue=C("选择目标站点"),W={car:"car",vehicle:"car",site:"site",track:"track"},j=A(()=>{const e=c.selection?.kind?.toLowerCase();return e?W[e]??null:null}),le=A(()=>{const e=c.selection?.kind?.toLowerCase();return e==="site"?"site":e==="vehicle"||e==="car"?"vehicle":e==="track"?"track":"other"}),h=A(()=>{const e=Number(c.selection?.id);return Number.isFinite(e)?e:c.selection?.id??"-"});function L(e,a=1){if(e==null||e==="")return"—";const d=Number(e);return Number.isFinite(d)?d.toFixed(a):e}function r(...e){for(const a of e){const d=O.value[a];if(d!=null&&d!=="")return d}return""}function m(...e){for(const a of e){const d=F.value.find(V=>V.key===a);if(d?.value)return d.value}for(const a of e){const d=F.value.find(V=>V.key.includes(a));if(d?.value)return d.value}return""}function B(){const e=m("标记","tags");return e?/unavailable/i.test(e):!1}const u=A(()=>({name:r("name")||N.value||c.selection?.name||`站点 ${h.value}`,x:L(r("x"),1),y:L(r("y"),1),z:L(r("z"),1),disabled:B()})),o=A(()=>{const e=Z.value;if(e.length){const a=new Set(e);return w.value.filter(d=>a.has(d.methodName))}return w.value.filter(a=>E.has(a.methodName))}),_=A(()=>{const e=K.value;if(!e.length)return w.value;const a=new Set(e);return w.value.filter(d=>a.has(d.methodName))});function I(){if(!c.selection||le.value!=="vehicle")return;const e=String(c.selection.id);return c.cars?.find(a=>a.id===e||String(a.rawId??"")===e||ie(a)===e)}function ie(e){return e.rawId!=null?String(e.rawId):e.id.replace(/^C/i,"").replace(/^0+/,"")||e.id}const de=A(()=>F.value.map(e=>({key:e.key,value:e.value||"—",warn:/alarm|error|fault|block|stop/i.test(`${e.key} ${e.value}`)&&e.value!=="0"&&e.value!=="无"})));function ge(){const e=r("tags");if(e)return e;const a=m("tags","标记");if(a)return a;for(const d of F.value)if(/tag|标记/i.test(d.key)&&d.value)return d.value;return""}function Le(){const e=ge();if(/occupied/i.test(e))return!0;for(const a of F.value)if(/occupied/i.test(a.value??""))return!0;return!1}function _e(){const e=I(),a=r("batterySoc","battery","电量");let d=null;if(a){const V=Number(a);Number.isFinite(V)&&(d=V<=1?Math.round(V*100):Math.round(V))}else e!=null&&(d=Math.round(e.batterySoc<=1?e.batterySoc*100:e.batterySoc));return d==null?{text:"—",low:!1}:{text:`${d}%`,low:d<20}}function ee(){const e=I(),a=r("x"),d=r("y"),V=r("th","theta"),k=a||(e!=null?String(e.x):""),ne=d||(e!=null?String(e.y):""),Ne=V||(e!=null?String(e.theta):"");if(k||ne)return`(${k||"—"}, ${ne||"—"}${Ne?`, ${L(Ne,1)}°`:""})`;const xe=r("siteID");return xe&&xe!=="-1"?`站点 #${xe}`:m("位姿","站点")||"—"}function Se(){const e=m("TCStat")||r("TCStat");if(e&&e!=="/"&&e.trim()!=="")return e;const a=m("blockedBy");if(a&&a!=="[]"&&a!=="/")try{const Ne=JSON.parse(a);if(Array.isArray(Ne)&&Ne.length>0){const xe=Ne.map(Ue=>Ue.carid).filter(Ue=>Ue!=null);return xe.length?`被车辆 ${xe.join("、")} 交管`:"交管阻塞"}}catch{return a.length>48?`${a.slice(0,48)}…`:a}const d=m("trafficStopped");if(d&&d!=="(0, 0)"&&d!=="(0,0)"&&d!=="/")return`交管暂停 ${d}`;const V=m("holdingLocks"),k=m("pendingLocks"),ne=[];return V&&V!=="[]"&&ne.push(`已占 ${V}`),k&&k!=="[]"&&ne.push(`待锁 ${k}`),ne.length?ne.join(";"):"正常"}function be(){const e=m("车体_AlarmInfo","AlarmInfo")||F.value.find(d=>/alarminfo/i.test(d.key))?.value;if(e&&e!=="0"&&e!=="/"&&e.trim()!=="")return{text:e,warn:!0};const a=r("lstatus")||m("lstatus");return a&&/故障|报警|异常|失联|超时|检修/i.test(a)?{text:a,warn:!0}:{text:"无",warn:!1}}const Q=A(()=>{const e=I(),a=Le(),d=a?"任务中":"空闲",V=be(),k=_e();return{id:e?.id??c.selection?.id??"-",name:N.value||e?.name||c.selection?.name||"车辆",runLabel:d,runTagType:a?"success":"info",traffic:Se(),alarm:V.text,alarmWarn:V.warn,battery:k.text,batteryLow:k.low,position:ee()}});function Te(){const e=Y.value,a=G.value,d=X.value;if(a&&e[a]?.length)return e[a];if(d&&e[d]?.length)return e[d];for(const[V,k]of Object.entries(e))if(k.length&&(a&&(V===a||V.endsWith("."+d)||a.endsWith("."+V))||d&&(V===d||V.endsWith("."+d))))return k;return[]}const S=A(()=>Te()),se=A(()=>{const e=S.value;if(!e.length)return[];const a=new Set(e);return w.value.filter(d=>a.has(d.methodName))}),we=A(()=>zt.filter(e=>e.target==="car"&&P.hasOp(e.code)));async function Oe(e){const a=Number(c.selection?.id);if(Number.isFinite(a)){if(e.needConfirm)try{await De.confirm(`确认执行 [${e.label}]?
|
||
目标车辆:${c.selection?.id}`,"二次确认",{type:"warning"})}catch{return}x.value=e.code;try{const d=await Bt({opCode:e.code,targetId:String(a),reason:""});d.ok?T.success(`已执行 ${e.label}(auditId=${d.auditId})`):T.warning(d.message||`执行未成功:${e.label}`)}catch(d){T.error(`执行失败:${d.message}`)}finally{x.value=null}}}const ze=A(()=>z.value?Object.keys(Y.value).length?S.value.length?"当前车型无可执行动作。":"当前车型未配置动作,或方法名与运营维护中勾选的不一致。":"未配置动作。请在「配置中心 → 运营维护」按车型勾选动作并保存。":"加载配置中…"),Ce=A(()=>({name:r("name")||N.value||c.selection?.name||`路径 ${h.value}`})),Me=A(()=>[{key:"layer",label:"图层",value:r("layerName","layer")||"—"},{key:"type",label:"类型",value:X.value||"—"}]);function Be(e){return e?`${e.kind}:${e.id}`:""}async function oe(e=!1){if(!(z.value&&!e))try{const a=await it(e);Y.value={...a.config.carActionByType??{}},Z.value=[...a.config.site?.methods??[]],K.value=[...a.config.track?.methods??[]]}catch{Y.value={},Z.value=[],K.value=[]}finally{z.value=!0}}function $e(e,a){N.value=e.summary?.name??a??"",X.value=e.typeName??"",G.value="fullTypeName"in e&&e.fullTypeName?e.fullTypeName:e.typeName??"",O.value={...e.fields};for(const d of e.fieldList??[])O.value[d.key]=d.value;F.value=e.status??[],w.value=e.methods??[]}function Ve(){const e=I();if(!e)return!1;N.value=e.name,X.value=e.typeName??"",G.value=e.typeName??"";const a=Math.round(e.batterySoc<=1?e.batterySoc*100:e.batterySoc);return O.value={x:String(e.x),y:String(e.y),th:String(e.theta),batterySoc:String(a)},F.value=[],w.value=[],!0}async function Ie(){if(!c.selection){N.value="",O.value={},F.value=[],w.value=[],s.value=!1;return}const e=j.value,a=Number(c.selection.id);if(!e||!Number.isFinite(a))return;const d=s.value,V=!d&&le.value==="vehicle"&&Ve();V&&(s.value=!0),d?y.value=!0:D.value=!V;try{if(c.readOnly){const ne=await pe.getBundle(e,a);$e(ne,c.selection.name??""),w.value=[],s.value=!0;return}await oe(!1);const k=await pe.getBundle(e,a);$e(k,c.selection.name??""),s.value=!0}catch(k){c.readOnly?console.warn("[MonitorSelection] 只读详情加载失败,降级用列表数据",k):T.error(`加载选中信息失败:${k.message}`)}finally{D.value=!1,y.value=!1}}async function t(e){const a=j.value;if(!a||!c.selection||!e.methodName)return;const d=Number(c.selection.id);if(Number.isFinite(d)){if(a==="car"&&Ye(e)){U.value=e,ue.value=`选择目标站点 — ${e.label||e.methodName}`,x.value=e.methodName;try{const V=await Ze();if(V!=null){await v(V);return}ae.value=await Wn(),R.value=!0}catch(V){T.error(`加载站点列表失败:${V.message}`)}finally{R.value||(x.value=null)}return}x.value=e.methodName;try{await jn(a,d,e)&&await Ie()}finally{x.value=null}}}async function v(e){const a=Number(c.selection?.id);if(Number.isFinite(a)){x.value=U.value?.methodName??"goto";try{await Kn(a,e)&&await Ie()}finally{x.value=null,U.value=null}}}async function $(){const e=await Ze();R.value=!1,e!=null&&await v(e)}let M=0,te="";return Fe(()=>[Be(c.selection),c.refreshKey],async(e,a)=>{const d=++M;if(a&&e[0]===a[0]&&e[0]&&e[1]!==a[1])return await oe(!0),void 0;e[0]!==te&&(s.value=!1,te=e[0]),await Ie()},{immediate:!0}),(e,a)=>{const d=Ge,V=je;return f(),b("div",Xn,[g.selection?(f(),b("div",Hn,[D.value?(f(),b("div",Yn,[l(d,{class:"is-loading"},{default:i(()=>[l(H(dt))]),_:1}),a[2]||(a[2]=n("span",null,"加载中…",-1))])):le.value==="site"?(f(),b(J,{key:1},[n("section",Zn,[n("div",Jn,[n("span",Qn,"#"+p(h.value),1),a[3]||(a[3]=n("span",{class:"type-tag"},"站点",-1))]),n("div",ea,p(u.value.name),1)]),n("section",ta,[a[7]||(a[7]=n("header",{class:"card-hd"},[n("span",null,"位置")],-1)),n("div",na,[n("div",aa,[a[4]||(a[4]=n("span",{class:"k"},"X",-1)),n("span",la,p(u.value.x),1)]),n("div",sa,[a[5]||(a[5]=n("span",{class:"k"},"Y",-1)),n("span",ia,p(u.value.y),1)]),n("div",oa,[a[6]||(a[6]=n("span",{class:"k"},"Z",-1)),n("span",ra,p(u.value.z),1)])])]),de.value.length?(f(),b("section",ca,[n("header",ua,[a[8]||(a[8]=n("span",null,"状态",-1)),n("span",da,p(de.value.length),1)]),n("div",fa,[(f(!0),b(J,null,ce(de.value,k=>(f(),b("div",{key:k.key,class:"kv-row"},[n("span",va,p(k.key),1),n("span",{class:"v",title:k.value},p(k.value),9,ma)]))),128))])])):ye("",!0),!g.readOnly&&o.value.length?(f(),b("section",pa,[a[9]||(a[9]=n("header",{class:"card-hd"},[n("span",null,"操作")],-1)),n("div",ga,[(f(!0),b(J,null,ce(o.value,k=>(f(),b("button",{key:k.methodName,type:"button",class:"action-btn",disabled:x.value===k.methodName,onClick:ne=>t(k)},p(k.label||k.methodName),9,ya))),128))])])):ye("",!0)],64)):le.value==="vehicle"?(f(),b(J,{key:2},[n("section",_a,[n("div",ha,[n("span",ka,p(Q.value.id),1),l(V,{size:"small",type:Q.value.runTagType,effect:"dark"},{default:i(()=>[q(p(Q.value.runLabel),1)]),_:1},8,["type"])]),n("div",ba,p(Q.value.name),1)]),n("section",wa,[a[15]||(a[15]=n("header",{class:"card-hd"},[n("span",null,"运行信息")],-1)),n("div",$a,[n("div",Sa,[a[10]||(a[10]=n("span",{class:"k"},"交管状态",-1)),n("span",{class:"v",title:Q.value.traffic},p(Q.value.traffic),9,Ca)]),n("div",Ia,[a[11]||(a[11]=n("span",{class:"k"},"运行状态",-1)),n("span",Na,p(Q.value.runLabel),1)]),n("div",{class:me(["kv-row",{"is-warn":Q.value.alarmWarn}])},[a[12]||(a[12]=n("span",{class:"k"},"报警状态",-1)),n("span",{class:"v",title:Q.value.alarm},p(Q.value.alarm),9,xa)],2),n("div",La,[a[13]||(a[13]=n("span",{class:"k"},"电量",-1)),n("span",{class:me(["v",{"is-low-battery":Q.value.batteryLow}])},p(Q.value.battery),3)]),n("div",Ta,[a[14]||(a[14]=n("span",{class:"k"},"位置",-1)),n("span",{class:"v mono",title:Q.value.position},p(Q.value.position),9,Ma)])])]),n("section",Va,[n("header",Ea,[n("span",null,p(g.readOnly?"运维动作":"动作"),1),!g.readOnly&&se.value.length?(f(),b("span",Aa,p(se.value.length),1)):g.readOnly&&we.value.length?(f(),b("span",Fa,p(we.value.length),1)):ye("",!0)]),g.readOnly?(f(),b(J,{key:0},[we.value.length?(f(),b("div",Da,[(f(!0),b(J,null,ce(we.value,k=>(f(),b("button",{key:k.code,type:"button",class:me(["action-btn",{"action-btn--goto":k.needConfirm}]),disabled:x.value===k.code,title:k.description,onClick:ne=>Oe(k)},p(k.label),11,Ra))),128))])):(f(),b("div",Pa,"当前账号无可执行的运维动作。"))],64)):(f(),b(J,{key:1},[y.value?(f(),b("div",Oa,"加载动作…")):se.value.length?(f(),b("div",Ba,[(f(!0),b(J,null,ce(se.value,k=>(f(),b("button",{key:k.methodName,type:"button",class:me(["action-btn",{"action-btn--goto":H(Ye)(k)}]),disabled:x.value===k.methodName,onClick:ne=>t(k)},p(k.label||k.methodName),11,Ua))),128))])):(f(),b("div",za,p(ze.value),1))],64))])],64)):le.value==="track"?(f(),b(J,{key:3},[n("section",Wa,[n("div",qa,[n("span",Ka,"#"+p(h.value),1),a[16]||(a[16]=n("span",{class:"type-tag"},"路径",-1))]),n("div",ja,p(Ce.value.name),1)]),de.value.length||Me.value.length?(f(),b("section",Xa,[a[17]||(a[17]=n("header",{class:"card-hd"},[n("span",null,"信息")],-1)),n("div",Ga,[(f(!0),b(J,null,ce(Me.value,k=>(f(),b("div",{key:k.key,class:"kv-row"},[n("span",Ha,p(k.label),1),n("span",Ya,p(k.value),1)]))),128)),(f(!0),b(J,null,ce(de.value,k=>(f(),b("div",{key:"s-"+k.key,class:"kv-row"},[n("span",Za,p(k.key),1),n("span",Ja,p(k.value),1)]))),128))])])):ye("",!0),!g.readOnly&&_.value.length?(f(),b("section",Qa,[a[18]||(a[18]=n("header",{class:"card-hd"},[n("span",null,"动作")],-1)),n("div",el,[(f(!0),b(J,null,ce(_.value,k=>(f(),b("button",{key:k.methodName,type:"button",class:"action-btn",disabled:x.value===k.methodName,onClick:ne=>t(k)},p(k.label||k.methodName),9,tl))),128))])])):ye("",!0)],64)):(f(),b("div",nl,"该类型暂不支持监控详情展示。"))])):(f(),b("div",Gn,[...a[1]||(a[1]=[n("span",{class:"empty-title"},"未选中对象",-1),n("span",{class:"empty-desc"},"在 3D 画布或车辆列表中点击以查看信息。",-1)])])),l(zn,{modelValue:R.value,"onUpdate:modelValue":a[0]||(a[0]=k=>R.value=k),title:ue.value,sites:ae.value,onConfirm:v,onPickOnMap:$},null,8,["modelValue","title","sites"])])}}}),ll=ke(al,[["__scopeId","data-v-c9236d99"]]),sl={class:"fac-header"},il={class:"fac-title"},ol={class:"fac-time"},rl={class:"fac-body"},cl={class:"fac-info"},ul={class:"fac-coord"},dl={key:0},fl={key:1,class:"muted"},vl={class:"fac-actions"},ml=he({__name:"FloatingAlarmCard",props:{alarm:{},initialOffset:{}},emits:["close","ack","snooze","locate"],setup(g,{emit:E}){const c=g,P=E,D=C(null),s=C(!1),y=C({right:c.initialOffset?.right??24,bottom:c.initialOffset?.bottom??24}),x=A(()=>typeof c.alarm.x=="number"&&Number.isFinite(c.alarm.x)),U=A(()=>{const W=(c.alarm.info||"").toLowerCase();return W.includes("critical")||W.includes("严重")||W.includes("紧急")?"critical":W.includes("error")||W.includes("故障")?"error":W.includes("warn")||W.includes("告警")?"warn":"info"}),N=A(()=>{try{return new Date(c.alarm.timestamp).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})}catch{return""}}),X=A(()=>({left:y.value.left!==void 0?`${y.value.left}px`:void 0,top:y.value.top!==void 0?`${y.value.top}px`:void 0,right:y.value.right!==void 0?`${y.value.right}px`:void 0,bottom:y.value.bottom!==void 0?`${y.value.bottom}px`:void 0}));let G=0,O=0,F=0,w=0;function Y(W){if(!D.value)return;const j=D.value.getBoundingClientRect();F=j.left,w=j.top,G=W.clientX,O=W.clientY,s.value=!0,window.addEventListener("mousemove",Z),window.addEventListener("mouseup",K)}function Z(W){y.value={left:F+(W.clientX-G),top:w+(W.clientY-O)}}function K(){s.value=!1,window.removeEventListener("mousemove",Z),window.removeEventListener("mouseup",K)}st(()=>{window.removeEventListener("mousemove",Z),window.removeEventListener("mouseup",K)});function z(){P("close")}function R(){P("ack")}function ae(){P("snooze")}function ue(){P("locate",c.alarm)}return(W,j)=>{const le=Ge,h=Ae;return f(),b("div",{ref_key:"cardRef",ref:D,class:me(["floating-alarm-card",[`lvl-${U.value}`,{dragging:s.value}]]),style:nt(X.value),onMousedown:ve(Y,["stop"])},[n("div",sl,[j[0]||(j[0]=n("span",{class:"fac-dot"},null,-1)),n("span",il,p(g.alarm.carName)+" #"+p(g.alarm.carId),1),n("span",ol,p(N.value),1),l(le,{class:"fac-close",onClick:ve(z,["stop"])},{default:i(()=>[l(H(ft))]),_:1})]),n("div",rl,[n("div",cl,p(g.alarm.info),1),n("div",ul,[x.value?(f(),b("span",dl,"坐标 ("+p(g.alarm.x?.toFixed(0))+", "+p(g.alarm.y?.toFixed(0))+") mm",1)):(f(),b("span",fl,"无坐标"))])]),n("div",vl,[l(h,{size:"small",plain:"",disabled:!x.value,onClick:ve(ue,["stop"])},{default:i(()=>[...j[1]||(j[1]=[q("定位",-1)])]),_:1},8,["disabled"]),l(h,{size:"small",plain:"",onClick:ve(R,["stop"])},{default:i(()=>[...j[2]||(j[2]=[q("确认",-1)])]),_:1}),l(h,{size:"small",plain:"",onClick:ve(ae,["stop"])},{default:i(()=>[...j[3]||(j[3]=[q("稍后",-1)])]),_:1})])],38)}}}),pl=ke(ml,[["__scopeId","data-v-0b6ee97c"]]),gl={class:"floating-alarm-stack"},yl=he({__name:"FloatingAlarmStack",props:{alarms:{}},emits:["locate","ack"],setup(g,{emit:E}){const c=g,P=E,D=C(new Set),s=C(new Set);function y(w){return`${w.carId}`}const x=A(()=>c.alarms.filter(w=>w.action!=="clear").filter(w=>!D.value.has(y(w))).filter(w=>!s.value.has(y(w)))),U=A(()=>c.alarms.filter(w=>s.value.has(y(w))));function N(w){D.value=new Set([...D.value,y(w)])}function X(w){D.value=new Set([...D.value,y(w)]),P("ack",w)}function G(w){s.value=new Set([...s.value,y(w)])}function O(w){P("locate",w)}function F(){s.value=new Set}return(w,Y)=>{const Z=Ae,K=vt;return f(),b("div",gl,[(f(!0),b(J,null,ce(x.value,(z,R)=>(f(),fe(pl,{key:`${z.carId}-${z.timestamp}`,alarm:z,"initial-offset":{right:24,bottom:24+R*132},onClose:ae=>N(z),onAck:ae=>X(z),onSnooze:ae=>G(z),onLocate:O},null,8,["alarm","initial-offset","onClose","onAck","onSnooze"]))),128)),U.value.length?(f(),b("div",{key:0,class:"snooze-tray",onClick:F},[l(K,{value:U.value.length,type:"warning"},{default:i(()=>[l(Z,{size:"small",circle:""},{default:i(()=>[...Y[0]||(Y[0]=[q("≡",-1)])]),_:1})]),_:1},8,["value"])])):ye("",!0)])}}}),_l=ke(yl,[["__scopeId","data-v-c37fdeb1"]]),hl={class:"canvas-toolbar"},kl=["onClick"],bl=["onClick"],wl={key:0,class:"menu-empty"},$l=["onClick"],Sl=["onClick"],Cl={class:"btn-label"},Il={class:"btn-label"},Nl={class:"btn-label"},xl={class:"btn-label"},Ll={class:"muted-hint"},Tl=he({__name:"WorkspaceCanvasToolbar",props:{followCarId:{default:null}},setup(g){const E=g,c=[{key:"sites",label:"站点"},{key:"cars",label:"AGV"},{key:"tracks",label:"路径"}],P=[{key:"tracks",label:"路径"},{key:"cars",label:"AGV"},{key:"decor",label:"区域/装饰"},{key:"sites",label:"站点"}],D=[{key:"labels",label:"场景图元标记"},{key:"primitives",label:"场景图元"},{key:"cars",label:"车辆"}],s=C(null),y=xt({align:!1,select:!1,display:!1,layer:!1,recording:!1,playback:!1,view:!1,follow:!1}),x=C(!1),U=C(!1);let N=null;const X=A(()=>{const u=s.value?.recording;if(!u?.isRecording)return"录制";const o=Math.floor((u.elapsedMs??0)/1e3),_=String(Math.floor(o/60)).padStart(2,"0"),I=String(o%60).padStart(2,"0");return`停止 ${_}:${I}`}),G=A(()=>s.value?.view?.map2D??!0),O=A(()=>s.value?.view?.follow?.enabled??!1),F=A(()=>{const u=E.followCarId;if(u!=null&&Number.isFinite(u))return u;const o=s.value?.view?.follow?.carId;return o!=null&&Number.isFinite(o)?o:null});async function w(){try{s.value=await re.getState()}catch(u){T.error(`同步工具栏状态失败:${u.message}`)}}async function Y(u){if(s.value){y.align=!0;try{s.value=await re.setAlign(u,!s.value.align[u])}catch(o){T.error(`切换对齐失败:${o.message}`)}finally{y.align=!1}}}async function Z(u){if(s.value){y.select=!0;try{s.value=await re.setSelect(u,!s.value.select[u])}catch(o){T.error(`切换选择过滤失败:${o.message}`)}finally{y.select=!1}}}async function K(u){if(s.value){y.display=!0;try{s.value=await re.setDisplay(u,!s.value.display[u])}catch(o){T.error(`切换显示内容失败:${o.message}`)}finally{y.display=!1}}}async function z(u,o){y.layer=!0;try{s.value=await re.setLayerVisibility(u,o)}catch(_){T.error(`切换图层失败:${_.message}`)}finally{y.layer=!1}}function R(){T.info("寻路右键动作尚未接入 SimpleLite;请使用 SegmentPlan.FindRoute / 工作台脚本。")}async function ae(){const u=s.value?.recording;if(u){if(u.isPlaying){T.warning("当前在回放中,请先停止回放。");return}y.recording=!0;try{s.value=u.isRecording?await re.stopRecording():await re.startRecording("")}catch(o){T.error(`录制操作失败:${o.message}`)}finally{y.recording=!1}}}async function ue(){const u=s.value?.recording;if(u){if(u.isRecording){T.warning("录制中无法进入回放,请先停止录制。");return}if(u.isPlaying){y.playback=!0;try{s.value=await re.stopPlayback()}catch(o){T.error(`停止回放失败:${o.message}`)}finally{y.playback=!1}return}await w(),x.value=!0}}async function W(u){y.playback=!0;try{s.value=await re.startPlayback(u),x.value=!1,U.value=!1,T.success(`已开始回放 ${u}`)}catch(o){T.error(`启动回放失败:${o.message}`)}finally{y.playback=!1}}async function j(u){try{await De.confirm(`确认删除录像 ${u}?此操作不可恢复。`,"删除录像",{type:"warning"})}catch{return}try{s.value=await re.deleteRecording(u),T.success(`已删除 ${u}`)}catch(o){T.error(`删除失败:${o.message}`)}}async function le(){await w(),U.value=!0}async function h(){y.view=!0;try{s.value=await re.toggleViewMode()}catch(u){T.error(`切换视图失败:${u.message}`)}finally{y.view=!1}}async function L(){const u=F.value;if(!O.value&&(u==null||!Number.isFinite(u))){T.warning("请先在车辆列表或 3D 画布中选中一辆车");return}y.follow=!0;try{const o=!O.value;s.value=await re.setCameraFollow(u,o),o?T.success({message:`已开始跟随车辆 #${u}`,duration:1500,grouping:!0}):T.info("已停止自动跟随")}catch(o){T.error(`自动跟随失败:${o.message}`)}finally{y.follow=!1}}function r(u){if(!Number.isFinite(u)||u<=0)return"0 B";if(u<1024)return`${u} B`;const o=u/1024;return o<1024?`${o.toFixed(0)} KB`:`${(o/1024).toFixed(1)} MB`}function m(u){if(!Number.isFinite(u)||u<=0)return"00:00:00";const o=Math.floor(u/1e3),_=String(Math.floor(o/3600)).padStart(2,"0"),I=String(Math.floor(o%3600/60)).padStart(2,"0"),ie=String(o%60).padStart(2,"0");return`${_}:${I}:${ie}`}function B(u){if(!u)return"—";const o=new Date(u);if(isNaN(o.getTime()))return u;const _=I=>String(I).padStart(2,"0");return`${o.getFullYear()}-${_(o.getMonth()+1)}-${_(o.getDate())} ${_(o.getHours())}:${_(o.getMinutes())}`}return Xe(()=>{w(),N=setInterval(()=>{const u=s.value?.recording;(u?.isRecording||u?.isPlaying||s.value?.view?.follow?.enabled)&&w()},1e3)}),st(()=>{N&&clearInterval(N),O.value&&re.setCameraFollow(null,!1).catch(()=>{})}),(u,o)=>{const _=Ge,I=Ae,ie=Qe,de=gt,ge=mt,Le=ht,_e=Lt,ee=tt,Se=et,be=at,Q=je,Te=Nt;return f(),b("div",hl,[l(ge,{trigger:"click","hide-on-click":!1,placement:"top-start"},{dropdown:i(()=>[l(de,{class:"toolbar-menu"},{default:i(()=>[(f(),b(J,null,ce(c,S=>n("div",{key:S.key,class:"menu-row",onClick:ve(se=>Y(S.key),["stop"])},[l(ie,{"model-value":s.value?.align[S.key]??!1},null,8,["model-value"]),n("span",null,p(S.label),1)],8,kl)),64))]),_:1})]),default:i(()=>[l(I,{size:"small",loading:y.align},{default:i(()=>[l(_,null,{default:i(()=>[l(H(pt))]),_:1}),o[2]||(o[2]=n("span",{class:"btn-label"},"对齐",-1)),l(_,{class:"caret"},{default:i(()=>[l(H(Ee))]),_:1})]),_:1},8,["loading"])]),_:1}),l(ge,{trigger:"click","hide-on-click":!1,placement:"top-start"},{dropdown:i(()=>[l(de,{class:"toolbar-menu"},{default:i(()=>[(f(),b(J,null,ce(P,S=>n("div",{key:S.key,class:"menu-row",onClick:ve(se=>Z(S.key),["stop"])},[l(ie,{"model-value":s.value?.select[S.key]??!1},null,8,["model-value"]),n("span",null,p(S.label),1)],8,bl)),64))]),_:1})]),default:i(()=>[l(I,{size:"small",loading:y.select},{default:i(()=>[l(_,null,{default:i(()=>[l(H(yt))]),_:1}),o[3]||(o[3]=n("span",{class:"btn-label"},"选择",-1)),l(_,{class:"caret"},{default:i(()=>[l(H(Ee))]),_:1})]),_:1},8,["loading"])]),_:1}),l(ge,{trigger:"click",placement:"top-start"},{dropdown:i(()=>[l(de,{class:"toolbar-menu"},{default:i(()=>[l(Le,{onClick:R},{default:i(()=>[...o[5]||(o[5]=[q("寻路",-1)])]),_:1})]),_:1})]),default:i(()=>[l(I,{size:"small"},{default:i(()=>[l(_,null,{default:i(()=>[l(H(_t))]),_:1}),o[4]||(o[4]=n("span",{class:"btn-label"},"右击功能",-1)),l(_,{class:"caret"},{default:i(()=>[l(H(Ee))]),_:1})]),_:1})]),_:1}),o[14]||(o[14]=n("span",{class:"separator"},null,-1)),l(ge,{trigger:"click","hide-on-click":!1,placement:"top-start"},{dropdown:i(()=>[l(de,{class:"toolbar-menu layer-menu"},{default:i(()=>[!s.value||s.value.layers.length===0?(f(),b("div",wl,"(无图层)")):(f(!0),b(J,{key:1},ce(s.value.layers,S=>(f(),b("div",{key:S.name,class:"menu-row",onClick:ve(se=>z(S.name,!S.visible),["stop"])},[l(ie,{"model-value":S.visible},null,8,["model-value"]),n("span",null,"图层 "+p(S.name),1)],8,$l))),128))]),_:1})]),default:i(()=>[l(I,{size:"small",loading:y.layer},{default:i(()=>[l(_,null,{default:i(()=>[l(H(kt))]),_:1}),o[6]||(o[6]=n("span",{class:"btn-label"},"显示图层",-1)),l(_,{class:"caret"},{default:i(()=>[l(H(Ee))]),_:1})]),_:1},8,["loading"])]),_:1}),l(ge,{trigger:"click","hide-on-click":!1,placement:"top-start"},{dropdown:i(()=>[l(de,{class:"toolbar-menu"},{default:i(()=>[(f(),b(J,null,ce(D,S=>n("div",{key:S.key,class:"menu-row",onClick:ve(se=>K(S.key),["stop"])},[l(ie,{"model-value":s.value?.display[S.key]??!1},null,8,["model-value"]),n("span",null,p(S.label),1)],8,Sl)),64))]),_:1})]),default:i(()=>[l(I,{size:"small",loading:y.display},{default:i(()=>[l(_,null,{default:i(()=>[l(H(He))]),_:1}),o[7]||(o[7]=n("span",{class:"btn-label"},"显示内容",-1)),l(_,{class:"caret"},{default:i(()=>[l(H(Ee))]),_:1})]),_:1},8,["loading"])]),_:1}),o[15]||(o[15]=n("span",{class:"separator"},null,-1)),l(I,{size:"small",type:s.value?.recording.isRecording?"danger":"default",loading:y.recording,onClick:ae},{default:i(()=>[s.value?.recording.isRecording?(f(),fe(_,{key:0},{default:i(()=>[l(H(bt))]),_:1})):(f(),fe(_,{key:1},{default:i(()=>[l(H(wt))]),_:1})),n("span",Cl,p(X.value),1)]),_:1},8,["type","loading"]),l(I,{size:"small",type:s.value?.recording.isPlaying?"warning":"default",loading:y.playback,onClick:ue},{default:i(()=>[s.value?.recording.isPlaying?(f(),fe(_,{key:0},{default:i(()=>[l(H($t))]),_:1})):(f(),fe(_,{key:1},{default:i(()=>[l(H(St))]),_:1})),n("span",Il,p(s.value?.recording.isPlaying?"退出回放":"回放"),1)]),_:1},8,["type","loading"]),l(I,{size:"small",onClick:le},{default:i(()=>[l(_,null,{default:i(()=>[l(H(Ct))]),_:1}),o[8]||(o[8]=n("span",{class:"btn-label"},"录像管理",-1))]),_:1}),l(I,{size:"small",type:G.value?"primary":"default",loading:y.view,onClick:h},{default:i(()=>[l(_,null,{default:i(()=>[l(H(He))]),_:1}),n("span",Nl,p(G.value?"2D":"3D"),1)]),_:1},8,["type","loading"]),l(I,{size:"small",type:O.value?"warning":"default",disabled:!O.value&&F.value==null,loading:y.follow,onClick:L},{default:i(()=>[l(_,null,{default:i(()=>[l(H(It))]),_:1}),n("span",xl,p(O.value?"停止跟随":"自动跟随"),1)]),_:1},8,["type","disabled","loading"]),l(be,{modelValue:x.value,"onUpdate:modelValue":o[0]||(o[0]=S=>x.value=S),title:"选择录像回放",width:"640px","append-to-body":"","destroy-on-close":""},{default:i(()=>[!s.value||s.value.recording.entries.length===0?(f(),fe(_e,{key:0,description:"(无可用录像。点 ● 录制 创建首份录像。)"})):(f(),fe(Se,{key:1,data:s.value.recording.entries,size:"small",stripe:""},{default:i(()=>[l(ee,{prop:"fileName",label:"文件名","min-width":"180"}),l(ee,{label:"大小",width:"90"},{default:i(({row:S})=>[q(p(r(S.fileSizeBytes)),1)]),_:1}),l(ee,{prop:"frameCount",label:"帧",width:"70"}),l(ee,{label:"时长",width:"100"},{default:i(({row:S})=>[q(p(m(S.durationMs)),1)]),_:1}),l(ee,{label:"时间",width:"160"},{default:i(({row:S})=>[q(p(B(S.fileWriteTime)),1)]),_:1}),l(ee,{label:"操作",width:"100",fixed:"right"},{default:i(({row:S})=>[l(I,{link:"",type:"primary",disabled:!S.headerReadable,onClick:se=>W(S.fileName)},{default:i(()=>[...o[9]||(o[9]=[q("回放",-1)])]),_:1},8,["disabled","onClick"])]),_:1})]),_:1},8,["data"]))]),_:1},8,["modelValue"]),l(be,{modelValue:U.value,"onUpdate:modelValue":o[1]||(o[1]=S=>U.value=S),title:"录像管理",width:"780px","append-to-body":"","destroy-on-close":""},{default:i(()=>[n("p",Ll,"目录:"+p(s.value?.recording.recordingsDirectory??"—"),1),!s.value||s.value.recording.entries.length===0?(f(),fe(_e,{key:0,description:"(无可用录像。)"})):(f(),fe(Se,{key:1,data:s.value.recording.entries,size:"small",stripe:""},{default:i(()=>[l(ee,{prop:"fileName",label:"文件名","min-width":"200"}),l(ee,{label:"大小",width:"90"},{default:i(({row:S})=>[q(p(r(S.fileSizeBytes)),1)]),_:1}),l(ee,{prop:"frameCount",label:"帧",width:"70"}),l(ee,{label:"时长",width:"100"},{default:i(({row:S})=>[q(p(m(S.durationMs)),1)]),_:1}),l(ee,{label:"时间",width:"160"},{default:i(({row:S})=>[q(p(B(S.fileWriteTime)),1)]),_:1}),l(ee,{label:"状态",width:"120"},{default:i(({row:S})=>[S.headerReadable?(f(),fe(Q,{key:0,type:"success",size:"small"},{default:i(()=>[...o[10]||(o[10]=[q("完整",-1)])]),_:1})):(f(),fe(Te,{key:1,content:S.error,placement:"top"},{default:i(()=>[l(Q,{type:"danger",size:"small"},{default:i(()=>[...o[11]||(o[11]=[q("头部不可读",-1)])]),_:1})]),_:1},8,["content"]))]),_:1}),l(ee,{label:"操作",width:"160",fixed:"right"},{default:i(({row:S})=>[l(I,{link:"",type:"primary",disabled:!S.headerReadable,onClick:se=>W(S.fileName)},{default:i(()=>[...o[12]||(o[12]=[q("回放",-1)])]),_:1},8,["disabled","onClick"]),l(I,{link:"",type:"danger",onClick:se=>j(S.fileName)},{default:i(()=>[...o[13]||(o[13]=[q("删除",-1)])]),_:1},8,["onClick"])]),_:1})]),_:1},8,["data"]))]),_:1},8,["modelValue"])])}}}),Ml=ke(Tl,[["__scopeId","data-v-968a4c89"]]),Vl={class:"map-monitor-page"},El={class:"muted"},Al={class:"canvas-with-alarms"},Fl={class:"workbench-header"},Pl=he({__name:"MapMonitorView",props:{readOnly:{type:Boolean}},setup(g){const E=lt(),c=Mt(),P=Vt(),D="localhost:8223",s=C([]),y=C([]),x=C([]),U=C({includeFinished:!0,includeAborted:!0}),N=C(null),X=C(0),G=C(!1),O=C("vehicle"),F=C(null),w=C(null),Y=C(!1),Z=C(null),K=C(null),z=C([]);async function R(t){const v=Number(t.carId);if(!Number.isFinite(v)){T.warning(`报警车辆 id 无法解析:${t.carId}`);return}N.value={kind:"vehicle",id:String(v),name:t.carName??String(t.carId)},await se(v)}function ae(t){}let ue=null;const W=A(()=>s.value.filter(t=>t.state!=="offline").length),j=A(()=>x.value.length>0?x.value.filter(t=>t.statusCode==="Fetching"||t.statusCode==="Putting").length:y.value.filter(t=>t.status==="running").length),le=A(()=>x.value.length>0?x.value.filter(t=>t.statusCode==="Waiting").length:y.value.filter(t=>t.status==="queued").length),h=A(()=>{if(!N.value||N.value.kind!=="vehicle")return null;const t=N.value;return s.value.find($=>$.id===t.id||oe($)===t.id)?.id??null}),L=A(()=>{if(!N.value||N.value.kind!=="vehicle")return null;const t=N.value.id,v=Number(t);if(Number.isFinite(v))return v;const $=s.value.find(M=>M.id===t||oe(M)===t);if($?.rawId!=null)return $.rawId;if($){const M=Number(oe($));if(Number.isFinite(M))return M}return null});function r(t){}const m=/^(?:UI)?(?:Car|Vehicle)-(\d+)$/i,B=/^UISite-(\d+)$/i,u=/^(?:UITrack|UICircularArcTrack|UIBezierTrack|UINurbsTrack)-(\d+)$/i;function o(t){const v=m.exec(t);if(v)return{kind:"vehicle",id:v[1]};const $=B.exec(t);if($)return{kind:"site",id:$[1]};const M=u.exec(t);if(M)return{kind:"track",id:M[1]};const te=/^UI([A-Za-z]+)-(\d+)$/.exec(t)??/^([A-Za-z]+)-(\d+)$/.exec(t);if(!te)return null;const e=te[1].toLowerCase(),a=te[2];return e==="site"?{kind:"site",id:a}:e==="car"||e==="vehicle"?{kind:"vehicle",id:a}:e.includes("track")?{kind:"track",id:a}:null}function _(t,v){return!t&&!v?!0:!t||!v?!1:t.kind===v.kind&&t.id===v.id}function I(t,v){F.value=null;let $;if(t.kind==="vehicle"){const M=(v?Me(v):void 0)??s.value.find(te=>oe(te)===t.id);$=M?{kind:"vehicle",id:oe(M),name:M.name}:{kind:"vehicle",id:t.id,name:`Vehicle ${t.id}`}}else $={kind:t.kind,id:t.id,name:v||`${t.kind==="site"?"Site":"Track"} ${t.id}`};_(N.value,$)||(N.value=$)}function ie(t,v,$){if(F.value=null,t==="car"){const a=String(v),d=$?.find(ne=>m.test(ne))??`Car-${v}`,V=Me(d)??s.value.find(ne=>oe(ne)===a||ne.id===a),k=V?{kind:"vehicle",id:oe(V),name:V.name}:{kind:"vehicle",id:a,name:`Vehicle ${a}`};_(N.value,k)||(N.value=k);return}const M=String(v),te=$?.find(a=>{const d=o(a);return d?.kind===t&&d.id===M}),e={kind:t,id:M,name:te||`${t==="site"?"Site":"Track"} ${M}`};_(N.value,e)||(N.value=e)}function de(t){const v=t.siteIds?.length??0,$=t.trackIds?.length??0,M=t.carIds?.length??0,te=Array.isArray(t.names)?t.names.length:0;if(v+$+M+te===0){N.value=null;return}if(Array.isArray(t.names))for(const e of t.names){const a=o(e);if(a){I(a,e);return}}if(t.kind&&t.id){ie(t.kind,t.id,t.names);return}if(v>0){ie("site",t.siteIds[0],t.names);return}if($>0){ie("track",t.trackIds[0],t.names);return}M>0&&ie("car",t.carIds[0],t.names)}function ge(t){if(!t.length){S();return}for(const v of t){const $=o(v);if($){I($,v);return}}S()}function Le(){const t=c.query.focusKind,v=c.query.focusId;if(typeof t!="string"||typeof v!="string"||t!=="car"&&t!=="site"&&t!=="track"&&t!=="special")return!1;const $=Number(v);if(!Number.isFinite($))return!1;Z.value={kind:t,id:$};const M={...c.query};return delete M.focusKind,delete M.focusId,P.replace({path:c.path,query:M}),!0}async function _e(){const t=Z.value;if(!t||!Y.value)return;Z.value=null;const{kind:v,id:$}=t;if(v==="car"){const M=s.value.find(te=>oe(te)===String($)||te.rawId===$);N.value=M?{kind:"vehicle",id:oe(M),name:M.name}:{kind:"vehicle",id:String($),name:`Vehicle ${$}`},await se($);return}if(v==="site"||v==="track"){ie(v,$);try{await pe.setSelection(v,$)}catch(M){T.error({message:`定位对象失败:${M.message}`,grouping:!0})}return}try{await pe.setSelection("special",$),N.value={kind:"special",id:String($),name:`装饰物 ${$}`}}catch(M){T.error({message:`定位对象失败:${M.message}`,grouping:!0})}}function ee(){Le()&&_e()}function Se(){const t=c.query.playback;if(typeof t!="string"||!t)return!1;K.value=t;const v={...c.query};return delete v.playback,P.replace({path:c.path,query:v}),!0}async function be(){const t=K.value;if(!(!t||!Y.value)){K.value=null;try{await re.startPlayback(t),T.success({message:`已开始回放:${t}`,grouping:!0})}catch(v){T.error({message:`启动回放失败:${v.message}`,grouping:!0})}}}function Q(){Se()&&be()}function Te(){Y.value=!0,S(),_e(),be()}async function S(){try{const t=await pe.getSelection();if(!t?.kind||t.id==null||t.kind!=="car"&&t.kind!=="site"&&t.kind!=="track")return;ie(t.kind,Number(t.id),t.name?[t.name]:void 0)}catch{}}async function se(t){if(!Number.isFinite(t))return;const[v,$]=await Promise.allSettled([pe.setSelection("car",t),re.locateCamera(t)]);v.status==="rejected"&&T.error({message:`同步 3D 选中失败:${v.reason.message}`,grouping:!0}),$.status==="rejected"&&T.error({message:`定位车辆失败:${$.reason.message}`,grouping:!0})}async function we(t){F.value=null,_(N.value,t)||(N.value=t),await se(Number(t.id))}async function Oe(t){if(F.value=t.id,t.carId!=null){const v=s.value.find($=>$.rawId===t.carId||oe($)===String(t.carId));if(v){await we({kind:"vehicle",id:oe(v),name:v.name});return}N.value={kind:"vehicle",id:String(t.carId),name:t.carName??`Vehicle ${t.carId}`},await se(t.carId);return}N.value={kind:"delivery",id:String(t.id),name:`${t.srcLabel} → ${t.dstLabel}`}}function ze(t){U.value=t,Ce()}async function Ce(){try{x.value=await hn(U.value)}catch(t){console.warn("[MapMonitor] refreshDeliveries failed",t),x.value=[]}}function Me(t){const v=Be(t);return s.value.find($=>$.name===t||$.id===t||v!=null&&oe($)===v)}function Be(t){return/^(?:UI)?(?:Car|Vehicle)-(\d+)$/i.exec(t)?.[1]??null}function oe(t){return t.rawId!=null?String(t.rawId):t.id.replace(/^C/i,"").replace(/^0+/,"")||t.id}async function $e(){G.value=!0;try{const[t,v]=await Promise.all([Wt(),qt()]);s.value=t,y.value=v,await Ce()}catch(t){console.warn("[MapMonitor] refreshAll failed",t)}finally{G.value=!1}}const Ve=Kt({autoConnect:!0});function Ie(t){if(t?.kind)switch(t.kind){case"alarm":{const v=t.payload;if(!v)return;z.value=[v,...z.value.filter($=>$.carId!==v.carId)].slice(0,30);break}case"car-state":case"mission-status":$e();break;case"selection-detail":t.payload&&typeof t.payload=="object"&&de(t.payload);break;case"monitor-config-updated":Ut(),X.value++;break}}return Ve.on(Ie),Fe(()=>[c.query.focusKind,c.query.focusId],()=>ee()),Fe(()=>c.query.playback,()=>Q()),Xe(async()=>{ee(),Q(),it(),await $e(),_e(),ue=setInterval(()=>{!Ve.connected.value||s.value.length===0?$e():O.value==="mission"&&Ce()},3e3)}),Je(()=>{ue&&clearInterval(ue),Ve.off(Ie)}),(t,v)=>{const $=At,M=Et,te=Tt,e=Dt,a=Pt,d=Ae,V=Ft;return f(),b("div",Vl,[l(te,{gutter:12,class:"kpi-row"},{default:i(()=>[l(M,{span:8},{default:i(()=>[l($,{title:"在线车辆",value:W.value},{suffix:i(()=>[n("span",El,"/ "+p(s.value.length),1)]),_:1},8,["value"])]),_:1}),l(M,{span:8},{default:i(()=>[l($,{title:"运行中任务",value:j.value},null,8,["value"])]),_:1}),l(M,{span:8},{default:i(()=>[l($,{title:"排队任务",value:le.value},null,8,["value"])]),_:1})]),_:1}),l(te,{gutter:12,class:"main-row"},{default:i(()=>[l(M,{span:16},{default:i(()=>[n("div",Al,[l(Rt,{ref_key:"workspaceRef",ref:w,host:H(D),scope:H(E).scope??"Platform",token:H(E).token??"","read-only":!!g.readOnly,"canvas-only":!0,"hide-toolbar":!0,onPick:r,onSelect:ge,onReady:Te},null,8,["host","scope","token","read-only"]),l(_l,{alarms:z.value,onLocate:R,onAck:ae},null,8,["alarms"]),l(Ml,{"follow-car-id":L.value},null,8,["follow-car-id"])])]),_:1}),l(M,{span:8,class:"side-col"},{default:i(()=>[l(V,{shadow:"never",class:"side-card workbench-card"},{header:i(()=>[n("div",Fl,[l(a,{modelValue:O.value,"onUpdate:modelValue":v[0]||(v[0]=k=>O.value=k),class:"workbench-tabs"},{default:i(()=>[l(e,{label:"车辆监控台",name:"vehicle"}),l(e,{label:"任务列表",name:"mission"})]),_:1},8,["modelValue"]),l(d,{link:"",type:"primary",size:"small",loading:G.value,onClick:$e},{default:i(()=>[...v[1]||(v[1]=[q(" 刷新 ",-1)])]),_:1},8,["loading"])])]),default:i(()=>[We(l(_n,{cars:s.value,missions:y.value,"selected-id":h.value,onSelect:we},null,8,["cars","missions","selected-id"]),[[qe,O.value==="vehicle"]]),We(l(An,{deliveries:x.value,"selected-id":F.value,onSelect:Oe,onRefresh:ze,onActionDone:Ce},null,8,["deliveries","selected-id"]),[[qe,O.value==="mission"]])]),_:1}),l(V,{shadow:"never",class:"side-card detail-card"},{header:i(()=>[...v[2]||(v[2]=[n("span",null,"选中信息",-1)])]),default:i(()=>[l(ll,{selection:N.value,"refresh-key":X.value,cars:s.value,missions:y.value,"read-only":!!g.readOnly},null,8,["selection","refresh-key","cars","missions","read-only"])]),_:1})]),_:1})]),_:1})])}}}),fs=ke(Pl,[["__scopeId","data-v-90324f90"]]);export{fs as default};
|