Files
Nexus/web/app/assets/ScriptsPage-8s8ONJ--.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
29 KiB
JavaScript

import{n as e,t}from"./initMonaco-BYcaM9ot.js";import{a as n,x as r}from"./VDataTable-ehpN_2aL.js";import{$n as i,Cr as a,Dr as o,Dt as s,Er as c,F as l,Hr as ee,Jn as te,L as u,M as d,N as f,Nr as p,P as m,Ur as h,X as ne,Xn as re,Y as ie,Yn as ae,Z as g,Zn as _,_ as oe,_r as v,ar as y,dr as se,er as b,fr as ce,gr as le,hr as ue,k as de,nr as x,or as S,pr as fe,rr as C,sr as w,t as T,tr as E,ur as D,w as pe,wr as me,yr as O,z as k,zr as A,zt as j}from"./index-DefLgbfN.js";import{o as he,t as ge}from"./VContainer-Cfs-evp_.js";import{t as M}from"./VChip-B776T65H.js";import{t as _e}from"./VSelect-CI0l_G9L.js";import{t as N}from"./VCheckbox-591wzIGe.js";import{t as ve}from"./VDataTableServer-BVvotZW1.js";import{n as P,t as ye}from"./VRow-DkDIFkCo.js";import{t as F}from"./VSpacer-K-VIfO9Y.js";import{t as I}from"./apiError-CYaCXuxN.js";import{t as be}from"./useServerList-N12V5EzK.js";import{s as L}from"./labels-CzOhyWto.js";import{i as xe}from"./validation-DMwOxx4a.js";import{t as Se}from"./VDialog-B2lws4ni.js";import{t as Ce}from"./VTextarea-Bb0421X2.js";import{t as R}from"./_plugin-vue_export-helper-BDNMzG2s.js";import{t as we}from"./VSwitch-NudRy7QS.js";import{t as Te}from"./useServerCategories-BkWtsoj7.js";var Ee=R(w({__name:`ScriptContentEditor`,props:{modelValue:{},readonly:{type:Boolean}},emits:[`update:modelValue`],setup(n,{emit:r}){let i=n,a=r,o=e(),s=p(),c=null,l=!1;function ee(){s.value&&(c?.dispose(),c=o.editor.create(s.value,{...t({language:`shell`,readOnly:i.readonly??!1}),value:i.modelValue||``}),c.onDidChangeModelContent(()=>{l||!c||a(`update:modelValue`,c.getValue())}))}return me(()=>i.modelValue,e=>{c&&c.getValue()!==e&&(l=!0,c.setValue(e||``),l=!1)}),me(()=>i.readonly,e=>{c?.updateOptions({readOnly:e??!1})}),ue(()=>{ee()}),fe(()=>{c?.dispose(),c=null}),(e,t)=>(v(),C(`div`,{ref_key:`host`,ref:s,class:`script-content-editor`},null,512))}}),[[`__scopeId`,`data-v-8c9e5994`]]),De={class:`server-category-picker`},z={class:`d-flex align-center flex-wrap ga-2 mb-2`},Oe={key:0,class:`text-center text-medium-emphasis py-4`},ke={class:`d-flex align-center px-1 mb-1`},B={class:`text-caption text-medium-emphasis ml-1`},V={class:`d-flex align-center ga-2`},H={class:`text-body-2 font-weight-medium text-truncate`},U={class:`text-caption text-medium-emphasis text-truncate`},Ae=R(w({__name:`ServerCategoryPicker`,props:D({servers:{},loading:{type:Boolean,default:!1},maxHeight:{default:`280px`}},{modelValue:{default:()=>[]},modelModifiers:{}}),emits:[`update:modelValue`],setup(e){let t=a(e,`modelValue`),n=e,r=p(``),o=i(()=>new Set(t.value)),s=i(()=>{let e=r.value.trim().toLowerCase();return e?n.servers.filter(t=>t.name.toLowerCase().includes(e)||(t.domain||``).toLowerCase().includes(e)||(t.category||``).toLowerCase().includes(e)):n.servers}),l=i(()=>{let e={};for(let t of s.value){let n=t.category?.trim()||`uncategorized`;e[n]||(e[n]=[]),e[n].push(t)}return Object.entries(e).map(([e,t])=>({category:e,label:Te(e),servers:[...t].sort((e,t)=>e.name.localeCompare(t.name,`zh`))})).sort((e,t)=>e.category===`uncategorized`?1:t.category===`uncategorized`?-1:e.label.localeCompare(t.label,`zh`))}),te=i(()=>{let e=s.value;return e.length>0&&e.every(e=>o.value.has(e.id))});function u(e){return e.servers.filter(e=>o.value.has(e.id)).length}function d(e){let t=l.value.find(t=>t.category===e);return!t||t.servers.length===0?!1:t.servers.every(e=>o.value.has(e.id))}function m(e){t.value=[...e]}function re(e){let n=new Set(t.value);n.has(e)?n.delete(e):n.add(e),m(n)}function ie(e){let n=l.value.find(t=>t.category===e);if(!n)return;let r=new Set(t.value),i=n.servers.every(e=>r.has(e.id));for(let e of n.servers)i?r.delete(e.id):r.add(e.id);m(r)}function ae(){let e=s.value,n=new Set(t.value),r=e.length>0&&e.every(e=>n.has(e.id));for(let t of e)r?n.delete(t.id):n.add(t.id);m(n)}return(n,i)=>(v(),C(`div`,De,[b(`div`,z,[S(N,{"model-value":te.value,label:`全选`,density:`compact`,"hide-details":``,"onUpdate:modelValue":ae},null,8,[`model-value`]),S(T,{modelValue:r.value,"onUpdate:modelValue":i[0]||=e=>r.value=e,"prepend-inner-icon":`mdi-magnify`,label:`搜索服务器`,density:`compact`,"hide-details":``,variant:`outlined`,rounded:``,style:{"max-width":`220px`},clearable:``},null,8,[`modelValue`]),t.value.length>0?(v(),E(M,{key:0,size:`small`,color:`primary`,variant:`tonal`,label:``},{default:c(()=>[y(` 已选 `+h(t.value.length)+` 台 `,1)]),_:1})):x(``,!0),e.loading?(v(),E(ne,{key:1,indeterminate:``,size:`18`,width:`2`})):x(``,!0)]),b(`div`,{class:`picker-scroll`,style:ee({maxHeight:e.maxHeight})},[!e.loading&&l.value.length===0?(v(),C(`div`,Oe,` 暂无服务器 `)):x(``,!0),(v(!0),C(_,null,O(l.value,e=>(v(),C(`div`,{key:e.category,class:`mb-3`},[b(`div`,ke,[S(k,{size:`x-small`,variant:`text`,color:d(e.category)?`primary`:`default`,onClick:t=>ie(e.category)},{default:c(()=>[S(g,{size:`16`,class:`mr-1`},{default:c(()=>[y(h(d(e.category)?`mdi-checkbox-marked`:`mdi-checkbox-blank-outline`),1)]),_:2},1024),y(` `+h(e.label),1)]),_:2},1032,[`color`,`onClick`]),b(`span`,B,` (`+h(u(e))+`/`+h(e.servers.length)+`) `,1)]),S(ye,{dense:``},{default:c(()=>[(v(!0),C(_,null,O(e.servers,e=>(v(),E(P,{key:e.id,cols:`12`,sm:`6`},{default:c(()=>[S(f,{color:o.value.has(e.id)?`primary`:void 0,variant:o.value.has(e.id)?`tonal`:`outlined`,rounded:`lg`,class:`pa-2 cursor-pointer`,onClick:t=>re(e.id)},{default:c(()=>[b(`div`,V,[S(g,{color:A(L)(e.is_online),size:`10`},{default:c(()=>[...i[1]||=[y(`mdi-circle`,-1)]]),_:1},8,[`color`]),b(`span`,H,h(e.name),1)]),b(`div`,U,h(e.domain),1)]),_:2},1032,[`color`,`variant`,`onClick`])]),_:2},1024))),128))]),_:2},1024)]))),128))],4)]))}}),[[`__scopeId`,`data-v-4d1df917`]]),je={class:`text-body-1 font-weight-medium`},Me={class:`text-body-2 text-medium-emphasis`},Ne={class:`text-caption text-medium-emphasis mt-2`},Pe={key:3,class:`d-flex justify-center mt-4`},Fe={class:`text-caption`},Ie={key:2,class:`text-center text-medium-emphasis py-6`},Le={class:`text-body-2`},Re={class:`text-caption text-medium-emphasis`},ze={class:`text-caption`},Be={key:0,class:`ml-1`},Ve={class:`d-flex align-center flex-wrap ga-1 justify-end`},He={class:`text-caption text-medium-emphasis mb-3`},Ue={class:`text-body-2 mb-4 pa-3 rounded bg-surface-variant overflow-auto`,style:{"max-height":`120px`}},We={class:`text-truncate`,style:{"max-width":`360px`}},Ge=w({__name:`ScriptsPage`,setup(e){let t=he(),{servers:a,loading:ee,loadServers:ne}=be(),fe=[{label:`运维`,value:`ops`},{label:`部署`,value:`deploy`},{label:`检查`,value:`check`},{label:`清理`,value:`cleanup`}],w=p(!1),D=p(``),N=p([]),L=p(null),R=p([]),Te=p(1),De=p(20),z=p(!1),Oe=p(null),ke=p(!1),B=p({name:``,category:`ops`,description:``,content:``}),V=p(!1),H=p(null),U=p([]),Ge=p(300),Ke=p(!1),qe=p(null),Je=p(!1),W=p(!1),Ye=p(null),Xe=p(null),Ze=p([]),G=p(!1),Qe=p([]),$e=p(0),K=p(1),et=p(20),tt=p(!1),q=p(null),nt=p(!1),J=p(``),Y=p([]),rt=p(60),it=p(!1),at=p(null),ot=p(!1),X=p([]),st=null,ct=p(!1),Z=p(null),lt=p(!1),ut=p(null),dt=i(()=>R.value.map(e=>({title:e.name,value:e.id}))),ft=i(()=>{let e=D.value.trim().toLowerCase();return e?N.value.filter(t=>t.name.toLowerCase().includes(e)||(t.category||``).toLowerCase().includes(e)||(t.description||``).toLowerCase().includes(e)):N.value}),pt=i(()=>ft.value.length),mt=i(()=>{let e=(Te.value-1)*De.value;return ft.value.slice(e,e+De.value)});me(D,()=>{Te.value=1});let ht=[{title:`ID`,key:`id`,width:72},{title:`脚本/命令`,key:`label`},{title:`状态`,key:`status`,width:100},{title:`进度`,key:`progress`,width:88},{title:`台数`,key:`server_count`,width:72},{title:`操作人`,key:`operator`,width:88},{title:`开始时间`,key:`started_at`,width:168},{title:`操作`,key:`actions`,width:180,sortable:!1}],gt=i(()=>q.value?N.value.find(e=>e.id===q.value)?.name||`脚本 #${q.value}`:``),_t={started:`开始`,batch_progress:`批次进度`,execution_finished:`结束`,stopped:`停止`,retry_requested:`重试`,stuck_marked:`标记卡住`,server_auto_stuck:`子机超时`,auto_stuck:`自动卡住`,job_completed:`回调完成`},vt=i(()=>Z.value?.results?Object.entries(Z.value.results).filter(([e])=>e!==`_meta`&&/^\d+$/.test(e)).map(([e,t])=>({serverId:e,status:String(t.status||t.phase||`—`),exitCode:t.exit_code??null,summary:(t.stdout||t.stderr||t.message||``).slice(0,200)||`—`})):[]);function yt(e){return fe.find(t=>t.value===e)?.label||e}function bt(e){if(!e)return`—`;let t=e.startsWith(`[long_task] `)?e.slice(12):e;return t.length>60?`${t.slice(0,60)}…`:t}function xt(e){return e.script_id?N.value.find(t=>t.id===e.script_id)?.name||`脚本 #${e.script_id}`:`临时命令`}function St(e){if(!e)return`—`;let t=new Date(e);if(Number.isNaN(t.getTime()))return e.replace(`T`,` `).slice(0,19);let n=e=>String(e).padStart(2,`0`);return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())} ${n(t.getHours())}:${n(t.getMinutes())}:${n(t.getSeconds())}`}function Ct(e){let t=e.events||[];return t.length?t.slice(-3).map(e=>{let t=_t[e.action||``]||e.action||`事件`,n=St(e.at),r=e.detail||``;return`${n} · ${t}${r?` — ${r}`:``}`}):[]}async function wt(){G.value=!0;try{Ze.value=(await j.get(`/scripts/executions`,{limit:5})).items||[]}catch{Ze.value=[]}finally{G.value=!1}}async function Q(){tt.value=!0;try{let e=(K.value-1)*et.value,t={limit:et.value,offset:e};q.value&&(t.script_id=q.value);let n=await j.get(`/scripts/executions`,t);Qe.value=n.items||[],$e.value=n.total||0}catch{Qe.value=[],$e.value=0}finally{tt.value=!1}}function $(){wt(),Q()}function Tt(e){K.value=e,Q()}function Et(e){et.value=e,K.value=1,Q()}function Dt(){q.value=null,K.value=1,Q()}async function Ot(e){q.value=e.id,K.value=1,await Q(),await ce(),Xe.value?.scrollIntoView({behavior:`smooth`,block:`start`})}function kt(e){return e||`—`}function At(e){if(!e)return 0;try{let t=JSON.parse(e);return Array.isArray(t)?t.length:0}catch{return 0}}function jt(e){let t=e.id??e.execution_id;if(t==null)throw Error(`执行响应缺少 id`);return t}async function Mt(){w.value=!0;try{N.value=(await j.getList(`/scripts/`)).items}catch(e){N.value=[],t(I(e,`加载脚本列表失败`),`error`)}finally{w.value=!1}}async function Nt(){try{L.value=await j.get(`/scripts/exec-config`)}catch{L.value=null}}async function Pt(){try{R.value=await j.getList(`/scripts/credentials`).then(e=>e.items)}catch{R.value=[]}}function Ft(e){Oe.value=e,e?B.value={name:e.name,category:e.category||`ops`,description:e.description||``,content:e.content||``}:B.value={name:``,category:`ops`,description:``,content:``},z.value=!0}async function It(){if(!B.value.name.trim()||!B.value.content.trim()){t(`请填写名称与脚本内容`,`warning`);return}ke.value=!0;try{let e={name:B.value.name.trim(),category:B.value.category,description:B.value.description.trim()||null,content:B.value.content};Oe.value?await j.put(`/scripts/${Oe.value.id}`,e):await j.post(`/scripts/`,e),z.value=!1,await Mt(),t(`保存成功`)}catch(e){t(I(e,`保存失败`),`error`)}finally{ke.value=!1}}function Lt(e){H.value=e,U.value=[],Ke.value=!1,qe.value=null,V.value=!0}async function Rt(e,t,n){let r=await j.post(`/scripts/exec`,e);return Ut(t,jt(r),n,!!e.long_task,r.progress,r.status),r}async function zt(){if(!H.value||!U.value.length){t(`请选择服务器`,`warning`);return}Je.value=!0;try{await Rt({script_id:H.value.id,server_ids:U.value,timeout:Ge.value,long_task:Ke.value,credential_id:qe.value??void 0},H.value.name,U.value.length),V.value=!1,t(`脚本已提交执行`),$()}catch(e){t(I(e,`执行失败`),`error`)}finally{Je.value=!1}}function Bt(e){Ye.value=e,W.value=!0}async function Vt(){if(Ye.value)try{await j.delete(`/scripts/${Ye.value.id}`),W.value=!1,await Mt(),t(`已删除`)}catch(e){t(I(e,`删除失败`),`error`)}}async function Ht(){if(!(!J.value.trim()||Y.value.length===0)){ot.value=!0;try{await Rt({command:J.value.trim(),server_ids:Y.value,timeout:rt.value,long_task:it.value,credential_id:at.value??void 0},`临时命令`,Y.value.length),t(`已在 ${Y.value.length} 台服务器上执行`),$()}catch(e){t(I(e,`执行失败`),`error`)}finally{ot.value=!1}}}function Ut(e,t,n,r,i,a){X.value.some(e=>e.id===t)||(X.value.unshift({id:t,name:e,status:a||`running`,totalServers:n,progress:i||`0/${n}`,longTask:r,refreshing:!1}),Wt())}function Wt(){st||=setInterval(async()=>{let e=X.value.filter(e=>e.status===`running`||e.status===`partial`);if(e.length===0){Gt();return}for(let t of e)await Kt(t)},1e4)}function Gt(){st&&=(clearInterval(st),null)}async function Kt(e){e.refreshing=!0;try{let t=await j.get(`/scripts/executions/${e.id}`);e.status=t.status,e.progress=kt(t.progress),e.longTask=!!t.long_task,t.status!==`running`&&t.status!==`partial`&&$()}catch{}finally{e.refreshing=!1}}async function qt(e){try{await j.post(`/scripts/executions/${e.id}/stop`),await Kt(e),t(`已发送停止指令`)}catch(e){t(I(e,`停止失败`),`error`)}}async function Jt(e){try{await j.post(`/scripts/executions/${e.id}/mark-stuck`,{detail:`用户在脚本库标记可能卡住`}),t(`已标记`)}catch(e){t(I(e,`标记失败`),`error`)}}async function Yt(e){try{let n=await j.post(`/scripts/executions/${e.id}/retry`,{}),r=jt(n);Ut(`${e.name}(重试)`,r,e.totalServers,e.longTask,n.progress,n.status),t(`已创建重试任务 #${r}`)}catch(e){t(I(e,`重试失败`),`error`)}}async function Xt(e){try{await j.post(`/scripts/executions/${e.id}/stop`),$(),t(`已发送停止指令`)}catch(e){t(I(e,`停止失败`),`error`)}}async function Zt(e){try{let n=await j.post(`/scripts/executions/${e.id}/retry`,{});Ut(`${xt(e)}(重试)`,jt(n),At(e.server_ids)||At(n.server_ids),!!e.long_task,n.progress,n.status),$(),t(`重试已提交`)}catch(e){t(I(e,`重试失败`),`error`)}}async function Qt(e){ut.value=e,ct.value=!0,await $t(!1)}async function $t(e){if(ut.value!=null){lt.value=!0;try{Z.value=await j.get(`/scripts/executions/${ut.value}`,{fetch_logs:e,log_lines:100})}catch(e){t(I(e,`加载详情失败`),`error`),ct.value=!1}finally{lt.value=!1}}}function en(e){return e===`running`?`blue`:e===`completed`?`green`:e===`failed`?`red`:e===`partial`?`orange`:e===`cancelled`?`grey`:`info`}function tn(e){return{running:`执行中`,completed:`已完成`,failed:`失败`,partial:`部分成功`,cancelled:`已取消`}[e]||e}return ue(()=>{Mt(),ne({all:!0}),Nt(),Pt(),$()}),le(()=>{Gt()}),(e,t)=>(v(),E(ge,{fluid:``,class:`pa-6`},{default:c(()=>[S(f,{elevation:`0`,border:``,rounded:`lg`,class:`mb-4`},{default:c(()=>[S(l,{class:`d-flex flex-wrap align-center ga-2`},{default:c(()=>[t[28]||=y(` 脚本库 `,-1),L.value?(v(),E(M,{key:0,size:`small`,variant:`tonal`,label:``,class:`ml-1`},{default:c(()=>[y(` 分批 `+h(L.value.batch_size)+` 台 · 并发 `+h(L.value.concurrency),1)]),_:1})):x(``,!0),S(F),S(T,{modelValue:D.value,"onUpdate:modelValue":t[0]||=e=>D.value=e,"prepend-inner-icon":`mdi-magnify`,label:`搜索...`,density:`compact`,"hide-details":``,variant:`outlined`,rounded:``,style:{"max-width":`240px`}},null,8,[`modelValue`]),S(k,{color:`primary`,variant:`flat`,class:`ml-1`,"prepend-icon":`mdi-plus`,size:`small`,onClick:t[1]||=e=>Ft(null)},{default:c(()=>[...t[27]||=[y(` 新建脚本 `,-1)]]),_:1})]),_:1})]),_:1}),S(f,{elevation:`0`,border:``,rounded:`lg`,class:`mb-4`},{default:c(()=>[S(l,{class:`d-flex align-center`,style:{cursor:`pointer`},onClick:t[2]||=e=>nt.value=!nt.value},{default:c(()=>[S(g,{class:`mr-2`},{default:c(()=>[...t[29]||=[y(`mdi-console`,-1)]]),_:1}),t[30]||=y(` 临时命令执行 `,-1),S(F),S(g,null,{default:c(()=>[y(h(nt.value?`mdi-chevron-up`:`mdi-chevron-down`),1)]),_:1})]),_:1}),S(s,null,{default:c(()=>[o(b(`div`,null,[S(d),S(m,null,{default:c(()=>[S(Ce,{modelValue:J.value,"onUpdate:modelValue":t[3]||=e=>J.value=e,label:`命令`,variant:`outlined`,density:`compact`,rows:`3`,placeholder:`输入要执行的命令... (Ctrl+Enter 执行)`,class:`mb-3 font-monospace`,onKeydown:ae(re(Ht,[`ctrl`]),[`enter`]),rules:[A(xe)(`命令`)]},null,8,[`modelValue`,`onKeydown`,`rules`]),t[32]||=b(`div`,{class:`text-caption text-medium-emphasis mb-1`},`目标服务器(按分类选择)`,-1),S(Ae,{modelValue:Y.value,"onUpdate:modelValue":t[4]||=e=>Y.value=e,servers:A(a),loading:A(ee),"max-height":`220px`,class:`mb-3`},null,8,[`modelValue`,`servers`,`loading`]),S(ye,{dense:``},{default:c(()=>[S(P,{cols:`6`,md:`2`},{default:c(()=>[S(T,{modelValue:rt.value,"onUpdate:modelValue":t[5]||=e=>rt.value=e,modelModifiers:{number:!0},label:`超时(秒)`,variant:`outlined`,density:`compact`,type:`number`,max:L.value?.max_timeout??600},null,8,[`modelValue`,`max`])]),_:1}),S(P,{cols:`6`,md:`3`},{default:c(()=>[S(_e,{modelValue:at.value,"onUpdate:modelValue":t[6]||=e=>at.value=e,items:dt.value,"item-title":`title`,"item-value":`value`,label:`DB 凭据(可选)`,variant:`outlined`,density:`compact`,clearable:``,"hide-details":``},null,8,[`modelValue`,`items`])]),_:1}),S(P,{cols:`12`,md:`2`,class:`d-flex align-center ga-2`},{default:c(()=>[S(we,{modelValue:it.value,"onUpdate:modelValue":t[7]||=e=>it.value=e,label:`长任务`,density:`compact`,"hide-details":``,color:`primary`},null,8,[`modelValue`]),S(k,{color:`primary`,variant:`flat`,onClick:Ht,loading:ot.value,disabled:!J.value.trim()||Y.value.length===0},{default:c(()=>[...t[31]||=[y(` 执行 `,-1)]]),_:1},8,[`loading`,`disabled`])]),_:1})]),_:1})]),_:1})],512),[[te,nt.value]])]),_:1})]),_:1}),w.value?(v(),E(ie,{key:0,indeterminate:``,color:`primary`})):x(``,!0),mt.value.length?(v(),E(ye,{key:1},{default:c(()=>[(v(!0),C(_,null,O(mt.value,e=>(v(),E(P,{cols:`12`,sm:`6`,md:`4`,key:e.id},{default:c(()=>[S(f,{elevation:`0`,border:``,rounded:`lg`,class:`fill-height`},{default:c(()=>[S(l,{class:`d-flex align-center`},{default:c(()=>[S(g,{color:`primary`,class:`mr-2`},{default:c(()=>[...t[33]||=[y(`mdi-code-braces`,-1)]]),_:1}),b(`span`,je,h(e.name),1),S(F),S(oe,null,{activator:c(({props:e})=>[S(k,se({icon:`mdi-dots-vertical`,variant:`text`,size:`small`},{ref_for:!0},e),null,16)]),default:c(()=>[S(pe,{density:`compact`},{default:c(()=>[S(de,{title:`编辑`,onClick:t=>Ft(e)},{prepend:c(()=>[S(g,null,{default:c(()=>[...t[34]||=[y(`mdi-pencil`,-1)]]),_:1})]),_:1},8,[`onClick`]),S(de,{title:`执行`,onClick:t=>Lt(e)},{prepend:c(()=>[S(g,null,{default:c(()=>[...t[35]||=[y(`mdi-play`,-1)]]),_:1})]),_:1},8,[`onClick`]),S(de,{title:`删除`,onClick:t=>Bt(e),class:`text-error`},{prepend:c(()=>[S(g,{color:`error`},{default:c(()=>[...t[36]||=[y(`mdi-delete`,-1)]]),_:1})]),_:1},8,[`onClick`])]),_:2},1024)]),_:2},1024)]),_:2},1024),S(m,null,{default:c(()=>[e.category?(v(),E(M,{key:0,size:`small`,variant:`tonal`,label:``,class:`mb-2`},{default:c(()=>[y(h(yt(e.category)),1)]),_:2},1024)):x(``,!0),b(`div`,Me,h(e.description||`无描述`),1),b(`div`,Ne,` 更新于 `+h(e.updated_at||e.created_at||`—`),1)]),_:2},1024),S(u,null,{default:c(()=>[S(k,{size:`small`,variant:`tonal`,"prepend-icon":`mdi-play`,color:`primary`,onClick:t=>Lt(e)},{default:c(()=>[...t[37]||=[y(` 执行 `,-1)]]),_:1},8,[`onClick`]),S(F),S(k,{size:`small`,variant:`text`,onClick:t=>Ot(e)},{default:c(()=>[...t[38]||=[y(`历史`,-1)]]),_:1},8,[`onClick`])]),_:2},1024)]),_:2},1024)]),_:2},1024))),128))]),_:1})):w.value?x(``,!0):(v(),E(f,{key:2,elevation:`0`,border:``,rounded:`lg`},{default:c(()=>[S(m,{class:`text-center text-medium-emphasis py-10`},{default:c(()=>[...t[39]||=[y(`暂无脚本,点击「新建脚本」添加`,-1)]]),_:1})]),_:1})),pt.value>De.value?(v(),C(`div`,Pe,[S(r,{modelValue:Te.value,"onUpdate:modelValue":t[8]||=e=>Te.value=e,length:Math.ceil(pt.value/De.value),rounded:``,density:`compact`},null,8,[`modelValue`,`length`])])):x(``,!0),b(`div`,{ref_key:`historySectionRef`,ref:Xe},[S(f,{elevation:`0`,border:``,rounded:`lg`,class:`mt-4`},{default:c(()=>[S(l,{class:`d-flex align-center text-subtitle-1`},{default:c(()=>[S(g,{class:`mr-2`},{default:c(()=>[...t[40]||=[y(`mdi-history`,-1)]]),_:1}),t[41]||=y(` 最近执行 `,-1),S(F),S(k,{size:`small`,variant:`text`,icon:`mdi-refresh`,loading:G.value,onClick:wt},null,8,[`loading`])]),_:1}),S(d),S(m,{class:`pa-0`},{default:c(()=>[G.value?(v(),E(ie,{key:0,indeterminate:``,color:`primary`})):x(``,!0),Ze.value.length?(v(),E(pe,{key:1,density:`compact`,class:`py-0`},{default:c(()=>[(v(!0),C(_,null,O(Ze.value,e=>(v(),E(de,{key:e.id,title:`#${e.id} · ${xt(e)}`,onClick:t=>Qt(e.id),style:{cursor:`pointer`}},{subtitle:c(()=>[b(`div`,Fe,h(tn(e.status))+` · `+h(At(e.server_ids))+` 台 · `+h(e.operator||`—`)+` · `+h(St(e.started_at)),1),(v(!0),C(_,null,O(Ct(e),(e,t)=>(v(),C(`div`,{key:t,class:`text-caption text-medium-emphasis font-monospace mt-1`},h(e),1))),128))]),append:c(()=>[S(M,{color:en(e.status),size:`x-small`,variant:`tonal`,label:``},{default:c(()=>[y(h(tn(e.status)),1)]),_:2},1032,[`color`])]),_:2},1032,[`title`,`onClick`]))),128))]),_:1})):G.value?x(``,!0):(v(),C(`div`,Ie,`暂无执行记录`))]),_:1})]),_:1}),S(f,{elevation:`0`,border:``,rounded:`lg`,class:`mt-4`},{default:c(()=>[S(l,{class:`d-flex flex-wrap align-center ga-2 text-subtitle-1`},{default:c(()=>[S(g,{class:`mr-1`},{default:c(()=>[...t[42]||=[y(`mdi-format-list-bulleted`,-1)]]),_:1}),t[43]||=y(` 全部执行历史 `,-1),q.value?(v(),E(M,{key:0,size:`small`,variant:`tonal`,closable:``,label:``,"onClick:close":Dt},{default:c(()=>[y(h(gt.value),1)]),_:1})):x(``,!0),S(F),S(k,{size:`small`,variant:`text`,icon:`mdi-refresh`,loading:tt.value,onClick:Q},null,8,[`loading`])]),_:1}),S(d),S(ve,{items:Qe.value,headers:ht,"items-length":$e.value,loading:tt.value,page:K.value,"items-per-page":et.value,density:`compact`,hover:``,"onUpdate:page":Tt,"onUpdate:itemsPerPage":Et},{"item.label":c(({item:e})=>[b(`div`,Le,h(xt(e)),1),b(`code`,Re,h(bt(e.command)),1)]),"item.status":c(({item:e})=>[S(M,{color:en(e.status),size:`x-small`,variant:`tonal`,label:``},{default:c(()=>[y(h(tn(e.status)),1)]),_:2},1032,[`color`])]),"item.server_count":c(({item:e})=>[y(h(At(e.server_ids)),1)]),"item.progress":c(({item:e})=>[y(h(kt(e.progress)),1)]),"item.started_at":c(({item:e})=>[y(h(St(e.started_at)),1)]),"item.actions":c(({item:e})=>[S(k,{size:`x-small`,variant:`text`,onClick:t=>Qt(e.id)},{default:c(()=>[...t[44]||=[y(`详情`,-1)]]),_:1},8,[`onClick`]),e.status===`running`||e.status===`partial`?(v(),E(k,{key:0,size:`x-small`,variant:`text`,color:`error`,onClick:t=>Xt(e)},{default:c(()=>[...t[45]||=[y(` 停止 `,-1)]]),_:1},8,[`onClick`])):x(``,!0),e.status===`failed`||e.status===`partial`?(v(),E(k,{key:1,size:`x-small`,variant:`text`,color:`primary`,onClick:t=>Zt(e)},{default:c(()=>[...t[46]||=[y(` 重试 `,-1)]]),_:1},8,[`onClick`])):x(``,!0)]),"no-data":c(()=>[...t[47]||=[b(`div`,{class:`text-center text-medium-emphasis py-6`},`暂无执行记录`,-1)]]),_:1},8,[`items`,`items-length`,`loading`,`page`,`items-per-page`])]),_:1})],512),X.value.length>0?(v(),E(f,{key:4,elevation:`0`,border:``,rounded:`lg`,class:`mt-4`},{default:c(()=>[S(l,{class:`d-flex align-center text-subtitle-1`},{default:c(()=>[S(g,{class:`mr-2`},{default:c(()=>[...t[48]||=[y(`mdi-progress-clock`,-1)]]),_:1}),t[50]||=y(` 批量执行状态 `,-1),S(F),S(k,{size:`small`,variant:`text`,onClick:t[9]||=e=>X.value=[]},{default:c(()=>[...t[49]||=[y(`清除`,-1)]]),_:1})]),_:1}),S(d),S(m,null,{default:c(()=>[S(pe,{density:`compact`},{default:c(()=>[(v(!0),C(_,null,O(X.value,e=>(v(),E(de,{key:e.id,title:e.name},{subtitle:c(()=>[b(`span`,ze,[y(` #`+h(e.id)+` · `+h(e.progress||`—`)+` · `+h(e.totalServers)+` 台 `,1),e.longTask?(v(),C(`span`,Be,`· 长任务`)):x(``,!0)])]),append:c(()=>[b(`div`,Ve,[S(M,{color:en(e.status),size:`x-small`,variant:`tonal`,label:``},{default:c(()=>[y(h(tn(e.status)),1)]),_:2},1032,[`color`]),S(k,{size:`x-small`,variant:`text`,onClick:t=>Qt(e.id)},{default:c(()=>[...t[51]||=[y(`详情`,-1)]]),_:1},8,[`onClick`]),S(k,{size:`x-small`,variant:`text`,onClick:t=>Kt(e),loading:e.refreshing},{default:c(()=>[...t[52]||=[y(` 刷新 `,-1)]]),_:1},8,[`onClick`,`loading`]),e.status===`running`?(v(),E(k,{key:0,size:`x-small`,variant:`text`,color:`warning`,onClick:t=>Jt(e)},{default:c(()=>[...t[53]||=[y(` 卡住 `,-1)]]),_:1},8,[`onClick`])):x(``,!0),e.status===`running`||e.status===`partial`?(v(),E(k,{key:1,size:`x-small`,variant:`text`,color:`error`,onClick:t=>qt(e)},{default:c(()=>[...t[54]||=[y(` 停止 `,-1)]]),_:1},8,[`onClick`])):x(``,!0),e.status===`failed`||e.status===`partial`?(v(),E(k,{key:2,size:`x-small`,variant:`text`,color:`primary`,onClick:t=>Yt(e)},{default:c(()=>[...t[55]||=[y(` 重试 `,-1)]]),_:1},8,[`onClick`])):x(``,!0)])]),_:2},1032,[`title`]))),128))]),_:1})]),_:1})]),_:1})):x(``,!0),S(Se,{modelValue:z.value,"onUpdate:modelValue":t[15]||=e=>z.value=e,"max-width":`900`,scrollable:``},{default:c(()=>[S(f,{border:``},{default:c(()=>[S(l,null,{default:c(()=>[y(h(Oe.value?`编辑脚本`:`新建脚本`),1)]),_:1}),S(d),S(m,null,{default:c(()=>[S(T,{modelValue:B.value.name,"onUpdate:modelValue":t[10]||=e=>B.value.name=e,label:`脚本名称`,variant:`outlined`,density:`compact`,class:`mb-2`,rules:[A(xe)(`脚本名称`)]},null,8,[`modelValue`,`rules`]),S(_e,{modelValue:B.value.category,"onUpdate:modelValue":t[11]||=e=>B.value.category=e,items:fe,"item-title":`label`,"item-value":`value`,label:`分类`,variant:`outlined`,density:`compact`,class:`mb-2`},null,8,[`modelValue`]),S(Ce,{modelValue:B.value.description,"onUpdate:modelValue":t[12]||=e=>B.value.description=e,label:`描述`,variant:`outlined`,density:`compact`,rows:`2`,class:`mb-2`},null,8,[`modelValue`]),t[56]||=b(`div`,{class:`text-caption text-medium-emphasis mb-1`},`脚本内容`,-1),S(Ee,{modelValue:B.value.content,"onUpdate:modelValue":t[13]||=e=>B.value.content=e},null,8,[`modelValue`])]),_:1}),S(d),S(u,null,{default:c(()=>[S(F),S(k,{variant:`text`,onClick:t[14]||=e=>z.value=!1},{default:c(()=>[...t[57]||=[y(`取消`,-1)]]),_:1}),S(k,{color:`primary`,variant:`flat`,onClick:It,loading:ke.value,disabled:!B.value.content.trim()},{default:c(()=>[...t[58]||=[y(` 保存 `,-1)]]),_:1},8,[`loading`,`disabled`])]),_:1})]),_:1})]),_:1},8,[`modelValue`]),S(Se,{modelValue:V.value,"onUpdate:modelValue":t[21]||=e=>V.value=e,"max-width":`720`,scrollable:``},{default:c(()=>[S(f,{border:``},{default:c(()=>[S(l,null,{default:c(()=>[y(`执行脚本: `+h(H.value?.name),1)]),_:1}),S(m,null,{default:c(()=>[t[59]||=b(`div`,{class:`text-caption text-medium-emphasis mb-1`},`选择服务器(按分类勾选)`,-1),S(Ae,{modelValue:U.value,"onUpdate:modelValue":t[16]||=e=>U.value=e,servers:A(a),loading:A(ee),"max-height":`360px`,class:`mb-2`},null,8,[`modelValue`,`servers`,`loading`]),S(ye,{dense:``},{default:c(()=>[S(P,{cols:`6`},{default:c(()=>[S(T,{modelValue:Ge.value,"onUpdate:modelValue":t[17]||=e=>Ge.value=e,modelModifiers:{number:!0},label:`超时(秒)`,variant:`outlined`,density:`compact`,type:`number`,max:L.value?.max_timeout??600},null,8,[`modelValue`,`max`])]),_:1}),S(P,{cols:`6`},{default:c(()=>[S(_e,{modelValue:qe.value,"onUpdate:modelValue":t[18]||=e=>qe.value=e,items:dt.value,"item-title":`title`,"item-value":`value`,label:`DB 凭据(可选)`,variant:`outlined`,density:`compact`,clearable:``},null,8,[`modelValue`,`items`])]),_:1})]),_:1}),S(we,{modelValue:Ke.value,"onUpdate:modelValue":t[19]||=e=>Ke.value=e,label:`长任务(nohup + Agent 回调,适合超时较长的脚本)`,density:`compact`,color:`primary`},null,8,[`modelValue`])]),_:1}),S(u,null,{default:c(()=>[S(F),S(k,{variant:`text`,onClick:t[20]||=e=>V.value=!1},{default:c(()=>[...t[60]||=[y(`取消`,-1)]]),_:1}),S(k,{color:`primary`,variant:`flat`,onClick:zt,loading:Je.value,disabled:!U.value.length},{default:c(()=>[...t[61]||=[y(` 执行 `,-1)]]),_:1},8,[`loading`,`disabled`])]),_:1})]),_:1})]),_:1},8,[`modelValue`]),S(Se,{modelValue:W.value,"onUpdate:modelValue":t[23]||=e=>W.value=e,"max-width":`400`},{default:c(()=>[S(f,{border:``},{default:c(()=>[S(l,null,{default:c(()=>[...t[62]||=[y(`确认删除`,-1)]]),_:1}),S(m,null,{default:c(()=>[t[63]||=y(`确定要删除脚本 `,-1),b(`strong`,null,h(Ye.value?.name),1),t[64]||=y(` 吗?`,-1)]),_:1}),S(u,null,{default:c(()=>[S(F),S(k,{variant:`text`,onClick:t[22]||=e=>W.value=!1},{default:c(()=>[...t[65]||=[y(`取消`,-1)]]),_:1}),S(k,{color:`error`,variant:`flat`,onClick:Vt},{default:c(()=>[...t[66]||=[y(`删除`,-1)]]),_:1})]),_:1})]),_:1})]),_:1},8,[`modelValue`]),S(Se,{modelValue:ct.value,"onUpdate:modelValue":t[26]||=e=>ct.value=e,"max-width":`900`,scrollable:``},{default:c(()=>[S(f,{border:``},{default:c(()=>[S(l,{class:`d-flex align-center`},{default:c(()=>[y(` 执行详情 #`+h(Z.value?.id)+` `,1),S(F),Z.value?.long_task?(v(),E(k,{key:0,size:`small`,variant:`tonal`,loading:lt.value,onClick:t[24]||=e=>$t(!0)},{default:c(()=>[...t[67]||=[y(` 拉取日志 `,-1)]]),_:1},8,[`loading`])):x(``,!0)]),_:1}),S(d),Z.value?(v(),E(m,{key:0},{default:c(()=>[b(`div`,He,h(tn(Z.value.status))+` · `+h(kt(Z.value.progress))+` · 操作人 `+h(Z.value.operator||`—`),1),b(`pre`,Ue,h(Z.value.command),1),S(n,{density:`compact`},{default:c(()=>[t[68]||=b(`thead`,null,[b(`tr`,null,[b(`th`,null,`服务器`),b(`th`,null,`状态`),b(`th`,null,`退出码`),b(`th`,null,`输出摘要`)])],-1),b(`tbody`,null,[(v(!0),C(_,null,O(vt.value,e=>(v(),C(`tr`,{key:e.serverId},[b(`td`,null,`#`+h(e.serverId),1),b(`td`,null,h(e.status),1),b(`td`,null,h(e.exitCode??`—`),1),b(`td`,We,h(e.summary),1)]))),128))])]),_:1})]),_:1})):x(``,!0),Z.value?(v(),E(u,{key:1},{default:c(()=>[S(F),S(k,{variant:`text`,onClick:t[25]||=e=>ct.value=!1},{default:c(()=>[...t[69]||=[y(`关闭`,-1)]]),_:1})]),_:1})):x(``,!0)]),_:1})]),_:1},8,[`modelValue`])]),_:1}))}});export{Ge as default};