import{a as e}from"./VDataTable-CA2-7Joy.js";import{$n as t,$t as n,Ar as r,Br as i,Cr as a,F as o,I as s,Ir as c,J as l,M as u,N as d,P as f,Pt as p,Qn as m,R as h,Rn as g,Rr as _,Rt as v,X as y,Xn as b,Yn as x,_r as S,ar as C,br as w,cn as T,er as E,fn as D,h as ee,hr as O,ir as k,k as A,kr as j,lr as M,mr as te,nn as N,nr as P,o as F,or as I,pr as ne,rr as re,s as ie,t as L,tn as R,tr as z,v as ae,w as B,wn as oe}from"./index-o0-2k-vI.js";import{a as se,i as ce,n as V,o as H,r as le,t as ue}from"./VContainer-BbTGUkA2.js";import{t as U}from"./VChip-B_7LyIUT.js";import{t as W}from"./VSelect-RidH-jin.js";import{t as de}from"./VCheckbox-BtPiDaqT.js";import{t as fe}from"./VDataTableServer-CYEpP3ht.js";import{n as G,t as K}from"./VRow-D9pCZkmz.js";import{t as q}from"./VSpacer-DE-o2Lgp.js";import{t as J}from"./VDialog-nLwlI-ms.js";import{t as Y}from"./VAlert-CJEBMMcd.js";import{t as pe}from"./wsUrl-CqmqkTTE.js";var me=[[/rsync:\s*connection unexpectedly closed/gi,`rsync:连接意外关闭`],[/rsync error:\s*some files\/attrs were not transferred/gi,`rsync 错误:部分文件或属性未能传输`],[/rsync error:\s*error in rsync protocol data stream/gi,`rsync 错误:协议数据流异常`],[/rsync error:\s*/gi,`rsync 错误:`],[/rsync:\s*/gi,`rsync:`],[/Host key verification failed/gi,`SSH 主机密钥验证失败`],[/Could not resolve hostname/gi,`无法解析主机名`],[/Permission denied,\s*please try again/gi,`权限被拒绝,请重试`],[/Permission denied\s*\(publickey/gi,`公钥认证失败,权限被拒绝`],[/Permission denied/gi,`权限被拒绝`],[/No such file or directory/gi,`文件或目录不存在`],[/Connection refused/gi,`连接被拒绝`],[/Connection timed out/gi,`连接超时`],[/Connection reset by peer/gi,`连接被对端重置`],[/Network is unreachable/gi,`网络不可达`],[/No route to host/gi,`无法路由到主机`],[/No space left on device/gi,`磁盘空间不足`],[/Read-only file system/gi,`文件系统为只读`],[/Operation timed out/gi,`操作超时`],[/Operation not permitted/gi,`操作不允许`],[/Authentication failed/gi,`认证失败`],[/Broken pipe/gi,`连接中断(管道破裂)`],[/Protocol error/gi,`协议错误`],[/Too many open files/gi,`打开的文件过多`],[/Name or service not known/gi,`无法解析主机名或服务名`],[/ssh:\s*connect to host/gi,`ssh:无法连接到主机`],[/ssh:\s*/gi,`ssh:`],[/Command failed\s*\(exit\s*(\d+)\)/gi,`命令失败(退出码 $1)`],[/rsync exited with code\s*(\d+)/gi,`rsync 退出码 $1`],[/\bexit code\s*(\d+)/gi,`退出码 $1`],[/Server not found/gi,`服务器不存在`],[/failed to set times on/gi,`无法设置文件时间戳:`],[/\bsender\b/gi,`发送端`],[/\breceiver\b/gi,`接收端`]],he=/[\u4e00-\u9fff\u3400-\u4dbf]/g;function ge(e){let t=e.match(he);if(!t?.length)return!1;let n=e.replace(/\s+/g,``);return n.length?t.length/n.length>=.2:!1}function X(e){if(e==null)return``;let t=e.trim();if(!t)return``;if(ge(t))return e;let n=t;for(let[e,t]of me)n=n.replace(e,t);return n}function Z(e){return e<1024?`${e} B`:e<1048576?`${(e/1024).toFixed(1)} KB`:`${(e/1048576).toFixed(1)} MB`}function _e(e){if(!e)return`—`;let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString(`zh-CN`,{hour12:!1})}function ve(e){switch(e){case`success`:return`成功`;case`failed`:return`失败`;case`running`:return`进行中`;case`cancelled`:return`已取消`;default:return e}}function ye(e){switch(e){case`success`:return`success`;case`failed`:return`error`;case`cancelled`:return`grey`;case`running`:return`info`;default:return`warning`}}function be(e){switch(e){case`incremental`:return`增量`;case`full`:return`全量`;case`checksum`:return`校验和`;case`overwrite`:return`覆盖`;default:return e||`—`}}function xe(e){return e===`成功`?`success`:e===`失败`?`error`:e===`已取消`?`grey`:`warning`}function Se(e){return e?`success`:`error`}var Ce=I({__name:`PushDiagnoseDialog`,props:{modelValue:{type:Boolean},loading:{type:Boolean},result:{},targetName:{}},emits:[`update:modelValue`],setup(e){return(t,n)=>(O(),E(J,{"model-value":e.modelValue,"max-width":`520`,"onUpdate:modelValue":n[1]||=e=>t.$emit(`update:modelValue`,e)},{default:a(()=>[C(d,{border:``},{default:a(()=>[C(o,null,{default:a(()=>[k(`推送失败诊断 — `+i(e.targetName),1)]),_:1}),C(f,null,{default:a(()=>[e.loading?(O(),E(l,{key:0,indeterminate:``,class:`mb-3`})):e.result?(O(),P(b,{key:1},[C(B,{density:`compact`},{default:a(()=>[C(A,{title:`SSH 连接`},{append:a(()=>[C(y,{color:e.result.ssh_ok?`success`:`error`},{default:a(()=>[k(i(e.result.ssh_ok?`mdi-check`:`mdi-close`),1)]),_:1},8,[`color`])]),_:1}),e.result.disk_avail?(O(),E(A,{key:0,title:`磁盘可用: ${e.result.disk_avail}`},null,8,[`title`])):z(``,!0),e.result.disk_used_pct==null?z(``,!0):(O(),E(A,{key:1,title:`磁盘使用率: ${e.result.disk_used_pct}%`},null,8,[`title`])),C(A,{title:`目标路径存在`},{append:a(()=>[C(y,{color:e.result.path_exists?`success`:`error`},{default:a(()=>[k(i(e.result.path_exists?`mdi-check`:`mdi-close`),1)]),_:1},8,[`color`])]),_:1}),e.result.path_perms?(O(),E(A,{key:2,subtitle:e.result.path_perms,title:`权限`},null,8,[`subtitle`])):z(``,!0),C(A,{title:`目标路径可写`},{append:a(()=>[C(y,{color:e.result.path_writable?`success`:`error`},{default:a(()=>[k(i(e.result.path_writable?`mdi-check`:`mdi-close`),1)]),_:1},8,[`color`])]),_:1})]),_:1}),(O(!0),P(b,null,S(e.result.errors,(e,t)=>(O(),E(Y,{key:t,type:`error`,density:`compact`,variant:`tonal`,class:`mt-2`},{default:a(()=>[k(i(c(X)(e)),1)]),_:2},1024))),128))],64)):z(``,!0)]),_:1}),C(s,null,{default:a(()=>[C(q),C(h,{variant:`text`,onClick:n[0]||=e=>t.$emit(`update:modelValue`,!1)},{default:a(()=>[...n[2]||=[k(`关闭`,-1)]]),_:1})]),_:1})]),_:1})]),_:1},8,[`model-value`]))}}),we={class:`text-caption`},Te={class:`text-caption text-medium-emphasis`},Ee=[`title`],De={key:1,class:`text-caption text-medium-emphasis`},Oe=I({__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(n,r)=>(O(),E(d,{elevation:`0`,border:``,rounded:`lg`},{default:a(()=>[C(o,{class:`d-flex flex-wrap align-center ga-2`},{default:a(()=>[r[6]||=t(`span`,null,`推送历史`,-1),C(q),C(W,{"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":r[0]||=e=>{n.$emit(`update:statusFilter`,e),n.$emit(`filter-change`)}},null,8,[`model-value`,`items`]),C(W,{"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":r[1]||=e=>{n.$emit(`update:syncModeFilter`,e),n.$emit(`filter-change`)}},null,8,[`model-value`,`items`]),C(W,{"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":r[2]||=e=>{n.$emit(`update:serverFilter`,e),n.$emit(`filter-change`)}},null,8,[`model-value`,`items`]),C(h,{size:`small`,variant:`tonal`,"prepend-icon":`mdi-wrench`,loading:e.reconciling,onClick:r[3]||=e=>n.$emit(`reconcile`)},{default:a(()=>[...r[5]||=[k(` 修复卡住记录 `,-1)]]),_:1},8,[`loading`])]),_:1}),C(fe,{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":r[4]||=e=>{n.$emit(`update:page`,e),n.$emit(`page-change`)}},{"item.status":a(({item:e})=>[C(U,{color:c(ye)(e.status),size:`x-small`,variant:`tonal`,label:``,border:`sm`},{default:a(()=>[k(i(c(ve)(e.status)),1)]),_:2},1032,[`color`])]),"item.sync_mode":a(({item:e})=>[t(`span`,we,i(c(be)(e.sync_mode)),1)]),"item.started_at":a(({item:e})=>[t(`span`,Te,i(c(_e)(e.started_at)),1)]),"item.error_message":a(({item:e})=>[e.error_message?(O(),P(`span`,{key:0,class:`text-caption text-error text-truncate d-inline-block`,style:{"max-width":`200px`},title:c(X)(e.error_message)},i(c(X)(e.error_message)),9,Ee)):(O(),P(`span`,De,`—`))]),"item.actions":a(({item:e})=>[e.status===`failed`?(O(),E(h,{key:0,size:`x-small`,variant:`tonal`,"prepend-icon":`mdi-stethoscope`,onClick:t=>n.$emit(`diagnose`,e)},{default:a(()=>[...r[7]||=[k(` 诊断 `,-1)]]),_:1},8,[`onClick`])):z(``,!0)]),"no-data":a(()=>[...r[8]||=[t(`div`,{class:`text-center text-medium-emphasis py-6`},`暂无数据`,-1)]]),_:1},8,[`items`,`headers`,`items-length`,`loading`,`page`])]),_:1}))}}),ke={class:`text-caption text-medium-emphasis`},Ae={key:2,class:`mb-2 text-body-2`},je={key:0,class:`text-error text-caption`},Me={key:1,class:`text-warning text-caption`},Ne={key:2,class:`text-caption text-medium-emphasis`},Pe=I({__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(n){return(r,u)=>(O(),E(J,{"model-value":n.modelValue,"max-width":`800`,"onUpdate:modelValue":u[2]||=e=>r.$emit(`update:modelValue`,e)},{default:a(()=>[C(d,{border:``},{default:a(()=>[C(o,{class:`d-flex align-center`},{default:a(()=>[u[3]||=k(` 推送预览 `,-1),C(q),t(`span`,ke,[n.loading?(O(),P(b,{key:0},[k(i(n.previewDone)+` / `+i(n.previewTotal)+` 台`,1)],64)):(O(),P(b,{key:1},[k(i(n.results.length)+` 台`,1)],64))])]),_:1}),C(f,null,{default:a(()=>[n.loading?(O(),E(l,{key:0,"model-value":n.previewTotal?Math.round(n.previewDone/n.previewTotal*100):0,class:`mb-3`},null,8,[`model-value`])):z(``,!0),n.largeBatch&&!n.loading?(O(),E(Y,{key:1,type:`info`,density:`compact`,variant:`tonal`,class:`mb-2`},{default:a(()=>[k(` 已预览 `+i(n.results.length)+` 台服务器(超过 `+i(n.warnThreshold)+` 台时推送耗时可能较长) `,1)]),_:1})):z(``,!0),n.loading?z(``,!0):(O(),P(`div`,Ae,[u[4]||=k(` 将推送到 `,-1),t(`strong`,null,i(n.selectedCount),1),u[5]||=k(` 台服务器 `,-1)])),n.results.length?(O(),E(e,{key:3,density:`compact`},{default:a(()=>[u[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,[(O(!0),P(b,null,S(n.results,e=>(O(),P(`tr`,{key:e.server_id},[t(`td`,null,i(e.server_name),1),t(`td`,null,i(e.stats?.files_total??`—`),1),t(`td`,null,i(e.stats?.files_transferred??`—`),1),t(`td`,null,i(e.stats?c(Z)(e.stats.transfer_size_bytes??0):`—`),1),t(`td`,null,[e.error?(O(),P(`span`,je,i(c(X)(e.error)),1)):n.syncMode===`full`&&(e.stats?.files_deleted??0)>0?(O(),P(`span`,Me,`将删除 `+i(e.stats?.files_deleted)+` 个远端文件`,1)):(O(),P(`span`,Ne,`—`))])]))),128))])]),_:1})):z(``,!0),n.errorCount>0&&!n.loading?(O(),E(Y,{key:4,type:`warning`,density:`compact`,variant:`tonal`,class:`mt-3`},{default:a(()=>[k(i(n.errorCount)+` 台预览失败,推送时这些服务器可能仍会失败 `,1)]),_:1})):z(``,!0)]),_:1}),C(s,null,{default:a(()=>[C(q),C(h,{variant:`text`,onClick:u[0]||=e=>r.$emit(`update:modelValue`,!1)},{default:a(()=>[...u[7]||=[k(`关闭`,-1)]]),_:1}),C(h,{color:`primary`,variant:`flat`,disabled:n.loading,onClick:u[1]||=e=>r.$emit(`confirm-push`)},{default:a(()=>[...u[8]||=[k(`确认推送`,-1)]]),_:1},8,[`disabled`])]),_:1})]),_:1})]),_:1},8,[`model-value`]))}}),Fe={key:1,class:`text-caption text-medium-emphasis mb-2`},Ie=I({__name:`PushProgressList`,props:{items:{},batchId:{},pushing:{type:Boolean},cancelling:{type:Boolean},doneCount:{},totalProgress:{}},emits:[`cancel`],setup(e){return(n,r)=>e.items.length>0?(O(),E(d,{key:0,class:`mb-4`,elevation:`0`,border:``,rounded:`lg`},{default:a(()=>[C(o,{class:`d-flex align-center text-subtitle-1`},{default:a(()=>[r[2]||=k(` 推送进度 `,-1),C(q),e.batchId&&e.items.some(e=>e.status===`running`||e.status===`pending`)&&e.pushing?(O(),E(h,{key:0,size:`small`,variant:`tonal`,color:`error`,class:`mr-2`,loading:e.cancelling,onClick:r[0]||=e=>n.$emit(`cancel`)},{default:a(()=>[...r[1]||=[k(` 取消推送 `,-1)]]),_:1},8,[`loading`])):z(``,!0),C(U,{size:`small`,variant:`tonal`,color:`primary`},{default:a(()=>[k(i(e.items.filter(e=>e.status===`success`).length)+`/`+i(e.items.length)+` 完成 `,1)]),_:1})]),_:1}),C(u),C(f,null,{default:a(()=>[e.pushing||e.totalProgress>0?(O(),E(l,{key:0,"model-value":e.totalProgress,color:`primary`,height:`8`,rounded:``,class:`mb-3`},null,8,[`model-value`])):z(``,!0),e.items.length?(O(),P(`div`,Fe,i(e.doneCount)+` / `+i(e.items.length)+` 台已结束 `,1)):z(``,!0),C(B,{density:`compact`},{default:a(()=>[(O(!0),P(b,null,S(e.items,e=>(O(),E(A,{key:e.id,title:e.name},re({append:a(()=>[e.status===`pending`?(O(),E(y,{key:0,color:`grey`},{default:a(()=>[...r[3]||=[k(`mdi-clock-outline`,-1)]]),_:1})):e.status===`running`?(O(),E(y,{key:1,color:`blue`,class:`mdi-spin`},{default:a(()=>[...r[4]||=[k(`mdi-loading`,-1)]]),_:1})):e.status===`success`?(O(),E(y,{key:2,color:`green`},{default:a(()=>[...r[5]||=[k(`mdi-check-circle`,-1)]]),_:1})):e.status===`cancelled`?(O(),E(y,{key:3,color:`grey`},{default:a(()=>[...r[6]||=[k(`mdi-cancel`,-1)]]),_:1})):(O(),E(y,{key:4,color:`red`},{default:a(()=>[...r[7]||=[k(`mdi-alert-circle`,-1)]]),_:1}))]),_:2},[e.detail?{name:`subtitle`,fn:a(()=>[t(`span`,{class:_(e.status===`failed`?`text-error`:`text-medium-emphasis`)},i(e.detail),3)]),key:`0`}:void 0]),1032,[`title`]))),128))]),_:1})]),_:1})]),_:1})):z(``,!0)}}),Le={key:0,class:`text-center text-medium-emphasis py-6`},Re={class:`d-flex align-center px-2 mb-2`},ze={class:`text-caption text-medium-emphasis ml-1`},Be={class:`d-flex align-center ga-2`},Ve={class:`text-body-2 font-weight-medium text-truncate`},He={class:`text-caption text-medium-emphasis text-truncate`},Ue={key:0,class:`text-caption mt-1`},We=I({__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(n,r)=>(O(),E(d,{elevation:`0`,border:``,rounded:`lg`,class:`mb-4`},{default:a(()=>[C(o,{class:`d-flex align-center`},{default:a(()=>[C(de,{"model-value":e.selectAll,label:`全选`,density:`compact`,"hide-details":``,class:`mr-4`,"onUpdate:modelValue":r[0]||=e=>n.$emit(`toggle-all`)},null,8,[`model-value`]),C(L,{"model-value":e.serverSearch,"prepend-inner-icon":`mdi-magnify`,label:`搜索服务器...`,density:`compact`,"hide-details":``,variant:`outlined`,rounded:``,style:{"max-width":`240px`},"onUpdate:modelValue":r[1]||=e=>n.$emit(`update:serverSearch`,e)},null,8,[`model-value`]),C(h,{icon:`mdi-refresh`,variant:`text`,size:`small`,loading:e.serversLoading,title:`刷新在线状态`,onClick:r[2]||=e=>n.$emit(`refresh`)},null,8,[`loading`])]),_:1}),C(u),C(f,{class:`pa-2`},{default:a(()=>[e.serversByCategory.length===0?(O(),P(`div`,Le,`暂无服务器`)):(O(!0),P(b,{key:1},S(e.serversByCategory,o=>(O(),P(`div`,{key:o.category,class:`mb-4`},[t(`div`,Re,[C(h,{size:`x-small`,variant:`text`,color:e.isCategoryAllSelected(o.category)?`primary`:`default`,onClick:e=>n.$emit(`toggle-category`,o.category)},{default:a(()=>[C(y,{size:`16`,class:`mr-1`},{default:a(()=>[k(i(e.isCategoryAllSelected(o.category)?`mdi-checkbox-marked`:`mdi-checkbox-blank-outline`),1)]),_:2},1024),k(` `+i(o.category),1)]),_:2},1032,[`color`,`onClick`]),t(`span`,ze,` (`+i(o.servers.filter(t=>e.selectedIds.has(t.id)).length)+`/`+i(o.servers.length)+`) `,1)]),C(K,{dense:``},{default:a(()=>[(O(!0),P(b,null,S(o.servers,o=>(O(),E(G,{key:o.id,cols:`6`,sm:`4`,md:`3`,lg:`2`},{default:a(()=>[C(d,{color:e.selectedIds.has(o.id)?`primary`:void 0,variant:e.selectedIds.has(o.id)?`tonal`:`outlined`,rounded:`lg`,class:`pa-3 cursor-pointer`,onClick:e=>n.$emit(`toggle-server`,o.id)},{default:a(()=>[t(`div`,Be,[C(y,{color:c(Se)(o.is_online),size:`12`},{default:a(()=>[...r[3]||=[k(`mdi-circle`,-1)]]),_:1},8,[`color`]),t(`span`,Ve,i(o.name),1)]),t(`div`,He,i(o.domain),1),e.pushStatus[o.id]?(O(),P(`div`,Ue,[C(U,{color:c(xe)(e.pushStatus[o.id]),size:`x-small`,variant:`tonal`,label:``,border:`sm`},{default:a(()=>[k(i(e.pushStatus[o.id]),1)]),_:2},1032,[`color`])])):z(``,!0)]),_:2},1032,[`color`,`variant`,`onClick`])]),_:2},1024))),128))]),_:2},1024)]))),128))]),_:1})]),_:1}))}}),Ge=D({...le({falseIcon:`$radioOff`,trueIcon:`$radioOn`})},`VRadio`),Q=T()({name:`VRadio`,props:Ge(),setup(e,{slots:t}){return N(()=>C(V,M(V.filterProps(e),{class:[`v-radio`,e.class],style:e.style,type:`radio`}),t)),{}}}),Ke=D({height:{type:[Number,String],default:`auto`},...g(ie(),[`direction`]),...g(se(),[`multiple`]),trueIcon:{type:R,default:`$radioOn`},falseIcon:{type:R,default:`$radioOff`},type:{type:String,default:`radio`}},`VRadioGroup`),qe=T()({name:`VRadioGroup`,inheritAttrs:!1,props:Ke(),emits:{"update:modelValue":e=>!0},setup(e,{attrs:i,slots:a}){let o=w(),s=m(()=>e.id||`radio-group-${o}`),c=n(e,`modelValue`),l=r();return N(()=>{let[n,r]=oe(i),o=F.filterProps(e),u=V.filterProps(e),d=a.label?a.label({label:e.label,props:{for:s.value}}):e.label;return C(F,M({ref:l,class:[`v-radio-group`,e.class],style:e.style},n,o,{modelValue:c.value,"onUpdate:modelValue":e=>c.value=e,id:s.value}),{...a,default:({id:n,messagesId:i,isDisabled:o,isReadonly:s})=>t(b,null,[d&&C(ee,{id:n.value},{default:()=>[d]}),C(ce,M(u,{id:n.value,"aria-describedby":i.value,defaultsTarget:`VRadio`,trueIcon:e.trueIcon,falseIcon:e.falseIcon,type:e.type,disabled:o.value,readonly:s.value,"aria-labelledby":d?n.value:void 0,multiple:!1},r,{modelValue:c.value,"onUpdate:modelValue":e=>c.value=e}),a)])})}),ae({},l)}}),Je={class:`text-caption text-medium-emphasis mt-1`},Ye=I({__name:`PushSyncModeCard`,props:{syncMode:{},syncModeDesc:{}},emits:[`update:syncMode`],setup(e,{emit:n}){let r=n;function s(e){e!=null&&r(`update:syncMode`,e)}return(n,r)=>(O(),E(d,{elevation:`0`,border:``,rounded:`lg`,class:`mb-4`},{default:a(()=>[C(o,{class:`text-subtitle-1`},{default:a(()=>[...r[0]||=[k(`同步模式`,-1)]]),_:1}),C(f,null,{default:a(()=>[C(qe,{"model-value":e.syncMode,inline:``,density:`compact`,"onUpdate:modelValue":s},{default:a(()=>[C(Q,{label:`增量同步`,value:`incremental`}),C(Q,{label:`全量同步`,value:`full`}),C(Q,{label:`校验和同步`,value:`checksum`})]),_:1},8,[`model-value`]),e.syncMode===`full`?(O(),E(Y,{key:0,type:`warning`,density:`compact`,variant:`tonal`,class:`mt-2`},{default:a(()=>[...r[1]||=[k(` 全量同步会删除目标目录中不存在于源目录的文件 `,-1)]]),_:1})):z(``,!0),t(`div`,Je,i(e.syncModeDesc),1)]),_:1})]),_:1}))}}),Xe=I({__name:`PushToolbar`,props:{sourcePath:{},targetPath:{},zipLocked:{type:Boolean},pushing:{type:Boolean}},emits:[`update:sourcePath`,`update:targetPath`,`preview`,`push`],setup(e){return(t,n)=>(O(),E(d,{elevation:`0`,border:``,rounded:`lg`,class:`mb-4 pa-4`},{default:a(()=>[C(K,{align:`center`,dense:``},{default:a(()=>[C(G,{cols:`12`,sm:`4`},{default:a(()=>[C(L,{"model-value":e.sourcePath,label:`推送源路径`,variant:`outlined`,density:`compact`,"prepend-inner-icon":`mdi-folder`,disabled:e.zipLocked,hint:e.zipLocked?`已使用 ZIP 解压目录作为源路径`:void 0,"persistent-hint":``,"onUpdate:modelValue":n[0]||=e=>t.$emit(`update:sourcePath`,e)},null,8,[`model-value`,`disabled`,`hint`])]),_:1}),C(G,{cols:`12`,sm:`4`},{default:a(()=>[C(L,{"model-value":e.targetPath,label:`目标路径`,variant:`outlined`,density:`compact`,"prepend-inner-icon":`mdi-folder-marker`,"onUpdate:modelValue":n[1]||=e=>t.$emit(`update:targetPath`,e)},null,8,[`model-value`])]),_:1}),C(G,{cols:`12`,sm:`4`,class:`d-flex ga-2 justify-end`},{default:a(()=>[C(h,{size:`small`,variant:`tonal`,"prepend-icon":`mdi-eye`,onClick:n[2]||=e=>t.$emit(`preview`)},{default:a(()=>[...n[4]||=[k(`预览`,-1)]]),_:1}),C(h,{size:`small`,color:`primary`,variant:`flat`,"prepend-icon":`mdi-upload`,loading:e.pushing,onClick:n[3]||=e=>t.$emit(`push`)},{default:a(()=>[...n[5]||=[k(` 推送 `,-1)]]),_:1},8,[`loading`])]),_:1})]),_:1})]),_:1}))}}),Ze={key:0},Qe={key:1,class:`d-flex align-center`},$e=I({__name:`PushZipUpload`,props:{uploadedZip:{},isDragging:{type:Boolean},zipUploading:{type:Boolean}},emits:[`dragover`,`dragleave`,`drop`,`file-select`,`clear`],setup(e){let n=r(null);return(r,s)=>(O(),E(d,{elevation:`0`,border:``,rounded:`lg`,class:`mb-4`},{default:a(()=>[C(o,{class:`text-subtitle-1`},{default:a(()=>[...s[6]||=[k(`源文件`,-1)]]),_:1}),C(f,null,{default:a(()=>[e.uploadedZip?(O(),P(`div`,Qe,[C(y,{class:`mr-2`},{default:a(()=>[...s[10]||=[k(`mdi-folder-zip`,-1)]]),_:1}),t(`span`,null,i(e.uploadedZip.name)+` (`+i(e.uploadedZip.fileCount)+` 个文件, `+i(c(Z)(e.uploadedZip.size))+`)`,1),C(q),C(h,{size:`small`,variant:`text`,color:`error`,onClick:s[5]||=e=>r.$emit(`clear`)},{default:a(()=>[...s[11]||=[k(`清除`,-1)]]),_:1})])):(O(),P(`div`,Ze,[t(`div`,{class:_([`border-dashed border rounded pa-6 text-center cursor-pointer`,{"border-primary bg-primary-lighten-5":e.isDragging}]),onDragover:s[0]||=x(e=>r.$emit(`dragover`),[`prevent`]),onDragleave:s[1]||=e=>r.$emit(`dragleave`),onDrop:s[2]||=x(e=>r.$emit(`drop`,e),[`prevent`]),onClick:s[3]||=e=>n.value?.click()},[C(y,{size:`48`,color:`grey`},{default:a(()=>[...s[7]||=[k(`mdi-cloud-upload-outline`,-1)]]),_:1}),s[8]||=t(`div`,{class:`text-body-2 mt-2`},`拖拽 ZIP 文件到此处,或点击选择`,-1),s[9]||=t(`div`,{class:`text-caption text-medium-emphasis`},`支持 .zip 格式`,-1)],34),t(`input`,{ref_key:`zipInputRef`,ref:n,type:`file`,accept:`.zip`,hidden:``,onChange:s[4]||=e=>r.$emit(`file-select`,e)},null,544)])),e.zipUploading?(O(),E(l,{key:2,indeterminate:``,class:`mt-2`})):z(``,!0)]),_:1})]),_:1}))}}),$=[`success`,`failed`,`cancelled`];function et(){let e=H(),t=r(``),n=r(``),i=r(`incremental`),a=r(!1),o=r(null),s=r(!1),c=m(()=>{switch(i.value){case`incremental`:return`仅传输新增或修改的文件`;case`full`:return`使目标目录与源目录完全一致,会删除不存在于源的文件`;case`checksum`:return`通过文件内容校验和判断是否需要传输`;default:return``}});function l(){return o.value?.sourcePath||t.value}function u(t){return l()?n.value.trim()?t===0?(e(`请选择至少一台服务器`,`warning`),!1):!0:(e(`请填写目标路径`,`warning`),!1):(e(`请选择源路径或上传 ZIP 文件`,`warning`),!1)}async function d(e){a.value=!1;let t=e.dataTransfer?.files[0];t?.name.endsWith(`.zip`)&&await p(t)}function f(e){let t=e.target.files?.[0];t&&p(t)}async function p(t){s.value=!0;try{let n=new FormData;n.append(`file`,t);let r=await v.upload(`/sync/upload-zip`,n);o.value={name:t.name,sourcePath:r.source_path,fileCount:r.file_count,size:r.size},e(`ZIP 上传成功`)}catch(t){e(t instanceof Error?t.message:`上传失败`,`error`)}finally{s.value=!1}}function h(){o.value=null}return{sourcePath:t,targetPath:n,syncMode:i,syncModeDesc:c,isDragging:a,uploadedZip:o,zipUploading:s,effectiveSourcePath:l,validateForm:u,handleZipDrop:d,handleZipSelect:f,clearZipUpload:h}}function tt(e){let t=r([]),n=r(!1),i=r(``),a=r(new Set),o=null;async function s(){n.value=!0;try{t.value=(await v.get(`/servers/`,{per_page:200})).items||[]}catch{t.value=[]}finally{n.value=!1}}function c(e){l(),o=setInterval(()=>{e()||s()},6e4)}function l(){o&&=(clearInterval(o),null)}let u=m(()=>{if(!i.value)return t.value;let e=i.value.toLowerCase();return t.value.filter(t=>t.name.toLowerCase().includes(e)||(t.domain||``).toLowerCase().includes(e))}),d=m(()=>{let e=u.value;return e.length>0&&e.every(e=>a.value.has(e.id))}),f=m(()=>{let e={};for(let t of u.value){let n=t.category||`未分类`;e[n]||(e[n]=[]),e[n].push(t)}return Object.entries(e).map(([e,t])=>({category:e,servers:t}))});function p(e){let t=f.value.find(t=>t.category===e);return!t||t.servers.length===0?!1:t.servers.every(e=>a.value.has(e.id))}function h(e){let t=f.value.find(t=>t.category===e);if(!t)return;let n=new Set(a.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);a.value=n}function g(e){let t=new Set(a.value);t.has(e)?t.delete(e):t.add(e),a.value=t}function _(){let e=u.value,t=e.length>0&&e.every(e=>a.value.has(e.id)),n=new Set(a.value);for(let r of e)t?n.delete(r.id):n.add(r.id);a.value=n}return{servers:t,serversLoading:n,serverSearch:i,selectedIds:a,pushStatus:e,filteredServers:u,selectAll:d,serversByCategory:f,loadServers:s,startAutoRefresh:c,stopAutoRefresh:l,isCategoryAllSelected:p,toggleCategory:h,toggleServer:g,toggleAll:_}}function nt(){return crypto.randomUUID().replace(/-/g,``).slice(0,12)}function rt(e,t,n){let i=H(),a=p(),o=r(!1),s=r(!1),c=r([]),l=r(``),u=r(null),d=[],f=m(()=>c.value.filter(e=>$.includes(e.status)).length),h=m(()=>{let e=c.value.length;return e?Math.round(f.value/e*100):0});function g(){d.forEach(e=>clearTimeout(e)),d.length=0}function _(){let e=c.value.length;if(!e||!o.value||c.value.filter(e=>$.includes(e.status)).lengthe.status===`failed`).length,r=c.value.filter(e=>e.status===`cancelled`).length,a=c.value.filter(e=>e.status===`success`).length;i(`推送完成:${a} 成功,${t} 失败${r?`,${r} 取消`:``}`)}function y(e){if(e.type!==`sync_progress`||e.batch_id!==l.value||e.server_id==null)return;let n=c.value.findIndex(t=>t.id===e.server_id);if(n===-1)return;let r=c.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=X(e.error_message)||`失败`,t.pushStatus.value[e.server_id]=`失败`):i===`cancelled`&&(r.status=`cancelled`,r.detail=X(e.error_message)||`已取消`,t.pushStatus.value[e.server_id]=`已取消`);_()}function b(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=c.value.findIndex(e=>e.id===n);if(i===-1)continue;let a=c.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=X(r.error_message)||`失败`,t.pushStatus.value[n]=`失败`):o===`cancelled`&&(a.status=`cancelled`,a.detail=X(r.error_message)||`已取消`,t.pushStatus.value[n]=`已取消`)}_()}}function x(){if(!a.token)return Promise.reject(Error(`未登录,无法连接推送进度`));S();let e=pe(`/ws/sync`,{token:a.token}),r=new WebSocket(e);return new Promise((e,s)=>{r.onopen=()=>e(),r.onerror=()=>s(Error(`推送进度 WebSocket 连接失败`)),r.onmessage=e=>{if(e.data!==`pong`)try{let t=JSON.parse(e.data);if(t.type===`ping`){r.send(`pong`);return}y(t)}catch{}},r.onclose=e=>{if(u.value=null,e.code===4001||e.code===4401){a.forceLogout();return}e.code!==1e3&&o.value&&(c.value.forEach(e=>{(e.status===`pending`||e.status===`running`)&&(e.status=`failed`,e.detail=`连接中断`,t.pushStatus.value[e.id]=`失败`)}),o.value=!1,i(`推送进度连接中断,部分服务器状态未知`,`warning`),n())},u.value=r})}function S(){u.value&&=(u.value.close(1e3),null)}async function C(){if(l.value){s.value=!0;try{await v.post(`/sync/cancel`,{batch_id:l.value}),c.value.forEach(e=>{(e.status===`pending`||e.status===`running`)&&(e.status=`cancelled`,e.detail=`已取消`,t.pushStatus.value[e.id]=`已取消`)}),o.value=!1,S(),n(),i(`推送已取消`)}catch(e){i(e instanceof Error?e.message:`取消失败`,`error`)}finally{s.value=!1}}}async function w(){if(o.value||!e.validateForm(t.selectedIds.value.size))return;g(),S(),l.value=``,t.pushStatus.value={};let r=[...t.selectedIds.value];c.value=r.map(e=>({id:e,name:t.servers.value.find(t=>t.id===e)?.name||`#${e}`,status:`pending`})),o.value=!0,l.value=nt();try{await x();let t=await v.post(`/sync/files`,{source_path:e.effectiveSourcePath(),target_path:e.targetPath.value,server_ids:r,sync_mode:e.syncMode.value,batch_id:l.value});t.batch_id&&t.batch_id!==l.value&&(l.value=t.batch_id),b(t)}catch(e){S();let t=e instanceof Error?e.message:`推送请求失败`;c.value.forEach(e=>{e.status=`failed`,e.detail=t}),o.value=!1,i(t,`error`),n();return}let a=setTimeout(()=>{o.value&&(c.value.forEach(e=>{(e.status===`pending`||e.status===`running`)&&(e.status=`failed`,e.detail=`等待超时`,t.pushStatus.value[e.id]=`失败`)}),o.value=!1,S(),n(),i(`推送超时,${f.value}/${c.value.length} 台已有结果`,`warning`))},3e5);d.push(a)}function T(){S(),g()}return{pushing:o,cancelling:s,wsProgressItems:c,pushBatchId:l,doneCount:f,totalProgress:h,doPush:w,cancelPush:C,dispose:T}}function it(e,t){let n=r(!1),i=r([]),a=r(!1),o=r(0),s=r(0),c=m(()=>o.value>30),l=m(()=>i.value.filter(e=>e.error).length);async function u(t,n){try{let r=await v.post(`/sync/preview`,{source_path:e.effectiveSourcePath(),target_path:e.targetPath.value,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 d(){if(!e.validateForm(t.selectedIds.value.size))return;let r=[...t.selectedIds.value];o.value=r.length,s.value=0,n.value=!0,a.value=!0,i.value=[];let c=r.map(e=>({id:e,name:t.servers.value.find(t=>t.id===e)?.name||`#${e}`}));for(let e=0;eu(e.id,e.name)));i.value=[...i.value,...n],s.value=i.value.length}a.value=!1}function f(){n.value=!1}function p(e){n.value=!1,e()}return{showPreview:n,previewResults:i,previewLoading:a,previewTotal:o,previewDone:s,previewLargeBatch:c,previewWarnThreshold:30,previewErrorCount:l,doPreview:d,closePreview:f,confirmAndPush:p}}var at=[{label:`成功`,value:`success`},{label:`失败`,value:`failed`},{label:`进行中`,value:`running`},{label:`已取消`,value:`cancelled`}],ot=[{label:`增量`,value:`incremental`},{label:`全量`,value:`full`},{label:`校验和`,value:`checksum`}],st=[{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:`error_message`,width:200},{title:`操作`,key:`actions`,width:88,sortable:!1}];function ct(e,t){let n=H(),i=r([]),a=r(0),o=r(!1),s=r(1),c=r(null),l=r(null),u=r(null),d=r(!1),f=r(!1),p=r(!1),h=r(null),g=r(null),_=m(()=>t.servers.value.map(e=>({title:e.name,value:e.id})));function y(){s.value=1,b()}async function b(){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 v.get(`/servers/logs`,e);i.value=t.items||[],a.value=t.total||0}catch{i.value=[],a.value=0}finally{o.value=!1}}async function x(){d.value=!0;try{let e=(await v.post(`/sync/reconcile-stale-logs`,{max_age_minutes:120})).reconciled??0;n(e>0?`已订正 ${e} 条卡住的推送记录`:`没有需要订正的记录`),await b()}catch(e){n(e instanceof Error?e.message:`订正失败`,`error`)}finally{d.value=!1}}async function S(t){g.value=t,h.value=null,f.value=!0,p.value=!0;try{h.value=await v.post(`/sync/diagnose`,{server_id:t.server_id,target_path:t.target_path||e.targetPath.value||void 0})}catch(e){n(e instanceof Error?e.message:`诊断失败`,`error`),f.value=!1}finally{p.value=!1}}function C(){f.value=!1}return{logs:i,logTotal:a,logLoading:o,logPage:s,logStatusFilter:c,logSyncModeFilter:l,logServerFilter:u,reconcilingLogs:d,logStatusOptions:at,logSyncModeOptions:ot,logHeaders:st,logServerOptions:_,showDiagnose:f,diagnoseLoading:p,diagnoseResult:h,diagnoseTarget:g,onLogFilterChange:y,loadLogs:b,reconcileStaleLogs:x,openDiagnose:S,closeDiagnose:C}}function lt(){let e=et(),t=tt(r({})),n=ct(e,t),i=rt(e,t,()=>n.loadLogs()),a=it(e,t);function o(){a.confirmAndPush(()=>i.doPush())}return ne(()=>{t.loadServers(),n.loadLogs(),t.startAutoRefresh(()=>i.pushing.value)}),te(()=>{i.dispose(),t.stopAutoRefresh()}),{form:j(e),servers:j(t),progress:j(i),preview:j(a),logs:j(n),onConfirmAndPush:o}}var ut=I({__name:`PushPage`,setup(e){let{form:t,servers:n,progress:r,preview:i,logs:o,onConfirmAndPush:s}=lt();return(e,l)=>(O(),E(ue,{fluid:``,class:`pa-6`},{default:a(()=>[C($e,{"uploaded-zip":c(t).uploadedZip,"is-dragging":c(t).isDragging,"zip-uploading":c(t).zipUploading,onDragover:l[0]||=e=>c(t).isDragging=!0,onDragleave:l[1]||=e=>c(t).isDragging=!1,onDrop:c(t).handleZipDrop,onFileSelect:c(t).handleZipSelect,onClear:c(t).clearZipUpload},null,8,[`uploaded-zip`,`is-dragging`,`zip-uploading`,`onDrop`,`onFileSelect`,`onClear`]),C(Xe,{"source-path":c(t).sourcePath,"onUpdate:sourcePath":l[2]||=e=>c(t).sourcePath=e,"target-path":c(t).targetPath,"onUpdate:targetPath":l[3]||=e=>c(t).targetPath=e,"zip-locked":!!c(t).uploadedZip,pushing:c(r).pushing,onPreview:c(i).doPreview,onPush:c(r).doPush},null,8,[`source-path`,`target-path`,`zip-locked`,`pushing`,`onPreview`,`onPush`]),C(We,{"select-all":c(n).selectAll,"server-search":c(n).serverSearch,"onUpdate:serverSearch":l[4]||=e=>c(n).serverSearch=e,"servers-loading":c(n).serversLoading,"servers-by-category":c(n).serversByCategory,"selected-ids":c(n).selectedIds,"push-status":c(n).pushStatus,"is-category-all-selected":c(n).isCategoryAllSelected,onToggleAll:c(n).toggleAll,onRefresh:c(n).loadServers,onToggleCategory:c(n).toggleCategory,onToggleServer:c(n).toggleServer},null,8,[`select-all`,`server-search`,`servers-loading`,`servers-by-category`,`selected-ids`,`push-status`,`is-category-all-selected`,`onToggleAll`,`onRefresh`,`onToggleCategory`,`onToggleServer`]),C(Ye,{"sync-mode":c(t).syncMode,"onUpdate:syncMode":l[5]||=e=>c(t).syncMode=e,"sync-mode-desc":c(t).syncModeDesc},null,8,[`sync-mode`,`sync-mode-desc`]),C(Ie,{items:c(r).wsProgressItems,"batch-id":c(r).pushBatchId,pushing:c(r).pushing,cancelling:c(r).cancelling,"done-count":c(r).doneCount,"total-progress":c(r).totalProgress,onCancel:c(r).cancelPush},null,8,[`items`,`batch-id`,`pushing`,`cancelling`,`done-count`,`total-progress`,`onCancel`]),C(Pe,{modelValue:c(i).showPreview,"onUpdate:modelValue":l[6]||=e=>c(i).showPreview=e,loading:c(i).previewLoading,results:c(i).previewResults,"selected-count":c(n).selectedIds.size,"preview-done":c(i).previewDone,"preview-total":c(i).previewTotal,"large-batch":c(i).previewLargeBatch,"warn-threshold":c(i).previewWarnThreshold,"error-count":c(i).previewErrorCount,"sync-mode":c(t).syncMode,onConfirmPush:c(s)},null,8,[`modelValue`,`loading`,`results`,`selected-count`,`preview-done`,`preview-total`,`large-batch`,`warn-threshold`,`error-count`,`sync-mode`,`onConfirmPush`]),C(Ce,{modelValue:c(o).showDiagnose,"onUpdate:modelValue":l[7]||=e=>c(o).showDiagnose=e,loading:c(o).diagnoseLoading,result:c(o).diagnoseResult,"target-name":c(o).diagnoseTarget?.server_name??void 0},null,8,[`modelValue`,`loading`,`result`,`target-name`]),C(Oe,{items:c(o).logs,headers:c(o).logHeaders,total:c(o).logTotal,loading:c(o).logLoading,page:c(o).logPage,"onUpdate:page":l[8]||=e=>c(o).logPage=e,"status-filter":c(o).logStatusFilter,"onUpdate:statusFilter":l[9]||=e=>c(o).logStatusFilter=e,"sync-mode-filter":c(o).logSyncModeFilter,"onUpdate:syncModeFilter":l[10]||=e=>c(o).logSyncModeFilter=e,"server-filter":c(o).logServerFilter,"onUpdate:serverFilter":l[11]||=e=>c(o).logServerFilter=e,"status-options":c(o).logStatusOptions,"sync-mode-options":c(o).logSyncModeOptions,"server-options":c(o).logServerOptions,reconciling:c(o).reconcilingLogs,onFilterChange:c(o).onLogFilterChange,onPageChange:c(o).loadLogs,onReconcile:c(o).reconcileStaleLogs,onDiagnose:c(o).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{ut as default};