Files
Nexus/web/app/assets/PushPage-JUycCQBy.js
T
Nexus Agent f127f07ab2 feat(rdp): 3389 页独立管理 RDP 主机
rdp_hosts 表与专用 API,在 3389远程页添加/连接,不再依赖子机列表。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-10 20:58:46 +08:00

1 line
34 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{a as e}from"./VDataTable-xIamJ7nl.js";import{n as t,t as n}from"./useSnackbar-yP7apGY8.js";import{n as r,t as i}from"./VRow-DQSkwKSy.js";import{Cr as a,Ct as o,Er as s,F as c,I as l,K as u,Kr as d,Mr as f,Or as p,Pr as m,Q as h,Rr as g,Sr as _,Tr as v,Un as y,Ur as b,Vr as x,Xt as ee,Zr as S,_ as C,_n as w,br as T,di as E,en as D,gr as O,hi as k,hn as te,ii as A,kn as j,l as M,m as N,pi as P,qt as ne,r as re,ri as F,rr as I,v as L,vn as R,wn as z,wr as ie,wt as ae,xr as B,y as V,yr as H,zr as oe}from"./index-_6O5JL4W.js";import{n as se}from"./paginatedFetch-BvAUiQXI.js";import{S as U,_ as W,b as G,g as ce,l as K,t as q,u as le,v as J}from"./VTextField-CD7WwKb1.js";import{g as ue,h as de,m as fe,p as Y,t as X}from"./VSelect-CDx3fXFa.js";import{t as pe}from"./VCheckbox-CjcHGgQY.js";import{t as me}from"./VDataTableServer-lHUUBg35.js";import{a as he,c as Z,i as ge,n as _e,o as ve,r as ye,s as be,t as xe}from"./labels-C-A2d08W.js";import{t as Q}from"./VDialog-DEJqI2_G.js";import{a as Se,i as Ce,n as we,r as Te,t as Ee}from"./usePushStaging-Duw4I7HY.js";import{t as De}from"./useServerCategories-PByuvSRp.js";import{t as Oe}from"./wsUrl-CqmqkTTE.js";var ke=p({__name:`PushDiagnoseDialog`,props:{modelValue:{type:Boolean},loading:{type:Boolean},result:{},targetName:{}},emits:[`update:modelValue`],setup(e){return(t,n)=>(x(),B(Q,{"model-value":e.modelValue,"max-width":`520`,"onUpdate:modelValue":n[1]||=e=>t.$emit(`update:modelValue`,e)},{default:S(()=>[s(W,{border:``},{default:S(()=>[s(G,null,{default:S(()=>[v(`推送失败诊断 — `+k(e.targetName),1)]),_:1}),s(J,null,{default:S(()=>[e.loading?(x(),B(u,{key:0,indeterminate:``,class:`mb-3`})):e.result?(x(),a(O,{key:1},[s(M,{density:`compact`},{default:S(()=>[s(N,{title:`SSH 连接`},{append:S(()=>[s(h,{color:e.result.ssh_ok?`success`:`error`},{default:S(()=>[v(k(e.result.ssh_ok?`mdi-check`:`mdi-close`),1)]),_:1},8,[`color`])]),_:1}),e.result.disk_avail?(x(),B(N,{key:0,title:`磁盘可用: ${e.result.disk_avail}`},null,8,[`title`])):_(``,!0),e.result.disk_used_pct==null?_(``,!0):(x(),B(N,{key:1,title:`磁盘使用率: ${e.result.disk_used_pct}%`},null,8,[`title`])),s(N,{title:`目标路径存在`},{append:S(()=>[s(h,{color:e.result.path_exists?`success`:`error`},{default:S(()=>[v(k(e.result.path_exists?`mdi-check`:`mdi-close`),1)]),_:1},8,[`color`])]),_:1}),e.result.path_perms?(x(),B(N,{key:2,subtitle:e.result.path_perms,title:`权限`},null,8,[`subtitle`])):_(``,!0),s(N,{title:`目标路径可写`},{append:S(()=>[s(h,{color:e.result.path_writable?`success`:`error`},{default:S(()=>[v(k(e.result.path_writable?`mdi-check`:`mdi-close`),1)]),_:1},8,[`color`])]),_:1})]),_:1}),(x(!0),a(O,null,b(e.result.errors,(e,t)=>(x(),B(c,{key:t,type:`error`,density:`compact`,variant:`tonal`,class:`mt-2`},{default:S(()=>[v(k(E(Z)(e)),1)]),_:2},1024))),128))],64)):_(``,!0)]),_:1}),s(U,null,{default:S(()=>[s(C),s(l,{variant:`text`,onClick:n[0]||=e=>t.$emit(`update:modelValue`,!1)},{default:S(()=>[...n[2]||=[v(`关闭`,-1)]]),_:1})]),_:1})]),_:1})]),_:1},8,[`model-value`]))}}),Ae={class:`text-caption`},je={class:`text-caption text-medium-emphasis`},Me=[`title`],Ne=[`title`],Pe={key:1,class:`text-caption text-medium-emphasis`},Fe=p({__name:`PushHistoryTable`,props:{items:{},headers:{},total:{},loading:{type:Boolean},page:{},statusFilter:{},syncModeFilter:{},serverFilter:{},statusOptions:{},syncModeOptions:{},serverOptions:{},reconciling:{type:Boolean}},emits:[`update:page`,`update:statusFilter`,`update:syncModeFilter`,`update:serverFilter`,`filter-change`,`page-change`,`reconcile`,`diagnose`],setup(e){return(t,n)=>(x(),B(W,{elevation:`0`,border:``,rounded:`lg`},{default:S(()=>[s(G,{class:`d-flex flex-wrap align-center ga-2`},{default:S(()=>[n[6]||=T(`span`,null,`推送历史`,-1),s(C),s(X,{"model-value":e.statusFilter,items:e.statusOptions,"item-title":`label`,"item-value":`value`,label:`状态`,variant:`outlined`,density:`compact`,"hide-details":``,clearable:``,style:{"max-width":`120px`},"onUpdate:modelValue":n[0]||=e=>{t.$emit(`update:statusFilter`,e),t.$emit(`filter-change`)}},null,8,[`model-value`,`items`]),s(X,{"model-value":e.syncModeFilter,items:e.syncModeOptions,"item-title":`label`,"item-value":`value`,label:`模式`,variant:`outlined`,density:`compact`,"hide-details":``,clearable:``,style:{"max-width":`120px`},"onUpdate:modelValue":n[1]||=e=>{t.$emit(`update:syncModeFilter`,e),t.$emit(`filter-change`)}},null,8,[`model-value`,`items`]),s(X,{"model-value":e.serverFilter,items:e.serverOptions,"item-title":`title`,"item-value":`value`,label:`服务器`,variant:`outlined`,density:`compact`,"hide-details":``,clearable:``,style:{"max-width":`180px`},"onUpdate:modelValue":n[2]||=e=>{t.$emit(`update:serverFilter`,e),t.$emit(`filter-change`)}},null,8,[`model-value`,`items`]),s(l,{size:`small`,variant:`tonal`,"prepend-icon":`mdi-wrench`,loading:e.reconciling,onClick:n[3]||=e=>t.$emit(`reconcile`)},{default:S(()=>[...n[5]||=[v(` 修复卡住记录 `,-1)]]),_:1},8,[`loading`])]),_:1}),s(me,{items:e.items,headers:e.headers,"items-length":e.total,loading:e.loading,page:e.page,"items-per-page":15,hover:``,density:`comfortable`,"onUpdate:page":n[4]||=e=>{t.$emit(`update:page`,e),t.$emit(`page-change`)}},{"item.status":S(({item:e})=>[s(V,{color:E(ye)(e.status),size:`x-small`,variant:`tonal`,label:``,border:`sm`},{default:S(()=>[v(k(E(ge)(e.status)),1)]),_:2},1032,[`color`])]),"item.sync_mode":S(({item:e})=>[T(`span`,Ae,k(E(be)(e.sync_mode)),1)]),"item.started_at":S(({item:e})=>[T(`span`,je,k(E(ne)(e.started_at)),1)]),"item.push_permission":S(({item:e})=>[T(`span`,{class:P([`text-caption`,e.push_permission?``:`text-medium-emphasis`]),title:e.push_permission||`本次推送未配置 rsync 属主/权限修正`},k(E(xe)(e.push_permission)),11,Me)]),"item.error_message":S(({item:e})=>[e.error_message?(x(),a(`span`,{key:0,class:`text-caption text-error text-truncate d-inline-block`,style:{"max-width":`200px`},title:E(Z)(e.error_message)},k(E(Z)(e.error_message)),9,Ne)):(x(),a(`span`,Pe,`—`))]),"item.actions":S(({item:e})=>[e.status===`failed`?(x(),B(l,{key:0,size:`x-small`,variant:`tonal`,"prepend-icon":`mdi-stethoscope`,onClick:n=>t.$emit(`diagnose`,e)},{default:S(()=>[...n[7]||=[v(` 诊断 `,-1)]]),_:1},8,[`onClick`])):_(``,!0)]),"no-data":S(()=>[...n[8]||=[T(`div`,{class:`text-center text-medium-emphasis py-6`},`暂无数据`,-1)]]),_:1},8,[`items`,`headers`,`items-length`,`loading`,`page`])]),_:1}))}}),Ie={class:`text-caption text-medium-emphasis`},Le={key:2,class:`mb-2 text-body-2`},Re={key:0,class:`text-error text-caption`},ze={key:1,class:`text-warning text-caption`},Be={key:2,class:`text-caption text-medium-emphasis`},Ve=p({__name:`PushPreviewDialog`,props:{modelValue:{type:Boolean},loading:{type:Boolean},results:{},selectedCount:{},previewDone:{},previewTotal:{},largeBatch:{type:Boolean},warnThreshold:{},errorCount:{},syncMode:{}},emits:[`update:modelValue`,`confirm-push`],setup(t){return(n,r)=>(x(),B(Q,{"model-value":t.modelValue,"max-width":`800`,"onUpdate:modelValue":r[2]||=e=>n.$emit(`update:modelValue`,e)},{default:S(()=>[s(W,{border:``},{default:S(()=>[s(G,{class:`d-flex align-center`},{default:S(()=>[r[3]||=v(` 推送预览 `,-1),s(C),T(`span`,Ie,[t.loading?(x(),a(O,{key:0},[v(k(t.previewDone)+` / `+k(t.previewTotal)+` 台`,1)],64)):(x(),a(O,{key:1},[v(k(t.results.length)+` 台`,1)],64))])]),_:1}),s(J,null,{default:S(()=>[t.loading?(x(),B(u,{key:0,"model-value":t.previewTotal?Math.round(t.previewDone/t.previewTotal*100):0,class:`mb-3`},null,8,[`model-value`])):_(``,!0),t.largeBatch&&!t.loading?(x(),B(c,{key:1,type:`info`,density:`compact`,variant:`tonal`,class:`mb-2`},{default:S(()=>[v(` 已预览 `+k(t.results.length)+` 台服务器(超过 `+k(t.warnThreshold)+` 台时推送耗时可能较长) `,1)]),_:1})):_(``,!0),t.loading?_(``,!0):(x(),a(`div`,Le,[r[4]||=v(` 将推送到 `,-1),T(`strong`,null,k(t.selectedCount),1),r[5]||=v(` 台服务器 `,-1)])),t.results.length?(x(),B(e,{key:3,density:`compact`},{default:S(()=>[r[6]||=T(`thead`,null,[T(`tr`,null,[T(`th`,null,`服务器`),T(`th`,null,`文件数`),T(`th`,null,`预计传输`),T(`th`,null,`大小`),T(`th`,null,`备注`)])],-1),T(`tbody`,null,[(x(!0),a(O,null,b(t.results,e=>(x(),a(`tr`,{key:e.server_id},[T(`td`,null,k(e.server_name),1),T(`td`,null,k(e.stats?.files_total??`—`),1),T(`td`,null,k(e.stats?.files_transferred??`—`),1),T(`td`,null,k(e.stats?E(_e)(e.stats.transfer_size_bytes??0):`—`),1),T(`td`,null,[e.error?(x(),a(`span`,Re,k(E(Z)(e.error)),1)):t.syncMode===`full`&&(e.stats?.files_deleted??0)>0?(x(),a(`span`,ze,`将删除 `+k(e.stats?.files_deleted)+` 个远端文件`,1)):(x(),a(`span`,Be,`—`))])]))),128))])]),_:1})):_(``,!0),t.errorCount>0&&!t.loading?(x(),B(c,{key:4,type:`warning`,density:`compact`,variant:`tonal`,class:`mt-3`},{default:S(()=>[v(k(t.errorCount)+` 台预览失败,推送时这些服务器可能仍会失败 `,1)]),_:1})):_(``,!0)]),_:1}),s(U,null,{default:S(()=>[s(C),s(l,{variant:`text`,onClick:r[0]||=e=>n.$emit(`update:modelValue`,!1)},{default:S(()=>[...r[7]||=[v(`关闭`,-1)]]),_:1}),s(l,{color:`primary`,variant:`flat`,disabled:t.loading,onClick:r[1]||=e=>n.$emit(`confirm-push`)},{default:S(()=>[...r[8]||=[v(`确认推送`,-1)]]),_:1},8,[`disabled`])]),_:1})]),_:1})]),_:1},8,[`model-value`]))}}),He={key:1,class:`text-caption text-medium-emphasis mb-2`},Ue={key:0},We=p({__name:`PushProgressList`,props:{items:{},batchId:{},pushing:{type:Boolean},cancelling:{type:Boolean},retryingAll:{type:Boolean},failedRetryCount:{},doneCount:{},totalProgress:{}},emits:[`cancel`,`retry-all`],setup(e){return(t,n)=>e.items.length>0?(x(),B(W,{key:0,class:`mb-4`,elevation:`0`,border:``,rounded:`lg`},{default:S(()=>[s(G,{class:`d-flex align-center text-subtitle-1`},{default:S(()=>[n[3]||=v(` 推送进度 `,-1),s(C),e.failedRetryCount>0&&!e.pushing?(x(),B(l,{key:0,size:`small`,variant:`tonal`,color:`warning`,class:`mr-2`,"prepend-icon":`mdi-refresh`,loading:e.retryingAll,onClick:n[0]||=e=>t.$emit(`retry-all`)},{default:S(()=>[v(` 重试全部失败 (`+k(e.failedRetryCount)+`) `,1)]),_:1},8,[`loading`])):_(``,!0),e.batchId&&e.items.some(e=>e.status===`running`||e.status===`pending`)&&e.pushing?(x(),B(l,{key:1,size:`small`,variant:`tonal`,color:`error`,class:`mr-2`,loading:e.cancelling,onClick:n[1]||=e=>t.$emit(`cancel`)},{default:S(()=>[...n[2]||=[v(` 取消推送 `,-1)]]),_:1},8,[`loading`])):_(``,!0),s(V,{size:`small`,variant:`tonal`,color:`primary`},{default:S(()=>[v(k(e.items.filter(e=>e.status===`success`).length)+`/`+k(e.items.length)+` 完成 `,1)]),_:1})]),_:1}),s(L),s(J,null,{default:S(()=>[e.pushing||e.totalProgress>0?(x(),B(u,{key:0,"model-value":e.totalProgress,color:`primary`,height:`8`,rounded:``,class:`mb-3`},null,8,[`model-value`])):_(``,!0),e.items.length?(x(),a(`div`,He,[v(k(e.doneCount)+` / `+k(e.items.length)+` 台已结束 `,1),e.items.some(e=>e.status===`failed`)?(x(),a(`span`,Ue,` · `+k(e.items.filter(e=>e.status===`failed`).length)+` 失败 `,1)):_(``,!0)])):_(``,!0),s(M,{density:`compact`},{default:S(()=>[(x(!0),a(O,null,b(e.items,e=>(x(),B(N,{key:e.id,title:e.name},ie({append:S(()=>[e.status===`pending`?(x(),B(h,{key:0,color:`grey`},{default:S(()=>[...n[4]||=[v(`mdi-clock-outline`,-1)]]),_:1})):e.status===`running`?(x(),B(h,{key:1,color:`blue`,class:`mdi-spin`},{default:S(()=>[...n[5]||=[v(`mdi-loading`,-1)]]),_:1})):e.status===`success`?(x(),B(h,{key:2,color:`green`},{default:S(()=>[...n[6]||=[v(`mdi-check-circle`,-1)]]),_:1})):e.status===`cancelled`?(x(),B(h,{key:3,color:`grey`},{default:S(()=>[...n[7]||=[v(`mdi-cancel`,-1)]]),_:1})):(x(),B(h,{key:4,color:`red`},{default:S(()=>[...n[8]||=[v(`mdi-alert-circle`,-1)]]),_:1}))]),_:2},[e.detail?{name:`subtitle`,fn:S(()=>[T(`span`,{class:P(e.status===`failed`?`text-error`:`text-medium-emphasis`)},k(e.detail),3)]),key:`0`}:void 0]),1032,[`title`]))),128))]),_:1})]),_:1})]),_:1})):_(``,!0)}}),Ge={key:0,class:`text-center text-medium-emphasis py-6`},Ke={class:`d-flex align-center px-2 mb-2`},qe={class:`text-caption text-medium-emphasis ml-1`},Je={class:`d-flex align-center ga-2`},Ye={class:`text-body-2 font-weight-medium text-truncate`},Xe={class:`text-caption text-medium-emphasis text-truncate`},Ze=[`title`],Qe={key:0,class:`text-caption mt-1`},$e=p({__name:`PushServerGrid`,props:{selectAll:{type:Boolean},serverSearch:{},serversLoading:{type:Boolean},serversByCategory:{},selectedIds:{},pushStatus:{},isCategoryAllSelected:{type:Function}},emits:[`update:serverSearch`,`toggle-all`,`refresh`,`toggle-category`,`toggle-server`],setup(e){return(t,n)=>(x(),B(W,{elevation:`0`,border:``,rounded:`lg`,class:`mb-4`},{default:S(()=>[s(G,{class:`d-flex align-center`},{default:S(()=>[s(pe,{"model-value":e.selectAll,label:`全选`,density:`compact`,"hide-details":``,class:`mr-4`,"onUpdate:modelValue":n[0]||=e=>t.$emit(`toggle-all`)},null,8,[`model-value`]),s(q,{"model-value":e.serverSearch,"prepend-inner-icon":`mdi-magnify`,label:`搜索服务器...`,density:`compact`,"hide-details":``,variant:`outlined`,rounded:``,style:{"max-width":`240px`},"onUpdate:modelValue":n[1]||=e=>t.$emit(`update:serverSearch`,e)},null,8,[`model-value`]),s(l,{icon:`mdi-refresh`,variant:`text`,size:`small`,loading:e.serversLoading,title:`刷新在线状态`,onClick:n[2]||=e=>t.$emit(`refresh`)},null,8,[`loading`])]),_:1}),s(L),s(J,{class:`pa-2`},{default:S(()=>[e.serversByCategory.length===0?(x(),a(`div`,Ge,`暂无服务器`)):(x(!0),a(O,{key:1},b(e.serversByCategory,o=>(x(),a(`div`,{key:o.category,class:`mb-4`},[T(`div`,Ke,[s(l,{size:`x-small`,variant:`text`,color:e.isCategoryAllSelected(o.category)?`primary`:`default`,onClick:e=>t.$emit(`toggle-category`,o.category)},{default:S(()=>[s(h,{size:`16`,class:`mr-1`},{default:S(()=>[v(k(e.isCategoryAllSelected(o.category)?`mdi-checkbox-marked`:`mdi-checkbox-blank-outline`),1)]),_:2},1024),v(` `+k(o.label),1)]),_:2},1032,[`color`,`onClick`]),T(`span`,qe,` (`+k(o.servers.filter(t=>e.selectedIds.has(t.id)).length)+`/`+k(o.servers.length)+`) `,1)]),s(i,{dense:``},{default:S(()=>[(x(!0),a(O,null,b(o.servers,i=>(x(),B(r,{key:i.id,cols:`6`,sm:`4`,md:`3`,lg:`2`},{default:S(()=>[s(W,{color:e.selectedIds.has(i.id)?`primary`:void 0,variant:e.selectedIds.has(i.id)?`tonal`:`outlined`,rounded:`lg`,class:`pa-3 cursor-pointer`,onClick:e=>t.$emit(`toggle-server`,i.id)},{default:S(()=>[T(`div`,Je,[s(h,{color:E(ve)(i.is_online),size:`12`},{default:S(()=>[...n[3]||=[v(`mdi-circle`,-1)]]),_:1},8,[`color`]),T(`span`,Ye,k(i.name),1)]),T(`div`,Xe,k(i.domain),1),T(`div`,{class:`text-caption text-medium-emphasis text-truncate`,title:i.target_path||`未配置目标路径`},` → `+k(i.target_path?.trim()||`未配置`),9,Ze),e.pushStatus[i.id]?(x(),a(`div`,Qe,[s(V,{color:E(he)(e.pushStatus[i.id]),size:`x-small`,variant:`tonal`,label:``,border:`sm`},{default:S(()=>[v(k(e.pushStatus[i.id]),1)]),_:2},1032,[`color`])])):_(``,!0)]),_:2},1032,[`color`,`variant`,`onClick`])]),_:2},1024))),128))]),_:2},1024)]))),128))]),_:1})]),_:1}))}}),et=j({...fe({falseIcon:`$radioOff`,trueIcon:`$radioOn`})},`VRadio`),$=z()({name:`VRadio`,props:et(),setup(e,{slots:t}){return R(()=>s(Y,f(Y.filterProps(e),{class:[`v-radio`,e.class],style:e.style,type:`radio`}),t)),{}}}),tt=j({height:{type:[Number,String],default:`auto`},...I(le(),[`direction`]),...I(ue(),[`multiple`]),trueIcon:{type:w,default:`$radioOn`},falseIcon:{type:w,default:`$radioOff`},type:{type:String,default:`radio`}},`VRadioGroup`),nt=z()({name:`VRadioGroup`,inheritAttrs:!1,props:tt(),emits:{"update:modelValue":e=>!0},setup(e,{attrs:t,slots:n}){let r=d(),i=H(()=>e.id||`radio-group-${r}`),a=te(e,`modelValue`),o=A();return R(()=>{let[r,c]=y(t),l=K.filterProps(e),u=Y.filterProps(e),d=n.label?n.label({label:e.label,props:{for:i.value}}):e.label;return s(K,f({ref:o,class:[`v-radio-group`,e.class],style:e.style},r,l,{modelValue:a.value,"onUpdate:modelValue":e=>a.value=e,id:i.value}),{...n,default:({id:t,messagesId:r,isDisabled:i,isReadonly:o})=>T(O,null,[d&&s(ce,{id:t.value},{default:()=>[d]}),s(de,f(u,{id:t.value,"aria-describedby":r.value,defaultsTarget:`VRadio`,trueIcon:e.trueIcon,falseIcon:e.falseIcon,type:e.type,disabled:i.value,readonly:o.value,"aria-labelledby":d?t.value:void 0,multiple:!1},c,{modelValue:a.value,"onUpdate:modelValue":e=>a.value=e}),n)])})}),re({},o)}}),rt={class:`text-caption text-medium-emphasis mt-1`},it=p({__name:`PushSyncModeCard`,props:{syncMode:{},syncModeDesc:{}},emits:[`update:syncMode`],setup(e,{emit:t}){let n=t;function r(e){e!=null&&n(`update:syncMode`,e)}return(t,n)=>(x(),B(W,{elevation:`0`,border:``,rounded:`lg`,class:`mb-4`},{default:S(()=>[s(G,{class:`text-subtitle-1`},{default:S(()=>[...n[0]||=[v(`同步模式`,-1)]]),_:1}),s(J,null,{default:S(()=>[s(nt,{"model-value":e.syncMode,inline:``,density:`compact`,"onUpdate:modelValue":r},{default:S(()=>[s($,{label:`增量同步`,value:`incremental`}),s($,{label:`全量同步`,value:`full`}),s($,{label:`校验和同步`,value:`checksum`})]),_:1},8,[`model-value`]),e.syncMode===`full`?(x(),B(c,{key:0,type:`warning`,density:`compact`,variant:`tonal`,class:`mt-2`},{default:S(()=>[...n[1]||=[v(` 全量同步会删除目标目录中不存在于源目录的文件 `,-1)]]),_:1})):_(``,!0),T(`div`,rt,k(e.syncModeDesc),1)]),_:1})]),_:1}))}}),at=p({__name:`PushToolbar`,props:{targetPath:{},submitting:{type:Boolean},pushing:{type:Boolean}},emits:[`update:targetPath`,`preview`,`push`],setup(e){return(t,n)=>(x(),B(W,{elevation:`0`,border:``,rounded:`lg`,class:`mb-4 pa-4`},{default:S(()=>[s(i,{align:`center`,dense:``},{default:S(()=>[s(r,{cols:`12`,sm:`8`},{default:S(()=>[s(q,{"model-value":e.targetPath,label:`目标路径`,placeholder:`/www/wwwroot`,hint:`留空则使用下方各服务器配置的路径;填写则统一覆盖所有选中服务器`,"persistent-hint":``,variant:`outlined`,density:`compact`,"prepend-inner-icon":`mdi-folder-marker`,clearable:``,"onUpdate:modelValue":n[0]||=e=>t.$emit(`update:targetPath`,e??``)},null,8,[`model-value`])]),_:1}),s(r,{cols:`12`,sm:`4`,class:`d-flex ga-2 justify-end`},{default:S(()=>[s(l,{size:`small`,variant:`tonal`,"prepend-icon":`mdi-eye`,onClick:n[1]||=e=>t.$emit(`preview`)},{default:S(()=>[...n[3]||=[v(`预览`,-1)]]),_:1}),s(l,{size:`small`,color:`primary`,variant:`flat`,"prepend-icon":`mdi-upload`,loading:e.submitting,disabled:e.pushing,onClick:n[2]||=e=>t.$emit(`push`)},{default:S(()=>[...n[4]||=[v(` 推送 `,-1)]]),_:1},8,[`loading`,`disabled`])]),_:1})]),_:1})]),_:1}))}}),ot=[`success`,`failed`,`cancelled`];function st(e){let t=A([]),n=A(!1),r=A(``),i=A(new Set),a=null;async function o(e=!1){e||(n.value=!0);try{t.value=(await se(`/servers/`,{},1,-1)).items}catch{t.value=[]}finally{e||(n.value=!1)}}function s(e){c(),a=setInterval(()=>{o(!0)},3e4)}function c(){a&&=(clearInterval(a),null)}let l=H(()=>{if(!r.value)return t.value;let e=r.value.toLowerCase();return t.value.filter(t=>t.name.toLowerCase().includes(e)||(t.domain||``).toLowerCase().includes(e)||(t.target_path||``).toLowerCase().includes(e))}),u=H(()=>{let e=l.value;return e.length>0&&e.every(e=>i.value.has(e.id))}),d=H(()=>{let e={};for(let t of l.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:De(e),servers:t})).sort((e,t)=>e.category===`uncategorized`?1:t.category===`uncategorized`?-1:e.label.localeCompare(t.label,`zh`))});function f(e){let t=d.value.find(t=>t.category===e);return!t||t.servers.length===0?!1:t.servers.every(e=>i.value.has(e.id))}function p(e){let t=d.value.find(t=>t.category===e);if(!t)return;let n=new Set(i.value),r=t.servers.every(e=>n.has(e.id));for(let e of t.servers)r?n.delete(e.id):n.add(e.id);i.value=n}function m(e){let t=new Set(i.value);t.has(e)?t.delete(e):t.add(e),i.value=t}function h(){let e=l.value,t=e.length>0&&e.every(e=>i.value.has(e.id)),n=new Set(i.value);for(let r of e)t?n.delete(r.id):n.add(r.id);i.value=n}return{servers:t,serversLoading:n,serverSearch:r,selectedIds:i,pushStatus:e,filteredServers:l,selectAll:u,serversByCategory:d,loadServers:o,startAutoRefresh:s,stopAutoRefresh:c,isCategoryAllSelected:f,toggleCategory:p,toggleServer:m,toggleAll:h}}function ct(){return crypto.randomUUID().replace(/-/g,``).slice(0,12)}function lt(e,t,r){let i=n(),a=ee(),{playPushCompleteSound:s}=ae(),c=A(!1),l=A(!1),u=A(!1),d=A(!1),f=A([]),p=A(``),m=A(null),h=[],g=H(()=>f.value.filter(e=>ot.includes(e.status)).length),_=H(()=>{let e=f.value.length;return e?Math.round(g.value/e*100):0});function v(){h.forEach(e=>clearTimeout(e)),h.length=0}function y(){let e=f.value.length;if(!e||!c.value||f.value.filter(e=>ot.includes(e.status)).length<e)return;c.value=!1,C(),r();let t=f.value.filter(e=>e.status===`failed`).length,n=f.value.filter(e=>e.status===`cancelled`).length,a=f.value.filter(e=>e.status===`success`).length;i(`推送完成:${a} 成功,${t} 失败${n?`${n} 取消`:``}`),a>0&&s()}function b(e){if(e.type!==`sync_progress`||e.batch_id!==p.value||e.server_id==null)return;let n=f.value.findIndex(t=>t.id===e.server_id);if(n===-1)return;let r=f.value[n],i=e.status;if(i===`running`)r.status=`running`,r.detail=`同步中...`;else if(i===`success`){r.status=`success`;let n=e.duration_seconds;r.detail=n==null?`完成`:`完成(${n}s`,t.pushStatus.value[e.server_id]=`成功`}else i===`failed`?(r.status=`failed`,r.detail=Z(e.error_message)||`失败`,e.retry_job_id!=null&&(r.retryJobId=e.retry_job_id),t.pushStatus.value[e.server_id]=`失败`):i===`cancelled`&&(r.status=`cancelled`,r.detail=Z(e.error_message)||`已取消`,t.pushStatus.value[e.server_id]=`已取消`);y()}function x(e){let n=e.results;if(n){for(let[e,r]of Object.entries(n)){let n=Number(e);if(!Number.isFinite(n))continue;let i=f.value.findIndex(e=>e.id===n);if(i===-1)continue;let a=f.value[i],o=r.status;if(o===`success`){a.status=`success`;let e=r.duration_seconds;a.detail=e==null?`完成`:`完成(${e}s`,t.pushStatus.value[n]=`成功`}else o===`failed`?(a.status=`failed`,a.detail=Z(r.error_message)||`失败`,r.retry_job_id!=null&&(a.retryJobId=r.retry_job_id),t.pushStatus.value[n]=`失败`):o===`cancelled`&&(a.status=`cancelled`,a.detail=Z(r.error_message)||`已取消`,t.pushStatus.value[n]=`已取消`)}y()}}function S(){if(!a.token)return Promise.reject(Error(`未登录,无法连接推送进度`));C();let e=Oe(`/ws/sync`,{token:a.token}),n=new WebSocket(e);return new Promise((e,o)=>{n.onopen=()=>e(),n.onerror=()=>o(Error(`推送进度 WebSocket 连接失败`)),n.onmessage=e=>{if(e.data!==`pong`)try{let t=JSON.parse(e.data);if(t.type===`ping`){n.send(`pong`);return}b(t)}catch{}},n.onclose=e=>{if(m.value=null,e.code===4001||e.code===4401){a.forceLogout();return}e.code!==1e3&&c.value&&(f.value.forEach(e=>{(e.status===`pending`||e.status===`running`)&&(e.status=`failed`,e.detail=`连接中断`,t.pushStatus.value[e.id]=`失败`)}),c.value=!1,i(`推送进度连接中断,部分服务器状态未知`,`warning`),r())},m.value=n})}function C(){m.value&&=(m.value.close(1e3),null)}async function w(){if(p.value){u.value=!0;try{await D.post(`/sync/cancel`,{batch_id:p.value}),f.value.forEach(e=>{(e.status===`pending`||e.status===`running`)&&(e.status=`cancelled`,e.detail=`已取消`,t.pushStatus.value[e.id]=`已取消`)}),c.value=!1,C(),r(),i(`推送已取消`)}catch(e){i(e instanceof Error?e.message:`取消失败`,`error`)}finally{u.value=!1}}}async function T(){if(c.value||l.value)return;let n=[...t.selectedIds.value].map(e=>t.servers.value.find(t=>t.id===e)).filter(e=>e!=null);if(!e.validateForm(n.length,n))return;v(),C(),p.value=``,t.pushStatus.value={};let a=n.map(e=>e.id);f.value=a.map(e=>({id:e,name:t.servers.value.find(t=>t.id===e)?.name||`#${e}`,status:`pending`})),c.value=!0,l.value=!0,p.value=ct();try{await S();let t=await D.post(`/sync/files`,{source_path:e.effectiveSourcePath(),target_path:e.effectiveTargetPath(),server_ids:a,sync_mode:e.syncMode.value,batch_id:p.value});t.batch_id&&t.batch_id!==p.value&&(p.value=t.batch_id),t.accepted?o(`推送已提交(${a.length} 台),请在下方查看进度`):x(t)}catch(e){C();let t=e instanceof Error?e.message:`推送请求失败`;f.value.forEach(e=>{e.status=`failed`,e.detail=t}),c.value=!1,i(t,`error`),r();return}finally{l.value=!1}let s=setTimeout(()=>{c.value&&(f.value.forEach(e=>{(e.status===`pending`||e.status===`running`)&&(e.status=`failed`,e.detail=`等待超时`,t.pushStatus.value[e.id]=`失败`)}),c.value=!1,C(),r(),i(`推送超时,${g.value}/${f.value.length} 台已有结果`,`warning`))},3e5);h.push(s)}let E=H(()=>f.value.filter(e=>e.status===`failed`&&e.retryJobId!=null).length);async function O(){let e=f.value.filter(e=>e.status===`failed`&&e.retryJobId!=null).map(e=>e.retryJobId);if(!e.length){i(`没有可重试的失败任务(重试任务可能尚未创建)`,`warning`);return}d.value=!0;let t=0,n=0;try{for(let r of e)try{await D.post(`/retries/${r}/retry`),t++}catch{n++}i(n>0?`已提交 ${t} 个重试,${n} 个提交失败`:`已提交 ${t} 个失败服务器的重试任务`)}finally{d.value=!1}}function k(){C(),v()}return{pushing:c,submitting:l,cancelling:u,retryingAll:d,wsProgressItems:f,pushBatchId:p,doneCount:g,totalProgress:_,failedRetryCount:E,doPush:T,cancelPush:w,retryAllFailed:O,dispose:k}}function ut(e,t){let n=A(!1),r=A([]),i=A(!1),a=A(0),o=A(0),s=H(()=>a.value>30),c=H(()=>r.value.filter(e=>e.error).length);async function l(t,n){try{let r=await D.post(`/sync/preview`,{source_path:e.effectiveSourcePath(),target_path:e.effectiveTargetPath(),server_id:t,sync_mode:e.syncMode.value});return r.error?{server_id:t,server_name:n,error:r.error}:{server_id:t,server_name:r.server_name||n,stats:r.stats}}catch(e){return{server_id:t,server_name:n,error:e instanceof Error?e.message:`预览失败`}}}async function u(){let s=[...t.selectedIds.value].map(e=>t.servers.value.find(t=>t.id===e)).filter(e=>e!=null);if(!e.validateForm(s.length,s))return;let c=s.map(e=>e.id);a.value=c.length,o.value=0,n.value=!0,i.value=!0,r.value=[];let u=c.map(e=>({id:e,name:t.servers.value.find(t=>t.id===e)?.name||`#${e}`}));for(let e=0;e<u.length;e+=4){let t=u.slice(e,e+4),n=await Promise.all(t.map(e=>l(e.id,e.name)));r.value=[...r.value,...n],o.value=r.value.length}i.value=!1}function d(){n.value=!1}function f(e){n.value=!1,e()}return{showPreview:n,previewResults:r,previewLoading:i,previewTotal:a,previewDone:o,previewLargeBatch:s,previewWarnThreshold:30,previewErrorCount:c,doPreview:u,closePreview:d,confirmAndPush:f}}var dt=[{label:`成功`,value:`success`},{label:`失败`,value:`failed`},{label:`进行中`,value:`running`},{label:`已取消`,value:`cancelled`}],ft=[{label:`增量`,value:`incremental`},{label:`全量`,value:`full`},{label:`校验和`,value:`checksum`}],pt=[{title:`时间`,key:`started_at`,width:170},{title:`服务器`,key:`server_name`,width:120},{title:`状态`,key:`status`,width:88},{title:`模式`,key:`sync_mode`,width:88},{title:`源路径`,key:`source_path`},{title:`目标路径`,key:`target_path`},{title:`权限`,key:`push_permission`,width:140},{title:`错误`,key:`error_message`,width:200},{title:`操作`,key:`actions`,width:88,sortable:!1}];function mt(e,t){let r=n(),i=A([]),a=A(0),o=A(!1),s=A(1),c=A(null),l=A(null),u=A(null),d=A(!1),f=A(!1),p=A(!1),m=A(null),h=A(null),g=H(()=>t.servers.value.map(e=>({title:e.name,value:e.id})));function _(){s.value=1,v()}async function v(e=!1){e||(o.value=!0);try{let e={page:s.value,per_page:15};c.value&&(e.status=c.value),l.value&&(e.sync_mode=l.value),u.value!=null&&(e.server_id=u.value);let t=await D.get(`/servers/logs`,e);i.value=t.items||[],a.value=t.total||0}catch{i.value=[],a.value=0}finally{e||(o.value=!1)}}async function y(){d.value=!0;try{let e=(await D.post(`/sync/reconcile-stale-logs`,{max_age_minutes:15})).reconciled??0;r(e>0?`已订正 ${e} 条卡住的推送记录`:`没有需要订正的记录`),await v()}catch(e){r(e instanceof Error?e.message:`订正失败`,`error`)}finally{d.value=!1}}async function b(t){h.value=t,m.value=null,f.value=!0,p.value=!0;try{m.value=await D.post(`/sync/diagnose`,{server_id:t.server_id,target_path:t.target_path||e.targetPath.value||void 0})}catch(e){r(e instanceof Error?e.message:`诊断失败`,`error`),f.value=!1}finally{p.value=!1}}function x(){f.value=!1}return{logs:i,logTotal:a,logLoading:o,logPage:s,logStatusFilter:c,logSyncModeFilter:l,logServerFilter:u,reconcilingLogs:d,logStatusOptions:dt,logSyncModeOptions:ft,logHeaders:pt,logServerOptions:g,showDiagnose:f,diagnoseLoading:p,diagnoseResult:m,diagnoseTarget:h,onLogFilterChange:_,loadLogs:v,reconcileStaleLogs:y,openDiagnose:b,closeDiagnose:x}}function ht(){let e=we(),t=Ee(e.uploadedSource),n=st(A({})),r=mt(e,n),i=lt(e,n,()=>r.loadLogs()),a=ut(e,n);function o(){a.confirmAndPush(()=>i.doPush())}let s=!1;function c(e=!1){e?(n.loadServers(!0),r.loadLogs(!0)):(n.loadServers(),r.loadLogs())}return g(()=>{c(!1),n.startAutoRefresh(()=>i.pushing.value),s=!0}),m(()=>{s&&c(!0)}),oe(()=>{i.dispose(),n.stopAutoRefresh()}),{form:F(e),staging:F(t),servers:F(n),progress:F(i),preview:F(a),logs:F(r),onConfirmAndPush:o}}var gt=p({name:`PushPage`,__name:`PushPage`,setup(e){let{form:n,staging:r,servers:i,progress:a,preview:o,logs:c,onConfirmAndPush:l}=ht();return(e,u)=>(x(),B(t,{fluid:``,class:`pa-6`},{default:S(()=>[s(Te,{"uploaded-source":E(n).uploadedSource,"validated-source":E(n).validatedSource,"source-path":E(n).sourcePath,"onUpdate:sourcePath":u[0]||=e=>E(n).sourcePath=e,"source-path-validating":E(n).sourcePathValidating,"is-dragging":E(n).isDragging,"source-uploading":E(n).sourceUploading,onDragover:u[1]||=e=>E(n).isDragging=!0,onDragleave:u[2]||=e=>E(n).isDragging=!1,onDrop:E(n).handleFileDrop,onFileSelect:E(n).handleFileSelect,onZipExtractSelect:E(n).handleZipExtractSelect,onClear:E(n).clearUploadedSource,onClearValidated:E(n).clearValidatedSource,onValidate:E(n).validateSourcePath},null,8,[`uploaded-source`,`validated-source`,`source-path`,`source-path-validating`,`is-dragging`,`source-uploading`,`onDrop`,`onFileSelect`,`onZipExtractSelect`,`onClear`,`onClearValidated`,`onValidate`]),E(n).uploadedSource?(x(),B(Se,{key:0,"root-path":E(n).uploadedSource.sourcePath,"relative-path":E(r).relativePath,entries:E(r).entries,loading:E(r).loading,"selected-count":E(r).selectedCount,"all-selected":E(r).allSelected,"some-selected":E(r).someSelected,"is-selected":E(r).isSelected,"rename-open":E(r).renameOpen,"onUpdate:renameOpen":u[3]||=e=>E(r).renameOpen=e,"rename-value":E(r).renameValue,"onUpdate:renameValue":u[4]||=e=>E(r).renameValue=e,"rename-loading":E(r).renameLoading,"delete-open":E(r).deleteOpen,"onUpdate:deleteOpen":u[5]||=e=>E(r).deleteOpen=e,"delete-targets":E(r).deleteTargets,"delete-loading":E(r).deleteLoading,onRefresh:u[6]||=e=>E(r).refreshCurrent(),onGoRoot:E(r).goRoot,onOpenDir:E(r).openDirectory,onPreview:E(r).previewFile,onRename:E(r).openRename,onDelete:E(r).openDelete,onBatchDelete:E(r).openBatchDelete,onToggleSelect:E(r).toggleSelect,onToggleSelectAll:E(r).toggleSelectAll,onConfirmRename:E(r).confirmRename,onConfirmDelete:E(r).confirmDelete},null,8,[`root-path`,`relative-path`,`entries`,`loading`,`selected-count`,`all-selected`,`some-selected`,`is-selected`,`rename-open`,`rename-value`,`rename-loading`,`delete-open`,`delete-targets`,`delete-loading`,`onGoRoot`,`onOpenDir`,`onPreview`,`onRename`,`onDelete`,`onBatchDelete`,`onToggleSelect`,`onToggleSelectAll`,`onConfirmRename`,`onConfirmDelete`])):_(``,!0),s(Ce,{modelValue:E(r).previewOpen,"onUpdate:modelValue":u[7]||=e=>E(r).previewOpen=e,loading:E(r).previewLoading,result:E(r).previewResult},null,8,[`modelValue`,`loading`,`result`]),s(at,{"target-path":E(n).targetPath,"onUpdate:targetPath":u[8]||=e=>E(n).targetPath=e,submitting:E(a).submitting,pushing:E(a).pushing,onPreview:E(o).doPreview,onPush:E(a).doPush},null,8,[`target-path`,`submitting`,`pushing`,`onPreview`,`onPush`]),s($e,{"select-all":E(i).selectAll,"server-search":E(i).serverSearch,"onUpdate:serverSearch":u[9]||=e=>E(i).serverSearch=e,"servers-loading":E(i).serversLoading,"servers-by-category":E(i).serversByCategory,"selected-ids":E(i).selectedIds,"push-status":E(i).pushStatus,"is-category-all-selected":E(i).isCategoryAllSelected,onToggleAll:E(i).toggleAll,onRefresh:E(i).loadServers,onToggleCategory:E(i).toggleCategory,onToggleServer:E(i).toggleServer},null,8,[`select-all`,`server-search`,`servers-loading`,`servers-by-category`,`selected-ids`,`push-status`,`is-category-all-selected`,`onToggleAll`,`onRefresh`,`onToggleCategory`,`onToggleServer`]),s(it,{"sync-mode":E(n).syncMode,"onUpdate:syncMode":u[10]||=e=>E(n).syncMode=e,"sync-mode-desc":E(n).syncModeDesc},null,8,[`sync-mode`,`sync-mode-desc`]),s(We,{items:E(a).wsProgressItems,"batch-id":E(a).pushBatchId,pushing:E(a).pushing,cancelling:E(a).cancelling,"retrying-all":E(a).retryingAll,"failed-retry-count":E(a).failedRetryCount,"done-count":E(a).doneCount,"total-progress":E(a).totalProgress,onCancel:E(a).cancelPush,onRetryAll:E(a).retryAllFailed},null,8,[`items`,`batch-id`,`pushing`,`cancelling`,`retrying-all`,`failed-retry-count`,`done-count`,`total-progress`,`onCancel`,`onRetryAll`]),s(Ve,{modelValue:E(o).showPreview,"onUpdate:modelValue":u[11]||=e=>E(o).showPreview=e,loading:E(o).previewLoading,results:E(o).previewResults,"selected-count":E(i).selectedIds.size,"preview-done":E(o).previewDone,"preview-total":E(o).previewTotal,"large-batch":E(o).previewLargeBatch,"warn-threshold":E(o).previewWarnThreshold,"error-count":E(o).previewErrorCount,"sync-mode":E(n).syncMode,onConfirmPush:E(l)},null,8,[`modelValue`,`loading`,`results`,`selected-count`,`preview-done`,`preview-total`,`large-batch`,`warn-threshold`,`error-count`,`sync-mode`,`onConfirmPush`]),s(ke,{modelValue:E(c).showDiagnose,"onUpdate:modelValue":u[12]||=e=>E(c).showDiagnose=e,loading:E(c).diagnoseLoading,result:E(c).diagnoseResult,"target-name":E(c).diagnoseTarget?.server_name??void 0},null,8,[`modelValue`,`loading`,`result`,`target-name`]),s(Fe,{items:E(c).logs,headers:E(c).logHeaders,total:E(c).logTotal,loading:E(c).logLoading,page:E(c).logPage,"onUpdate:page":u[13]||=e=>E(c).logPage=e,"status-filter":E(c).logStatusFilter,"onUpdate:statusFilter":u[14]||=e=>E(c).logStatusFilter=e,"sync-mode-filter":E(c).logSyncModeFilter,"onUpdate:syncModeFilter":u[15]||=e=>E(c).logSyncModeFilter=e,"server-filter":E(c).logServerFilter,"onUpdate:serverFilter":u[16]||=e=>E(c).logServerFilter=e,"status-options":E(c).logStatusOptions,"sync-mode-options":E(c).logSyncModeOptions,"server-options":E(c).logServerOptions,reconciling:E(c).reconcilingLogs,onFilterChange:E(c).onLogFilterChange,onPageChange:E(c).loadLogs,onReconcile:E(c).reconcileStaleLogs,onDiagnose:E(c).openDiagnose},null,8,[`items`,`headers`,`total`,`loading`,`page`,`status-filter`,`sync-mode-filter`,`server-filter`,`status-options`,`sync-mode-options`,`server-options`,`reconciling`,`onFilterChange`,`onPageChange`,`onReconcile`,`onDiagnose`])]),_:1}))}});export{gt as default};