Files
Migu2.0/MiGu.Server/wwwroot/assets/MapMonitorView-BSY4Dsk8.js
T
zhaowei.huangandCursor be0503c535 chore(web): 重新构建前端静态资源
同步 simple-platform-vue 构建产物与 index.html 入口哈希。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 00:16:56 +08:00

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