Files
Nexus/web/app/assets/PushPage-hbK-Hf1a.js
T
Nexus Agent dfb0ea2d8f fix(frontend): 脚本库与推送调度对齐设计文档
修复 ScriptsPage 执行契约(script_id/command、历史过滤、长任务/凭据)及 SchedulesPage 缺失能力(target_path、next_run、push/script、cron/once、sync_mode);后端补迁移与 schedule_runner 传参。
2026-06-08 02:39:18 +08:00

1 line
53 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-CynA26OW.js";import{$n as t,Ar as n,F as r,Ft as i,I as a,L as o,Lr as s,M as c,N as l,P as u,Sr as d,Tn as f,Vr as p,Xn as m,Y as h,Yn as g,Z as _,Zn as v,ar as y,en as b,er as x,gr as S,h as C,hr as w,ir as ee,jr as T,k as E,ln as D,mr as O,nn as te,nr as k,o as A,or as j,pn as M,rn as N,rr as P,s as ne,sr as F,t as I,tr as L,ur as re,v as ie,vr as R,w as ae,wr as z,xr as oe,z as B,zn as se,zr as V,zt as H}from"./index-BihgjXCy.js";import{a as ce,i as le,n as U,o as W,r as ue,t as de}from"./VContainer-V_R05OUP.js";import{t as G}from"./VChip-FKNgTWw3.js";import{f as fe,t as K}from"./VSelect-CGF0mOJJ.js";import{t as pe}from"./VCheckbox-C4OWnQkf.js";import{t as me}from"./VDataTableServer-Pl72x6lf.js";import{n as q,t as he}from"./VRow-D6NnUZV_.js";import{t as J}from"./VSpacer-2YW4-MQQ.js";import{t as Y}from"./VDialog-C6lmIorM.js";import{t as ge}from"./_plugin-vue_export-helper-BDNMzG2s.js";import{t as X}from"./VAlert-Dm_0fgK_.js";import{t as _e}from"./wsUrl-CqmqkTTE.js";var ve=[[/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,`接收端`]],ye=/[\u4e00-\u9fff\u3400-\u4dbf]/g;function be(e){let t=e.match(ye);if(!t?.length)return!1;let n=e.replace(/\s+/g,``);return n.length?t.length/n.length>=.2:!1}function Z(e){if(e==null)return``;let t=e.trim();if(!t)return``;if(be(t))return e;let n=t;for(let[e,t]of ve)n=n.replace(e,t);return n}function Q(e){return e<1024?`${e} B`:e<1048576?`${(e/1024).toFixed(1)} KB`:`${(e/1048576).toFixed(1)} MB`}function xe(e){if(!e)return`—`;let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString(`zh-CN`,{hour12:!1})}function Se(e){switch(e){case`success`:return`成功`;case`failed`:return`失败`;case`running`:return`进行中`;case`cancelled`:return`已取消`;default:return e}}function Ce(e){switch(e){case`success`:return`success`;case`failed`:return`error`;case`cancelled`:return`grey`;case`running`:return`info`;default:return`warning`}}function we(e){switch(e){case`incremental`:return`增量`;case`full`:return`全量`;case`checksum`:return`校验和`;case`overwrite`:return`覆盖`;default:return e||`—`}}function Te(e){return e===`成功`?`success`:e===`失败`?`error`:e===`已取消`?`grey`:`warning`}function Ee(e){return e?`success`:`error`}var De={key:0},Oe={style:{width:`44px`}},ke={key:0},Ae={colspan:`4`},je={key:1},Me=[`onClick`],Ne={class:`text-end text-caption text-medium-emphasis`},Pe={class:`text-end`},Fe={class:`mb-2`},Ie={class:`delete-target-list pl-4 mb-0`},Le={key:0},Re=ge(F({__name:`PushStagingPanel`,props:{rootPath:{},relativePath:{},entries:{},loading:{type:Boolean},selectedCount:{},allSelected:{type:Boolean},someSelected:{type:Boolean},isSelected:{type:Function},renameOpen:{type:Boolean},renameValue:{},renameLoading:{type:Boolean},deleteOpen:{type:Boolean},deleteTargets:{},deleteLoading:{type:Boolean}},emits:[`refresh`,`go-root`,`open-dir`,`preview`,`rename`,`delete`,`batch-delete`,`toggle-select`,`toggle-select-all`,`confirm-rename`,`confirm-delete`,`update:renameOpen`,`update:renameValue`,`update:deleteOpen`],setup(t){return(n,i)=>(S(),P(v,null,[j(l,{elevation:`0`,border:``,rounded:`lg`,class:`mb-4`},{default:z(()=>[j(r,{class:`d-flex align-center text-subtitle-1 flex-wrap ga-2`},{default:z(()=>[i[14]||=y(` 暂存文件 `,-1),j(J),t.selectedCount>0?(S(),L(B,{key:0,size:`small`,variant:`tonal`,color:`error`,"prepend-icon":`mdi-delete`,loading:t.deleteLoading,onClick:i[0]||=e=>n.$emit(`batch-delete`)},{default:z(()=>[y(` 删除选中 (`+p(t.selectedCount)+`) `,1)]),_:1},8,[`loading`])):k(``,!0),j(B,{size:`small`,variant:`text`,"prepend-icon":`mdi-refresh`,loading:t.loading,onClick:i[1]||=e=>n.$emit(`refresh`)},{default:z(()=>[...i[13]||=[y(` 刷新 `,-1)]]),_:1},8,[`loading`])]),_:1}),j(a,{class:`text-caption pb-2`},{default:z(()=>[y(p(t.rootPath)+` `,1),t.relativePath?(S(),P(`span`,De,` / `+p(t.relativePath),1)):k(``,!0)]),_:1}),j(c),j(u,{class:`pa-0`},{default:z(()=>[t.loading?(S(),L(h,{key:0,indeterminate:``})):(S(),L(e,{key:1,density:`compact`,hover:``},{default:z(()=>[x(`thead`,null,[x(`tr`,null,[x(`th`,Oe,[j(fe,{"model-value":t.allSelected,indeterminate:t.someSelected,disabled:!t.entries.length,density:`compact`,"hide-details":``,"onUpdate:modelValue":i[2]||=e=>n.$emit(`toggle-select-all`,e)},null,8,[`model-value`,`indeterminate`,`disabled`])]),i[15]||=x(`th`,null,`名称`,-1),i[16]||=x(`th`,{class:`text-end`,style:{width:`100px`}},`大小`,-1),i[17]||=x(`th`,{class:`text-end`,style:{width:`160px`}},`操作`,-1)])]),x(`tbody`,null,[t.relativePath?(S(),P(`tr`,ke,[x(`td`,Ae,[j(B,{size:`small`,variant:`text`,"prepend-icon":`mdi-arrow-up`,onClick:i[3]||=e=>n.$emit(`go-root`)},{default:z(()=>[...i[18]||=[y(` 返回根目录 `,-1)]]),_:1})])])):k(``,!0),t.entries.length?k(``,!0):(S(),P(`tr`,je,[...i[19]||=[x(`td`,{colspan:`4`,class:`text-medium-emphasis text-center py-4`},`目录为空`,-1)]])),(S(!0),P(v,null,R(t.entries,e=>(S(),P(`tr`,{key:e.name},[x(`td`,{onClick:i[4]||=m(()=>{},[`stop`])},[j(fe,{"model-value":t.isSelected(e.name),density:`compact`,"hide-details":``,"onUpdate:modelValue":t=>n.$emit(`toggle-select`,e.name,t)},null,8,[`model-value`,`onUpdate:modelValue`])]),x(`td`,null,[x(`div`,{class:V([`d-flex align-center`,{"cursor-pointer":e.is_dir}]),onClick:t=>e.is_dir?n.$emit(`open-dir`,e):void 0},[j(_,{size:`small`,class:`mr-2`,color:e.is_dir?`primary`:void 0},{default:z(()=>[y(p(e.is_dir?`mdi-folder`:`mdi-file-outline`),1)]),_:2},1032,[`color`]),x(`span`,null,p(e.name),1)],10,Me)]),x(`td`,Ne,p(e.is_dir?`—`:s(Q)(e.size)),1),x(`td`,Pe,[e.is_dir?k(``,!0):(S(),L(B,{key:0,size:`x-small`,variant:`text`,onClick:t=>n.$emit(`preview`,e)},{default:z(()=>[...i[20]||=[y(` 预览 `,-1)]]),_:1},8,[`onClick`])),j(B,{size:`x-small`,variant:`text`,onClick:t=>n.$emit(`rename`,e)},{default:z(()=>[...i[21]||=[y(`重命名`,-1)]]),_:1},8,[`onClick`]),j(B,{size:`x-small`,variant:`text`,color:`error`,onClick:t=>n.$emit(`delete`,e)},{default:z(()=>[...i[22]||=[y(`删除`,-1)]]),_:1},8,[`onClick`])])]))),128))])]),_:1}))]),_:1})]),_:1}),j(Y,{"model-value":t.renameOpen,"max-width":`420`,"onUpdate:modelValue":i[9]||=e=>n.$emit(`update:renameOpen`,e)},{default:z(()=>[j(l,{border:``},{default:z(()=>[j(r,null,{default:z(()=>[...i[23]||=[y(`重命名`,-1)]]),_:1}),j(u,null,{default:z(()=>[j(I,{"model-value":t.renameValue,label:`新名称`,variant:`outlined`,density:`compact`,"hide-details":``,autofocus:``,"onUpdate:modelValue":i[5]||=e=>n.$emit(`update:renameValue`,e),onKeydown:i[6]||=g(m(e=>n.$emit(`confirm-rename`),[`prevent`]),[`enter`])},null,8,[`model-value`])]),_:1}),j(o,null,{default:z(()=>[j(J),j(B,{variant:`text`,onClick:i[7]||=e=>n.$emit(`update:renameOpen`,!1)},{default:z(()=>[...i[24]||=[y(`取消`,-1)]]),_:1}),j(B,{color:`primary`,variant:`flat`,loading:t.renameLoading,onClick:i[8]||=e=>n.$emit(`confirm-rename`)},{default:z(()=>[...i[25]||=[y(`确定`,-1)]]),_:1},8,[`loading`])]),_:1})]),_:1})]),_:1},8,[`model-value`]),j(Y,{"model-value":t.deleteOpen,"max-width":`480`,"onUpdate:modelValue":i[12]||=e=>n.$emit(`update:deleteOpen`,e)},{default:z(()=>[j(l,{border:``},{default:z(()=>[j(r,null,{default:z(()=>[...i[26]||=[y(`确认删除`,-1)]]),_:1}),j(u,null,{default:z(()=>[t.deleteTargets.length===1?(S(),P(v,{key:0},[y(` 确定删除「`+p(t.deleteTargets[0].name)+`」?`+p(t.deleteTargets[0].is_dir?`将删除整个目录及其内容。`:``),1)],64)):(S(),P(v,{key:1},[x(`div`,Fe,`确定删除以下 `+p(t.deleteTargets.length)+` 项?`,1),x(`ul`,Ie,[(S(!0),P(v,null,R(t.deleteTargets.slice(0,8),e=>(S(),P(`li`,{key:e.name},p(e.name)+p(e.is_dir?`(目录)`:``),1))),128)),t.deleteTargets.length>8?(S(),P(`li`,Le,`… 等共 `+p(t.deleteTargets.length)+` 项`,1)):k(``,!0)])],64))]),_:1}),j(o,null,{default:z(()=>[j(J),j(B,{variant:`text`,onClick:i[10]||=e=>n.$emit(`update:deleteOpen`,!1)},{default:z(()=>[...i[27]||=[y(`取消`,-1)]]),_:1}),j(B,{color:`error`,variant:`flat`,loading:t.deleteLoading,onClick:i[11]||=e=>n.$emit(`confirm-delete`)},{default:z(()=>[y(p(t.deleteTargets.length>1?`删除 ${t.deleteTargets.length} 项`:`删除`),1)]),_:1},8,[`loading`])]),_:1})]),_:1})]),_:1},8,[`model-value`])],64))}}),[[`__scopeId`,`data-v-5939ddcd`]]),ze={key:0,class:`text-caption text-medium-emphasis ml-2`},Be={class:`staging-preview-body`},Ve=ge(F({__name:`PushStagingPreviewDialog`,props:{modelValue:{type:Boolean},loading:{type:Boolean},result:{}},emits:[`update:modelValue`],setup(e){let n=e,i=t(()=>{let e=n.result;if(!e?.content_base64)return``;try{let t=atob(e.content_base64);return e.encoding_hint===`text`?t:e.content_base64}catch{return e.content_base64}});return(t,n)=>(S(),L(Y,{"model-value":e.modelValue,"max-width":`720`,"onUpdate:modelValue":n[1]||=e=>t.$emit(`update:modelValue`,e)},{default:z(()=>[j(l,{border:``},{default:z(()=>[j(r,{class:`text-subtitle-1`},{default:z(()=>[y(p(e.result?.name??`文件预览`)+` `,1),e.result?(S(),P(`span`,ze,` (`+p(s(Q)(e.result.size))+`) `,1)):k(``,!0)]),_:1}),j(u,null,{default:z(()=>[e.loading?(S(),L(h,{key:0,indeterminate:``,class:`mb-3`})):e.result?(S(),P(v,{key:1},[e.result.truncated?(S(),L(X,{key:0,type:`info`,density:`compact`,variant:`tonal`,class:`mb-2`},{default:z(()=>[...n[2]||=[y(` 仅显示前 4KB 内容 `,-1)]]),_:1})):k(``,!0),e.result.encoding_hint===`text`?k(``,!0):(S(),L(X,{key:1,type:`warning`,density:`compact`,variant:`tonal`,class:`mb-2`},{default:z(()=>[...n[3]||=[y(` 二进制文件,以下为 Base64 片段 `,-1)]]),_:1})),x(`pre`,Be,p(i.value),1)],64)):k(``,!0)]),_:1}),j(o,null,{default:z(()=>[j(J),j(B,{variant:`text`,onClick:n[0]||=e=>t.$emit(`update:modelValue`,!1)},{default:z(()=>[...n[4]||=[y(`关闭`,-1)]]),_:1})]),_:1})]),_:1})]),_:1},8,[`model-value`]))}}),[[`__scopeId`,`data-v-adb4800a`]]),He=F({__name:`PushDiagnoseDialog`,props:{modelValue:{type:Boolean},loading:{type:Boolean},result:{},targetName:{}},emits:[`update:modelValue`],setup(e){return(t,n)=>(S(),L(Y,{"model-value":e.modelValue,"max-width":`520`,"onUpdate:modelValue":n[1]||=e=>t.$emit(`update:modelValue`,e)},{default:z(()=>[j(l,{border:``},{default:z(()=>[j(r,null,{default:z(()=>[y(`推送失败诊断 — `+p(e.targetName),1)]),_:1}),j(u,null,{default:z(()=>[e.loading?(S(),L(h,{key:0,indeterminate:``,class:`mb-3`})):e.result?(S(),P(v,{key:1},[j(ae,{density:`compact`},{default:z(()=>[j(E,{title:`SSH 连接`},{append:z(()=>[j(_,{color:e.result.ssh_ok?`success`:`error`},{default:z(()=>[y(p(e.result.ssh_ok?`mdi-check`:`mdi-close`),1)]),_:1},8,[`color`])]),_:1}),e.result.disk_avail?(S(),L(E,{key:0,title:`磁盘可用: ${e.result.disk_avail}`},null,8,[`title`])):k(``,!0),e.result.disk_used_pct==null?k(``,!0):(S(),L(E,{key:1,title:`磁盘使用率: ${e.result.disk_used_pct}%`},null,8,[`title`])),j(E,{title:`目标路径存在`},{append:z(()=>[j(_,{color:e.result.path_exists?`success`:`error`},{default:z(()=>[y(p(e.result.path_exists?`mdi-check`:`mdi-close`),1)]),_:1},8,[`color`])]),_:1}),e.result.path_perms?(S(),L(E,{key:2,subtitle:e.result.path_perms,title:`权限`},null,8,[`subtitle`])):k(``,!0),j(E,{title:`目标路径可写`},{append:z(()=>[j(_,{color:e.result.path_writable?`success`:`error`},{default:z(()=>[y(p(e.result.path_writable?`mdi-check`:`mdi-close`),1)]),_:1},8,[`color`])]),_:1})]),_:1}),(S(!0),P(v,null,R(e.result.errors,(e,t)=>(S(),L(X,{key:t,type:`error`,density:`compact`,variant:`tonal`,class:`mt-2`},{default:z(()=>[y(p(s(Z)(e)),1)]),_:2},1024))),128))],64)):k(``,!0)]),_:1}),j(o,null,{default:z(()=>[j(J),j(B,{variant:`text`,onClick:n[0]||=e=>t.$emit(`update:modelValue`,!1)},{default:z(()=>[...n[2]||=[y(`关闭`,-1)]]),_:1})]),_:1})]),_:1})]),_:1},8,[`model-value`]))}}),Ue={class:`text-caption`},We={class:`text-caption text-medium-emphasis`},Ge=[`title`],Ke={key:1,class:`text-caption text-medium-emphasis`},qe=F({__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)=>(S(),L(l,{elevation:`0`,border:``,rounded:`lg`},{default:z(()=>[j(r,{class:`d-flex flex-wrap align-center ga-2`},{default:z(()=>[n[6]||=x(`span`,null,`推送历史`,-1),j(J),j(K,{"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`]),j(K,{"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`]),j(K,{"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`]),j(B,{size:`small`,variant:`tonal`,"prepend-icon":`mdi-wrench`,loading:e.reconciling,onClick:n[3]||=e=>t.$emit(`reconcile`)},{default:z(()=>[...n[5]||=[y(` 修复卡住记录 `,-1)]]),_:1},8,[`loading`])]),_:1}),j(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":z(({item:e})=>[j(G,{color:s(Ce)(e.status),size:`x-small`,variant:`tonal`,label:``,border:`sm`},{default:z(()=>[y(p(s(Se)(e.status)),1)]),_:2},1032,[`color`])]),"item.sync_mode":z(({item:e})=>[x(`span`,Ue,p(s(we)(e.sync_mode)),1)]),"item.started_at":z(({item:e})=>[x(`span`,We,p(s(xe)(e.started_at)),1)]),"item.error_message":z(({item:e})=>[e.error_message?(S(),P(`span`,{key:0,class:`text-caption text-error text-truncate d-inline-block`,style:{"max-width":`200px`},title:s(Z)(e.error_message)},p(s(Z)(e.error_message)),9,Ge)):(S(),P(`span`,Ke,`—`))]),"item.actions":z(({item:e})=>[e.status===`failed`?(S(),L(B,{key:0,size:`x-small`,variant:`tonal`,"prepend-icon":`mdi-stethoscope`,onClick:n=>t.$emit(`diagnose`,e)},{default:z(()=>[...n[7]||=[y(` 诊断 `,-1)]]),_:1},8,[`onClick`])):k(``,!0)]),"no-data":z(()=>[...n[8]||=[x(`div`,{class:`text-center text-medium-emphasis py-6`},`暂无数据`,-1)]]),_:1},8,[`items`,`headers`,`items-length`,`loading`,`page`])]),_:1}))}}),Je={class:`text-caption text-medium-emphasis`},Ye={key:2,class:`mb-2 text-body-2`},Xe={key:0,class:`text-error text-caption`},Ze={key:1,class:`text-warning text-caption`},Qe={key:2,class:`text-caption text-medium-emphasis`},$e=F({__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,i)=>(S(),L(Y,{"model-value":t.modelValue,"max-width":`800`,"onUpdate:modelValue":i[2]||=e=>n.$emit(`update:modelValue`,e)},{default:z(()=>[j(l,{border:``},{default:z(()=>[j(r,{class:`d-flex align-center`},{default:z(()=>[i[3]||=y(` 推送预览 `,-1),j(J),x(`span`,Je,[t.loading?(S(),P(v,{key:0},[y(p(t.previewDone)+` / `+p(t.previewTotal)+` 台`,1)],64)):(S(),P(v,{key:1},[y(p(t.results.length)+` 台`,1)],64))])]),_:1}),j(u,null,{default:z(()=>[t.loading?(S(),L(h,{key:0,"model-value":t.previewTotal?Math.round(t.previewDone/t.previewTotal*100):0,class:`mb-3`},null,8,[`model-value`])):k(``,!0),t.largeBatch&&!t.loading?(S(),L(X,{key:1,type:`info`,density:`compact`,variant:`tonal`,class:`mb-2`},{default:z(()=>[y(` 已预览 `+p(t.results.length)+` 台服务器(超过 `+p(t.warnThreshold)+` 台时推送耗时可能较长) `,1)]),_:1})):k(``,!0),t.loading?k(``,!0):(S(),P(`div`,Ye,[i[4]||=y(` 将推送到 `,-1),x(`strong`,null,p(t.selectedCount),1),i[5]||=y(` 台服务器 `,-1)])),t.results.length?(S(),L(e,{key:3,density:`compact`},{default:z(()=>[i[6]||=x(`thead`,null,[x(`tr`,null,[x(`th`,null,`服务器`),x(`th`,null,`文件数`),x(`th`,null,`预计传输`),x(`th`,null,`大小`),x(`th`,null,`备注`)])],-1),x(`tbody`,null,[(S(!0),P(v,null,R(t.results,e=>(S(),P(`tr`,{key:e.server_id},[x(`td`,null,p(e.server_name),1),x(`td`,null,p(e.stats?.files_total??`—`),1),x(`td`,null,p(e.stats?.files_transferred??`—`),1),x(`td`,null,p(e.stats?s(Q)(e.stats.transfer_size_bytes??0):`—`),1),x(`td`,null,[e.error?(S(),P(`span`,Xe,p(s(Z)(e.error)),1)):t.syncMode===`full`&&(e.stats?.files_deleted??0)>0?(S(),P(`span`,Ze,`将删除 `+p(e.stats?.files_deleted)+` 个远端文件`,1)):(S(),P(`span`,Qe,`—`))])]))),128))])]),_:1})):k(``,!0),t.errorCount>0&&!t.loading?(S(),L(X,{key:4,type:`warning`,density:`compact`,variant:`tonal`,class:`mt-3`},{default:z(()=>[y(p(t.errorCount)+` 台预览失败,推送时这些服务器可能仍会失败 `,1)]),_:1})):k(``,!0)]),_:1}),j(o,null,{default:z(()=>[j(J),j(B,{variant:`text`,onClick:i[0]||=e=>n.$emit(`update:modelValue`,!1)},{default:z(()=>[...i[7]||=[y(`关闭`,-1)]]),_:1}),j(B,{color:`primary`,variant:`flat`,disabled:t.loading,onClick:i[1]||=e=>n.$emit(`confirm-push`)},{default:z(()=>[...i[8]||=[y(`确认推送`,-1)]]),_:1},8,[`disabled`])]),_:1})]),_:1})]),_:1},8,[`model-value`]))}}),et={key:1,class:`text-caption text-medium-emphasis mb-2`},tt={key:0},nt=F({__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?(S(),L(l,{key:0,class:`mb-4`,elevation:`0`,border:``,rounded:`lg`},{default:z(()=>[j(r,{class:`d-flex align-center text-subtitle-1`},{default:z(()=>[n[3]||=y(` 推送进度 `,-1),j(J),e.failedRetryCount>0&&!e.pushing?(S(),L(B,{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:z(()=>[y(` 重试全部失败 (`+p(e.failedRetryCount)+`) `,1)]),_:1},8,[`loading`])):k(``,!0),e.batchId&&e.items.some(e=>e.status===`running`||e.status===`pending`)&&e.pushing?(S(),L(B,{key:1,size:`small`,variant:`tonal`,color:`error`,class:`mr-2`,loading:e.cancelling,onClick:n[1]||=e=>t.$emit(`cancel`)},{default:z(()=>[...n[2]||=[y(` 取消推送 `,-1)]]),_:1},8,[`loading`])):k(``,!0),j(G,{size:`small`,variant:`tonal`,color:`primary`},{default:z(()=>[y(p(e.items.filter(e=>e.status===`success`).length)+`/`+p(e.items.length)+` 完成 `,1)]),_:1})]),_:1}),j(c),j(u,null,{default:z(()=>[e.pushing||e.totalProgress>0?(S(),L(h,{key:0,"model-value":e.totalProgress,color:`primary`,height:`8`,rounded:``,class:`mb-3`},null,8,[`model-value`])):k(``,!0),e.items.length?(S(),P(`div`,et,[y(p(e.doneCount)+` / `+p(e.items.length)+` 台已结束 `,1),e.items.some(e=>e.status===`failed`)?(S(),P(`span`,tt,` · `+p(e.items.filter(e=>e.status===`failed`).length)+` 失败 `,1)):k(``,!0)])):k(``,!0),j(ae,{density:`compact`},{default:z(()=>[(S(!0),P(v,null,R(e.items,e=>(S(),L(E,{key:e.id,title:e.name},ee({append:z(()=>[e.status===`pending`?(S(),L(_,{key:0,color:`grey`},{default:z(()=>[...n[4]||=[y(`mdi-clock-outline`,-1)]]),_:1})):e.status===`running`?(S(),L(_,{key:1,color:`blue`,class:`mdi-spin`},{default:z(()=>[...n[5]||=[y(`mdi-loading`,-1)]]),_:1})):e.status===`success`?(S(),L(_,{key:2,color:`green`},{default:z(()=>[...n[6]||=[y(`mdi-check-circle`,-1)]]),_:1})):e.status===`cancelled`?(S(),L(_,{key:3,color:`grey`},{default:z(()=>[...n[7]||=[y(`mdi-cancel`,-1)]]),_:1})):(S(),L(_,{key:4,color:`red`},{default:z(()=>[...n[8]||=[y(`mdi-alert-circle`,-1)]]),_:1}))]),_:2},[e.detail?{name:`subtitle`,fn:z(()=>[x(`span`,{class:V(e.status===`failed`?`text-error`:`text-medium-emphasis`)},p(e.detail),3)]),key:`0`}:void 0]),1032,[`title`]))),128))]),_:1})]),_:1})]),_:1})):k(``,!0)}}),rt={key:0,class:`text-center text-medium-emphasis py-6`},it={class:`d-flex align-center px-2 mb-2`},at={class:`text-caption text-medium-emphasis ml-1`},ot={class:`d-flex align-center ga-2`},st={class:`text-body-2 font-weight-medium text-truncate`},ct={class:`text-caption text-medium-emphasis text-truncate`},lt=[`title`],ut={key:0,class:`text-caption mt-1`},dt=F({__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)=>(S(),L(l,{elevation:`0`,border:``,rounded:`lg`,class:`mb-4`},{default:z(()=>[j(r,{class:`d-flex align-center`},{default:z(()=>[j(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`]),j(I,{"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`]),j(B,{icon:`mdi-refresh`,variant:`text`,size:`small`,loading:e.serversLoading,title:`刷新在线状态`,onClick:n[2]||=e=>t.$emit(`refresh`)},null,8,[`loading`])]),_:1}),j(c),j(u,{class:`pa-2`},{default:z(()=>[e.serversByCategory.length===0?(S(),P(`div`,rt,`暂无服务器`)):(S(!0),P(v,{key:1},R(e.serversByCategory,r=>(S(),P(`div`,{key:r.category,class:`mb-4`},[x(`div`,it,[j(B,{size:`x-small`,variant:`text`,color:e.isCategoryAllSelected(r.category)?`primary`:`default`,onClick:e=>t.$emit(`toggle-category`,r.category)},{default:z(()=>[j(_,{size:`16`,class:`mr-1`},{default:z(()=>[y(p(e.isCategoryAllSelected(r.category)?`mdi-checkbox-marked`:`mdi-checkbox-blank-outline`),1)]),_:2},1024),y(` `+p(r.category),1)]),_:2},1032,[`color`,`onClick`]),x(`span`,at,` (`+p(r.servers.filter(t=>e.selectedIds.has(t.id)).length)+`/`+p(r.servers.length)+`) `,1)]),j(he,{dense:``},{default:z(()=>[(S(!0),P(v,null,R(r.servers,r=>(S(),L(q,{key:r.id,cols:`6`,sm:`4`,md:`3`,lg:`2`},{default:z(()=>[j(l,{color:e.selectedIds.has(r.id)?`primary`:void 0,variant:e.selectedIds.has(r.id)?`tonal`:`outlined`,rounded:`lg`,class:`pa-3 cursor-pointer`,onClick:e=>t.$emit(`toggle-server`,r.id)},{default:z(()=>[x(`div`,ot,[j(_,{color:s(Ee)(r.is_online),size:`12`},{default:z(()=>[...n[3]||=[y(`mdi-circle`,-1)]]),_:1},8,[`color`]),x(`span`,st,p(r.name),1)]),x(`div`,ct,p(r.domain),1),x(`div`,{class:`text-caption text-medium-emphasis text-truncate`,title:r.target_path||`未配置目标路径`},` → `+p(r.target_path?.trim()||`未配置`),9,lt),e.pushStatus[r.id]?(S(),P(`div`,ut,[j(G,{color:s(Te)(e.pushStatus[r.id]),size:`x-small`,variant:`tonal`,label:``,border:`sm`},{default:z(()=>[y(p(e.pushStatus[r.id]),1)]),_:2},1032,[`color`])])):k(``,!0)]),_:2},1032,[`color`,`variant`,`onClick`])]),_:2},1024))),128))]),_:2},1024)]))),128))]),_:1})]),_:1}))}}),ft=M({...ue({falseIcon:`$radioOff`,trueIcon:`$radioOn`})},`VRadio`),pt=D()({name:`VRadio`,props:ft(),setup(e,{slots:t}){return N(()=>j(U,re(U.filterProps(e),{class:[`v-radio`,e.class],style:e.style,type:`radio`}),t)),{}}}),mt=M({height:{type:[Number,String],default:`auto`},...se(ne(),[`direction`]),...se(ce(),[`multiple`]),trueIcon:{type:te,default:`$radioOn`},falseIcon:{type:te,default:`$radioOff`},type:{type:String,default:`radio`}},`VRadioGroup`),ht=D()({name:`VRadioGroup`,inheritAttrs:!1,props:mt(),emits:{"update:modelValue":e=>!0},setup(e,{attrs:n,slots:r}){let i=oe(),a=t(()=>e.id||`radio-group-${i}`),o=b(e,`modelValue`),s=T();return N(()=>{let[t,i]=f(n),c=A.filterProps(e),l=U.filterProps(e),u=r.label?r.label({label:e.label,props:{for:a.value}}):e.label;return j(A,re({ref:s,class:[`v-radio-group`,e.class],style:e.style},t,c,{modelValue:o.value,"onUpdate:modelValue":e=>o.value=e,id:a.value}),{...r,default:({id:t,messagesId:n,isDisabled:a,isReadonly:s})=>x(v,null,[u&&j(C,{id:t.value},{default:()=>[u]}),j(le,re(l,{id:t.value,"aria-describedby":n.value,defaultsTarget:`VRadio`,trueIcon:e.trueIcon,falseIcon:e.falseIcon,type:e.type,disabled:a.value,readonly:s.value,"aria-labelledby":u?t.value:void 0,multiple:!1},i,{modelValue:o.value,"onUpdate:modelValue":e=>o.value=e}),r)])})}),ie({},s)}}),gt={class:`text-caption text-medium-emphasis mt-1`},_t=F({__name:`PushSyncModeCard`,props:{syncMode:{},syncModeDesc:{}},emits:[`update:syncMode`],setup(e,{emit:t}){let n=t;function i(e){e!=null&&n(`update:syncMode`,e)}return(t,n)=>(S(),L(l,{elevation:`0`,border:``,rounded:`lg`,class:`mb-4`},{default:z(()=>[j(r,{class:`text-subtitle-1`},{default:z(()=>[...n[0]||=[y(`同步模式`,-1)]]),_:1}),j(u,null,{default:z(()=>[j(ht,{"model-value":e.syncMode,inline:``,density:`compact`,"onUpdate:modelValue":i},{default:z(()=>[j(pt,{label:`增量同步`,value:`incremental`}),j(pt,{label:`全量同步`,value:`full`}),j(pt,{label:`校验和同步`,value:`checksum`})]),_:1},8,[`model-value`]),e.syncMode===`full`?(S(),L(X,{key:0,type:`warning`,density:`compact`,variant:`tonal`,class:`mt-2`},{default:z(()=>[...n[1]||=[y(` 全量同步会删除目标目录中不存在于源目录的文件 `,-1)]]),_:1})):k(``,!0),x(`div`,gt,p(e.syncModeDesc),1)]),_:1})]),_:1}))}}),vt=F({__name:`PushToolbar`,props:{targetPath:{},pushing:{type:Boolean}},emits:[`update:targetPath`,`preview`,`push`],setup(e){return(t,n)=>(S(),L(l,{elevation:`0`,border:``,rounded:`lg`,class:`mb-4 pa-4`},{default:z(()=>[j(he,{align:`center`,dense:``},{default:z(()=>[j(q,{cols:`12`,sm:`8`},{default:z(()=>[j(I,{"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}),j(q,{cols:`12`,sm:`4`,class:`d-flex ga-2 justify-end`},{default:z(()=>[j(B,{size:`small`,variant:`tonal`,"prepend-icon":`mdi-eye`,onClick:n[1]||=e=>t.$emit(`preview`)},{default:z(()=>[...n[3]||=[y(`预览`,-1)]]),_:1}),j(B,{size:`small`,color:`primary`,variant:`flat`,"prepend-icon":`mdi-upload`,loading:e.pushing,onClick:n[2]||=e=>t.$emit(`push`)},{default:z(()=>[...n[4]||=[y(` 推送 `,-1)]]),_:1},8,[`loading`])]),_:1})]),_:1})]),_:1}))}}),yt={key:0},bt={class:`mt-3`},xt={key:1,class:`d-flex align-center flex-wrap ga-2`},St={class:`d-flex align-center flex-wrap ga-2`},Ct={class:`text-body-2`},wt={key:3},Tt={class:`d-flex ga-2 align-start flex-wrap`},Et={key:4,class:`text-caption text-medium-emphasis mt-2`},Dt=F({__name:`PushZipUpload`,props:{uploadedSource:{},validatedSource:{},sourcePath:{},sourcePathValidating:{type:Boolean},isDragging:{type:Boolean},sourceUploading:{type:Boolean}},emits:[`dragover`,`dragleave`,`drop`,`file-select`,`zip-extract-select`,`clear`,`clear-validated`,`update:sourcePath`,`validate`],setup(e){let t=T(null),n=T(null);return(i,a)=>(S(),L(l,{elevation:`0`,border:``,rounded:`lg`,class:`mb-4`},{default:z(()=>[j(r,{class:`text-subtitle-1`},{default:z(()=>[...a[12]||=[y(`源文件`,-1)]]),_:1}),j(u,null,{default:z(()=>[e.validatedSource?(S(),L(X,{key:1,type:`success`,variant:`tonal`,density:`compact`,class:`mb-0`},{default:z(()=>[x(`div`,St,[j(_,null,{default:z(()=>[...a[18]||=[y(`mdi-folder-check`,-1)]]),_:1}),x(`span`,Ct,p(e.validatedSource.path)+` (`+p(e.validatedSource.fileCount)+` 个文件, `+p(s(Q)(e.validatedSource.sizeBytes))+`) `,1),j(J),j(B,{size:`small`,variant:`text`,color:`error`,onClick:a[8]||=e=>i.$emit(`clear-validated`)},{default:z(()=>[...a[19]||=[y(`清除`,-1)]]),_:1})])]),_:1})):(S(),P(v,{key:0},[e.uploadedSource?(S(),P(`div`,xt,[j(_,{class:`mr-1`},{default:z(()=>[y(p(e.uploadedSource.kind===`zip`?`mdi-folder-zip`:`mdi-file-multiple`),1)]),_:1}),x(`span`,null,p(e.uploadedSource.name)+` (`+p(e.uploadedSource.fileCount)+` 个文件, `+p(s(Q)(e.uploadedSource.size))+`) `,1),j(J),j(B,{size:`small`,variant:`text`,color:`error`,onClick:a[7]||=e=>i.$emit(`clear`)},{default:z(()=>[...a[17]||=[y(`清除`,-1)]]),_:1})])):(S(),P(`div`,yt,[x(`div`,{class:V([`border-dashed border rounded pa-6 text-center cursor-pointer`,{"border-primary bg-primary-lighten-5":e.isDragging}]),onDragover:a[1]||=m(e=>i.$emit(`dragover`),[`prevent`]),onDragleave:a[2]||=e=>i.$emit(`dragleave`),onDrop:a[3]||=m(e=>i.$emit(`drop`,e),[`prevent`]),onClick:a[4]||=e=>t.value?.click()},[j(_,{size:`48`,color:`grey`},{default:z(()=>[...a[13]||=[y(`mdi-cloud-upload-outline`,-1)]]),_:1}),a[15]||=x(`div`,{class:`text-body-2 mt-2`},`拖拽文件到此处,或点击选择`,-1),a[16]||=x(`div`,{class:`text-caption text-medium-emphasis`},` 支持任意后缀文件(可多选);ZIP 拖拽/选择时原样上传 `,-1),x(`div`,bt,[j(B,{size:`small`,variant:`tonal`,"prepend-icon":`mdi-folder-zip`,disabled:e.sourceUploading,onClick:a[0]||=m(e=>n.value?.click(),[`stop`])},{default:z(()=>[...a[14]||=[y(` ZIP 解压上传 `,-1)]]),_:1},8,[`disabled`])])],34),x(`input`,{ref_key:`fileInputRef`,ref:t,type:`file`,multiple:``,hidden:``,onChange:a[5]||=e=>i.$emit(`file-select`,e)},null,544),x(`input`,{ref_key:`zipInputRef`,ref:n,type:`file`,accept:`.zip,application/zip`,hidden:``,onChange:a[6]||=e=>i.$emit(`zip-extract-select`,e)},null,544)])),e.sourceUploading?(S(),L(h,{key:2,indeterminate:``,class:`mt-2`})):k(``,!0)],64)),e.validatedSource?k(``,!0):(S(),L(c,{key:2,class:`my-4`})),!e.validatedSource&&!e.uploadedSource?(S(),P(`div`,wt,[a[21]||=x(`div`,{class:`text-caption text-medium-emphasis mb-2`},`或输入 Nexus 主机源路径(容器内绝对路径)`,-1),x(`div`,Tt,[j(I,{"model-value":e.sourcePath,placeholder:`/path/to/files`,variant:`outlined`,density:`compact`,"hide-details":``,"prepend-inner-icon":`mdi-folder`,class:`flex-grow-1`,style:{"min-width":`240px`},"onUpdate:modelValue":a[9]||=e=>i.$emit(`update:sourcePath`,e),onKeydown:a[10]||=g(m(e=>i.$emit(`validate`),[`prevent`]),[`enter`])},null,8,[`model-value`]),j(B,{variant:`tonal`,color:`primary`,loading:e.sourcePathValidating,disabled:!e.sourcePath.trim(),onClick:a[11]||=e=>i.$emit(`validate`)},{default:z(()=>[...a[20]||=[y(` 验证路径 `,-1)]]),_:1},8,[`loading`,`disabled`])])])):e.uploadedSource?(S(),P(`div`,Et,` 已使用上传暂存目录作为源;可在下方管理文件,或清除后改用主机源路径 `)):k(``,!0)]),_:1})]),_:1}))}}),Ot=[`success`,`failed`,`cancelled`];function kt(){let e=W(),n=T(``),r=T(null),i=T(``),a=T(!1),o=T(``),s=T(`incremental`),c=T(!1),l=T(null),u=T(!1);d(n,e=>{r.value&&e.trim()!==i.value&&(r.value=null)});let f=t(()=>{switch(s.value){case`incremental`:return`仅传输新增或修改的文件`;case`full`:return`使目标目录与源目录完全一致,会删除不存在于源的文件`;case`checksum`:return`通过文件内容校验和判断是否需要传输`;default:return``}});function p(){return l.value?.sourcePath||r.value?.path||``}function m(){return o.value.trim()||void 0}function h(t,i=[]){return p()?!m()&&i.filter(e=>!(e.target_path||``).trim()).length>0?(e(`目标路径留空时,所选服务器须已在「服务器管理」中配置目标路径`,`warning`),!1):t===0?(e(`请选择至少一台服务器`,`warning`),!1):!0:(n.value.trim()&&!r.value?e(`请先点击「验证路径」确认 Nexus 主机上的源目录`,`warning`):e(`请上传文件或验证 Nexus 主机源路径`,`warning`),!1)}async function g(){let t=n.value.trim();if(!t){e(`请输入 Nexus 主机上的源目录路径`,`warning`);return}if(l.value){e(`请先清除已上传的源文件`,`warning`);return}a.value=!0;try{let a=await H.post(`/sync/validate-source-path`,{path:t});r.value={path:a.path,fileCount:a.file_count,sizeBytes:a.size_bytes},i.value=a.path,n.value=a.path,e(`路径验证通过:${a.file_count} 个文件`)}catch(t){r.value=null,e(t instanceof Error?t.message:`路径验证失败`,`error`)}finally{a.value=!1}}function _(){r.value=null,i.value=``,n.value=``}function v(){l.value=null}async function y(t){if(t.length){if(r.value){e(`请先清除已验证的源路径`,`warning`);return}await w(t)}}async function b(e){c.value=!1,await y(Array.from(e.dataTransfer?.files??[]))}function x(e){let t=e.target,n=Array.from(t.files??[]);t.value=``,y(n)}function S(e){let t=e.target,n=t.files?.[0];t.value=``,n&&C(n)}async function C(t){if(r.value){e(`请先清除已验证的源路径`,`warning`);return}u.value=!0;try{let n=new FormData;n.append(`file`,t);let r=await H.upload(`/sync/upload-zip`,n);l.value={kind:`zip`,name:t.name,sourcePath:r.source_path,fileCount:r.file_count,size:r.size},e(`ZIP 已解压到暂存目录`)}catch(t){e(t instanceof Error?t.message:`ZIP 解压失败`,`error`)}finally{u.value=!1}}async function w(t){if(t.length){u.value=!0;try{let n=new FormData;for(let e of t)n.append(`files`,e);let r=await H.upload(`/sync/upload-files`,n);l.value={kind:`files`,name:t.length===1?t[0].name:`${t.length} 个文件`,sourcePath:r.source_path,fileCount:r.file_count,size:r.size},e(`已上传 ${r.file_count} 个文件`)}catch(t){e(t instanceof Error?t.message:`上传失败`,`error`)}finally{u.value=!1}}}return{sourcePath:n,validatedSource:r,sourcePathValidating:a,targetPath:o,syncMode:s,syncModeDesc:f,isDragging:c,uploadedSource:l,sourceUploading:u,effectiveSourcePath:p,effectiveTargetPath:m,validateForm:h,validateSourcePath:g,clearValidatedSource:_,clearUploadedSource:v,handleFileDrop:b,handleFileSelect:x,handleZipExtractSelect:S}}function At(e){let n=T([]),r=T(!1),i=T(``),a=T(new Set),o=null;async function s(){r.value=!0;try{n.value=(await H.get(`/servers/`,{per_page:200})).items||[]}catch{n.value=[]}finally{r.value=!1}}function c(e){l(),o=setInterval(()=>{e()||s()},6e4)}function l(){o&&=(clearInterval(o),null)}let u=t(()=>{if(!i.value)return n.value;let e=i.value.toLowerCase();return n.value.filter(t=>t.name.toLowerCase().includes(e)||(t.domain||``).toLowerCase().includes(e)||(t.target_path||``).toLowerCase().includes(e))}),d=t(()=>{let e=u.value;return e.length>0&&e.every(e=>a.value.has(e.id))}),f=t(()=>{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 m(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 h(e){let t=new Set(a.value);t.has(e)?t.delete(e):t.add(e),a.value=t}function g(){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:n,serversLoading:r,serverSearch:i,selectedIds:a,pushStatus:e,filteredServers:u,selectAll:d,serversByCategory:f,loadServers:s,startAutoRefresh:c,stopAutoRefresh:l,isCategoryAllSelected:p,toggleCategory:m,toggleServer:h,toggleAll:g}}function jt(){return crypto.randomUUID().replace(/-/g,``).slice(0,12)}function Mt(e,n,r){let a=W(),o=i(),s=T(!1),c=T(!1),l=T(!1),u=T([]),d=T(``),f=T(null),p=[],m=t(()=>u.value.filter(e=>Ot.includes(e.status)).length),h=t(()=>{let e=u.value.length;return e?Math.round(m.value/e*100):0});function g(){p.forEach(e=>clearTimeout(e)),p.length=0}function _(){let e=u.value.length;if(!e||!s.value||u.value.filter(e=>Ot.includes(e.status)).length<e)return;s.value=!1,x(),r();let t=u.value.filter(e=>e.status===`failed`).length,n=u.value.filter(e=>e.status===`cancelled`).length,i=u.value.filter(e=>e.status===`success`).length;a(`推送完成:${i} 成功,${t} 失败${n?`${n} 取消`:``}`)}function v(e){if(e.type!==`sync_progress`||e.batch_id!==d.value||e.server_id==null)return;let t=u.value.findIndex(t=>t.id===e.server_id);if(t===-1)return;let r=u.value[t],i=e.status;if(i===`running`)r.status=`running`,r.detail=`同步中...`;else if(i===`success`){r.status=`success`;let t=e.duration_seconds;r.detail=t==null?`完成`:`完成(${t}s`,n.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),n.pushStatus.value[e.server_id]=`失败`):i===`cancelled`&&(r.status=`cancelled`,r.detail=Z(e.error_message)||`已取消`,n.pushStatus.value[e.server_id]=`已取消`);_()}function y(e){let t=e.results;if(t){for(let[e,r]of Object.entries(t)){let t=Number(e);if(!Number.isFinite(t))continue;let i=u.value.findIndex(e=>e.id===t);if(i===-1)continue;let a=u.value[i],o=r.status;if(o===`success`){a.status=`success`;let e=r.duration_seconds;a.detail=e==null?`完成`:`完成(${e}s`,n.pushStatus.value[t]=`成功`}else o===`failed`?(a.status=`failed`,a.detail=Z(r.error_message)||`失败`,r.retry_job_id!=null&&(a.retryJobId=r.retry_job_id),n.pushStatus.value[t]=`失败`):o===`cancelled`&&(a.status=`cancelled`,a.detail=Z(r.error_message)||`已取消`,n.pushStatus.value[t]=`已取消`)}_()}}function b(){if(!o.token)return Promise.reject(Error(`未登录,无法连接推送进度`));x();let e=_e(`/ws/sync`,{token:o.token}),t=new WebSocket(e);return new Promise((e,i)=>{t.onopen=()=>e(),t.onerror=()=>i(Error(`推送进度 WebSocket 连接失败`)),t.onmessage=e=>{if(e.data!==`pong`)try{let n=JSON.parse(e.data);if(n.type===`ping`){t.send(`pong`);return}v(n)}catch{}},t.onclose=e=>{if(f.value=null,e.code===4001||e.code===4401){o.forceLogout();return}e.code!==1e3&&s.value&&(u.value.forEach(e=>{(e.status===`pending`||e.status===`running`)&&(e.status=`failed`,e.detail=`连接中断`,n.pushStatus.value[e.id]=`失败`)}),s.value=!1,a(`推送进度连接中断,部分服务器状态未知`,`warning`),r())},f.value=t})}function x(){f.value&&=(f.value.close(1e3),null)}async function S(){if(d.value){c.value=!0;try{await H.post(`/sync/cancel`,{batch_id:d.value}),u.value.forEach(e=>{(e.status===`pending`||e.status===`running`)&&(e.status=`cancelled`,e.detail=`已取消`,n.pushStatus.value[e.id]=`已取消`)}),s.value=!1,x(),r(),a(`推送已取消`)}catch(e){a(e instanceof Error?e.message:`取消失败`,`error`)}finally{c.value=!1}}}async function C(){if(s.value)return;let t=[...n.selectedIds.value].map(e=>n.servers.value.find(t=>t.id===e)).filter(e=>e!=null);if(!e.validateForm(t.length,t))return;g(),x(),d.value=``,n.pushStatus.value={};let i=t.map(e=>e.id);u.value=i.map(e=>({id:e,name:n.servers.value.find(t=>t.id===e)?.name||`#${e}`,status:`pending`})),s.value=!0,d.value=jt();try{await b();let t=await H.post(`/sync/files`,{source_path:e.effectiveSourcePath(),target_path:e.effectiveTargetPath(),server_ids:i,sync_mode:e.syncMode.value,batch_id:d.value});t.batch_id&&t.batch_id!==d.value&&(d.value=t.batch_id),y(t)}catch(e){x();let t=e instanceof Error?e.message:`推送请求失败`;u.value.forEach(e=>{e.status=`failed`,e.detail=t}),s.value=!1,a(t,`error`),r();return}let o=setTimeout(()=>{s.value&&(u.value.forEach(e=>{(e.status===`pending`||e.status===`running`)&&(e.status=`failed`,e.detail=`等待超时`,n.pushStatus.value[e.id]=`失败`)}),s.value=!1,x(),r(),a(`推送超时,${m.value}/${u.value.length} 台已有结果`,`warning`))},3e5);p.push(o)}let w=t(()=>u.value.filter(e=>e.status===`failed`&&e.retryJobId!=null).length);async function ee(){let e=u.value.filter(e=>e.status===`failed`&&e.retryJobId!=null).map(e=>e.retryJobId);if(!e.length){a(`没有可重试的失败任务(重试任务可能尚未创建)`,`warning`);return}l.value=!0;let t=0,n=0;try{for(let r of e)try{await H.post(`/retries/${r}/retry`),t++}catch{n++}a(n>0?`已提交 ${t} 个重试,${n} 个提交失败`:`已提交 ${t} 个失败服务器的重试任务`)}finally{l.value=!1}}function E(){x(),g()}return{pushing:s,cancelling:c,retryingAll:l,wsProgressItems:u,pushBatchId:d,doneCount:m,totalProgress:h,failedRetryCount:w,doPush:C,cancelPush:S,retryAllFailed:ee,dispose:E}}function Nt(e,n){let r=T(!1),i=T([]),a=T(!1),o=T(0),s=T(0),c=t(()=>o.value>30),l=t(()=>i.value.filter(e=>e.error).length);async function u(t,n){try{let r=await H.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 d(){let t=[...n.selectedIds.value].map(e=>n.servers.value.find(t=>t.id===e)).filter(e=>e!=null);if(!e.validateForm(t.length,t))return;let c=t.map(e=>e.id);o.value=c.length,s.value=0,r.value=!0,a.value=!0,i.value=[];let l=c.map(e=>({id:e,name:n.servers.value.find(t=>t.id===e)?.name||`#${e}`}));for(let e=0;e<l.length;e+=4){let t=l.slice(e,e+4),n=await Promise.all(t.map(e=>u(e.id,e.name)));i.value=[...i.value,...n],s.value=i.value.length}a.value=!1}function f(){r.value=!1}function p(e){r.value=!1,e()}return{showPreview:r,previewResults:i,previewLoading:a,previewTotal:o,previewDone:s,previewLargeBatch:c,previewWarnThreshold:30,previewErrorCount:l,doPreview:d,closePreview:f,confirmAndPush:p}}var Pt=[{label:`成功`,value:`success`},{label:`失败`,value:`failed`},{label:`进行中`,value:`running`},{label:`已取消`,value:`cancelled`}],Ft=[{label:`增量`,value:`incremental`},{label:`全量`,value:`full`},{label:`校验和`,value:`checksum`}],It=[{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 Lt(e,n){let r=W(),i=T([]),a=T(0),o=T(!1),s=T(1),c=T(null),l=T(null),u=T(null),d=T(!1),f=T(!1),p=T(!1),m=T(null),h=T(null),g=t(()=>n.servers.value.map(e=>({title:e.name,value:e.id})));function _(){s.value=1,v()}async function v(){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 H.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 y(){d.value=!0;try{let e=(await H.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 H.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:Pt,logSyncModeOptions:Ft,logHeaders:It,logServerOptions:g,showDiagnose:f,diagnoseLoading:p,diagnoseResult:m,diagnoseTarget:h,onLogFilterChange:_,loadLogs:v,reconcileStaleLogs:y,openDiagnose:b,closeDiagnose:x}}function $(e,t){return`${e.replace(/\/+$/,``)}/${t}`}function Rt(e){let n=W(),r=T(!1),i=T(``),a=T([]),o=T(!1),s=T(!1),c=T(null),l=T(!1),u=T(null),f=T(``),p=T(!1),m=T(!1),h=T([]),g=T(!1),_=T(new Set),v=()=>e.value?.sourcePath??``,y=t(()=>_.value.size),b=t(()=>{let e=a.value;return e.length>0&&e.every(e=>_.value.has(e.name))}),x=t(()=>_.value.size>0&&!b.value);function S(){_.value=new Set}function C(e){return _.value.has(e)}function w(e,t){let n=new Set(_.value);t?n.add(e):n.delete(e),_.value=n}function ee(e){if(!e){S();return}_.value=new Set(a.value.map(e=>e.name))}let E=t(()=>{let e=v(),t=i.value;return!e||!t||t===e?``:t.startsWith(`${e}/`)?t.slice(e.length+1):t});async function D(){let t=v();if(!(!t||!e.value))try{let n=await H.post(`/sync/validate-source-path`,{path:t});e.value={...e.value,fileCount:n.file_count,size:n.size_bytes}}catch{}}async function O(e){if(!e){a.value=[],i.value=``;return}r.value=!0;try{let t=await H.post(`/sync/browse-local`,{path:e});i.value=t.path,a.value=t.entries??[],S()}catch(e){a.value=[],n(e instanceof Error?e.message:`加载暂存目录失败`,`error`)}finally{r.value=!1}}function te(){O(v())}function k(){O(i.value||v())}function A(e){!e.is_dir||!i.value||O($(i.value,e.name))}function j(e){u.value=e,f.value=e.name,l.value=!0}async function M(){let e=u.value,t=f.value.trim();if(!e||!i.value||!t||t===e.name){l.value=!1;return}p.value=!0;try{await H.post(`/sync/local-file-ops`,{operation:`rename`,path:$(i.value,e.name),new_name:t}),n(`已重命名`),l.value=!1,await O(i.value),await D()}catch(e){n(e instanceof Error?e.message:`重命名失败`,`error`)}finally{p.value=!1}}function N(e){h.value=[e],m.value=!0}function P(){let e=a.value.filter(e=>_.value.has(e.name));if(!e.length){n(`请先选择要删除的项`,`warning`);return}h.value=e,m.value=!0}async function ne(){let e=h.value;if(!e.length||!i.value){m.value=!1;return}g.value=!0;let t=0,r=0;try{for(let n of e)try{await H.post(`/sync/local-file-ops`,{operation:`delete`,path:$(i.value,n.name)}),t++}catch{r++}m.value=!1,S(),await O(i.value),await D(),r>0?n(`已删除 ${t} 项,${r} 项失败`,`warning`):n(e.length>1?`已删除 ${t} 项`:`已删除`)}finally{g.value=!1}}async function F(e){if(!(e.is_dir||!i.value)){o.value=!0,s.value=!0,c.value=null;try{c.value=await H.post(`/sync/local-file-preview`,{path:$(i.value,e.name)})}catch(e){o.value=!1,n(e instanceof Error?e.message:`预览失败`,`error`)}finally{s.value=!1}}}return d(()=>e.value?.sourcePath,e=>{e?O(e):(a.value=[],i.value=``,S())},{immediate:!0}),{loading:r,currentPath:i,entries:a,relativePath:E,goRoot:te,refreshCurrent:k,openDirectory:A,loadDirectory:O,openRename:j,confirmRename:M,renameOpen:l,renameValue:f,renameLoading:p,renameTarget:u,openDelete:N,openBatchDelete:P,confirmDelete:ne,deleteOpen:m,deleteLoading:g,deleteTargets:h,selectedCount:y,allSelected:b,someSelected:x,isSelected:C,toggleSelect:w,toggleSelectAll:ee,clearSelection:S,previewFile:F,previewOpen:o,previewLoading:s,previewResult:c}}function zt(){let e=kt(),t=Rt(e.uploadedSource),r=At(T({})),i=Lt(e,r),a=Mt(e,r,()=>i.loadLogs()),o=Nt(e,r);function s(){o.confirmAndPush(()=>a.doPush())}return O(()=>{r.loadServers(),i.loadLogs(),r.startAutoRefresh(()=>a.pushing.value)}),w(()=>{a.dispose(),r.stopAutoRefresh()}),{form:n(e),staging:n(t),servers:n(r),progress:n(a),preview:n(o),logs:n(i),onConfirmAndPush:s}}var Bt=F({__name:`PushPage`,setup(e){let{form:t,staging:n,servers:r,progress:i,preview:a,logs:o,onConfirmAndPush:c}=zt();return(e,l)=>(S(),L(de,{fluid:``,class:`pa-6`},{default:z(()=>[j(Dt,{"uploaded-source":s(t).uploadedSource,"validated-source":s(t).validatedSource,"source-path":s(t).sourcePath,"onUpdate:sourcePath":l[0]||=e=>s(t).sourcePath=e,"source-path-validating":s(t).sourcePathValidating,"is-dragging":s(t).isDragging,"source-uploading":s(t).sourceUploading,onDragover:l[1]||=e=>s(t).isDragging=!0,onDragleave:l[2]||=e=>s(t).isDragging=!1,onDrop:s(t).handleFileDrop,onFileSelect:s(t).handleFileSelect,onZipExtractSelect:s(t).handleZipExtractSelect,onClear:s(t).clearUploadedSource,onClearValidated:s(t).clearValidatedSource,onValidate:s(t).validateSourcePath},null,8,[`uploaded-source`,`validated-source`,`source-path`,`source-path-validating`,`is-dragging`,`source-uploading`,`onDrop`,`onFileSelect`,`onZipExtractSelect`,`onClear`,`onClearValidated`,`onValidate`]),s(t).uploadedSource?(S(),L(Re,{key:0,"root-path":s(t).uploadedSource.sourcePath,"relative-path":s(n).relativePath,entries:s(n).entries,loading:s(n).loading,"selected-count":s(n).selectedCount,"all-selected":s(n).allSelected,"some-selected":s(n).someSelected,"is-selected":s(n).isSelected,"rename-open":s(n).renameOpen,"onUpdate:renameOpen":l[3]||=e=>s(n).renameOpen=e,"rename-value":s(n).renameValue,"onUpdate:renameValue":l[4]||=e=>s(n).renameValue=e,"rename-loading":s(n).renameLoading,"delete-open":s(n).deleteOpen,"onUpdate:deleteOpen":l[5]||=e=>s(n).deleteOpen=e,"delete-targets":s(n).deleteTargets,"delete-loading":s(n).deleteLoading,onRefresh:l[6]||=e=>s(n).refreshCurrent(),onGoRoot:s(n).goRoot,onOpenDir:s(n).openDirectory,onPreview:s(n).previewFile,onRename:s(n).openRename,onDelete:s(n).openDelete,onBatchDelete:s(n).openBatchDelete,onToggleSelect:s(n).toggleSelect,onToggleSelectAll:s(n).toggleSelectAll,onConfirmRename:s(n).confirmRename,onConfirmDelete:s(n).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`])):k(``,!0),j(Ve,{modelValue:s(n).previewOpen,"onUpdate:modelValue":l[7]||=e=>s(n).previewOpen=e,loading:s(n).previewLoading,result:s(n).previewResult},null,8,[`modelValue`,`loading`,`result`]),j(vt,{"target-path":s(t).targetPath,"onUpdate:targetPath":l[8]||=e=>s(t).targetPath=e,pushing:s(i).pushing,onPreview:s(a).doPreview,onPush:s(i).doPush},null,8,[`target-path`,`pushing`,`onPreview`,`onPush`]),j(dt,{"select-all":s(r).selectAll,"server-search":s(r).serverSearch,"onUpdate:serverSearch":l[9]||=e=>s(r).serverSearch=e,"servers-loading":s(r).serversLoading,"servers-by-category":s(r).serversByCategory,"selected-ids":s(r).selectedIds,"push-status":s(r).pushStatus,"is-category-all-selected":s(r).isCategoryAllSelected,onToggleAll:s(r).toggleAll,onRefresh:s(r).loadServers,onToggleCategory:s(r).toggleCategory,onToggleServer:s(r).toggleServer},null,8,[`select-all`,`server-search`,`servers-loading`,`servers-by-category`,`selected-ids`,`push-status`,`is-category-all-selected`,`onToggleAll`,`onRefresh`,`onToggleCategory`,`onToggleServer`]),j(_t,{"sync-mode":s(t).syncMode,"onUpdate:syncMode":l[10]||=e=>s(t).syncMode=e,"sync-mode-desc":s(t).syncModeDesc},null,8,[`sync-mode`,`sync-mode-desc`]),j(nt,{items:s(i).wsProgressItems,"batch-id":s(i).pushBatchId,pushing:s(i).pushing,cancelling:s(i).cancelling,"retrying-all":s(i).retryingAll,"failed-retry-count":s(i).failedRetryCount,"done-count":s(i).doneCount,"total-progress":s(i).totalProgress,onCancel:s(i).cancelPush,onRetryAll:s(i).retryAllFailed},null,8,[`items`,`batch-id`,`pushing`,`cancelling`,`retrying-all`,`failed-retry-count`,`done-count`,`total-progress`,`onCancel`,`onRetryAll`]),j($e,{modelValue:s(a).showPreview,"onUpdate:modelValue":l[11]||=e=>s(a).showPreview=e,loading:s(a).previewLoading,results:s(a).previewResults,"selected-count":s(r).selectedIds.size,"preview-done":s(a).previewDone,"preview-total":s(a).previewTotal,"large-batch":s(a).previewLargeBatch,"warn-threshold":s(a).previewWarnThreshold,"error-count":s(a).previewErrorCount,"sync-mode":s(t).syncMode,onConfirmPush:s(c)},null,8,[`modelValue`,`loading`,`results`,`selected-count`,`preview-done`,`preview-total`,`large-batch`,`warn-threshold`,`error-count`,`sync-mode`,`onConfirmPush`]),j(He,{modelValue:s(o).showDiagnose,"onUpdate:modelValue":l[12]||=e=>s(o).showDiagnose=e,loading:s(o).diagnoseLoading,result:s(o).diagnoseResult,"target-name":s(o).diagnoseTarget?.server_name??void 0},null,8,[`modelValue`,`loading`,`result`,`target-name`]),j(qe,{items:s(o).logs,headers:s(o).logHeaders,total:s(o).logTotal,loading:s(o).logLoading,page:s(o).logPage,"onUpdate:page":l[13]||=e=>s(o).logPage=e,"status-filter":s(o).logStatusFilter,"onUpdate:statusFilter":l[14]||=e=>s(o).logStatusFilter=e,"sync-mode-filter":s(o).logSyncModeFilter,"onUpdate:syncModeFilter":l[15]||=e=>s(o).logSyncModeFilter=e,"server-filter":s(o).logServerFilter,"onUpdate:serverFilter":l[16]||=e=>s(o).logServerFilter=e,"status-options":s(o).logStatusOptions,"sync-mode-options":s(o).logSyncModeOptions,"server-options":s(o).logServerOptions,reconciling:s(o).reconcilingLogs,onFilterChange:s(o).onLogFilterChange,onPageChange:s(o).loadLogs,onReconcile:s(o).reconcileStaleLogs,onDiagnose:s(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{Bt as default};