Files
Nexus/web/app/assets/DashboardPage-CjC4nl2o.js
T
Nexus Agent 0b2d7ac50d feat(scripts): 异步执行、全局进度看板与完成提示音设置
脚本 exec 立即返回 running 并在后台跑批次;/ws/alerts 推送 script_progress/complete;
新增 ScriptRunsPage、Telegram 汇总通知与可配置的浏览器完成提示音。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-08 07:07:02 +08:00

1 line
8.6 KiB
JavaScript

import{Er as e,N as t,Nr as n,Nt as r,Or as i,R as a,Ur as o,Ut as s,Vr as c,Y as l,Zn as u,_r as d,ar as f,er as p,hr as ee,k as m,nr as h,or as g,rr as _,sr as te,t as ne,tr as v,wr as re,yr as y,z as b,zr as x,zt as S}from"./index-HeC-ymfd.js";import{o as ie,t as ae}from"./VContainer-Bqb4OsjX.js";import{t as oe}from"./dataTable-esDY4cOk.js";import{t as C}from"./VChip-C-HpH-oj.js";import{t as se}from"./VDataTableServer-_AO1gvgs.js";import{n as w,t as T}from"./VRow-w4SO-kR5.js";import{i as ce,t as le}from"./auditNormalize-bmSA0RyN.js";import{a as ue,i as de,n as E,r as fe,t as pe}from"./StatCardsRow-BwYodvYm.js";import{t as D}from"./_plugin-vue_export-helper-BDNMzG2s.js";var O={class:`font-weight-medium`},k={class:`text-medium-emphasis`},A={class:`text-medium-emphasis`},j={class:`text-medium-emphasis`},M={class:`text-caption text-medium-emphasis`},N={class:`d-flex ga-1`},P={key:0,class:`text-center text-medium-emphasis py-4`},F={class:`text-body-large font-weight-regular`},I={class:`d-flex justify-space-between align-center text-medium-emphasis`},L={class:`py-1`},R={key:0,class:`text-center text-medium-emphasis py-4`},z={class:`text-caption`},B={class:`d-flex justify-space-between align-center`},me={class:`text-medium-emphasis`},he={class:`text-body-2 font-weight-medium`},ge={key:0,class:`text-center text-medium-emphasis py-4`},V=D(te({__name:`DashboardPage`,setup(te){let D=[...oe],V=ie(),H=s(),U=n([{subtitle:`服务器总数`,title:`0`,icon:`mdi-server-network`,color:`blue`},{subtitle:`在线`,title:`0`,icon:`mdi-check-circle-outline`,color:`green`},{subtitle:`离线`,title:`0`,icon:`mdi-alert-circle-outline`,color:`orange`},{subtitle:`告警中`,title:`0`,icon:`mdi-bell-alert-outline`,color:`red`}]),{servers:_e,loading:ve,page:ye,itemsPerPage:be,total:xe,search:W,sortBy:G,loadServers:Se,onSearch:Ce,onPageChange:we,onItemsPerPageChange:Te,onSortByChange:Ee}=ue();async function De(){try{await Se()}catch{V(`加载服务器列表失败`,`error`)}}let K=[{title:`状态`,key:`status`,width:100},{title:`名称`,key:`name`},{title:`地址`,key:`domain`},{title:`分类`,key:`category`,width:100},{title:`Agent`,key:`agent_version`,width:100},{title:`心跳`,key:`last_heartbeat`,width:140},{title:`操作`,key:`actions`,width:140,align:`end`,sortable:!1}],q=n([]),J=n([{title:`在线率`,progress:0,text:`在`,value:`0%`},{title:`Agent 覆盖`,progress:0,text:`A`,value:`0%`},{title:`CPU 平均`,progress:0,text:`C`,value:`0%`},{title:`内存平均`,progress:0,text:`M`,value:`0%`}]),Y=n({}),X=n(0),Z=n([]);async function Q(){try{let e=await S.get(`/servers/stats`);U.value[0].title=String(e.total),U.value[1].title=String(e.online),U.value[2].title=String(e.offline),U.value[3].title=String(e.alerts??0),Y.value=e.categories||{},X.value=e.total;let t=e.total?Math.round(e.online/e.total*100):0;J.value[0].progress=t,J.value[0].value=`${t}%`}catch{V(`加载统计数据失败`,`error`)}}async function $(){try{q.value=((await S.get(`/alert-history/`,{limit:5})).items||[]).map(e=>({title:e.server_name,subtitle:`${e.alert_type} ${e.is_recovery?`(已恢复)`:``} · ${E(e.created_at)}`,value:e.value,color:e.is_recovery?`green`:`red`,icon:e.is_recovery?`mdi-check-circle`:`mdi-alert-circle`}))}catch{q.value=[],V(`加载告警记录失败`,`error`)}}async function Oe(){try{Z.value=le((await S.get(`/audit/`,{limit:10})).items||[]).slice(0,10)}catch{Z.value=[],V(`加载审计记录失败`,`error`)}}async function ke(){try{let e=await S.get(`/servers/`,{per_page:200}),t=e.items||[],n=e.total||t.length;if(n===0)return;let r=t.filter(e=>e.agent_version).length,i=Math.round(r/n*100);J.value[1].progress=i,J.value[1].value=`${i}%`;let a=t.filter(e=>e.system_info?.cpu_usage!=null),o=t.filter(e=>e.system_info?.mem_usage!=null);if(a.length>0){let e=Math.round(a.reduce((e,t)=>e+(t.system_info.cpu_usage||0),0)/a.length);J.value[2].progress=e,J.value[2].value=`${e}%`}if(o.length>0){let e=Math.round(o.reduce((e,t)=>e+(t.system_info.mem_usage||0),0)/o.length);J.value[3].progress=e,J.value[3].value=`${e}%`}}catch{}}function Ae(e){H.push({path:`/terminal`,query:{server_id:String(e.id)}})}function je(e){H.push({path:`/files`,query:{server_id:String(e.id)}})}return re(r().alerts,()=>{Q(),$()}),ee(()=>{Q(),De(),$(),ke(),Oe(),S.post(`/settings/bing-wallpapers/sync`).catch(()=>{})}),(n,r)=>(d(),v(ae,{fluid:``,class:`pa-4 pa-md-6 dashboard-root`},{default:e(()=>[g(pe,{items:U.value},null,8,[`items`]),g(t,{class:`my-5`,elevation:`0`,rounded:`lg`,title:`服务器列表`,border:``},{text:e(()=>[g(ne,{modelValue:x(W),"onUpdate:modelValue":r[0]||=e=>i(W)?W.value=e:null,autocomplete:`off`,placeholder:`搜索...`,"prepend-inner-icon":`mdi-magnify`,variant:`outlined`,"hide-details":``,rounded:``,class:`mb-4`},null,8,[`modelValue`]),g(se,{items:x(_e),headers:K,"items-length":x(xe),loading:x(ve),page:x(ye),"items-per-page":x(be),"items-per-page-options":D,"sort-by":x(G),"onUpdate:sortBy":[r[1]||=e=>i(G)?G.value=e:null,x(Ee)],hover:``,"item-value":`id`,"onUpdate:page":x(we),"onUpdate:itemsPerPage":x(Te)},{"item.status":e(({item:e})=>[g(C,{color:x(fe)(e.status),text:x(de)(e.status),border:`sm`,size:`x-small`,label:``},null,8,[`color`,`text`])]),"item.name":e(({item:e})=>[p(`span`,O,o(e.name),1)]),"item.domain":e(({item:e})=>[p(`span`,k,o(e.domain),1)]),"item.category":e(({item:e})=>[p(`span`,A,o(e.category||`—`),1)]),"item.agent_version":e(({item:e})=>[p(`span`,j,o(e.agent_version||`—`),1)]),"item.last_heartbeat":e(({item:e})=>[p(`span`,M,o(x(E)(e.last_heartbeat)),1)]),"item.actions":e(({item:t})=>[p(`div`,N,[g(b,{variant:`text`,size:`x-small`,color:`primary`,density:`compact`,onClick:e=>Ae(t)},{default:e(()=>[...r[2]||=[f(`终端`,-1)]]),_:1},8,[`onClick`]),g(b,{variant:`text`,size:`x-small`,density:`compact`,onClick:e=>je(t)},{default:e(()=>[...r[3]||=[f(`文件`,-1)]]),_:1},8,[`onClick`])])]),"no-data":e(()=>[...r[4]||=[p(`div`,{class:`text-center text-medium-emphasis py-6`},`暂无服务器数据`,-1)]]),_:1},8,[`items`,`items-length`,`loading`,`page`,`items-per-page`,`sort-by`,`onUpdate:sortBy`,`onUpdate:page`,`onUpdate:itemsPerPage`])]),_:1}),g(T,null,{default:e(()=>[g(w,{cols:`12`,md:`6`},{default:e(()=>[g(t,{elevation:`0`,rounded:`lg`,title:`告警历史`,border:``},{append:e(()=>[...r[5]||=[p(`div`,{class:`my-5`},null,-1)]]),text:e(()=>[q.value.length===0?(d(),_(`div`,P,` 暂无告警 `)):h(``,!0),(d(!0),_(u,null,y(q.value,(t,n)=>(d(),v(m,{key:n,class:c([n!==0&&`mt-4`,`px-0`]),subtitle:t.subtitle,title:t.title,lines:`one`},{prepend:e(()=>[g(a,{color:t.color,icon:t.icon,variant:`tonal`,rounded:``},null,8,[`color`,`icon`])]),append:e(()=>[p(`span`,F,o(t.value),1)]),_:2},1032,[`class`,`subtitle`,`title`]))),128))]),_:1})]),_:1}),g(w,{cols:`12`,md:`6`},{default:e(()=>[g(t,{elevation:`0`,rounded:`lg`,title:`资源概览`,border:``},{append:e(()=>[...r[6]||=[p(`div`,{class:`my-5`},null,-1)]]),text:e(()=>[(d(!0),_(u,null,y(J.value,(t,n)=>(d(),v(m,{key:n,class:c([n!==0&&`mt-4`,`px-0`])},{prepend:e(()=>[g(a,{text:t.text,color:`primary`,size:`large`,variant:`tonal`},null,8,[`text`])]),title:e(()=>[p(`div`,I,[p(`span`,null,o(t.title),1),p(`span`,null,o(t.value),1)])]),subtitle:e(()=>[p(`div`,L,[g(l,{"model-value":t.progress,"bg-color":`surface-light`,"bg-opacity":`1`,color:`primary`,height:`8`,rounded:``},null,8,[`model-value`])])]),_:2},1032,[`class`]))),128))]),_:1})]),_:1})]),_:1}),g(T,null,{default:e(()=>[g(w,{cols:`12`,md:`6`},{default:e(()=>[g(t,{elevation:`0`,rounded:`lg`,title:`分类分布`,border:``},{text:e(()=>[Object.keys(Y.value).length===0?(d(),_(`div`,R,` 暂无分类数据 `)):h(``,!0),(d(!0),_(u,null,y(Y.value,(t,n)=>(d(),v(m,{key:n,class:`px-0`},{prepend:e(()=>[g(a,{color:`primary`,variant:`tonal`,size:`small`},{default:e(()=>[p(`span`,z,o(n[0]?.toUpperCase()),1)]),_:2},1024)]),title:e(()=>[p(`div`,B,[p(`span`,me,o(n===`uncategorized`?`未分类`:n),1),p(`span`,he,o(t)+` 台`,1)])]),subtitle:e(()=>[g(l,{"model-value":X.value>0?t/X.value*100:0,"bg-color":`surface-light`,"bg-opacity":`1`,color:`primary`,height:`6`,rounded:``},null,8,[`model-value`])]),_:2},1024))),128))]),_:1})]),_:1}),g(w,{cols:`12`,md:`6`},{default:e(()=>[g(t,{elevation:`0`,rounded:`lg`,title:`最近操作`,border:``},{append:e(()=>[g(b,{size:`small`,variant:`text`,to:`/audit`},{default:e(()=>[...r[7]||=[f(`查看全部`,-1)]]),_:1})]),text:e(()=>[Z.value.length===0?(d(),_(`div`,ge,` 暂无操作记录 `)):h(``,!0),(d(!0),_(u,null,y(Z.value,t=>(d(),v(m,{key:t.id,title:x(ce)(t),subtitle:`${t.admin_username} · ${x(E)(t.created_at)}`,class:`px-0`,lines:`two`},{append:e(()=>[g(C,{size:`x-small`,variant:`tonal`,label:``},{default:e(()=>[f(o(t.ip_address||`—`),1)]),_:2},1024)]),_:2},1032,[`title`,`subtitle`]))),128))]),_:1})]),_:1})]),_:1})]),_:1}))}}),[[`__scopeId`,`data-v-6c1f6cde`]]);export{V as default};