PageSourceSearch

https://hiiiid-ispace1.hf.space/assets/ResourceOpsDatabasePage-Dkvg9Whx.js

js hiiiid-ispace1.hf.space collected 2026-10-03 16:57:51 UTC 146,622 bytes, 8 lines download raw bytes

1const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/DatabasePlatformPage-CPWU_ay1.js","assets/vendor-vue-DHGubi9Q.js","assets/index-D1LoOqJz.js","assets/vendor-monaco-iaZ6B9cc.js","assets/vendor-monaco-B_19GPAS.css","assets/index-CYMnIztW.css","assets/Textarea.vue_vue_type_script_setup_true_lang-Dfqxngaw.js","assets/SelectValue.vue_vue_type_script_setup_true_lang-DRmoB7_S.js","assets/check-BiUcNZQp.js","assets/createLucideIcon-C73RGe63.js","assets/ResourceOpsPage-BlVnStXZ.js","assets/CardContent.vue_vue_type_script_setup_true_lang-Cwvzk9V4.js","assets/DialogTitle.vue_vue_type_script_setup_true_lang-CKzTxb5z.js","assets/trash-2-Bn8J2fow.js","assets/copy-D8zafuJA.js","assets/list-C9VxHXeS.js","assets/databasePlatformUtils--fXUZKaC.js"])))=>i.map(i=>d[i]);
2import{_ as mt}from"./vendor-monaco-iaZ6B9cc.js";import{d as ye,f as i,i as A,u as t,a7 as _t,v as Oe,w as Re,z as p,l as a,j as n,L as e,F as B,A as Q,G as r,H as d,y,a5 as se,q as Ke,r as k,c as oe,R as J,S as Se,ab as gt,a9 as at,aa as re,M as bt,x as vt,af as He,a0 as xt,B as yt,m as kt,ae as $t,ad as wt}from"./vendor-vue-DHGubi9Q.js";import{d as De,a as Te,c as Me,b as qe,_ as U}from"./CardContent.vue_vue_type_script_setup_true_lang-Cwvzk9V4.js";import{_ as ae}from"./Badge.vue_vue_type_script_setup_true_lang-BfoFr9jl.js";import{c as K,_ as T,a as ee,b as ht}from"./index-D1LoOqJz.js";import{_ as Ge}from"./Textarea.vue_vue_type_script_setup_true_lang-Dfqxngaw.js";import{_ as Fe,a as Ne,b as Pe,c as Ae,d as ve}from"./SelectValue.vue_vue_type_script_setup_true_lang-DRmoB7_S.js";import{_ as Ct}from"./Table.vue_vue_type_script_setup_true_lang-C59TbDTf.js";import{b as St,a as nt,_ as ot,c as Dt,d as lt}from"./TableRow.vue_vue_type_script_setup_true_lang-DBu1NxO5.js";import{_ as Ee,a as ze,b as Ve,c as je,d as Be}from"./DialogTitle.vue_vue_type_script_setup_true_lang-CKzTxb5z.js";import{b as Tt,_ as Et,a as Le}from"./TabsTrigger.vue_vue_type_script_setup_true_lang-CPB1URld.js";import{_ as Ue}from"./TabsContent.vue_vue_type_script_setup_true_lang-CaTe9jcM.js";import{e as rt,a as it,b as Je,c as ut}from"./databasePlatformUtils--fXUZKaC.js";import"./createLucideIcon-C73RGe63.js";import"./check-BiUcNZQp.js";const dt=ye({name:"ConnectionsTab",__name:"ConnectionsTab",props:{locale:{}},emits:["focus-appsystem-architecture","focus-appsystem-dossier","focus-devops-project","focus-devops-environment","focus-devops-resource","connection-selected","open-account-detail"],setup(M,{emit:q}){const z=_t(()=>mt(()=>import("./DatabasePlatformPage-CPWU_ay1.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]))),u=q;return(w,O)=>(i(),A(t(z),{locale:M.locale,onFocusAppsystemArchitecture:O[0]||(O[0]=S=>u("focus-appsystem-architecture",S)),onFocusAppsystemDossier:O[1]||(O[1]=S=>u("focus-appsystem-dossier",S)),onFocusDevopsProject:O[2]||(O[2]=S=>u("focus-devops-project",S)),onFocusDevopsEnvironment:O[3]||(O[3]=S=>u("focus-devops-environment",S)),onFocusDevopsResource:O[4]||(O[4]=S=>u("focus-devops-resource",S)),onConnectionSelected:O[5]||(O[5]=(S,H)=>u("connection-selected",S,H)),onOpenAccountDetail:O[6]||(O[6]=S=>u("open-account-detail",S))},null,8,["locale"]))}}),zt={class:"flex gap-2 items-center mb-3 flex-wrap"},Vt={class:"mb-3"},jt={class:"flex flex-wrap gap-2"},Lt={class:"border-b"},Ut={class:"flex items-center"},Ot={class:"flex overflow-x-auto"},It=["onClick"],Rt={class:"truncate max-w-[100px]"},Ft=["onClick"],Nt=["onClick"],Pt={class:"border rounded-lg overflow-hidden mt-3"},At={class:"bg-muted px-3 py-2 border-b flex items-center justify-between"},Bt={class:"flex items-center gap-2"},Mt={class:"flex gap-2"},qt={class:"flex items-center justify-between"},Qt={class:"max-h-96 overflow-y-auto space-y-2"},Wt={class:"flex items-center justify-between mb-2"},Ht={class:"flex items-center gap-2"},Jt={class:"font-semibold text-sm"},Kt={class:"text-xs text-muted-foreground"},Gt={class:"text-xs bg-muted p-2 rounded overflow-x-auto whitespace-pre-wrap"},Yt={class:"flex gap-2 mt-2 items-center"},Xt={key:0,class:"text-center py-8 text-muted-foreground"},Zt={class:"flex items-center justify-between"},es={class:"flex gap-2"},ts={class:"max-h-96 overflow-y-auto space-y-2"},ss={class:"flex items-center justify-between mb-2"},as={class:"flex items-center gap-2"},ns={class:"text-xs text-muted-foreground"},os={class:"text-xs text-muted-foreground"},ls={class:"text-xs bg-muted p-2 rounded overflow-x-auto whitespace-pre-wrap"},rs={class:"flex gap-2 mt-2 items-center"},is={class:"text-xs text-muted-foreground"},us={class:"border-b px-4 py-2 flex gap-4 items-center"},ds={key:0,class:"flex gap-2"},cs={key:0,class:"border border-destructive/50 bg-destructive/5 rounded-lg p-4"},vs={class:"text-sm text-destructive/80 whitespace-pre-wrap font-mono"}
2,ps={key:1,class:"border border-green-500/30 bg-green-500/5 dark:bg-green-500/10 rounded-lg p-4"},fs={class:"space-y-1 text-sm text-green-700/80 dark:text-green-400/80"},ms={key:0},_s={key:2},gs={key:0,class:"overflow-x-auto"},bs={class:"mb-2 text-sm text-muted-foreground"},xs={class:"font-semibold text-foreground"},ys={key:0,class:"text-muted-foreground italic"},ks={key:1},$s={key:1,class:"text-center py-12 text-muted-foreground"},ws={class:"mt-2"},hs={class:"text-sm text-muted-foreground mt-1"},Cs={key:3,class:"text-center py-16 text-muted-foreground"},Ss=ye({name:"SQLWorkspace",__name:"SQLWorkspace",props:{connectionId:{},connectionKey:{}},setup(M){const q=M,z=k([]),u=oe(()=>m.value.connectionId),w=oe(()=>m.value.database),O=oe(()=>m.value.connectionId?S.value[m.value.connectionId]||[]:[]),S=k({}),H=k(!1),N=k([{id:1,name:"查询 1",sql:"",connectionId:null,database:"",result:null,error:null,lastExecuted:null,isRunning:!1}]),C=k(1),o=k(2),l=k([]),R=k([]),X=k(!1),ne=k(!1),G=k(""),W=k(""),F=k(!1),I=k("result"),P=k([]),V=[{name:"查询表数据",sql:"SELECT * FROM table_name LIMIT 100;"},{name:"统计行数",sql:"SELECT COUNT(*) AS total FROM table_name;"},{name:"查询表结构",sql:"DESCRIBE table_name;"},{name:"查询索引",sql:"SHOW INDEX FROM table_name;"},{name:"查看慢查询",sql:"SELECT * FROM information_schema.processlist WHERE TIME > 5 ORDER BY TIME DESC;"},{name:"数据库大小",sql:"SELECT table_schema AS 'Database', ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS 'Size (MB)' FROM information_schema.tables GROUP BY table_schema;"}],m=oe(()=>N.value.find(_=>_.id===C.value)||N.value[0]);async function E(){H.value=!0;try{const _=await fetch("/api/resource-ops/dbspace/instances?page=1&page_size=100");if(!_.ok)throw new Error("加载数据库实例失败");const f=await _.json();z.value=(f.items||[]).filter(x=>x.status==="active"),q.connectionId&&z.value.find(x=>x.id===q.connectionId)&&(N.value[0].connectionId=q.connectionId,await j(q.connectionId))}catch(_){console.error("Failed to load connections:",_)}finally{H.value=!1}}async function j(_){if(S.value[_])return S.value[_];try{const f=await fetch(`/api/resource-ops/dbspace/instances/${_}/databases`);if(f.ok){const L=(await f.json()).databases||[];return S.value[_]=L,L}}catch(f){console.error("Failed to load databases:",f)}return[]}function $(_){const f=[],x=_.toUpperCase();return x.includes("DROP ")&&f.push("DROP"),x.includes("TRUNCATE ")&&f.push("TRUNCATE"),x.includes("DELETE ")&&!x.includes("DELETE FROM ")&&f.push("DELETE"),x.includes("ALTER ")&&f.push("ALTER"),x.includes("CREATE ")&&x.includes("DATABASE")&&f.push("CREATE DATABASE"),f}async function Z(){var x;const _=m.value.connectionId;if(!_){alert("请先选择数据库连接");return}if(!m.value.sql.trim()){alert("请输入SQL语句");return}if(F.value){const L=m.value.sql.toUpperCase();if(!L.startsWith("SELECT")&&!L.startsWith("SHOW")&&!L.startsWith("DESCRIBE")){alert("只读模式下只能执行SELECT、SHOW、DESCRIBE语句");return}}const f=$(m.value.sql);if(!(f.length>0&&!confirm(`⚠️ 检测到高风险操作: ${f.join(", ")}
3
4确认继续执行吗?`))){m.value.isRunning=!0,m.value.error=null,m.value.result=null;try{const L={sql:m.value.sql};m.value.database&&(L.database=m.value.database);const le=await fetch(`/api/db-platform/connections/${_}/sql`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(L)});if(!le.ok){const Qe=await le.json();throw new Error(Qe.detail||"SQL执行失败")}const Ce=await le.json();m.value.result=Ce,m.value.lastExecuted=new Date().toISOString(),l.value.unshift({id:Date.now(),sql:m.value.sql,database:L.database,executed_at:new Date().toISOString(),duration_ms:Ce.duration_ms,success:!0,error_message:null,row_count:((x=Ce.rows)==null?void 0:x.length)||Ce.affected_rows||0}),ce()}catch(L){m.value.error=L.message||"SQL执行失败",l.value.unshift({id:Date.now(),sql:m.value.sql,database:m.value.database,executed_at:new Date().toISOString(),duration_ms:0,success:!1,error_message:L.message,row_count:0}),ce()}finally{m.value.isRunning=!1}}}function h(){const _={id:o.value++,name:`查询 ${o.value-1}`,sql:"",connectionId:m.value.connectionId,database:m.value.database,result:null,error:null,lastExecuted:null,isRunning:!1};N.value.push(_),C.value=_.id}function ie(_){if(N.value.length===1){alert("至少保留一个查询标签页");return}const f=N.value.findIndex(x=>x.id===_);N.value.splice(f,1),C.value===_&&(C.value=N.value[Math.max(0,f-1)].id)}function te(_){const f=N.value.find(L=>
4L.id===_);if(!f)return;const x=prompt("输入标签页名称:",f.name);x&&x.trim()&&(f.name=x.trim())}function ue(){if(!m.value.sql.trim()){alert("SQL语句不能为空");return}const _=prompt("输入保存名称:");!_||!_.trim()||(R.value.unshift({id:Date.now(),name:_.trim(),sql:m.value.sql,database:m.value.database||w.value||null,created_at:new Date().toISOString(),is_favorite:!1}),Y(),alert("SQL已保存"))}function _e(_){m.value.sql=_.sql,_.database&&(m.value.database=_.database),ne.value=!1}function ge(_){const f=R.value.find(x=>x.id===_);f&&(f.is_favorite=!f.is_favorite,Y())}function ke(_){if(confirm("确定删除此保存的SQL吗?")){const f=R.value.findIndex(x=>x.id===_);f>=0&&(R.value.splice(f,1),Y())}}function pe(_){const f=m.value;if(!f.result||!f.result.rows)return;let x,L,le;if(_==="csv"){const Xe=f.result.columns.join(","),Ze=f.result.rows.map(We=>We.map(et=>`"${String(et).replace(/"/g,'""')}"`).join(","));x=[Xe,...Ze].join(`
5`),L="text/csv",le="csv"}else{const Xe=f.result.rows.map(Ze=>{const We={};return f.result.columns.forEach((et,ft)=>{We[et]=Ze[ft]}),We});x=JSON.stringify(Xe,null,2),L="application/json",le="json"}const Ce=new Blob([x],{type:L}),Qe=URL.createObjectURL(Ce),Ye=document.createElement("a");Ye.href=Qe,Ye.download=`query_result_${Date.now()}.${le}`,Ye.click(),URL.revokeObjectURL(Qe)}function ce(){const _=l.value.slice(0,200);localStorage.setItem("sql_workspace_history",JSON.stringify(_)),localStorage.setItem("sql_workspace_favorites",JSON.stringify(P.value))}function be(){try{const _=localStorage.getItem("sql_workspace_history");_&&(l.value=JSON.parse(_));const f=localStorage.getItem("sql_workspace_favorites");f&&(P.value=JSON.parse(f))}catch(_){console.error("Failed to load history:",_)}}function fe(_){m.value.sql=_.sql,_.database&&(m.value.database=_.database),X.value=!1}function xe(_){const f=P.value.indexOf(_);f>=0?P.value.splice(f,1):P.value.push(_),ce()}function b(){confirm("确定要清空所有历史记录吗?")&&(l.value=[],P.value=[],ce())}function Y(){localStorage.setItem("sql_workspace_saved",JSON.stringify(R.value))}function $e(){try{const _=localStorage.getItem("sql_workspace_saved");_&&(R.value=JSON.parse(_))}catch(_){console.error("Failed to load saved SQL:",_)}}function he(_){m.value.sql=_.sql}function we(_){return _<1e3?`${_}ms`:`${(_/1e3).toFixed(2)}s`}function me(_){return new Date(_).toLocaleString("zh-CN")}function de(){const _=z.value.find(f=>f.id===m.value.connectionId);return _?`${_.instance_name} (${_.db_type})`:"未选择连接"}const D=oe({get:()=>m.value.connectionId!=null?String(m.value.connectionId):"",set:_=>{m.value.connectionId=_?Number(_):null,_&&j(Number(_))}}),g=oe({get:()=>m.value.database||"",set:_=>{m.value.database=_}});function v(_){(_.ctrlKey||_.metaKey)&&_.key==="Enter"&&(_.preventDefault(),Z())}const s=oe(()=>{if(!G.value)return l.value;const _=G.value.toLowerCase();return l.value.filter(f=>f.sql.toLowerCase().includes(_)||f.database&&f.database.toLowerCase().includes(_))}),c=oe(()=>{if(!W.value)return R.value;const _=W.value.toLowerCase();return R.value.filter(f=>f.name.toLowerCase().includes(_)||f.sql.toLowerCase().includes(_))});return Oe(async()=>{await E(),be(),$e()}),Re(()=>q.connectionId,async _=>{_&&z.value.length>0&&z.value.find(x=>x.id===_)&&m.value.connectionId!==_&&(m.value.connectionId=_,await j(_))}),(_,f)=>(i(),p("div",{class:"space-y-4",onKeydown:v},[a(t(Te),null,{default:n(()=>[a(t(De),{class:"p-4"},{default:n(()=>[e("div",zt,[a(t(Fe),{modelValue:D.value,"onUpdate:modelValue":f[0]||(f[0]=x=>D.value=x)},{default:n(()=>[a(t(Ne),{class:"min-w-[200px]"},{default:n(()=>[a(t(Pe),{placeholder:"选择数据库连接"})]),_:1}),a(t(Ae),null,{default:n(()=>[(i(!0),p(B,null,Q(z.value,x=>(i(),A(t(ve),{key:x.id,value:String(x.id)},{default:n(()=>[r(d(x.instance_name)+" ("+d(x.db_type)+" @ "+d(x.host)+":"+d(x.port)+") ",1)]),_:2},1032,["value"]))),128))]),_:1})]),_:1},8,["modelValue"]),m.value.connectionId?(i(),A(t(ae),{key:0,variant:"outline",class:"text-xs"},{default:n(()=>[a(K,{name:"dashboard",size:14,class:"mr-1"}),r(" "+d(de()),1)]),_:1})):y("",!0),a(t(Fe),{modelValue:g.value,"onUpdate:modelValue":f[1]||(f[1]=x=>g.value=x)},{default:n(()=>[a(t(Ne),{class:"min-w-[180px]"},{default:n(()=>[a(t(Pe),{placeholder:"选择数据库"})]),_:1}),a(t(Ae),null,{default:n(()=>[(i(!0),p(B,null,Q(O.value,x=>(i(),A(t(ve),{key:x,value:x},{default:n(()=>[r(d(x),1)]),_:2},1032,["value"]))),128))]),_:1})]),_:1},8,["modelValue"]),f[13]||(f[13]=e("div",{class:"flex-1"},null,-1)),F.value?(i(),A(t(ae),{key:1,variant:"secondary",class:"text-xs"},{default:n(()=>[a(K,{name:"settings",size:14,class:"mr-1"}),f[12]||(f[12]=r(" 只读模式 ",-1))]),_:1})):y("",!0),a(t(T),{variant:"outline",size:"sm",onClick:f[2]||(f[2]=x=>ne.value=!ne.value)},{default:n(()=>[a(K,{name:"archive",size:14,class:"mr-1"}),r(" 已保存 ("+d(R.value.length)+") ",1)]),_:1}),a(t(T),{variant:"outline",size:"sm",onClick:f[3]||(f[3]=x=>X.value=!X.value)},{default:n(()=>[a(K,{name:"clock",size:14,class:"mr-1"}),r(" 历史 ("+d(l.value.length)+") ",1)]),_:1})]),e("div",Vt,[f[14]||(f[14]=e("div",{class:"text-xs text-muted-foreground mb-2 font-semibold"},"SQL 模板:",-1)),e("div",jt,[(i(),p(B,null,Q(V,x=>a(t(T),{key:x.name,variant:"outline",size:"sm",onClick:L=>he(x)},{default:n(()=>[r(d(x.name),1)]),_:2},1032,["onClick"])),64))])]),e("div",Lt,[e("div",Ut,[e("div",Ot,[(i(!0),p(B,null,Q(N.value,x=>(i(),p("div",{key:x.id,onClick:L=>C.value=x.id,class:se(["px-4 py-2 text-sm border-r cursor-pointer flex items-center gap-2 min-w-[120px] transition-colors",C.value===x.id?"bg-muted font-semibold border-b-2 border-b-primary text-foreground":"text-muted-foreground hover:bg-muted/50"])},[e("span",Rt,d(x.name),1),e("button",{onClick:Ke(L=>te(x.id),["stop"]),class:"text-xs opacity-50 hover:opacity-100 text-muted-foreground",title:"重命名"},[a(K,{name:"edit",size:12})],8,Ft),e("button",{onClick:Ke(L=>ie(x.id),["stop"]),class:"text-xs opacity-50 hover:opacity-100 hover:text-destructive",title:"关闭"},[a(K,{name:"x",size:12})],8,Nt)],10,It))),128))]),a(t(T),{variant:"ghost",size:"sm",onClick:h,title:"新建查询标签页"},{default:n(()=>[a(K,{name:"plus",size:14,class:"mr-1"}),f[15]||(f[15]=r(" 新建 ",-1))]),_:1})])]),e("div",Pt,[e("div",At,[e("div",Bt,[f[16]||(f[16]=e("span",{class:"text-sm font-semibold"},"SQL 编辑器",-1)),m.value.database?(i(),A(t(ae),{key:0,variant:"secondary",class:"text-xs"},{default:n(()=>[r(" DB: "+d(m.value.database),1)]),_:1})):w.value?(i(),A(t(ae),{key:1,variant:"outline",class:"text-xs"},{default:n(()=>[r(" 默认DB: "+d(w.value),1)]),_:1})):y("",!0)]),e("div",Mt,[a(t(T),{variant:"outline",size:"sm",onClick:f[4]||(f[4]=x=>m.value.sql=""),title:"清空编辑器"},{default:n(()=>[...f[17]||(f[17]=[r(" 清空 ",-1)])]),_:1}),a(t(T),{variant:"outline",size:"sm",onClick:ue,title:"保存此SQL"},{default:n(()=>[a(K,{name:"archive",size:14,class:"mr-1"}),f[18]||(f[18]=r(" 保存 ",-1))]),_:1}),a(t(T),{size:"sm",onClick:Z,disabled:m.value.isRunning||!u.value,title:"Ctrl+Enter 执行"},{default:n(()=>[a(K,{name:"play",size:14,class:"mr-1"}),r(" "+d(m.value.isRunning?"执行中...":"执行 (Ctrl+Enter)"),1)]),_:1},8,["disabled"])])]),a(t(Ge),{modelValue:m.value.sql,"onUpdate:modelValue":f[5]||
5(f[5]=x=>m.value.sql=x),rows:"12",class:"w-full font-mono text-sm border-0 rounded-none resize-none focus-visible:ring-0",placeholder:`-- 输入SQL语句
6SELECT * FROM table_name LIMIT 10;
7
8-- 快捷键: Ctrl+Enter 执行`,spellcheck:"false"},null,8,["modelValue"])])]),_:1})]),_:1}),ne.value?(i(),A(t(Te),{key:0},{default:n(()=>[a(t(qe),{class:"pb-3"},{default:n(()=>[e("div",qt,[a(t(Me),{class:"text-base flex items-center gap-2"},{default:n(()=>[a(K,{name:"archive",size:16}),f[19]||(f[19]=r(" 已保存的SQL ",-1))]),_:1}),a(t(ee),{modelValue:W.value,"onUpdate:modelValue":f[6]||(f[6]=x=>W.value=x),placeholder:"搜索已保存SQL...",class:"w-48 h-8"},null,8,["modelValue"])])]),_:1}),a(t(De),null,{default:n(()=>[e("div",Qt,[(i(!0),p(B,null,Q(c.value,x=>(i(),p("div",{key:x.id,class:"p-3 border rounded-lg hover:bg-muted/50 transition-colors"},[e("div",Wt,[e("div",Ht,[e("span",Jt,d(x.name),1),a(t(T),{variant:"ghost",size:"sm",class:"h-6 w-6 p-0",onClick:L=>ge(x.id)},{default:n(()=>[a(K,{name:x.is_favorite?"star":"star-outline",size:14},null,8,["name"])]),_:2},1032,["onClick"])]),e("span",Kt,d(me(x.created_at)),1)]),e("pre",Gt,d(x.sql),1),e("div",Yt,[a(t(T),{variant:"ghost",size:"sm",class:"h-6 text-xs",onClick:L=>_e(x)},{default:n(()=>[...f[20]||(f[20]=[r(" 加载 ",-1)])]),_:1},8,["onClick"]),a(t(T),{variant:"ghost",size:"sm",class:"h-6 text-xs text-destructive",onClick:L=>ke(x.id)},{default:n(()=>[...f[21]||(f[21]=[r(" 删除 ",-1)])]),_:1},8,["onClick"]),x.database?(i(),A(t(ae),{key:0,variant:"outline",class:"text-xs"},{default:n(()=>[r("DB: "+d(x.database),1)]),_:2},1024)):y("",!0)])]))),128)),c.value.length===0?(i(),p("div",Xt," 暂无保存的SQL ")):y("",!0)])]),_:1})]),_:1})):y("",!0),X.value?(i(),A(t(Te),{key:1},{default:n(()=>[a(t(qe),{class:"pb-3"},{default:n(()=>[e("div",Zt,[a(t(Me),{class:"text-base flex items-center gap-2"},{default:n(()=>[a(K,{name:"clock",size:16}),f[22]||(f[22]=r(" 执行历史 ",-1))]),_:1}),e("div",es,[a(t(ee),{modelValue:G.value,"onUpdate:modelValue":f[7]||(f[7]=x=>G.value=x),placeholder:"搜索SQL...",class:"w-48 h-8"},null,8,["modelValue"]),a(t(T),{variant:"outline",size:"sm",onClick:b},{default:n(()=>[a(K,{name:"trash",size:14,class:"mr-1"}),f[23]||(f[23]=r(" 清空 ",-1))]),_:1})])])]),_:1}),a(t(De),null,{default:n(()=>[e("div",ts,[(i(!0),p(B,null,Q(s.value.slice(0,50),x=>(i(),p("div",{key:x.id,class:"p-3 border rounded-lg hover:bg-muted/50 transition-colors"},[e("div",ss,[e("div",as,[a(t(ae),{variant:x.success?"default":"destructive",class:"text-xs h-5 px-1.5"},{default:n(()=>[r(d(x.success?"成功":"失败"),1)]),_:2},1032,["variant"]),e("span",ns,d(me(x.executed_at)),1),a(t(T),{variant:"ghost",size:"sm",class:"h-6 w-6 p-0",onClick:L=>xe(x.id)},{default:n(()=>[a(K,{name:P.value.includes(x.id)?"star":"star-outline",size:14},null,8,["name"])]),_:2},1032,["onClick"])]),e("span",os,d(we(x.duration_ms)),1)]),e("pre",ls,d(x.sql),1),e("div",rs,[a(t(T),{variant:"ghost",size:"sm",class:"h-6 text-xs",onClick:L=>fe(x)},{default:n(()=>[...f[24]||(f[24]=[r(" 加载 ",-1)])]),_:1},8,["onClick"]),x.database?(i(),A(t(ae),{key:0,variant:"outline",class:"text-xs"},{default:n(()=>[r("DB: "+d(x.database),1)]),_:2},1024)):y("",!0),e("span",is,d(x.row_count)+" 行",1)])]))),128))])]),_:1})]),_:1})):y("",!0),a(t(Te),null,{default:n(()=>[e("div",us,[a(t(T),{variant:"ghost",size:"sm",class:se(I.value==="result"?"font-semibold":"text-muted-foreground"),onClick:f[8]||(f[8]=x=>I.value="result")},{default:n(()=>[...f[25]||(f[25]=[r(" 结果 ",-1)])]),_:1},8,["class"]),a(t(T),{variant:"ghost",size:"sm",class:se(I.value==="message"?"font-semibold":"text-muted-foreground"),onClick:f[9]||(f[9]=x=>I.value="message")},{default:n(()=>[...f[26]||(f[26]=[r(" 消息 ",-1)])]),_:1},8,["class"]),f[29]||(f[29]=e("div",{class:"flex-1"},null,-1)),m.value.result?(i(),p("div",ds,[a(t(T),{variant:"outline",size:"sm",onClick:f[10]||(f[10]=x=>pe("csv"))},{default:n(()=>[...f[27]||(f[27]=[r(" 导出 CSV ",-1)])]),_:1}),a(t(T),{variant:"outline",size:"sm",onClick:f[11]||(f[11]=x=>pe("json"))},{default:n(()=>[...f[28]||(f[28]=[r(" 导出 JSON ",-1)])]),_:1})])):y("",!0)]),a(t(De),{class:"p-4"},{default:n(()=>[I.value==="message"&&m.value.error?(i(),p("div",cs,[f[30]||(f[30]=e("h4",{class:"font-semibold text-destructive mb-2"},"执行错误",-1)),e("pre",vs,d(m.value.error),1)])):I.value==="message"&&m.value.result?(i(),p("div",ps,[f[31]||(f[31]=e("h4",{class:"font-semibold text-green-700 dark:text-green-400 mb-2"},"执行成功",-1)),e("div",fs,[e("p",null,"语句类型: "+d(m.value.result.statement_kind),1),e("p",null,"影响行数: "+d(m.value.result.affected_rows),1),e("p",null,"执行耗时: "+d(we(m.value.result.duration_ms)),1),m.value.lastExecuted?(i(),p("p",ms,"执行时间: "+d(me(m.value.lastExecuted)),1)):y("",!0)])])):I.value==="result"&&m.value.result?(i(),p("div",_s,[m.value.result.columns.length>0?(i(),p("div",gs,[e("div",bs,[f[32]||(f[32]=r(" 查询返回 ",-1)),e("span",xs,d(m.value.result.rows.length),1),r(" 行数据 (耗时 "+d(we(m.value.result.duration_ms))+") ",1)]),a(t(Ct),null,{default:n(()=>[a(t(St),null,{default:n(()=>[a(t(nt),null,{default:n(()=>[a(t(ot),{class:"w-12"},{default:n(()=>[...f[33]||(f[33]=[r("#",-1)])]),_:1}),(i(!0),p(B,null,Q(m.value.result.columns,x=>(i(),A(t(ot),{key:x},{default:n(()=>[r(d(x),1)]),_:2},1024))),128))]),_:1})]),_:1}),a(t(Dt),null,{default:n(()=>[(i(!0),p(B,null,Q(m.value.result.rows,(x,L)=>(i(),A(t(nt),{key:L},{default:n(()=>[a(t(lt),{class:"text-muted-foreground text-xs"},{default:n(()=>[r(d(L+1),1)]),_:2},1024),(i(!0),p(B,null,Q(x,(le,Ce)=>(i(),A(t(lt),{key:Ce,class:"font-mono text-xs"},{default:n(()=>[le===null?(i(),p("span",ys,"NULL")):(i(),p("span",ks,d(le),1))]),_:2},1024))),128))]),_:2},1024))),128))]),_:1})]),_:1})])):(i(),p("div",$s,[f[34]||(f[34]=e("p",{class:"text-lg font-semibold text-foreground"}
8,"SQL执行成功",-1)),e("p",ws,"影响 "+d(m.value.result.affected_rows)+" 行",1),e("p",hs,"耗时 "+d(we(m.value.result.duration_ms)),1)]))])):(i(),p("div",Cs,[...f[35]||(f[35]=[e("p",{class:"text-lg"},"执行SQL查询查看结果",-1),e("p",{class:"text-sm mt-2"},"提示: 使用 Ctrl+Enter 快速执行",-1)])]))]),_:1})]),_:1})],32))}}),Ds=ye({name:"SqlWorkspaceTab",__name:"SqlWorkspaceTab",props:{connectionId:{},connectionKey:{}},setup(M){return(q,z)=>(i(),A(t(Te),null,{default:n(()=>[a(t(qe),{class:"pb-3"},{default:n(()=>[a(t(Me),{class:"flex items-center gap-2 text-lg"},{default:n(()=>[a(K,{name:"edit",size:20}),z[0]||(z[0]=r(" SQL工作台 ",-1)),M.connectionKey?(i(),A(t(ae),{key:0,variant:"secondary",class:"ml-2"},{default:n(()=>[r(" 当前连接: "+d(M.connectionKey),1)]),_:1})):y("",!0)]),_:1})]),_:1}),a(t(De),null,{default:n(()=>[a(Ss,{"connection-id":M.connectionId,"connection-key":M.connectionKey},null,8,["connection-id","connection-key"])]),_:1})]),_:1}))}}),Ts={class:"space-y-2"},Es={class:"space-y-2"},zs={class:"grid grid-cols-2 gap-4"},Vs={class:"space-y-2"},js=["value"],Ls={class:"space-y-2"},Us={key:0,class:"text-xs text-muted-foreground"},Os={key:1,class:"max-h-20 overflow-y-auto border rounded-md p-2 bg-muted/30"},Is={class:"text-xs text-muted-foreground font-medium mb-1"},Rs={class:"flex flex-wrap gap-1"},Fs={class:"space-y-2"},Ns={class:"flex items-center justify-between"},Ps={class:"border rounded-md p-3 max-h-40 overflow-y-auto space-y-1"},As=["onClick"],Bs=["checked"],Ms={class:"flex-1"},qs={class:"text-sm font-medium"},Qs={key:0,class:"text-xs text-muted-foreground"},Ws={key:0,class:"text-xs text-muted-foreground text-center py-2"},Hs={key:0,class:"text-xs text-muted-foreground"},Js={key:0,class:"space-y-2"},Ks={class:"flex items-center justify-between"},Gs={key:0,class:"border rounded-md p-3 text-center text-sm text-muted-foreground"},Ys={key:1,class:"space-y-2"},Xs=["onUpdate:modelValue"],Zs=["value"],ea={key:0,class:"space-y-1"},ta={class:"text-xs text-muted-foreground font-medium"},sa={class:"flex flex-wrap gap-1 mt-1"},aa={class:"grid grid-cols-2 gap-4"},na={class:"space-y-2"},oa={class:"space-y-2"},la={class:"space-y-2"},ra={class:"grid grid-cols-2 gap-4"},ia={class:"space-y-2"},ua={class:"flex items-center gap-2"},da={class:"text-sm text-muted-foreground"},ca={class:"flex items-center gap-2"},va={class:"space-y-2"},pa={class:"flex items-center justify-between"},fa={class:"flex gap-2"},ma={key:0,class:"text-sm text-muted-foreground py-4 text-center"},_a={key:1,class:"text-sm text-muted-foreground py-4 text-center border rounded-md"},ga={key:2,class:"text-sm text-muted-foreground py-4 text-center border rounded-md"},ba={key:3,class:"border rounded-md max-h-96 overflow-y-auto"},xa=["onClick"],ya={class:"flex items-center gap-3"},ka=["checked"],$a={class:"font-medium text-sm"},wa={class:"text-xs text-muted-foreground"},ha={key:4,class:"text-sm text-muted-foreground"},Ca={class:"space-y-3"},Sa={class:"grid grid-cols-2 gap-4"},Da={class:"space-y-2"},Ta={class:"space-y-2"},Ea={class:"flex items-center gap-3"},za={class:"text-xs text-muted-foreground"},Va={key:0,class:"text-sm text-muted-foreground py-4 text-center"},ja={key:1,class:"border rounded-md p-6 text-center"},La={key:2,class:"border rounded-md divide-y max-h-96 overflow-y-auto"},Ua={class:"flex items-center justify-between"},Oa={class:"flex items-center gap-2"},Ia=["onUpdate:modelValue"],Ra={class:"text-sm font-medium"},Fa={class:"grid grid-cols-3 gap-2 pl-6"},Na={class:"space-y-1"},Pa=["onUpdate:modelValue"],Aa={key:0,class:"space-y-1"},Ba={class:"flex items-center gap-1"},Ma={key:1,class:"text-xs text-muted-foreground"},qa={key:0,class:"flex flex-wrap gap-1 mt-1"},Qa={key:1,class:"col-span-2 space-y-1"},Wa={key:2,class:"space-y-1"},Ha={class:"space-y-2"},Ja={class:"space-y-2"},Ka={class:"space-y-2"},Ga={class:"grid grid-cols-2 gap-4"},Ya={class:"space-y-2"},Xa={class:"space-y-2"},Za={class:"space-y-3"},en={class:"grid grid-cols-2 gap-2"},tn={class:"flex items-center gap-2 text-sm"},sn={class:"flex items-center gap-2 text-sm"},an={class:"flex items-center gap-2 text-sm"},nn={class:"flex items-center gap-2 text-sm"},on={class:"flex items-center gap-2 text-sm"},ln={class:"flex items-center gap-2 text-sm"},rn={class:"flex items-center gap-2 text-sm"},un={class:"flex items-center gap-2 text-sm"},dn={class:"flex items-center gap-2"},cn={key:0,class:"space-y-4 pl-4 border-l-2 border-blue-300"},vn={class:"space-y-2"}
8,pn={key:0,class:"space-y-2"},fn={key:1,class:"space-y-2"},mn={class:"flex items-center gap-2"},_n={key:0,class:"space-y-4 pl-4 border-l-2 border-green-300"},gn={class:"space-y-2"},bn={class:"flex gap-2"},xn={key:0,class:"bg-gray-50 dark:bg-gray-900 rounded p-3 space-y-2"},yn={class:"block text-xs bg-white dark:bg-gray-800 p-2 rounded border break-all"},kn={class:"text-xs text-muted-foreground mt-1"},$n={class:"bg-gray-100 dark:bg-gray-700 px-1 rounded"},wn={class:"space-y-4"},hn={class:"space-y-2"},Cn={key:0,class:"bg-green-50 dark:bg-green-950 border border-green-200 dark:border-green-800 rounded p-3 text-xs text-green-800 dark:text-green-200"},Sn={key:1,class:"bg-gray-50 dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded p-3 text-xs text-muted-foreground"},pt=ye({__name:"DataTransferConfigDialog",props:{open:{type:Boolean},instanceOptions:{},connections:{},editingConfig:{},transferSummary:{}},emits:["close","saved","expand-connection","update:open"],setup(M,{emit:q}){const z=M,u=q,w=oe(()=>!!z.editingConfig&&z.editingConfig.id!=null),O=k(!1),S=k("basic"),H=k(z.open??!0);Re(S,v=>{v==="tables"&&(console.log("[activeTab watch] Switched to tables tab"),!P.value&&o.value.source_instance_id&&o.value.source_database&&(console.log("[activeTab watch] Loading tables..."),ue())),v==="strategy"&&o.value.source_instance_id&&o.value.source_database&&$()}),Re(()=>z.open,v=>{v!==void 0&&(H.value=v)}),Oe(()=>{var v,s;console.log("[DataTransferConfigDialog] Component mounted"),console.log("[DataTransferConfigDialog] editingConfig:",(v=z.editingConfig)==null?void 0:v.id),console.log("[DataTransferConfigDialog] transferSummary:",(s=z.transferSummary)==null?void 0:s.source_instance_id),console.log("[DataTransferConfigDialog] open:",z.open),S.value="basic",R(),z.editingConfig?(console.log("[DataTransferConfigDialog] Initializing from editingConfig in onMounted"),N(z.editingConfig)):z.transferSummary?(console.log("[DataTransferConfigDialog] Initializing from transferSummary in onMounted"),C(z.transferSummary)):console.log("[DataTransferConfigDialog] New config mode in onMounted")});function N(v){console.log("[initializeFromEditingConfig] Initializing from config:",v.id),console.log("[initializeFromEditingConfig] config.name:",v.name),console.log("[initializeFromEditingConfig] config.source_instance_id:",v.source_instance_id),console.log("[initializeFromEditingConfig] config.source_database:",v.source_database),console.log("[initializeFromEditingConfig] config.target_instance_ids:",v.target_instance_ids),console.log("[initializeFromEditingConfig] config.target_databases:",v.target_databases);const s=v;let c=[];if(s.target_databases)try{c=typeof s.target_databases=="string"?JSON.parse(s.target_databases):s.target_databases}catch(_){console.error("[initializeFromEditingConfig] Failed to parse target_databases:",_),c=[]}console.log("[initializeFromEditingConfig] config.extended_insert:",s.extended_insert),console.log("[initializeFromEditingConfig] config.use_transaction:",s.use_transaction),o.value={name:s.name||"",description:s.description||"",source_instance_id:s.source_instance_id,target_instance_ids:s.target_instance_ids||[],source_database:s.source_database||"",target_databases:c,sync_mode:s.sync_mode||"full",default_incremental_strategy:s.default_incremental_strategy||"timestamp",database_name:s.database_name||"",tables:(s.tables||[]).join(", "),exclude_tables:(s.exclude_tables||[]).join(", "),where_clause:s.where_clause||"",max_rows:s.max_rows,batch_size:s.batch_size||1e3,sync_indexes:s.sync_indexes??!0,sync_triggers:s.sync_triggers??!0,sync_constraints:s.sync_constraints??!0,sync_views:s.sync_views??!1,sync_stored_procedures:s.sync_stored_procedures??!1,on_conflict:s.on_conflict||"skip",drop_target_before_sync:s.drop_target_before_sync??!1,extended_insert:!!(s.extended_insert??!0),use_transaction:!!(s.use_transaction??!0),schedule_enabled:s.schedule_enabled??!1,schedule_type:s.schedule_type||"manual",interval_minutes:s.interval_minutes,cron_expression:s.cron_expression||"",webhook_enabled:s.webhook_enabled??!1,webhook_token:s.webhook_token||"",is_active:s.is_active??!0,notes:s.notes||"",history_retention_days:s.history_retention_days??30,notification_config_id:s.notification_config_id??null},s.table_sync_configs&&(V.value=s.table_sync_configs.map(_=>({..._}))),o.value.source_instance_id&&fe();for(const _ of c)_.instance_id&&b(_.instance_id);o.value.source_instance_id&&o.value.source_database&&(console.log("[Edit mode] Preloading tables for database:",o.value.source_database),ue())}function C(v){var c;console.log("[initializeFromTransferSummary] Initializing from summary");const s=v;if(o.value={name:s.name||"",description:s.description||"",source_instance_id:s.source_instance_id||null,target_instance_ids:s.target_instance_ids||[],source_database:s.source_database||"",target_databases:s.target_databases||[],sync_mode:s.sync_mode||"full",default_incremental_strategy:s.default_incremental_strategy||"timestamp",database_name:s.database_name||"",tables:(s.tables||[]).join(", "),exclude_tables:(s.exclude_tables||[]).join(", "),where_clause:s.where_clause||"",max_rows:s.max_rows||null,batch_size:s.batch_size||1e3,sync_indexes:s.sync_indexes??!0,sync_triggers:s.sync_triggers??!0,sync_constraints:s.sync_constraints??!0,sync_views:s.sync_views??!1,sync_stored_procedures:s.sync_stored_procedures??!1,on_conflict:s.on_conflict||"ski
8p",drop_target_before_sync:s.drop_target_before_sync??!1,extended_insert:!!(s.extended_insert??!0),use_transaction:!!(s.use_transaction??!0),schedule_enabled:!1,schedule_type:"manual",interval_minutes:null,cron_expression:"",webhook_enabled:!1,webhook_token:"",is_active:!0,notes:"",history_retention_days:30,notification_config_id:null},o.value.source_instance_id&&fe(),((c=o.value.target_databases)==null?void 0:c.length)>0)for(const _ of o.value.target_databases)_.instance_id&&b(_.instance_id);o.value.source_instance_id&&o.value.source_database&&ue()}Re([()=>z.editingConfig,()=>z.transferSummary],([v,s],[c,_])=>{if(!z.open&&!H.value){console.log("[DataTransferConfigDialog] Dialog not open, skipping initialization");return}if(console.log("[DataTransferConfigDialog] Initializing form, editingConfig:",v==null?void 0:v.id,"transferSummary:",s==null?void 0:s.source_instance_id),S.value="basic",v){N(v);return}if(s){C(s);return}console.log("[DataTransferConfigDialog] New config mode, resetting form"),o.value={name:"",description:"",source_instance_id:null,target_instance_ids:[],source_database:"",target_databases:[],sync_mode:"full",default_incremental_strategy:"timestamp",database_name:"",tables:"",exclude_tables:"",where_clause:"",max_rows:null,batch_size:1e3,sync_indexes:!0,sync_triggers:!0,sync_constraints:!0,sync_views:!1,sync_stored_procedures:!1,on_conflict:"skip",drop_target_before_sync:!1,extended_insert:!0,use_transaction:!0,schedule_enabled:!1,schedule_type:"manual",interval_minutes:null,cron_expression:"",webhook_enabled:!1,webhook_token:"",is_active:!0,notes:"",history_retention_days:30,notification_config_id:null}});const o=k({name:"",description:"",source_instance_id:null,source_database:"",target_instance_ids:[],target_databases:[],sync_mode:"full",default_incremental_strategy:"timestamp",database_name:"",tables:"",exclude_tables:"",where_clause:"",max_rows:null,batch_size:1e3,sync_indexes:!0,sync_triggers:!0,sync_constraints:!0,sync_views:!1,sync_stored_procedures:!1,on_conflict:"skip",drop_target_before_sync:!1,extended_insert:!0,use_transaction:!0,schedule_enabled:!1,schedule_type:"manual",interval_minutes:null,cron_expression:"",webhook_enabled:!1,webhook_token:"",is_active:!0,notes:"",history_retention_days:30,notification_config_id:null}),l=k([]);async function R(){try{const v=await ht("/api/notification/business-configs?page_size=100");if(v.ok){const s=await v.json();l.value=(s.configs||s.items||[]).filter(c=>c.is_active)}}catch(v){console.error("Failed to load notification configs:",v)}}function X(v){const s=o.value.target_instance_ids.indexOf(v);s>=0?(o.value.target_instance_ids.splice(s,1),o.value.target_databases=o.value.target_databases.filter(c=>c.instance_id!==v)):o.value.target_instance_ids.push(v)}function ne(v){X(v),o.value.target_instance_ids.includes(v)&&(delete W.value[v],b(v))}const G=k([]),W=k({}),F=k(!1),I=k([]),P=k(!1),V=k([]),m=k(!1),E=k({}),j=oe(()=>Object.values(E.value).some(v=>v));async function $(){if(!w.value){V.value.length===0&&I.value.length>0&&(V.value=I.value.filter(v=>v.selected).map(v=>({table_name:v.name,strategy:o.value.default_incremental_strategy||"timestamp",tracking_column:null,custom_where:null,state_mode:"record_position",window_minutes:60,is_enabled:!0})));return}m.value=!0;try{const v=await fetch(`/api/resource-ops/dbspace/transfer-configs/${z.editingConfig.id}/table-sync-configs`);if(v.ok){const s=await v.json();V.value=(s.items||[]).map(c=>({...c}))}}catch(v){console.error("[loadTableSyncConfigs] Failed:",v)}finally{m.value=!1}}async function Z(v){E.value[v]=!0;try{const s=`/api/resource-ops/dbspace/transfer-configs/detect-columns/${o.value.source_instance_id}?database=${encodeURIComponent(o.value.source_database)}&table_name=${encodeURIComponent(v)}`,c=await fetch(s);if(c.ok){const x=((await c.json()).tables||{})[v];if(x){const L=V.value.find(le=>le.table_name===v);L&&(L.available_columns=x.columns||[],L.recommended_strategy=x.recommended_strategy||"timestamp",!L.tracking_column&&x.recommended_column&&(L.tracking_column=x.recommended_column,L.strategy=x.recommended_strategy||"timestamp"))}}}catch(s){console.error(`[detectColumns] Failed for ${v}:`,s)}finally{E.value[v]=!1}}async function h(){for(const v of V.value)await Z(v.table_name)}function ie(v){V.value=V.value.filter(s=>s.table_name!==v)}function te(){const v=o.value.default_incremental_strategy;for(const s of V.value)s.strategy=v}async function ue(){if(!o.value.source_instance_id||!o.value.source_database){console.log("[loadTables] No source instance or database, clearing tables"),console.log("[loadTables] source_instance_id:",o.value.source_instance_id),console.log("[loadTables] source_database:",o.value.source_database),I.value=[];return}P.value=!0;try{const v=`/api/resource-ops/dbspace/transfer-configs/tables/${o.value.source_instance_id}?database=${encodeURIComponent(o.value.source_database)}`;console.log("[loadTables] Fetching tables from:",v);const s=await fetch(v);if(s.ok){const c=await s.json();console.log("[loadTables] API returned:",c),console.log("[loadTables] tables array:",c.tables);const _=o.value.tables?o.value.tables.split(",").map(f=>
8f.trim()).filter(Boolean):[];console.log("[loadTables] Selected tables from form:",_),console.log("[loadTables] Will mark as selected:",_.length===0?"ALL":_),I.value=(c.tables||[]).map(f=>({name:f.name,rows_count:f.rows_count,data_size_mb:f.data_size_mb,selected:_.length===0||_.includes(f.name)})),console.log("[loadTables] Loaded",I.value.length,"tables"),console.log("[loadTables] Selected count:",I.value.filter(f=>f.selected).length)}else{const c=await s.text();console.error("[loadTables] API error:",s.status,c),I.value=[]}}catch(v){console.error("[loadTables] Failed to load tables:",v),I.value=[]}finally{P.value=!1}}function _e(v){const s=I.value.find(c=>c.name===v);s&&(s.selected=!s.selected,pe())}function ge(){I.value.forEach(v=>v.selected=!0),pe()}function ke(){I.value.forEach(v=>v.selected=!1),pe()}function pe(){const v=I.value.filter(s=>s.selected).map(s=>s.name);o.value.tables=v.join(",")}function ce(){G.value=[],I.value=[],o.value.source_instance_id&&fe()}function be(){I.value=[],o.value.tables="",console.log("[onSourceDatabaseChange] Database changed to:",o.value.source_database),console.log("[onSourceDatabaseChange] Tables cleared, will load when switching to tables tab")}async function fe(){var v;if(!o.value.source_instance_id){G.value=[];return}F.value=!0;try{const s=(v=z.connections)==null?void 0:v.find(_=>_.id===o.value.source_instance_id);if(!s){console.warn("No connection found for instance",o.value.source_instance_id),G.value=[];return}const c=await fetch(`/api/db-platform/connections/${s.id}/databases`);if(c.ok){const _=await c.json();G.value=(_.items||[]).map(f=>f.name)}else console.error("Failed to load databases:",await c.text()),G.value=[]}catch(s){console.error("Failed to load source databases:",s),G.value=[]}finally{F.value=!1}}const xe=k({});async function b(v){var s;if(v){xe.value[v]=!0;try{const c=(s=z.connections)==null?void 0:s.find(f=>f.id===v);if(!c){W.value[v]=[];return}const _=await fetch(`/api/db-platform/connections/${c.id}/databases`);if(_.ok){const f=await _.json();W.value[v]=(f.items||[]).map(x=>x.name)}else W.value[v]=[]}catch(c){console.error("Failed to load target databases:",c),W.value[v]=[]}finally{xe.value[v]=!1}}}function Y(){if(o.value.target_instance_ids.length===0){alert("请先选择目标实例");return}o.value.target_databases.push({instance_id:o.value.target_instance_ids[0],database:""})}function $e(v){o.value.target_databases.splice(v,1)}function he(){o.value.webhook_token="wh_"+Math.random().toString(36).substring(2,14)+Date.now().toString(36)}function we(){if(!o.value.name.trim())return"请输入配置名称";if(!o.value.source_instance_id)return"请选择源实例";if(!o.value.source_database.trim())return"请输入源数据库名称";if(o.value.target_instance_ids.length===0)return"请至少选择一个目标实例";if(o.value.target_instance_ids.includes(o.value.source_instance_id))return"目标实例不能包含源实例";if(o.value.target_databases.length===0)return"请至少添加一个目标数据库映射";for(const v of o.value.target_databases)if(!v.database.trim())return"请填写目标数据库名称";return o.value.schedule_enabled&&o.value.schedule_type==="interval"&&(!o.value.interval_minutes||o.value.interval_minutes<1)?"请输入有效的间隔分钟数":o.value.schedule_enabled&&o.value.schedule_type==="cron"&&!o.value.cron_expression.trim()?"请输入Cron表达式":o.value.webhook_enabled&&!o.value.webhook_token.trim()?"请生成Webhook Token":null}async function me(){const v=we();if(v){alert(v);return}console.log("[saveConfig] Saving config, extended_insert:",o.value.extended_insert,"use_transaction:",o.value.use_transaction),O.value=!0;try{const s={name:o.value.name.trim(),description:o.value.description.trim()||null,source_instance_id:o.value.source_instance_id,source_database:o.value.source_database.trim()||null,target_instance_ids:o.value.target_instance_ids,target_databases:o.value.target_databases.length>0?o.value.target_databases:null,sync_mode:o.value.sync_mode,default_incremental_strategy:o.value.default_incremental_strategy||"timestamp",database_name:o.value.database_name.trim()||null,tables:o.value.tables.trim()?o.value.tables.split(",").map(L=>
8L.trim()).filter(Boolean):null,exclude_tables:o.value.exclude_tables.trim()?o.value.exclude_tables.split(",").map(L=>L.trim()).filter(Boolean):null,where_clause:o.value.where_clause.trim()||null,max_rows:o.value.max_rows,batch_size:o.value.batch_size,sync_indexes:o.value.sync_indexes,sync_triggers:o.value.sync_triggers,sync_constraints:o.value.sync_constraints,sync_views:o.value.sync_views,sync_stored_procedures:o.value.sync_stored_procedures,on_conflict:o.value.on_conflict,drop_target_before_sync:o.value.drop_target_before_sync,extended_insert:o.value.extended_insert,use_transaction:o.value.use_transaction,schedule_enabled:o.value.schedule_enabled,schedule_type:o.value.schedule_type,interval_minutes:o.value.interval_minutes,cron_expression:o.value.cron_expression.trim()||null,webhook_enabled:o.value.webhook_enabled,webhook_token:o.value.webhook_token.trim()||null,is_active:o.value.is_active,notes:o.value.notes.trim()||null,notification_config_id:o.value.notification_config_id,table_sync_configs:o.value.sync_mode==="incremental"?V.value.map(L=>({table_name:L.table_name,strategy:L.strategy,tracking_column:L.tracking_column||null,custom_where:L.custom_where||null,state_mode:L.state_mode,window_minutes:L.window_minutes,is_enabled:L.is_enabled})):[]},c=w.value?`/api/resource-ops/dbspace/transfer-configs/${z.editingConfig.id}`:"/api/resource-ops/dbspace/transfer-configs",_=w.value?"PUT":"POST",f=await fetch(c,{method:_,headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!f.ok){const L=await f.json().catch(()=>({}));throw new Error(L.detail||"保存失败")}const x=await f.json();console.log("[saveConfig] Saved config response, extended_insert:",x.extended_insert,"use_transaction:",x.use_transaction),u("saved")}catch(s){alert(`保存失败: ${s.message||s}`)}finally{O.value=!1}}const de=oe(()=>(z.connections&&z.connections.length>0?z.connections.map(s=>({id:s.id,instance_name:s.instance_name,db_type:s.db_type,host:s.host,port:s.port})):z.instanceOptions.map(s=>({...s,db_type:"",host:"",port:0}))).filter(s=>s.id!==o.value.source_instance_id)),D=oe(()=>`${typeof window<"u"?window.location.origin:""}/api/resource-ops/dbspace/transfers/webhook/${o.value.webhook_token}`);function g(v){var c;return((c=(z.connections&&z.connections.length>0?z.connections:z.instanceOptions).find(_=>_.id===v))==null?void 0:c.instance_name)??`实例 ${v}`}return(v,s)=>(i(),A(t(Ee),{open:H.value,"onUpdate:open":s[35]||(s[35]=c=>{H.value=c,u("update:open",c),c||u("close")})},{default:n(()=>[a(t(ze),{class:"max-w-3xl max-h-[85vh] flex flex-col",onPointerDownOutside:s[33]||(s[33]=c=>c.preventDefault()),onFocusOutside:s[34]||(s[34]=c=>c.preventDefault())},{default:n(()=>[a(t(Ve),null,{default:n(()=>[a(t(je),null,{default:n(()=>[r(d(w.value?"编辑同步配置":"新建同步配置"),1)]),_:1})]),_:1}),a(t(Tt),{modelValue:S.value,"onUpdate:modelValue":s[31]||(s[31]=c=>S.value=c),class:"w-full flex-1 flex flex-col min-h-0"},{default:n(()=>[a(t(Et),{class:"grid grid-cols-7 w-full shrink-0"},{default:n(()=>[a(t(Le),{value:"basic"},{default:n(()=>[...s[36]||(s[36]=[r("基本信息",-1)])]),_:1}),a(t(Le),{value:"tables"},{default:n(()=>[...s[37]||(s[37]=[r("选择表",-1)])]),_:1}),a(t(Le),{value:"strategy",disabled:o.value.sync_mode!=="incremental"},{default:n(()=>[...s[38]||(s[38]=[r("同步策略",-1)])]),_:1},8,["disabled"]),a(t(Le),{value:"sync"},{default:n(()=>[...s[39]||(s[39]=[r("同步选项",-1)])]),_:1}),a(t(Le),{value:"schedule"},{default:n(()=>[...s[40]||(s[40]=[r("调度设置",-1)])]),_:1}),a(t(Le),{value:"webhook"},{default:n(()=>[...s[41]||(s[41]=[r("Webhook",-1)])]),_:1}),a(t(Le),{value:"notification"},{default:n(()=>[...s[42]||(s[42]=[r("消息通知",-1)])]),_:1})]),_:1}),a(t(Ue),{value:"basic",class:"mt-4 space-y-4 overflow-y-auto flex-1"},{default:n(()=>[e("div",Ts,[a(t(U),null,{default:n(()=>[...s[43]||(s[43]=[r("配置名称 *",-1)])]),_:1}),a(t(ee),{modelValue:o.value.name,"onUpdate:modelValue":s[0]||(s[0]=c=>o.value.name=c),placeholder:"例如: 生产库→分析库同步"},null,8,["modelValue"])]),e("div",Es,[a(t(U),null,{default:n(()=>[...s[44]||(s[44]=[r("描述",-1)])]),_:1}),a(t(ee),{modelValue:o.value.description,"onUpdate:modelValue":s[1]||(s[1]=c=>o.value.description=c),placeholder:"可选描述信息"},null,8,["modelValue"])]),e("div",zs,[e("div",Vs,[a(t(U),null,{default:n(()=>[...s[45]||(s[45]=[r("源实例 *",-1)])]),_:1}),J(e("select",{"onUpdate:modelValue":s[2]||(s[2]=c=>o.value.source_instance_id=c),onChange:ce,class:"w-full px-3 py-2 text-sm border rounded-md bg-background"},[s[46]||(s[46]=e("option",{value:null,disabled:""},"选择源实例",-1)),(i(!0),p(B,null,Q(z.connections&&z.connections.length>0?z.connections:z.instanceOptions,c=>(i(),p("option",{key:c.id,value:c.id},[r(d(c.instance_name)+" ",1),"db_type"in c&&c.db_type?(i(),p(B,{key:0},[r(" ("+d(c.db_type)+" @ "+d(c.host)+":"+d(c.port)+")",1)],64)):y("",!0)],8,js))),128))],544),[[Se,o.value.source_instance_id]])]),e("div",Ls,[a(t(U),null,{default:n(()=>
8[...s[47]||(s[47]=[r("源数据库 *",-1)])]),_:1}),a(t(ee),{modelValue:o.value.source_database,"onUpdate:modelValue":s[3]||(s[3]=c=>o.value.source_database=c),onInput:be,placeholder:"输入源数据库名称(留空则同步所有数据库)"},null,8,["modelValue"]),F.value?(i(),p("div",Us,"加载数据库列表中...")):G.value.length>0?(i(),p("div",Os,[e("div",Is,"可用数据库 ("+d(G.value.length)+"):",1),e("div",Rs,[(i(!0),p(B,null,Q(G.value,c=>(i(),A(t(ae),{key:c,variant:"secondary",class:"text-xs"},{default:n(()=>[r(d(c),1)]),_:2},1024))),128))])])):y("",!0)])]),e("div",Fs,[e("div",Ns,[a(t(U),null,{default:n(()=>[...s[48]||(s[48]=[r("目标实例 * (可多选)",-1)])]),_:1}),o.value.target_instance_ids.length>0?(i(),A(t(T),{key:0,type:"button",variant:"outline",size:"sm",onClick:Y},{default:n(()=>[...s[49]||(s[49]=[r(" + 添加目标数据库 ",-1)])]),_:1})):y("",!0)]),e("div",Ps,[(i(!0),p(B,null,Q(de.value,c=>(i(),p("div",{key:c.id,class:"flex items-center gap-2 p-1.5 rounded hover:bg-muted cursor-pointer",onClick:_=>ne(c.id)},[e("input",{type:"checkbox",checked:o.value.target_instance_ids.includes(c.id),class:"rounded pointer-events-none"},null,8,Bs),e("div",Ms,[e("div",qs,d(c.instance_name),1),c.db_type?(i(),p("div",Qs,d(c.db_type)+" @ "+d(c.host)+":"+d(c.port),1)):y("",!0)]),a(t(ae),{variant:"outline",class:"text-xs ml-auto"},{default:n(()=>[r("ID: "+d(c.id),1)]),_:2},1024)],8,As))),128)),de.value.length===0?(i(),p("p",Ws," 无可用目标实例 ")):y("",!0)]),o.value.target_instance_ids.length>0?(i(),p("p",Hs," 已选 "+d(o.value.target_instance_ids.length)+" 个目标实例 ",1)):y("",!0)]),o.value.target_instance_ids.length>0?(i(),p("div",Js,[e("div",Ks,[a(t(U),null,{default:n(()=>[...s[50]||(s[50]=[r("目标数据库映射 *",-1)])]),_:1}),a(t(T),{type:"button",variant:"outline",size:"sm",onClick:Y},{default:n(()=>[...s[51]||(s[51]=[r(" + 添加目标数据库 ",-1)])]),_:1})]),s[54]||(s[54]=e("p",{class:"text-xs text-muted-foreground"},"选择已有数据库或输入新数据库名称(不存在时将自动创建)",-1)),o.value.target_databases.length===0?(i(),p("div",Gs," 点击上方「添加目标数据库」按钮配置目标数据库映射 ")):(i(),p("div",Ys,[(i(!0),p(B,null,Q(o.value.target_databases,(c,_)=>(i(),p("div",{key:_,class:"flex items-center gap-2"},[J(e("select",{"onUpdate:modelValue":f=>c.instance_id=f,class:"flex-1 px-3 py-2 text-sm border rounded-md bg-background"},[s[52]||(s[52]=e("option",{value:null,disabled:""},"选择目标实例",-1)),(i(!0),p(B,null,Q(de.value,f=>(i(),p("option",{key:f.id,value:f.id},d(f.instance_name),9,Zs))),128))],8,Xs),[[Se,c.instance_id]]),a(t(ee),{modelValue:c.database,"onUpdate:modelValue":f=>c.database=f,placeholder:"输入目标数据库名称",class:"flex-1"},null,8,["modelValue","onUpdate:modelValue"]),a(t(T),{type:"button",variant:"ghost",size:"sm",onClick:f=>$e(_),class:"text-red-500"},{default:n(()=>[...s[53]||(s[53]=[r(" × ",-1)])]),_:1},8,["onClick"])]))),128)),o.value.target_instance_ids.length>0?(i(),p("div",ea,[(i(!0),p(B,null,Q(o.value.target_instance_ids,c=>{var _,f;return J((i(),p("div",{key:`ref-${c}`},[e("div",ta,d(g(c))+" 可用数据库 ("+d((_=W.value[c])==null?void 0:_.length)+"): ",1),e("div",sa,[(i(!0),p(B,null,Q(W.value[c],x=>(i(),A(t(ae),{key:x,variant:"secondary",class:"text-xs"},{default:n(()=>[r(d(x),1)]),_:2},1024))),128))])])),[[gt,((f=W.value[c])==null?void 0:f.length)>0]])}),128))])):y("",!0)]))])):y("",!0),e("div",aa,[e("div",na,[a(t(U),null,{default:n(()=>[...s[55]||(s[55]=[r("同步模式",-1)])]),_:1}),J(e("select",{"onUpdate:modelValue":s[4]||(s[4]=c=>o.value.sync_mode=c),class:"w-full px-3 py-2 text-sm border rounded-md bg-background"},[...s[56]||(s[56]=[e("option",{value:"full"},"全量同步 (结构+数据)",-1),e("option",{value:"schema_only"},"仅结构",-1),e("option",{value:"data_only"},"仅数据",-1),e("option",{value:"incremental"},"增量同步",-1)])],512),[[Se,o.value.sync_mode]])]),e("div",oa,[a(t(U),null,{default:n(()=>[...s[57]||(s[57]=[r("冲突处理",-1)])]),_:1}),J(e("select",{"onUpdate:modelValue":s[5]||(s[5]=c=>o.value.on_conflict=c),class:"w-full px-3 py-2 text-sm border rounded-md bg-background"},[...s[58]||(s[58]=[e("option",{value:"skip"},"跳过 (INSERT IGNORE)",-1),e("option",{value:"update"},"覆盖更新 (ON DUPLICATE KEY UPDATE)",-1),e("option",{value:"error"},"报错中止",-1)])],512),[[Se,o.value.on_conflict]])])]),e("div",la,[a(t(U),null,{default:n(()=>[...s[59]||(s[59]=[r("备注",-1)])]),_:1}),J(e("textarea",{"onUpdate:modelValue":s[6]||(s[6]=c=>o.value.notes=c),rows:"2",class:"w-full px-3 py-2 text-sm border rounded-md bg-background",placeholder:"可选备注"},null,512),[[at,o.value.notes]])]),e("div",ra,[e("div",ia,[a(t(U),null,{default:n(()=>[...s[60]||(s[60]=[r("执行历史保留天数",-1)])]),_:1}),e("div",ua,[J(e("input",{type:"number","onUpdate:modelValue":s[7]||(s[7]=c=>o.value.history_retention_days=c),min:"0",class:"w-24 px-3 py-2 text-sm border rounded-md bg-background",placeholder:"30"},null,512),[[at,o.value.history_retention_days,void 0,{number:!0}]]),e("span",da,d(o.value.history_retention_days===0?"永久保留":"天"),1)]),s[61]||(s[61]=e("p",{class:"text-xs text-muted-foreground"},"设为0表示无限期保留执行历史",-1))])]),e("div",ca,[J(e("input",{type:"checkbox","onUpdate:modelValue":s[8]||(s[8]=c=>o.value.is_active=c),id:"is_active",class:"rounded"},null,512),[[re,o.value.is_active]]),a(t(U),{for:"is_active"},{default:n(()=>[...s[62]||(s[62]=[r("启用配置",-1)])]),_:1})])]),_:1}),a(t(Ue),{value:"tables",class:"mt-4 space-y-4"},{default:n(()=>[e("div",va,[e("div",pa,[a(t(U),null,{default:n(()=>[...s[63]||(s[63]=[r("选择同步表",-1)])]),_:1}),e("div",fa,[a(t(T),{type:"button",variant:"outline",size:"sm",onClick:ge,disabled:I.value.length===0},{default:n(()=>[...s[64]||(s[64]=[r(" 全选 ",-1)])]),_:1},8,["disabled"]),a(t(T),{type:"button",variant:"outline",size:"sm",onClick:ke,disabled:I.value.length===0},{default:n(()=>
8[...s[65]||(s[65]=[r(" 取消全选 ",-1)])]),_:1},8,["disabled"]),a(t(T),{type:"button",variant:"outline",size:"sm",onClick:ue,disabled:P.value||!o.value.source_database},{default:n(()=>[a(K,{name:"refresh",size:14,class:"mr-1"}),s[66]||(s[66]=r(" 刷新 ",-1))]),_:1},8,["disabled"])])]),P.value?(i(),p("div",ma,[a(K,{name:"refresh",size:16,class:"mr-2 animate-spin inline-block"}),s[67]||(s[67]=r(" 加载表列表中... ",-1))])):I.value.length===0&&o.value.source_database?(i(),p("div",_a,[a(K,{name:"x",size:16,class:"mr-2 inline-block"}),s[68]||(s[68]=r(" 该数据库中没有表 ",-1)),s[69]||(s[69]=e("div",{class:"text-xs mt-2"},"如果确认有表,请检查数据库连接和权限",-1))])):I.value.length===0&&!o.value.source_database?(i(),p("div",ga,[a(K,{name:"x",size:16,class:"mr-2 inline-block"}),s[70]||(s[70]=r(' 请先在"基本信息"标签页选择源数据库 ',-1))])):(i(),p("div",ba,[(i(!0),p(B,null,Q(I.value,c=>(i(),p("div",{key:c.name,onClick:_=>_e(c.name),class:se(["flex items-center justify-between p-3 border-b last:border-b-0 cursor-pointer transition-colors",c.selected?"bg-blue-50 dark:bg-blue-950":"hover:bg-muted"])},[e("div",ya,[e("input",{type:"checkbox",checked:c.selected,class:"rounded accent-blue-600 pointer-events-none"},null,8,ka),e("div",null,[e("div",$a,d(c.name),1),e("div",wa,[r(d(c.rows_count??0)+" 行 ",1),c.data_size_mb?(i(),p(B,{key:0},[r(" · "+d(c.data_size_mb)+" MB ",1)],64)):y("",!0)])])])],10,xa))),128))])),I.value.length>0?(i(),p("div",ha," 已选择 "+d(I.value.filter(c=>c.selected).length)+" / "+d(I.value.length)+" 个表 ",1)):y("",!0)])]),_:1}),a(t(Ue),{value:"strategy",class:"mt-4 space-y-4 overflow-y-auto flex-1"},{default:n(()=>[e("div",Ca,[e("div",Sa,[e("div",Da,[a(t(U),null,{default:n(()=>[...s[71]||(s[71]=[r("默认增量策略",-1)])]),_:1}),J(e("select",{"onUpdate:modelValue":s[9]||(s[9]=c=>o.value.default_incremental_strategy=c),class:"w-full px-3 py-2 text-sm border rounded-md bg-background"},[...s[72]||(s[72]=[e("option",{value:"timestamp"},"时间戳 (updated_at/modified_at)",-1),e("option",{value:"primary_key"},"主键递增 (id)",-1),e("option",{value:"custom_where"},"自定义 WHERE 条件",-1),e("option",{value:"full"},"全量 (不做增量)",-1)])],512),[[Se,o.value.default_incremental_strategy]])]),e("div",Ta,[a(t(U),null,{default:n(()=>[...s[73]||(s[73]=[r("状态追踪模式",-1)])]),_:1}),e("select",{class:"w-full px-3 py-2 text-sm border rounded-md bg-background",onChange:s[10]||(s[10]=c=>{const _=c.target.value;V.value.forEach(f=>f.state_mode=_)})},[...s[74]||(s[74]=[e("option",{value:"record_position"},"记录最后同步位置",-1),e("option",{value:"sliding_window"},"固定时间窗口",-1)])],32)])]),e("div",Ea,[a(t(T),{type:"button",variant:"outline",size:"sm",onClick:h,disabled:j.value},{default:n(()=>[r(d(j.value?"检测中...":"智能检测所有表增量列"),1)]),_:1},8,["disabled"]),a(t(T),{type:"button",variant:"outline",size:"sm",onClick:te},{default:n(()=>[...s[75]||(s[75]=[r(" 应用默认策略到所有表 ",-1)])]),_:1}),e("span",za," 已配置 "+d(V.value.length)+" 个表 ",1)])]),m.value?(i(),p("div",Va," 加载表同步配置中... ")):V.value.length===0?(i(),p("div",ja,[s[77]||(s[77]=e("div",{class:"text-sm text-muted-foreground mb-2"},"还没有配置表级同步策略",-1)),s[78]||(s[78]=e("div",{class:"text-xs text-muted-foreground mb-3"}," 请先在“选择表”Tab中选择表,或点击下方按钮从已选表生成 ",-1)),a(t(T),{type:"button",variant:"outline",size:"sm",onClick:$},{default:n(()=>[...s[76]||(s[76]=[r(" 从已选表生成配置 ",-1)])]),_:1})])):(i(),p("div",La,[(i(!0),p(B,null,Q(V.value,c=>(i(),p("div",{key:c.table_name,class:"p-3 space-y-2"},[e("div",Ua,[e("div",Oa,[J(e("input",{type:"checkbox","onUpdate:modelValue":_=>c.is_enabled=_,class:"rounded accent-blue-600"},null,8,Ia),[[re,c.is_enabled]]),e("span",Ra,d(c.table_name),1),c.recommended_strategy?(i(),A(t(ae),{key:0,variant:"outline",class:"text-xs"},{default:n(()=>[r(" 推荐: "+d(c.recommended_strategy),1)]),_:2},1024)):y("",!0)]),a(t(T),{type:"button",variant:"ghost",size:"sm",class:"text-red-500 h-6 px-2",onClick:_=>ie(c.table_name)},{default:n(()=>[...s[79]||(s[79]=[r(" × ",-1)])]),_:1},8,["onClick"])]),e("div",Fa,[e("div",Na,[a(t(U),{class:"text-xs"},{default:n(()=>[...s[80]||(s[80]=[r("同步策略",-1)])]),_:1}),J(e("select",{"onUpdate:modelValue":_=>c.strategy=_,class:"w-full px-2 py-1 text-xs border rounded-md bg-background"},[...s[81]||(s[81]=[e("option",{value:"timestamp"},"时间戳",-1),e("option",{value:"primary_key"},"主键递增",-1),e("option",{value:"custom_where"},"自定义 WHERE",-1),e("option",{value:"full"},"全量",-1)])],8,Pa),[[Se,c.strategy]])]),c.strategy!=="custom_where"&&c.strategy!=="full"?(i(),p("div",Aa,[e("div",Ba,[a(t(U),{class:"text-xs"},{default:n(()=>[...s[82]||(s[82]=[r("追踪列",-1)])]),_:1}),E.value[c.table_name]?(i(),p("span",Ma,"检测中...")):(i(),A(t(T),{key:0,t
8ype:"button",variant:"ghost",size:"sm",class:"h-4 px-1 text-xs",onClick:_=>Z(c.table_name)},{default:n(()=>[...s[83]||(s[83]=[r(" 检测 ",-1)])]),_:1},8,["onClick"]))]),a(t(ee),{modelValue:c.tracking_column,"onUpdate:modelValue":_=>c.tracking_column=_,placeholder:"例如: updated_at",class:"h-7 text-xs"},null,8,["modelValue","onUpdate:modelValue"]),c.available_columns&&c.available_columns.length>0?(i(),p("div",qa,[(i(!0),p(B,null,Q(c.available_columns,_=>(i(),A(t(ae),{key:_,variant:"secondary",class:"text-xs cursor-pointer hover:bg-blue-100",onClick:Ke(f=>c.tracking_column=_,["stop"])},{default:n(()=>[r(d(_),1)]),_:2},1032,["onClick"]))),128))])):y("",!0)])):y("",!0),c.strategy==="custom_where"?(i(),p("div",Qa,[a(t(U),{class:"text-xs"},{default:n(()=>[...s[84]||(s[84]=[r("自定义 WHERE 条件",-1)])]),_:1}),a(t(ee),{modelValue:c.custom_where,"onUpdate:modelValue":_=>c.custom_where=_,placeholder:"例如: status = 'active' AND created_at > DATE_SUB(NOW(), INTERVAL 7 DAY)",class:"h-7 text-xs"},null,8,["modelValue","onUpdate:modelValue"])])):y("",!0),c.state_mode==="sliding_window"?(i(),p("div",Wa,[a(t(U),{class:"text-xs"},{default:n(()=>[...s[85]||(s[85]=[r("窗口分钟数",-1)])]),_:1}),a(t(ee),{modelValue:c.window_minutes,"onUpdate:modelValue":_=>c.window_minutes=_,modelModifiers:{number:!0},type:"number",min:"1",class:"h-7 text-xs",placeholder:"60"},null,8,["modelValue","onUpdate:modelValue"])])):y("",!0)])]))),128))])),s[86]||(s[86]=e("div",{class:"bg-blue-50 dark:bg-blue-950 border border-blue-200 dark:border-blue-800 rounded p-3 text-xs text-blue-800 dark:text-blue-200"},[e("strong",null,"提示:"),e("ul",{class:"mt-1 space-y-0.5 list-disc pl-4"},[e("li",null,[e("strong",null,"时间戳"),r(":按 updated_at/modified_at 列增量拉取,适合有更新时间字段的表")]),e("li",null,[e("strong",null,"主键递增"),r(":按自增 id 列增量拉取,适合流水表、日志表")]),e("li",null,[e("strong",null,"自定义 WHERE"),r(":使用自定义 SQL WHERE 条件过滤同步数据")]),e("li",null,[e("strong",null,"全量"),r(":每次全表同步,适合小表或配置表")])])],-1))]),_:1}),a(t(Ue),{value:"sync",class:"space-y-4 mt-4 overflow-y-auto flex-1"},{default:n(()=>[e("div",Ha,[a(t(U),null,{default:n(()=>[...s[87]||(s[87]=[r("同步表 (留空=全部, 逗号分隔)",-1)])]),_:1}),a(t(ee),{modelValue:o.value.tables,"onUpdate:modelValue":s[11]||(s[11]=c=>o.value.tables=c),placeholder:"例如: users, orders, products"},null,8,["modelValue"])]),e("div",Ja,[a(t(U),null,{default:n(()=>[...s[88]||(s[88]=[r("排除表 (逗号分隔)",-1)])]),_:1}),a(t(ee),{modelValue:o.value.exclude_tables,"onUpdate:modelValue":s[12]||(s[12]=c=>o.value.exclude_tables=c),placeholder:"例如: tmp_*, log_*"},null,8,["modelValue"])]),e("div",Ka,[a(t(U),null,{default:n(()=>[...s[89]||(s[89]=[r("WHERE 过滤条件",-1)])]),_:1}),a(t(ee),{modelValue:o.value.where_clause,"onUpdate:modelValue":s[13]||(s[13]=c=>o.value.where_clause=c),placeholder:"例如: created_at > '2025-01-01'"},null,8,["modelValue"])]),e("div",Ga,[e("div",Ya,[a(t(U),null,{default:n(()=>[...s[90]||(s[90]=[r("最大行数",-1)])]),_:1}),a(t(ee),{modelValue:o.value.max_rows,"onUpdate:modelValue":s[14]||(s[14]=c=>o.value.max_rows=c),modelModifiers:{number:!0},type:"number",placeholder:"不限"},null,8,["modelValue"])]),e("div",Xa,[a(t(U),null,{default:n(()=>[...s[91]||(s[91]=[r("批量大小",-1)])]),_:1}),a(t(ee),{modelValue:o.value.batch_size,"onUpdate:modelValue":s[15]||(s[15]=c=>o.value.batch_size=c),modelModifiers:{number:!0},type:"number",placeholder:"1000"},null,8,["modelValue"])])]),e("div",Za,[a(t(U),null,{default:n(()=>[...s[92]||(s[92]=[r("结构同步选项",-1)])]),_:1}),e("div",en,[e("label",tn,[J(e("input",{type:"checkbox","onUpdate:modelValue":s[16]||(s[16]=c=>o.value.sync_indexes=c),class:"rounded"},null,512),[[re,o.value.sync_indexes]]),s[93]||(s[93]=r(" 同步索引 ",-1))]),e("label",sn,[J(e("input",{type:"checkbox","onUpdate:modelValue":s[17]||(s[17]=c=>o.value.sync_triggers=c),class:"rounded"},null,512),[[re,o.value.sync_triggers]]),s[94]||(s[94]=r(" 同步触发器 ",-1))]),e("label",an,[J(e("input",{type:"checkbox","onUpdate:modelValue":s[18]||(s[18]=c=>o.value.sync_constraints=c),class:"rounded"},null,512),[[re,o.value.sync_constraints]]),s[95]||(s[95]=r(" 同步约束 ",-1))]),e("label",nn,[J(e("input",{type:"checkbox","onUpdate:modelValue":s[19]||(s[19]=c=>o.value.sync_views=c),class:"rounded"},null,512),[[re,o.value.sync_views]]),s[96]||(s[96]=r(" 同步视图 ",-1))]),e("label",on,[J(e("input",{type:"checkbox","onUpdate:modelValue":s[20]||(s[20]=c=>o.value.sync_stored_procedures=c),class:"rounded"},null,512),[[re,o.value.sync_stored_procedures]]),s[97]||(s[97]=r(" 同步存储过程 ",-1))]),e("label",ln,[J(e("input",{type:"checkbox","onUpdate:modelValue":s[21]||(s[21]=c=>o.value.drop_target_before_sync=c),class:"rounded"},null,512),[[re,o.value.drop_target_before_sync]]),s[98]||(s[98]=r(" 同步前删除目标表 ",-1))]),e("label",rn,[J(e("input",{type:"checkbox","onUpdate:modelValue":s[22]||(s[22]=c=>o.value.extended_insert=c),class:"rounded"},null,512),[[re,o.value.extended_insert]]),s[99]||(s[99]=r(" 使用扩展INSERT (更快) ",-1))]),e("label",un,[J(e("input",{type:"checkbox","onUpdate:modelValue":s[23]||(s[23]=c=>o.value.use_transaction=c),class:"rounded"},null,512),[[re,o.value.use_transaction]]),s[100]||(s[100]=r(" 使用事务 ",-1))])])])]),_:1}
8),a(t(Ue),{value:"schedule",class:"space-y-4 mt-4 overflow-y-auto flex-1"},{default:n(()=>[e("div",dn,[J(e("input",{type:"checkbox","onUpdate:modelValue":s[24]||(s[24]=c=>o.value.schedule_enabled=c),id:"schedule_enabled",class:"rounded"},null,512),[[re,o.value.schedule_enabled]]),a(t(U),{for:"schedule_enabled"},{default:n(()=>[...s[101]||(s[101]=[r("启用定时调度",-1)])]),_:1})]),o.value.schedule_enabled?(i(),p("div",cn,[e("div",vn,[a(t(U),null,{default:n(()=>[...s[102]||(s[102]=[r("调度类型",-1)])]),_:1}),J(e("select",{"onUpdate:modelValue":s[25]||(s[25]=c=>o.value.schedule_type=c),class:"w-full px-3 py-2 text-sm border rounded-md bg-background"},[...s[103]||(s[103]=[e("option",{value:"manual"},"手动 (仅触发)",-1),e("option",{value:"interval"},"固定间隔",-1),e("option",{value:"cron"},"Cron 表达式",-1)])],512),[[Se,o.value.schedule_type]])]),o.value.schedule_type==="interval"?(i(),p("div",pn,[a(t(U),null,{default:n(()=>[...s[104]||(s[104]=[r("间隔分钟数",-1)])]),_:1}),a(t(ee),{modelValue:o.value.interval_minutes,"onUpdate:modelValue":s[26]||(s[26]=c=>o.value.interval_minutes=c),modelModifiers:{number:!0},type:"number",placeholder:"60"},null,8,["modelValue"])])):y("",!0),o.value.schedule_type==="cron"?(i(),p("div",fn,[a(t(U),null,{default:n(()=>[...s[105]||(s[105]=[r("Cron 表达式",-1)])]),_:1}),a(t(ee),{modelValue:o.value.cron_expression,"onUpdate:modelValue":s[27]||(s[27]=c=>o.value.cron_expression=c),placeholder:"0 2 * * * (每天凌晨2点)"},null,8,["modelValue"]),s[106]||(s[106]=e("p",{class:"text-xs text-muted-foreground"},[r(" 标准5段cron: 分 时 日 月 周。例: "),e("code",null,"*/30 * * * *"),r(" 每30分钟, "),e("code",null,"0 2 * * *"),r(" 每天2点 ")],-1))])):y("",!0),s[107]||(s[107]=e("div",{class:"bg-yellow-50 dark:bg-yellow-950 border border-yellow-200 dark:border-yellow-800 rounded p-3 text-xs text-yellow-800 dark:text-yellow-200"},[e("strong",null,"注意:"),r(" 定时调度需要在服务器启动时配置 "),e("code",null,"ENABLE_TRANSFER_SCHEDULER=true"),r(" 环境变量才会生效。多部署环境下仅在一个实例启用调度器以避免任务冲突。 ")],-1))])):y("",!0)]),_:1}),a(t(Ue),{value:"webhook",class:"space-y-4 mt-4 overflow-y-auto flex-1"},{default:n(()=>[e("div",mn,[J(e("input",{type:"checkbox","onUpdate:modelValue":s[28]||(s[28]=c=>o.value.webhook_enabled=c),id:"webhook_enabled",class:"rounded"},null,512),[[re,o.value.webhook_enabled]]),a(t(U),{for:"webhook_enabled"},{default:n(()=>[...s[108]||(s[108]=[r("启用 Webhook 触发",-1)])]),_:1})]),o.value.webhook_enabled?(i(),p("div",_n,[e("div",gn,[a(t(U),null,{default:n(()=>[...s[109]||(s[109]=[r("Webhook Token",-1)])]),_:1}),e("div",bn,[a(t(ee),{modelValue:o.value.webhook_token,"onUpdate:modelValue":s[29]||(s[29]=c=>o.value.webhook_token=c),placeholder:"wh_xxxxxxxxxxxx 或自定义Token",class:"flex-1 font-mono text-xs"},null,8,["modelValue"]),a(t(T),{variant:"outline",size:"sm",onClick:he},{default:n(()=>[...s[110]||(s[110]=[r("生成",-1)])]),_:1})]),s[111]||(s[111]=e("p",{class:"text-xs text-muted-foreground"},"可输入自定义Token或点击生成随机Token",-1))]),o.value.webhook_token?(i(),p("div",xn,[a(t(U),{class:"text-xs"},{default:n(()=>[...s[112]||(s[112]=[r("Webhook URL (GET/POST 均可访问):",-1)])]),_:1}),e("code",yn,d(D.value),1),e("p",kn,[s[113]||(s[113]=r(" 只需复制路径部分: ",-1)),e("code",$n,"/api/resource-ops/dbspace/transfers/webhook/"+d(o.value.webhook_token),1)])])):y("",!0)])):y("",!0)]),_:1}),a(t(Ue),{value:"notification",class:"space-y-4 mt-4 overflow-y-auto flex-1"},{default:n(()=>[e("div",wn,[e("div",hn,[a(t(U),null,{default:n(()=>[...s[114]||(s[114]=[r("关联业务通知配置",-1)])]),_:1}),a(t(Fe),{"model-value":o.value.notification_config_id?String(o.value.notification_config_id):"_none_","onUpdate:modelValue":s[30]||(s[30]=c=>{o.value.notification_config_id=c&&c!=="_none_"?Number(c):null})},{default:n(()=>[a(t(Ne),{class:"w-full"},{default:n(()=>[a(t(Pe),{placeholder:"选择通知配置(可选)"})]),_:1}),a(t(Ae),null,{default:n(()=>[a(t(ve),{value:"_none_"},{default:n(()=>[...s[115]||(s[115]=[r("不关联通知",-1)])]),_:1}),(i(!0),p(B,null,Q(l.value,c=>
8(i(),A(t(ve),{key:c.id,value:String(c.id)},{default:n(()=>[r(d(c.business_name)+" ("+d(c.channel_name||c.business_type)+") ",1)]),_:2},1032,["value"]))),128))]),_:1})]),_:1},8,["model-value"]),s[116]||(s[116]=e("p",{class:"text-xs text-muted-foreground"}," 选择后,传输完成/失败时将自动通过该业务配置发送消息通知。 ",-1))]),o.value.notification_config_id?(i(),p("div",Cn,[...s[117]||(s[117]=[e("strong",null,"已启用通知:",-1),r(" 传输执行完成后将自动触发通知。通知内容取决于所选业务配置的消息模板和触发事件设置。 ",-1)])])):(i(),p("div",Sn,' 未关联通知配置。如需在传输完成后自动发送通知,请先在"消息通知"模块创建业务配置,然后在此选择。 '))])]),_:1})]),_:1},8,["modelValue"]),a(t(Be),{class:"mt-4"},{default:n(()=>[a(t(T),{variant:"outline",onClick:s[32]||(s[32]=c=>u("close"))},{default:n(()=>[...s[118]||(s[118]=[r("取消",-1)])]),_:1}),a(t(T),{onClick:me,disabled:O.value},{default:n(()=>[r(d(O.value?"保存中...":w.value?"更新配置":"创建配置"),1)]),_:1},8,["disabled"])]),_:1})]),_:1})]),_:1},8,["open"]))}}),Dn={class:"space-y-4"},Tn={class:"flex items-center justify-between gap-4 pb-3 border-b"},En={class:"flex items-center gap-4 text-sm text-muted-foreground"},zn={key:0},Vn={key:1},jn={class:"flex items-center gap-2"},Ln={key:0,class:"text-center py-8 text-muted-foreground"},Un={key:1,class:"text-center py-8 text-muted-foreground"},On={key:2,class:"space-y-2"},In=["onClick"],Rn={class:"flex items-center justify-between gap-4"},Fn={class:"flex items-center gap-2 min-w-0"},Nn={class:"text-xs text-muted-foreground"},Pn={key:0,class:"text-xs text-muted-foreground"},An={class:"text-xs text-muted-foreground shrink-0"},Bn={key:0,class:"mt-2"},Mn={class:"w-full bg-gray-200 dark:bg-gray-700 rounded-full h-1.5"},qn={class:"flex items-center gap-4 mt-1 text-xs text-muted-foreground"},Qn={key:0},Wn={key:1},Hn={key:1,class:"flex items-center gap-4 mt-1 text-xs text-muted-foreground"},Jn={key:0},Kn={key:1},Gn={key:2},Yn={key:3},Xn={key:3,class:"border-t pt-4 space-y-3"},Zn={class:"font-semibold text-sm"},eo={key:0,class:"text-center py-4 text-muted-foreground"},to={key:1,class:"space-y-3"},so={class:"grid grid-cols-3 gap-3 text-sm"},ao={class:"ml-2"},no={class:"ml-2"},oo={class:"ml-2"},lo={class:"ml-2"},ro={class:"ml-2"},io={class:"ml-2"},uo={class:"ml-2"},co={class:"ml-2"},vo={key:0,class:"space-y-2"},po={class:"flex items-center gap-2"},fo={class:"font-medium"},mo={key:0,class:"text-xs text-muted-foreground"},_o={key:1,class:"text-xs text-red-500"},go={key:1,class:"bg-red-50 dark:bg-red-950 border border-red-200 dark:border-red-800 rounded p-3"},bo={class:"text-sm text-red-600 dark:text-red-400"},xo={key:2,class:"space-y-2"},yo={key:0,class:"font-medium"},ko={key:1,class:"font-medium"},$o={key:3,class:"space-y-2"},wo={class:"bg-gray-50 dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded p-3 max-h-96 overflow-y-auto"},ho={class:"text-xs font-mono whitespace-pre-wrap break-all text-gray-800 dark:text-gray-200"},Co={key:0,class:"border-t pt-4 space-y-4"},So={class:"space-y-3"},Do={class:"space-y-2"},To={class:"flex items-center gap-2 text-sm"},Eo={class:"flex items-center gap-2 text-sm"},zo={class:"flex items-center gap-2 text-sm"},Vo={class:"flex items-center gap-2 text-sm"},jo={class:"flex items-center gap-2 pt-2"},Lo=ye({__name:"ExecutionHistoryDialog",props:{configId:{},configName:{}},emits:["close"],setup(M,{emit:q}){const z=M,u=q,w=k([]),O=k(!1),S=k(null),H=k(!1),N=k(!1),C=k(0),o=k(!1),l=k(30);let R=null;async function X(){O.value=!0;try{const j=await fetch(`/api/resource-ops/dbspace/transfer-configs/${z.configId}/executions?page=1&page_size=50`);if(!j.ok)throw new Error("加载执行历史失败");const $=await j.json();w.value=$.items||[];const Z=await fetch(`/api/resource-ops/dbspace/transfer-configs/${z.configId}`);if(Z.ok){const h=await Z.json();l.value=h.history_retention_days||30}ne()}catch(j){console.error("Failed to load executions:",j)}finally{O.value=!1}}function ne(){const j=w.value.some($=>$.status==="running"||$.status==="pending");j&&!R?(console.log("[ExecutionHistoryDialog] Starting polling for running executions"),R=setInterval(async()=>{await X(),!w.value.some(Z=>Z.status==="running"||Z.status==="pending")&&R&&(console.log("[ExecutionHistoryDialog] No more running executions, stopping polling"),clearInterval(R),R=null)},2e3)):!j&&R&&(console.log("[ExecutionHistoryDialog] No running executions, clearing poll timer"),clearInterval(R),R=null)}async function G(j){H.value=!0;try{const $=await fetch(`/api/resource-ops/dbspace/transfer-executions/${j}`);if(!$.ok)throw new Error("加载执行详情失败");S.value=await $.json()}
8catch($){console.error("Failed to load execution detail:",$)}finally{H.value=!1}}function W(j){return{pending:"bg-yellow-100 text-yellow-700 dark:bg-yellow-900 dark:text-yellow-300",running:"bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-300",success:"bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-300",completed:"bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-300",failed:"bg-red-100 text-red-700 dark:bg-red-900 dark:text-red-300",cancelled:"bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400"}[j]||"bg-gray-100 text-gray-600"}function F(j){return{pending:"待执行",running:"执行中",success:"成功",completed:"已完成",failed:"失败",cancelled:"已取消"}[j]||j}function I(j){return{manual:"手动",webhook:"Webhook",schedule:"定时"}[j]||j}function P(j){if(j==null)return"-";if(j<60)return`${j}秒`;if(j<3600)return`${Math.floor(j/60)}分${j%60}秒`;const $=Math.floor(j/3600),Z=Math.floor(j%3600/60);return`${$}时${Z}分`}function V(j){return j?new Date(j).toLocaleString("zh-CN"):"-"}async function m(){N.value=!0,C.value=0}async function E(){if(confirm(`确认清除${C.value>0?C.value+"天前的":"所有"}执行历史?`)){o.value=!0;try{const j=`/api/resource-ops/dbspace/transfer-configs/${z.configId}/executions`,$=C.value>0?`?older_than_days=${C.value}`:"",Z=await fetch(j+$,{method:"DELETE"});if(!Z.ok)throw new Error("清除历史失败");const h=await Z.json();alert(h.message||"清除成功"),N.value=!1,C.value=0,await X()}catch(j){console.error("Failed to clear history:",j),alert("清除失败: "+j)}finally{o.value=!1}}}return Oe(()=>{X()}),bt(()=>{R&&clearInterval(R)}),(j,$)=>(i(),A(t(Ee),{open:!0,"onUpdate:open":$[5]||($[5]=Z=>u("close"))},{default:n(()=>[a(t(ze),{class:"max-w-4xl max-h-[85vh] overflow-y-auto"},{default:n(()=>{var Z;return[a(t(Ve),null,{default:n(()=>[a(t(je),null,{default:n(()=>[r("执行历史 - "+d(M.configName),1)]),_:1})]),_:1}),e("div",Dn,[e("div",Tn,[e("div",En,[e("span",null,"共 "+d(w.value.length)+" 条记录",1),l.value>0?(i(),p("span",zn,"保留"+d(l.value)+"天",1)):(i(),p("span",Vn,"永久保留"))]),e("div",jn,[a(t(T),{variant:"outline",size:"sm",class:"text-red-600 border-red-300 hover:bg-red-50",onClick:m},{default:n(()=>[a(K,{name:"trash",class:"h-4 w-4 mr-1"}),$[6]||($[6]=r(" 清除历史 ",-1))]),_:1})])]),O.value&&w.value.length===0?(i(),p("div",Ln," 加载中... ")):w.value.length===0?(i(),p("div",Un," 暂无执行记录 ")):(i(),p("div",On,[(i(!0),p(B,null,Q(w.value,h=>{var ie,te,ue;return i(),p("div",{key:h.id,class:se(["border rounded-lg p-3 hover:border-blue-300 dark:hover:border-blue-700 transition-colors cursor-pointer",{"border-blue-400 bg-blue-50/50 dark:bg-blue-950/30":((ie=S.value)==null?void 0:ie.id)===h.id}]),onClick:_e=>G(h.id)},[e("div",Rn,[e("div",Fn,[e("span",{class:se(["inline-flex items-center px-2 py-0.5 rounded text-xs font-medium",W(h.status)])},d(F(h.status)),3),a(t(ae),{variant:"outline",class:"text-xs font-mono shrink-0"},{default:n(()=>[r(d(h.execution_key),1)]),_:2},1024),e("span",Nn,d(I(h.trigger_type)),1),h.initiated_by?(i(),p("span",Pn,"by "+d(h.initiated_by),1)):y("",!0)]),e("div",An,d(V(h.created_at)),1)]),h.status==="running"?(i(),p("div",Bn,[e("div",Mn,[e("div",{class:"bg-blue-500 h-1.5 rounded-full transition-all",style:vt({width:`${h.progress_pct||0}%`})},null,4)]),e("div",qn,[e("span",null,d(h.progress_pct||0)+"%",1),h.current_table?(i(),p("span",Qn,"当前: "+d(h.current_table),1)):y("",!0),h.tables_processed?(i(),p("span",Wn,d(h.tables_processed)+"/"+d(h.tables_total)+" 表",1)):y("",!0)])])):y("",!0),h.status==="success"||h.status==="completed"||h.status==="failed"?(i(),p("div",Hn,[h.tables_processed!=null?(i(),p("span",Jn,"表: "+d(h.tables_processed)+"/"+d(h.tables_total),1)):y("",!0),h.rows_transferred!=null?(i(),p("span",Kn,"行: "+d((te=h.rows_transferred)==null?void 0:te.toLocaleString()),1)):y("",!0),h.data_size_mb!=null?(i(),p("span",Gn,d((ue=h.data_size_mb)==null?void 0:ue.toFixed(2))+" MB",1)):y("",!0),h.duration_seconds!=null?(i(),p("span",Yn,"耗时: "+d(P(h.duration_seconds)),1)):y("",!0)])):y("",!0)],10,In)}),128))])),S.value?(i(),p("div",Xn,[e("h4",Zn,"执行详情 - "+d(S.value.execution_key),1),H.value?(i(),p("div",eo,"加载中...")):(i(),p("div",to,[e("div",so,[e("div",null,[$[7]||($[7]=e("span",{class:"text-muted-foreground"},"状态:",-1)),e("span",{class:se(["ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium",W(S.value.status)])},d(F(S.value.status)),3)]),e("div",null,[$[8]||($[8]=e("span",{class:"text-muted-foreground"},"触发方式:",-1)),e("span",ao,d(I(S.value.trigger_type)),1)]),e("div",null,[$[9]||($[9]=e("span",{class:"text-muted-foreground"},"进度:",-1)),e("span",no,d(S.value.progress_pct||0)+"%",1)]),e("div",null,[$[10]||($[10]=e("span",{class:"text-muted-foreground"},"开始时间:",-1)),e("span",oo,d(V(S.value.started_at)),1)]),e("div",null,[$[11]||($[11]=e("span",{class:"text-muted-foreground"},"完成时间:",-1)),e("span",lo,d(V(S.value.completed_at)),1)]),e("div",null,[$[12]||($[12]=e("span",{class:"text-muted-foreground"},"耗时:",-1)),e("span",ro,d(P(S.value.duration_seconds)),1)]),e("div",null,[$[13]||($[13]=e("span",{class:"text-muted-foreground"},"处理表数:",-1)),e("span",io,d(S.value.tables_processed)+"/"+d(S.value.tables_total),1)]),e("div",null,[$[14]||($[14]=e("span",{class:"text-muted-foreground"},"传输行数:",-1)),e("span",uo,d(((Z=S.value.rows_transferred)==null?void 0:Z.toLocaleStr
8ing())||"-"),1)]),e("div",null,[$[15]||($[15]=e("span",{class:"text-muted-foreground"},"数据大小:",-1)),e("span",co,d(S.value.data_size_mb?`${S.value.data_size_mb.toFixed(2)} MB`:"-"),1)])]),S.value.target_results&&S.value.target_results.length>0?(i(),p("div",vo,[$[16]||($[16]=e("h5",{class:"text-sm font-medium"},"各目标执行结果",-1)),(i(!0),p(B,null,Q(S.value.target_results,(h,ie)=>{var te;return i(),p("div",{key:ie,class:"border rounded p-3 text-sm space-y-1"},[e("div",po,[e("span",{class:se(["inline-flex items-center px-2 py-0.5 rounded text-xs font-medium",W(h.status||"pending")])},d(F(h.status||"pending")),3),e("span",fo,"目标实例 "+d(h.target_instance_id),1)]),h.tables_processed!=null?(i(),p("div",mo," 表: "+d(h.tables_processed)+"/"+d(h.tables_total)+" | 行: "+d(((te=h.rows_transferred)==null?void 0:te.toLocaleString())||"-")+" | 耗时: "+d(P(h.duration_seconds)),1)):y("",!0),h.error_message?(i(),p("div",_o," 错误: "+d(h.error_message),1)):y("",!0)])}),128))])):y("",!0),S.value.error_message?(i(),p("div",go,[$[17]||($[17]=e("h5",{class:"text-sm font-medium text-red-700 dark:text-red-300 mb-1"},"错误信息",-1)),e("p",bo,d(S.value.error_message),1)])):y("",!0),S.value.error_details&&S.value.error_details.length>0?(i(),p("div",xo,[$[18]||($[18]=e("h5",{class:"text-sm font-medium text-red-700"},"详细错误",-1)),(i(!0),p(B,null,Q(S.value.error_details,(h,ie)=>(i(),p("div",{key:ie,class:"bg-red-50 dark:bg-red-950 border border-red-200 dark:border-red-800 rounded p-2 text-xs text-red-600 dark:text-red-400"},[h.table?(i(),p("span",yo,"表 "+d(h.table)+":",1)):y("",!0),h.target_instance_id?(i(),p("span",ko," (目标 "+d(h.target_instance_id)+"):",1)):y("",!0),r(" "+d(h.message||h.error||JSON.stringify(h)),1)]))),128))])):y("",!0),S.value.execution_logs?(i(),p("div",$o,[$[19]||($[19]=e("h5",{class:"text-sm font-medium"},"详细执行日志",-1)),e("div",wo,[e("pre",ho,d(S.value.execution_logs),1)])])):y("",!0)]))])):y("",!0)]),N.value?(i(),p("div",Co,[$[25]||($[25]=e("h4",{class:"font-semibold text-sm text-red-600"},"清除执行历史",-1)),e("div",So,[$[24]||($[24]=e("div",{class:"text-sm text-muted-foreground"},[e("p",null,"选择清除范围:")],-1)),e("div",Do,[e("label",To,[J(e("input",{type:"radio","onUpdate:modelValue":$[0]||($[0]=h=>C.value=h),value:0,class:"accent-red-600"},null,512),[[He,C.value]]),e("span",null,"清除所有执行历史 ("+d(w.value.length)+" 条)",1)]),e("label",Eo,[J(e("input",{type:"radio","onUpdate:modelValue":$[1]||($[1]=h=>C.value=h),value:7,class:"accent-red-600"},null,512),[[He,C.value]]),$[20]||($[20]=e("span",null,"清除 7 天前的执行历史",-1))]),e("label",zo,[J(e("input",{type:"radio","onUpdate:modelValue":$[2]||($[2]=h=>C.value=h),value:30,class:"accent-red-600"},null,512),[[He,C.value]]),$[21]||($[21]=e("span",null,"清除 30 天前的执行历史",-1))]),e("label",Vo,[J(e("input",{type:"radio","onUpdate:modelValue":$[3]||($[3]=h=>C.value=h),value:90,class:"accent-red-600"},null,512),[[He,C.value]]),$[22]||($[22]=e("span",null,"清除 90 天前的执行历史",-1))])]),e("div",jo,[a(t(T),{variant:"destructive",size:"sm",disabled:o.value,onClick:E},{default:n(()=>[r(d(o.value?"清除中...":"确认清除"),1)]),_:1},8,["disabled"]),a(t(T),{variant:"outline",size:"sm",disabled:o.value,onClick:$[4]||($[4]=h=>N.value=!1)},{default:n(()=>[...$[23]||($[23]=[r(" 取消 ",-1)])]),_:1},8,["disabled"])])])])):y("",!0)]}),_:1})]),_:1}))}});function ct(){return{sync_mode:"full",create_tables:!0,drop_target:!1,sync_indexes:!0,sync_foreign_keys:!0,sync_triggers:!1,sync_constraints:!0,extended_insert:!0,batch_size:1e3,on_conflict:"skip",use_transaction:!1,where_clause:"",max_rows:null}}const st="/api/data-transfer";async function Ie(M){const q=await fetch(`${st}${M}`);if(!q.ok)throw new Error((await q.json().catch(()=>({}))).detail||`请求失败: ${q.status}`);return q.json()}async function tt(M,q){const z=await fetch(`${st}${M}`,{method:"POST",headers:q?{"Content-Type":"application/json"}:void 0,body:q?JSON.stringify(q):void 0});if(!z.ok)throw new Error((await z.json().catch(()=>({}))).detail||`请求失败: ${z.status}`);return z.json()}
8function Uo(){const M=k(1),q=6,z=k(!1),u=k([]),w=k(!1),O=k(null),S=k(null),H=k([]),N=k([]),C=k(!1),o=k(""),l=k(""),R=k([]),X=k(!1),ne=k(["table","view","function","procedure","event"]),G=xt(ct()),W=k(null),F=k(""),I=k(null),P=k([]),V=k(!1),m=k(!1);let E=null,j=null;const $=oe(()=>u.value.find(g=>g.id===O.value)||null),Z=oe(()=>u.value.find(g=>g.id===S.value)||null),h=oe(()=>R.value.filter(g=>g.selected)),ie=oe(()=>{switch(M.value){case 1:return O.value!=null&&S.value!=null;case 2:return!!o.value;case 3:return h.value.length>0;case 4:return!0;case 5:return!0;case 6:return!0;default:return!1}}),te=oe(()=>M.value>1&&!V.value);function ue(){ge(),z.value=!0,ce()}function _e(){de(),z.value=!1,ge()}function ge(){M.value=1,O.value=null,S.value=null,H.value=[],N.value=[],o.value="",l.value="",R.value=[],W.value=null,F.value="",I.value=null,P.value=[],V.value=!1,m.value=!1,Object.assign(G,ct())}function ke(){M.value<q&&ie.value&&(M.value++,M.value===2&&be(),M.value===3&&fe())}function pe(){te.value&&M.value--}async function ce(){w.value=!0;try{u.value=await Ie("/connections")}catch(g){console.error("Failed to load connections:",g),u.value=[]}finally{w.value=!1}}async function be(){C.value=!0;try{if(O.value){const g=await Ie(`/connections/${O.value}/databases`);H.value=g.databases}if(S.value&&S.value!==O.value){const g=await Ie(`/connections/${S.value}/databases`);N.value=g.databases}else N.value=[...H.value]}catch(g){console.error("Failed to load databases:",g)}finally{C.value=!1}}async function fe(){if(!(!O.value||!o.value)){X.value=!0;try{const g=O.value,v=o.value,s=[],c=[["tables","table"],["views","view"],["functions","function"],["procedures","procedure"],["events","event"]],_=await Promise.allSettled(c.map(([f,x])=>Ie(`/connections/${g}/${f}?database=${encodeURIComponent(v)}`).then(L=>({type:x,items:L[f]||[]}))));for(const f of _)if(f.status==="fulfilled"){const{type:x,items:L}=f.value;for(const le of L)s.push({object_type:x,object_name:le.name||le.table_name||le.routine_name||le.event_name||"",database:v,selected:x==="table",rows_count:le.rows_count??le.rows??le.table_rows,data_size:le.data_length?`${Math.round(le.data_length/1024)}KB`:void 0})}R.value=s.map(f=>({...f}))}catch(g){console.error("Failed to load objects:",g)}finally{X.value=!1}}}function xe(g,v){R.value.forEach(s=>{s.object_type===g&&(s.selected=v)})}function b(g){R.value.forEach(v=>{v.selected=g})}async function Y(){if(!(!O.value||!o.value||h.value.length===0)){m.value=!0;try{const g={source_connection_id:O.value,target_connection_id:S.value,target_type:"connection",source_database:o.value,target_database:l.value||o.value,objects:h.value.map(s=>({object_type:s.object_type,object_name:s.object_name,database:s.database})),options:{...G}},v=await tt("/sessions",g);W.value=v.id,F.value=v.session_key,await tt(`/sessions/${v.id}/start`),V.value=!0,$e(v.id)}catch(g){console.error("Failed to start transfer:",g),alert(`启动传输失败: ${g.message||g}`)}finally{m.value=!1}}}function $e(g){de(),E=new EventSource(`${st}/sessions/${g}/stream`),E.onmessage=v=>{try{const s=JSON.parse(v.data);if(s.error){de();return}I.value=s,["completed","failed","cancelled"].includes(s.status)&&(de(),V.value=!1,me(g))}catch{}},E.onerror=()=>{de(),he(g)},we(g)}function he(g){j=setInterval(async()=>{try{const v=await Ie(`/sessions/${g}/progress`);I.value=v,["completed","failed","cancelled"].includes(v.status)&&(de(),V.value=!1,me(g))}catch{}},2e3)}function we(g){const v=setInterval(async()=>{if(!V.value){clearInterval(v);return}await me(g)},3e3)}async function me(g){try{const v=await Ie(`/sessions/${g}/logs?limit=200`);P.value=v.logs}catch{}}function de(){E&&(E.close(),E=null),j&&(clearInterval(j),j=null)}async function D(){if(W.value)try{await tt(`/sessions/${W.value}/cancel`),V.value=!1,de()}catch(g){alert(`取消失败: ${g.message||g}`)}}return{currentStep:M,totalSteps:q,isOpen:z,connections:u,connectionsLoading:w,sourceConnectionId:O,targetConnectionId:S,sourceDatabases:H,targetDatabases:N,databasesLoading:C,sourceDatabase:o,targetDatabase:l,transferObjects:R,objectsLoading:X,objectTypes:ne,options:G,sessionId:W,sessionKey:F,progress:I,logs:P,isRunning:V,isCreating:m,sourceConnection:$,targetConnection:Z,selectedObjects:h,canProceed:ie,canGoBack:te,openWizard:ue,closeWizard:_e,goNext:ke,goBack:pe,loadConnections:ce,loadDatabases:be,loadObjects:fe,selectAll:b,selectAllByType:xe,startTransfer:Y,cancelTransfer:D,loadLogs:me}}const Oo={class:"flex items-center gap-1 py-3 border-b"},Io={key:0,class:"flex-1 h-px bg-gray-200 dark:bg-gray-700 mx-1"},Ro={class:"flex-1 overflow-y-auto py-4 min-h-[400px]"},Fo={key:0,class:"space-y-6"},No={key:0,class:"text-center py-8 text-muted-foreground"},Po={key:1,class:"grid grid-cols-2 gap-6"},Ao={class:"space-y-2"},Bo={class:"border rounded-md p-3 max-h-64 overflow-y-auto space-y-1"},Mo=["onClick"],qo=["checked"],Qo=["innerHTML"],Wo={class:"flex-1 min-w-0"},Ho={class:"text-sm font-medium truncate"},Jo={class:"text-xs text-muted-foreground"},Ko={key:0,class:"text-xs text-center py-4 text-muted-foreground"},Go={class:"space-y-2"},Yo={class:"border rounded-md p-3 max-h-64 overflow-y-auto space-y-1"},Xo=["onClick"],Zo=["checked"],el=["innerHTML"],tl={class:"flex-1 min-w-0"},sl={class:"text-sm font-medium truncate"},al={class:"text-xs text-muted-foreground"},nl={key:2,class:"bg-blue-50 dark:bg-blue-950 rounded-lg p-4 text-sm"},ol={class:"flex items-center gap-4"},ll={key:0},rl={class:"font-medium ml-1"},il={key:1},ul={class:"font-medium ml-1"},dl={key:1,class:"space-y-6"},cl={key:0,class:"text-center py-8 text-muted-foreground"},vl={key:1,class:"grid grid-cols-2 gap-6"},pl={class:"space-y-2"},fl={class:"border rounded-md p-3 max-h-64 overflow-y-auto space-y-1"},ml=["onClick"],_l=["checked"],gl={class:"flex-1"},bl={class:"text-sm font-medium"},xl={key:0,class:"text-xs text-muted-foreground"},yl={key:0,class:"text-xs text-center py-4 text-muted-foreground"},kl={class:"space-y-2"},$l={class:"flex items-center gap-2 mb-2"},wl=["checked"],hl=["checked"],Cl={class:"text-sm"},Sl={class:"border rounded-md p-3 max-h-48 overflow-y-auto space-y-1 mt-2"},Dl=["onClick"],Tl=["checked"],El={class:"flex-1"},zl={class:"text-sm font-medium"},Vl={key:2,class:"space-y-4"},jl={key:0,class:"text-center py-8 text-muted-foreground"},Ll={class:"flex items-center gap-2 flex-wrap"},Ul={class:"border rounded-md overflow-hidden"},Ol={class:"w-full text-sm"},Il={class:"bg-gray-50 dark:bg-gray-800"},Rl={class:"w-10 px-3 py-2 text-center"},Fl=["checked"],Nl={class:"divide-y"},Pl=["onClick"],Al={class:"px-3 py-1.5 text-center"},Bl=["checked"],Ml={class:"px-3 py-1.5"},ql={class:"px-3 py-1.5 font-mono text-xs"},Ql={class:"px-3 py-1.5 text-right text-xs text-muted-foreground"},Wl={class:"px-3 py-1.5 text-right text-xs text-muted-foreground"},Hl={key:0,class:"text-center py-8 text-muted-foreground text-sm"},Jl={key:3,class:"space-y-6"},Kl={class:"space-y-3"},Gl={class:"grid grid-cols-3 gap-3"},Yl=["onClick"],Xl={class:"text-xl mb-1"},Zl={class:"text-sm font-medium"},er={class:"text-xs text-muted-foreground"},tr={class:"space-y-3"},sr={class:"grid grid-cols-2 gap-2 border rounded-md p-4"},ar={class:"flex items-center gap-2 text-sm cursor-pointer"},nr={class:"flex items-center gap-2 text-sm cursor-pointer"},or={class:"flex items-center gap-2 text-sm cursor-pointer"},lr={class:"flex items-center gap-2 text-sm cursor-pointer"},rr={class:"flex items-center gap-2 text-sm cursor-pointer"},ir={class:"flex items-center gap-2 text-sm cursor-pointer"},ur={key:0,class:"space-y-3"},dr={class:"border rounded-md p-4 space-y-3"},cr={class:"grid grid-cols-2 gap-4"},vr={class:"space-y-1"},pr={class:"space-y-1"},fr={class:"grid grid-cols-2 gap-2"},mr={class:"flex items-center gap-2 text-sm cursor-pointer"},_r={class:"flex items-center gap-2 text-sm cursor-pointer"},gr={class:"space-y-1"},br={class:"space-y-1"},xr={key:4,class:"space-y-6"},yr={class:"flex items-center justify-between"},kr={class:"border rounded-lg overflow-hidden"},$r={class:"w-full text-sm"},wr={class:"divide-y"},hr={class:"bg-gray-50 dark:bg-gray-800"},Cr={class:"px-4 py-2.5"},Sr={class:"font-medium"},Dr={class:"text-muted-foreground ml-2 text-xs"},Tr={class:"px-4 py-2.5 font-mono text-sm"},Er={class:"bg-gray-50 dark:bg-gray-800"},zr={class:"px-4 py-2.5"},Vr={class:"font-medium"},jr={class:"text-muted-foreground ml-2 text-xs"},Lr={class:"px-4 py-2.5 font-mono text-sm"},Ur={class:"bg-gray-50 dark:bg-gray-800"},Or={class:"px-4 py-2.5"},Ir={class:"px-4 py-2.5"},Rr={class:"flex items-center gap-2 flex-wrap"},Fr={class:"text-xs text-muted-foreground ml-1"},Nr={class:"bg-gray-50 dark:bg-gray-800"},Pr={class:"px-4 py-2.5"},Ar={class:"px-4 py-2.5"},Br={class:"space-y-2"},Mr={class:"border rounded-md max-h-40 overflow-y-auto p-2 space-y-1"},qr={class:"font-mono truncate"},Qr={key:0,class:"text-muted-foreground ml-auto shrink-0"},Wr={key:5,class:"space-y-4"},Hr={key:0,class:"text-center py-8 space-y-4"},Jr={class:"flex items-center justify-center gap-3"},Kr={key:1,class:"space-y-4"},Gr={class:"flex items-center justify-between"},Yr={class:"flex items-center gap-2"},Xr={class:"text-sm font-medium"},Zr={class:"flex items-center gap-2"},ei={class:"space-y-1"},ti={class:"flex justify-between text-xs text-muted-foreground"},si={class:"h-3 bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden"},ai={class:"grid grid-cols-4 gap-3"},ni={class:"border rounded-md p-3 text-center"},oi={class:"text-lg font-bold"},li={class:"border rounded-md p-3 text-center"},ri={class:"text-lg font-bold"},ii={class:"border rounded-md p-3 text-center"},ui={class:"text-lg font-bold"},di={class:"border rounded-md p-3 text-center"},ci={class:"text-lg font-bold"},vi={key:0,class:"bg-red-50 dark:bg-red-950 border border-red-200 dark:border-red-800 rounded-md p-3 text-sm text-red-700 dark:text-red-300"},pi={key:1,class:"bg-blue-50 dark:bg-blue-950 border border-blue-200 dark:border-blue-800 rounded-lg p-4 space-y-3"},fi={class:"flex items-center gap-2 text-blue-700 dark:text-blue-300"},mi={key:2,class:"space-y-2"},_i={class:"border rounded-md max-h-48 overflow-y-auto font-mono text-xs bg-gray-50 dark:bg-gray-900 p-2 space-y-0.5"},gi={class:"text-muted-foreground mr-2"},bi={class:"font-semibold mr-1"},xi={key:3,class:"bg-green-50 dark:bg-green-950 border border-green-200 dark:border-green-800 rounded-lg p-4 text-center"},yi={class:"text-xs text-muted-foreground mt-1"},ki={class:"border-t pt-3 flex items-center justify-between"},$i={key:1},wi={class:"flex items-center gap-2"},hi=ye({__name:"DataTransferWizard",emits:["close"],setup(M,{emit:q}){const z=q,u=Uo(),w=k(!1);Oe(()=>{u.isOpen.value=!0,u.loadConnections()});
8const O=["连接选择","数据库选择","对象选择","传输选项","确认摘要","执行监控"];function S(){u.closeWizard(),z("close")}function H(){w.value=!0}function N(o){o.selected=!o.selected,u.transferObjects.value=[...u.transferObjects.value]}const C=oe(()=>{var o,l,R,X,ne,G,W;return!u.currentStep.value||u.currentStep.value<5?null:{name:`${((o=u.sourceConnection.value)==null?void 0:o.name)||""}-${((l=u.targetConnection.value)==null?void 0:l.name)||""}`,description:`从 ${((R=u.sourceConnection.value)==null?void 0:R.name)||""} 到 ${((X=u.targetConnection.value)==null?void 0:X.name)||""} 的数据传输`,source_instance_id:(ne=u.sourceConnection.value)==null?void 0:ne.id,source_database:u.sourceDatabase.value,target_instance_ids:[(G=u.targetConnection.value)==null?void 0:G.id].filter(Boolean),target_databases:[{instance_id:(W=u.targetConnection.value)==null?void 0:W.id,database:u.targetDatabase.value||u.sourceDatabase.value}],sync_mode:u.options.sync_mode||"full",tables:u.selectedObjects.value.filter(F=>F.object_type==="table").map(F=>F.object_name),batch_size:u.options.batch_size||1e3,on_conflict:u.options.on_conflict||"skip",drop_target_before_sync:u.options.drop_target||!1,sync_indexes:u.options.sync_indexes||!0,sync_triggers:u.options.sync_triggers||!1,sync_constraints:u.options.sync_constraints||!0,where_clause:u.options.where_clause||null,max_rows:u.options.max_rows||null}});return(o,l)=>(i(),p(B,null,[a(t(Ee),{open:t(u).isOpen.value,"onUpdate:open":S},{default:n(()=>[a(t(ze),{class:"max-w-4xl max-h-[90vh] flex flex-col"},{default:n(()=>{var R,X,ne,G,W,F,I,P,V,m,E,j,$,Z,h,ie,te,ue,_e,ge,ke,pe,ce,be,fe,xe;return[a(t(Ve),null,{default:n(()=>[a(t(je),{class:"flex items-center gap-2"},{default:n(()=>[a(K,{name:"refresh",size:20}),l[29]||(l[29]=r(" 数据传输向导 ",-1))]),_:1})]),_:1}),e("div",Oo,[(i(),p(B,null,Q(O,(b,Y)=>(i(),p(B,{key:Y},[e("div",{class:se(["flex items-center gap-1.5 px-3 py-1.5 rounded-full text-xs font-medium transition-colors",t(u).currentStep.value===Y+1?"bg-blue-600 text-white":t(u).currentStep.value>Y+1?"bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-300":"bg-gray-100 text-gray-500 dark:bg-gray-800 dark:text-gray-400"])},[e("span",{class:se(["w-5 h-5 rounded-full flex items-center justify-center text-[10px] font-bold",t(u).currentStep.value===Y+1?"bg-white text-blue-600":t(u).currentStep.value>Y+1?"bg-green-600 text-white":"bg-gray-300 text-gray-600 dark:bg-gray-600 dark:text-gray-300"])},d(t(u).currentStep.value>Y+1?"✓":Y+1),3),r(" "+d(b),1)],2),Y<O.length-1?(i(),p("div",Io)):y("",!0)],64))),64))]),e("div",Ro,[t(u).currentStep.value===1?(i(),p("div",Fo,[l[35]||(l[35]=e("p",{class:"text-sm text-muted-foreground"},"选择数据传输的源数据库实例和目标数据库实例。",-1)),t(u).connectionsLoading.value?(i(),p("div",No,"加载连接列表...")):(i(),p("div",Po,[e("div",Ao,[a(t(U),{class:"text-sm font-semibold"},{default:n(()=>[...l[30]||(l[30]=[r("源实例 *",-1)])]),_:1}),e("div",Bo,[(i(!0),p(B,null,Q(t(u).connections.value,b=>(i(),p("div",{key:"src-"+b.id,class:se(["flex items-center gap-2 p-2 rounded cursor-pointer transition-colors",t(u).sourceConnectionId.value===b.id?"bg-blue-50 border border-blue-300 dark:bg-blue-950 dark:border-blue-700":"hover:bg-muted"]),onClick:Y=>t(u).sourceConnectionId.value=b.id},[e("input",{type:"radio",checked:t(u).sourceConnectionId.value===b.id,class:"accent-blue-600"},null,8,qo),e("span",{class:se(["shrink-0",t(it)(b.engine)]),innerHTML:t(rt)(b.engine)},null,10,Qo),e("div",Wo,[e("div",Ho,d(b.name),1),e("div",Jo,d(t(Je)(b.engine))+" · "+d(b.host)+":"+d(b.port),1)]),a(t(ae),{class:se(["text-[10px] shrink-0 border",t(ut)(b.engine)])},{default:n(()=>[r(d(t(Je)(b.engine)),1)]),_:2},1032,["class"])],10,Mo))),128)),t(u).connections.value.length===0?(i(),p("p",Ko," 无可用连接,请先在「连接管理」中添加数据库连接 ")):y("",!0)])]),e("div",Go,[a(t(U),{class:"text-sm font-semibold"},{default:n(()=>[...l[31]||(l[31]=[r("目标实例 *",-1)])]),_:1}),e("div",Yo,[(i(!0),p(B,null,Q(t(u).connections.value,b=>(i(),p("div",{key:"tgt-"+b.id,class:se(["flex items-center gap-2 p-2 rounded cursor-pointer transition-colors",t(u).targetConnectionId.value===b.
8id?"bg-green-50 border border-green-300 dark:bg-green-950 dark:border-green-700":"hover:bg-muted"]),onClick:Y=>t(u).targetConnectionId.value=b.id},[e("input",{type:"radio",checked:t(u).targetConnectionId.value===b.id,class:"accent-green-600"},null,8,Zo),e("span",{class:se(["shrink-0",t(it)(b.engine)]),innerHTML:t(rt)(b.engine)},null,10,el),e("div",tl,[e("div",sl,d(b.name),1),e("div",al,d(t(Je)(b.engine))+" · "+d(b.host)+":"+d(b.port),1)]),a(t(ae),{class:se(["text-[10px] shrink-0 border",t(ut)(b.engine)])},{default:n(()=>[r(d(t(Je)(b.engine)),1)]),_:2},1032,["class"])],10,Xo))),128))])])])),t(u).sourceConnection.value||t(u).targetConnection.value?(i(),p("div",nl,[e("div",ol,[t(u).sourceConnection.value?(i(),p("div",ll,[l[32]||(l[32]=e("span",{class:"text-muted-foreground"},"源:",-1)),e("span",rl,d(t(u).sourceConnection.value.name),1)])):y("",!0),l[34]||(l[34]=e("span",{class:"text-lg"},"→",-1)),t(u).targetConnection.value?(i(),p("div",il,[l[33]||(l[33]=e("span",{class:"text-muted-foreground"},"目标:",-1)),e("span",ul,d(t(u).targetConnection.value.name),1)])):y("",!0)])])):y("",!0)])):y("",!0),t(u).currentStep.value===2?(i(),p("div",dl,[l[40]||(l[40]=e("p",{class:"text-sm text-muted-foreground"},"选择要传输的源数据库和目标数据库。",-1)),t(u).databasesLoading.value?(i(),p("div",cl,"加载数据库列表...")):(i(),p("div",vl,[e("div",pl,[a(t(U),{class:"text-sm font-semibold"},{default:n(()=>[...l[36]||(l[36]=[r("源数据库 *",-1)])]),_:1}),e("div",fl,[(i(!0),p(B,null,Q(t(u).sourceDatabases.value,b=>(i(),p("div",{key:"sdb-"+b.name,class:se(["flex items-center gap-2 p-2 rounded cursor-pointer transition-colors",t(u).sourceDatabase.value===b.name?"bg-blue-50 border border-blue-300 dark:bg-blue-950 dark:border-blue-700":"hover:bg-muted"]),onClick:Y=>t(u).sourceDatabase.value=b.name},[e("input",{type:"radio",checked:t(u).sourceDatabase.value===b.name,class:"accent-blue-600"},null,8,_l),e("div",gl,[e("div",bl,d(b.name),1),b.size?(i(),p("div",xl,d(b.size),1)):y("",!0)]),b.tables_count?(i(),A(t(ae),{key:0,variant:"secondary",class:"text-[10px]"},{default:n(()=>[r(d(b.tables_count)+" 表",1)]),_:2},1024)):y("",!0)],10,ml))),128)),t(u).sourceDatabases.value.length===0?(i(),p("p",yl," 未找到数据库 ")):y("",!0)])]),e("div",kl,[a(t(U),{class:"text-sm font-semibold"},{default:n(()=>[...l[37]||(l[37]=[r("目标数据库",-1)])]),_:1}),l[39]||(l[39]=e("p",{class:"text-xs text-muted-foreground"},"留空则使用与源相同的数据库名,或手动输入自定义数据库名",-1)),e("div",$l,[e("input",{type:"radio",checked:!!t(u).targetDatabase.value&&!t(u).targetDatabases.value.some(b=>b.name===t(u).targetDatabase.value),onChange:l[0]||(l[0]=b=>t(u).targetDatabase.value=""),class:"accent-green-600"},null,40,wl),l[38]||(l[38]=e("span",{class:"text-sm"},"手动输入",-1)),t(u).targetDatabase.value&&!t(u).targetDatabases.value.some(b=>b.name===t(u).targetDatabase.value)?(i(),A(t(ee),{key:0,modelValue:t(u).targetDatabase.value,"onUpdate:modelValue":l[1]||(l[1]=b=>t(u).targetDatabase.value=b),placeholder:"输入数据库名称",class:"h-8 flex-1 ml-2"},null,8,["modelValue"])):y("",!0)]),e("div",{class:se(["flex items-center gap-2 p-2 rounded cursor-pointer transition-colors",t(u).targetDatabase.value?"hover:bg-muted":"bg-green-50 border border-green-300 dark:bg-green-950 dark:border-green-700"]),onClick:l[2]||(l[2]=b=>t(u).targetDatabase.value="")},[e("input",{type:"radio",checked:!t(u).targetDatabase.value,class:"accent-green-600"},null,8,hl),e("span",Cl,"与源数据库同名 ("+d(t(u).sourceDatabase.value||"-")+")",1)],2),e("div",Sl,[(i(!0),p(B,null,Q(t(u).targetDatabases.value,b=>(i(),p("div",{key:"tdb-"+b.name,class:se(["flex items-center gap-2 p-2 rounded cursor-pointer transition-colors",t(u).targetDatabase.value===b.name?"bg-green-50 border border-green-300 dark:bg-green-950 dark:border-green-700":"hover:bg-muted"]),onClick:Y=>t(u).targetDatabase.value=b.name},[e("input",{type:"radio",checked:t(u).targetDatabase.value===b.name,class:"accent-green-600"},null,8,Tl),e("div",El,[e("div",zl,d(b.name),1)])],10,Dl))),128))])])]))])):y("",!0),t(u).currentStep.value===3?(i(),p("div",Vl,[l[53]||(l[53]=e("p",{class:"text-sm text-muted-foreground"},"选择要传输的数据库对象。",-1)),t(u).objectsLoading.value?(i(),p("div",jl,"加载对象列表...")):(i(),p(B,{key:1},[e("div",Ll,[a(t(T),{variant:"outline",size:"sm",onClick:l[3]||(l[3]=b=>t(u).selectAll(!0))},{default:n(()=>[...l[41]||(l[41]=[r("全选",-1)])]),_:1}),a(t(T),{variant:"outline",size:"sm",onClick:l[4]||(l[4]=b=>t(u).selectAll(!1))},{default:n(()=>[...l[42]||(l[42]=[r("全不选",-1)])]),_:1}),l[47]||(l[47]=e("div",{class:"h-4 w-px bg-gray-300 mx-1"},null,-1)),a(t(T),{variant:"ghost",size:"sm",onClick:l[5]||(l[5]=b=>t(u).selectAllByType("table",!0))},{default:n(()=>[...l[43]||(l[43]=[r("选全部表",-1)])]),_:1}),a(t(T),{variant:"ghost",size:"sm",onClick:l[6]||(l[6]=b=>t(u).selectAllByType("view",!0))},{default:n(()=>[...l[44]||(l[44]=[r("选全部视图",-1)])]),_:1}),a(t(T),{variant:"ghost",size:"sm",onClick:l[7]||(l[7]=b=>t(u).selectAllByType("function",!0))},{default:n(()=>[...l[45]||(l[45]=[r("选全部函数",-1)])]),_:1}),a(t(T),{variant:"ghost",size:"sm",onClick:l[8]||(l[8]=b=>t(u).selectAllByType("procedure",!0))},{default:n(()=>[...l[46]||(l[46]=[r("选全部存储过程",-1)])]),_:1}),l[48]||(l[48]=e("div",{class:"flex-1"},null,-1)),a(t(ae),{variant:"secondary"},{default:n(()=>[r("已选 "+d(t(u).selectedObjects.value.length)+" / "+d(t(u).transferObjects.value.length),1)]),_:1})]),e("div",Ul,[e("table",Ol,[e("thead",Il,[e("tr",null,[e("th",Rl,[e("input",{type:"checkbox",checked:t(u).transferObjects.value.length>0&&t(u).selectedObjects.value.length===t(u).transferObjects.value.length,onChange:l[9]||(l[9]=b=>t(u).selectAll(b.target.checked)),class:"rounded"},null,40,Fl)]),l[49]||(l[49]=e("th",{class:"px-3 py-2 text-left text-xs font-medium text-muted-foreground"},"类型",-1)),l[50]||(l[50]=e("th",{class:"px-3 py-2 text-left text-xs font-medium text-muted-foreground"},"名称",-1)),l[51]||(l[51]=e("th",{class:"px-3 py-2 text-right text-xs font-medium text-muted-foreground"},"行数",-1)),l[52]||(l[52]=e("th",{class:"px-3 py-2 text-right text-xs font-medium text-muted-foreground"}
8,"大小",-1))])]),e("tbody",Nl,[(i(!0),p(B,null,Q(t(u).transferObjects.value,(b,Y)=>{var $e;return i(),p("tr",{key:Y,class:se(["hover:bg-muted/50 cursor-pointer",b.selected?"bg-blue-50/50 dark:bg-blue-950/30":""]),onClick:he=>N(b)},[e("td",Al,[e("input",{type:"checkbox",checked:b.selected,class:"rounded",onClick:l[10]||(l[10]=Ke(()=>{},["stop"]))},null,8,Bl)]),e("td",Ml,[a(t(ae),{variant:b.object_type==="table"?"default":"outline",class:se(["text-[10px]",b.object_type==="table"?"bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-300":"",b.object_type==="view"?"bg-purple-100 text-purple-700 dark:bg-purple-900 dark:text-purple-300":""])},{default:n(()=>[r(d({table:"表",view:"视图",function:"函数",procedure:"存储过程",event:"事件"}[b.object_type]||b.object_type),1)]),_:2},1032,["variant","class"])]),e("td",ql,d(b.object_name),1),e("td",Ql,d((($e=b.rows_count)==null?void 0:$e.toLocaleString())||"-"),1),e("td",Wl,d(b.data_size||"-"),1)],10,Pl)}),128))])]),t(u).transferObjects.value.length===0?(i(),p("div",Hl," 未找到数据库对象 ")):y("",!0)])],64))])):y("",!0),t(u).currentStep.value===4?(i(),p("div",Jl,[l[70]||(l[70]=e("p",{class:"text-sm text-muted-foreground"},"配置传输选项。",-1)),e("div",Kl,[a(t(U),{class:"text-sm font-semibold"},{default:n(()=>[...l[54]||(l[54]=[r("传输模式",-1)])]),_:1}),e("div",Gl,[(i(),p(B,null,Q([{value:"full",label:"完整传输",desc:"结构 + 数据",icon:"📦"},{value:"schema_only",label:"仅结构",desc:"只传输表结构等DDL",icon:"🏗️"},{value:"data_only",label:"仅数据",desc:"假设目标表已存在",icon:"📊"}],b=>e("div",{key:b.value,class:se(["border rounded-lg p-3 cursor-pointer transition-colors text-center",t(u).options.sync_mode===b.value?"border-blue-500 bg-blue-50 dark:bg-blue-950 dark:border-blue-700":"hover:border-gray-300"]),onClick:Y=>t(u).options.sync_mode=b.value},[e("div",Xl,d(b.icon),1),e("div",Zl,d(b.label),1),e("div",er,d(b.desc),1)],10,Yl)),64))])]),e("div",tr,[a(t(U),{class:"text-sm font-semibold"},{default:n(()=>[...l[55]||(l[55]=[r("结构选项",-1)])]),_:1}),e("div",sr,[e("label",ar,[J(e("input",{type:"checkbox","onUpdate:modelValue":l[11]||(l[11]=b=>t(u).options.create_tables=b),class:"rounded accent-blue-600"},null,512),[[re,t(u).options.create_tables]]),l[56]||(l[56]=r(" 创建表(如不存在) ",-1))]),e("label",nr,[J(e("input",{type:"checkbox","onUpdate:modelValue":l[12]||(l[12]=b=>t(u).options.drop_target=b),class:"rounded accent-blue-600"},null,512),[[re,t(u).options.drop_target]]),l[57]||(l[57]=r(" 传输前删除目标表 ",-1))]),e("label",or,[J(e("input",{type:"checkbox","onUpdate:modelValue":l[13]||(l[13]=b=>t(u).options.sync_indexes=b),class:"rounded accent-blue-600"},null,512),[[re,t(u).options.sync_indexes]]),l[58]||(l[58]=r(" 传输索引 ",-1))]),e("label",lr,[J(e("input",{type:"checkbox","onUpdate:modelValue":l[14]||(l[14]=b=>t(u).options.sync_foreign_keys=b),class:"rounded accent-blue-600"},null,512),[[re,t(u).options.sync_foreign_keys]]),l[59]||(l[59]=r(" 传输外键 ",-1))]),e("label",rr,[J(e("input",{type:"checkbox","onUpdate:modelValue":l[15]||(l[15]=b=>t(u).options.sync_triggers=b),class:"rounded accent-blue-600"},null,512),[[re,t(u).options.sync_triggers]]),l[60]||(l[60]=r(" 传输触发器 ",-1))]),e("label",ir,[J(e("input",{type:"checkbox","onUpdate:modelValue":l[16]||(l[16]=b=>t(u).options.sync_constraints=b),class:"rounded accent-blue-600"},null,512),[[re,t(u).options.sync_constraints]]),l[61]||(l[61]=r(" 传输约束 ",-1))])])]),t(u).options.sync_mode!=="schema_only"?(i(),p("div",ur,[a(t(U),{class:"text-sm font-semibold"},{default:n(()=>[...l[62]||(l[62]=[r("数据选项",-1)])]),_:1}),e("div",dr,[e("div",cr,[e("div",vr,[a(t(U),{class:"text-xs"},{default:n(()=>[...l[63]||(l[63]=[r("冲突处理",-1)])]),_:1}),J(e("select",{"onUpdate:modelValue":l[17]||(l[17]=b=>t(u).options.on_conflict=b),class:"w-full px-3 py-2 text-sm border rounded-md bg-background"},[...l[64]||(l[64]=[e("option",{value:"skip"},"跳过 (INSERT IGNORE)",-1),e("option",{value:"overwrite"},"覆盖 (REPLACE INTO)",-1),e("option",{value:"error"},"报错中止",-1)])],512),[[Se,t(u).options.on_conflict]])]),e("div",pr,[a(t(U),{class:"text-xs"},{default:n(()=>[...l[65]||(l[65]=[r("批量大小",-1)])]),_:1}),a(t(ee),{modelValue:t(u).options.batch_size,"onUpdate:modelValue":l[18]||(l[18]=b=>t(u).options.batch_size=b),modelModifiers:{number:!0},type:"number",placeholder:"1000"},null,8,["modelValue"])])]),e("div",fr,[e("label",mr,[J(e("input",{type:"checkbox","onUpdate:modelValue":l[19]||(l[19]=b=>t(u).options.extended_insert=b),class:"rounded accent-blue-600"},null,512),[[re,t(u).options.extended_insert]]),l[66]||(l[66]=r(" 使用扩展INSERT (更快) ",-1))]),e("label",_r,[J(e("input",{type:"checkbox","onUpdate:modelValue":l[20]||(l[20]=b=>t(u).options.use_transaction=b),class:"rounded accent-blue-600"},null,512),[[re,t(u).options.use_transaction]]),l[67]||(l[67]=r(" 使用事务 ",-1))])]),e("div",gr,[a(t(U),{class:"text-xs"},{default:n(()=>[...l[68]||(l[68]=[r("WHERE 过滤条件 (可选)",-1)])]),_:1}),a(t(ee),{modelValue:t(u).options.where_clause,"onUpdate:modelValue":l[21]||(l[21]=b=>
8t(u).options.where_clause=b),placeholder:"例如: created_at > '2025-01-01'"},null,8,["modelValue"])]),e("div",br,[a(t(U),{class:"text-xs"},{default:n(()=>[...l[69]||(l[69]=[r("最大行数 (可选)",-1)])]),_:1}),a(t(ee),{modelValue:t(u).options.max_rows,"onUpdate:modelValue":l[22]||(l[22]=b=>t(u).options.max_rows=b),modelModifiers:{number:!0},type:"number",placeholder:"不限制"},null,8,["modelValue"])])])])):y("",!0)])):y("",!0),t(u).currentStep.value===5?(i(),p("div",xr,[e("div",yr,[l[72]||(l[72]=e("p",{class:"text-sm text-muted-foreground"},"请确认以下传输配置信息,确认无误后点击「开始传输」。",-1)),a(t(T),{onClick:H,variant:"outline",size:"sm"},{default:n(()=>[a(K,{name:"pin",size:14,class:"mr-2"}),l[71]||(l[71]=r(" 保存为配置 ",-1))]),_:1})]),e("div",kr,[e("table",$r,[e("tbody",wr,[e("tr",hr,[l[73]||(l[73]=e("td",{class:"px-4 py-2.5 font-medium w-36 text-muted-foreground"},"源实例",-1)),e("td",Cr,[e("span",Sr,d(((R=t(u).sourceConnection.value)==null?void 0:R.name)||"-"),1),e("span",Dr,"("+d((X=t(u).sourceConnection.value)==null?void 0:X.engine)+" "+d((ne=t(u).sourceConnection.value)==null?void 0:ne.host)+":"+d((G=t(u).sourceConnection.value)==null?void 0:G.port)+")",1)])]),e("tr",null,[l[74]||(l[74]=e("td",{class:"px-4 py-2.5 font-medium text-muted-foreground"},"源数据库",-1)),e("td",Tr,d(t(u).sourceDatabase.value||"-"),1)]),e("tr",Er,[l[75]||(l[75]=e("td",{class:"px-4 py-2.5 font-medium text-muted-foreground"},"目标实例",-1)),e("td",zr,[e("span",Vr,d(((W=t(u).targetConnection.value)==null?void 0:W.name)||"-"),1),e("span",jr,"("+d((F=t(u).targetConnection.value)==null?void 0:F.engine)+" "+d((I=t(u).targetConnection.value)==null?void 0:I.host)+":"+d((P=t(u).targetConnection.value)==null?void 0:P.port)+")",1)])]),e("tr",null,[l[76]||(l[76]=e("td",{class:"px-4 py-2.5 font-medium text-muted-foreground"},"目标数据库",-1)),e("td",Lr,d(t(u).targetDatabase.value||t(u).sourceDatabase.value||"-"),1)]),e("tr",Ur,[l[77]||(l[77]=e("td",{class:"px-4 py-2.5 font-medium text-muted-foreground"},"传输模式",-1)),e("td",Or,d({full:"完整传输",schema_only:"仅结构",data_only:"仅数据"}[t(u).options.sync_mode]),1)]),e("tr",null,[l[78]||(l[78]=e("td",{class:"px-4 py-2.5 font-medium text-muted-foreground"},"传输对象",-1)),e("td",Ir,[e("div",Rr,[(i(),p(B,null,Q(["table","view","function","procedure","event"],b=>a(t(ae),{key:b,variant:"outline",class:"text-xs"},{default:n(()=>[r(d({table:"表",view:"视图",function:"函数",procedure:"存储过程",event:"事件"}[b])+": "+d(t(u).selectedObjects.value.filter(Y=>Y.object_type===b).length),1)]),_:2},1024)),64)),e("span",Fr,"共 "+d(t(u).selectedObjects.value.length)+" 个对象",1)])])]),e("tr",Nr,[l[79]||(l[79]=e("td",{class:"px-4 py-2.5 font-medium text-muted-foreground"},"冲突处理",-1)),e("td",Pr,d({skip:"跳过",overwrite:"覆盖",error:"报错"}[t(u).options.on_conflict]),1)]),e("tr",null,[l[80]||(l[80]=e("td",{class:"px-4 py-2.5 font-medium text-muted-foreground"},"批量大小",-1)),e("td",Ar,d(t(u).options.batch_size)+" 行/批",1)])])])]),e("div",Br,[a(t(U),{class:"text-sm font-semibold"},{default:n(()=>[...l[81]||(l[81]=[r("传输对象列表",-1)])]),_:1}),e("div",Mr,[(i(!0),p(B,null,Q(t(u).selectedObjects.value,b=>(i(),p("div",{key:b.object_type+":"+b.object_name,class:"flex items-center gap-2 text-xs"},[a(t(ae),{variant:"outline",class:"text-[10px] shrink-0"},{default:n(()=>[r(d({table:"表",view:"视图",function:"函数",procedure:"存储过程",event:"事件"}[b.object_type]),1)]),_:2},1024),e("span",qr,d(b.object_name),1),b.rows_count?(i(),p("span",Qr,d(b.rows_count.toLocaleString())+" 行",1)):y("",!0)]))),128))])])])):y("",!0),t(u).currentStep.value===6?(i(),p("div",Wr,[!t(u).isRunning.value&&!t(u).progress.value?(i(),p("div",Hr,[l[83]||(l[83]=e("p",{class:"text-sm"},"准备就绪,点击「开始传输」执行数据同步。",-1)),e("div",Jr,[a(t(T),{onClick:H,variant:"outline",size:"lg"},{default:n(()=>[a(K,{name:"pin",size:16,class:"mr-2"}),l[82]||(l[82]=r(" 保存为配置 ",-1))]),_:1}),a(t(T),{onClick:l[23]||(l[23]=b=>
8t(u).startTransfer()),disabled:t(u).isCreating.value,size:"lg",class:"px-8"},{default:n(()=>[r(d(t(u).isCreating.value?"创建中...":"开始传输"),1)]),_:1},8,["disabled"])])])):y("",!0),t(u).progress.value||t(u).isRunning.value?(i(),p("div",Kr,[e("div",Gr,[e("div",Yr,[e("div",{class:se(["w-3 h-3 rounded-full",((V=t(u).progress.value)==null?void 0:V.status)==="completed"?"bg-green-500":((m=t(u).progress.value)==null?void 0:m.status)==="failed"?"bg-red-500":((E=t(u).progress.value)==null?void 0:E.status)==="cancelled"?"bg-yellow-500":"bg-blue-500 animate-pulse"])},null,2),e("span",Xr,d({pending:"等待中",running:"传输中",completed:"已完成",failed:"失败",cancelled:"已取消"}[((j=t(u).progress.value)==null?void 0:j.status)||"pending"]||(($=t(u).progress.value)==null?void 0:$.status)||"准备中"),1)]),e("div",Zr,[t(u).isRunning.value?(i(),A(t(T),{key:0,variant:"destructive",size:"sm",onClick:l[24]||(l[24]=b=>t(u).cancelTransfer())},{default:n(()=>[...l[84]||(l[84]=[r(" 取消传输 ",-1)])]),_:1})):y("",!0)])]),e("div",ei,[e("div",ti,[e("span",null,d(((Z=t(u).progress.value)==null?void 0:Z.current_step)||"初始化..."),1),e("span",null,d(((h=t(u).progress.value)==null?void 0:h.progress_pct)||0)+"%",1)]),e("div",si,[e("div",{class:se(["h-full rounded-full transition-all duration-500",((ie=t(u).progress.value)==null?void 0:ie.status)==="completed"?"bg-green-500":((te=t(u).progress.value)==null?void 0:te.status)==="failed"?"bg-red-500":"bg-blue-500"]),style:vt({width:`${((ue=t(u).progress.value)==null?void 0:ue.progress_pct)||0}%`})},null,6)])]),e("div",ai,[e("div",ni,[e("div",oi,d(((_e=t(u).progress.value)==null?void 0:_e.objects_processed)||0)+" / "+d(((ge=t
8(u).progress.value)==null?void 0:ge.objects_total)||0),1),l[85]||(l[85]=e("div",{class:"text-xs text-muted-foreground"},"对象",-1))]),e("div",li,[e("div",ri,d((((ke=t(u).progress.value)==null?void 0:ke.rows_transferred)||0).toLocaleString()),1),l[86]||(l[86]=e("div",{class:"text-xs text-muted-foreground"},"行数",-1))]),e("div",ii,[e("div",ui,d((pe=t(u).progress.value)!=null&&pe.data_size_mb?t(u).progress.value.data_size_mb.toFixed(1)+"MB":"0MB"),1),l[87]||(l[87]=e("div",{class:"text-xs text-muted-foreground"},"数据量",-1))]),e("div",di,[e("div",ci,d(((ce=t(u).progress.value)==null?void 0:ce.progress_pct)||0)+"%",1),l[88]||(l[88]=e("div",{class:"text-xs text-muted-foreground"},"进度",-1))])]),(be=t(u).progress.value)!=null&&be.error_message?(i(),p("div",vi,d(t(u).progress.value.error_message),1)):y("",!0),((fe=t(u).progress.value)==null?void 0:fe.status)==="completed"?(i(),p("div",pi,[e("div",fi,[a(K,{name:"pin",size:18}),l[89]||(l[89]=e("span",{class:"font-semibold"},"保存为传输配置",-1))]),l[91]||(l[91]=e("p",{class:"text-xs text-muted-foreground"}," 将当前的传输设置保存为可重复使用的配置,支持调度和 Webhook 触发 ",-1)),a(t(T),{onClick:H,variant:"default",size:"sm"},{default:n(()=>[a(K,{name:"pin",size:14,class:"mr-2"}),l[90]||(l[90]=r(" 保存为配置 ",-1))]),_:1})])):y("",!0)])):y("",!0),t(u).logs.value.length>0?(i(),p("div",mi,[a(t(U),{class:"text-sm font-semibold"},{default:n(()=>[...l[92]||(l[92]=[r("传输日志",-1)])]),_:1}),e("div",_i,[(i(!0),p(B,null,Q(t(u).logs.value,b=>(i(),p("div",{key:b.id,class:se(["px-2 py-0.5",b.level==="ERROR"?"text-red-600 dark:text-red-400":b.level==="WARNING"?"text-yellow-600 dark:text-yellow-400":"text-gray-700 dark:text-gray-300"])},[e("span",gi,d(new Date(b.created_at).toLocaleTimeString("zh-CN")),1
8),e("span",bi,"["+d(b.level)+"]",1),r(" "+d(b.message),1)],2))),128))])])):y("",!0),((xe=t(u).progress.value)==null?void 0:xe.status)==="completed"?(i(),p("div",xi,[l[93]||(l[93]=e("div",{class:"text-2xl mb-1"},"✅",-1)),l[94]||(l[94]=e("p",{class:"text-sm font-medium text-green-700 dark:text-green-300"},"数据传输完成!",-1)),e("p",yi," 共传输 "+d(t(u).progress.value.objects_processed)+" 个对象,"+d((t(u).progress.value.rows_transferred||0).toLocaleString())+" 行数据 ",1)])):y("",!0)])):y("",!0)]),e("div",ki,[t(u).currentStep.value>1&&!t(u).isRunning.value?(i(),A(t(T),{key:0,variant:"outline",onClick:l[25]||(l[25]=b=>t(u).goBack()),disabled:!t(u).canGoBack.value},{default:n(()=>[...l[95]||(l[95]=[r(" 上一步 ",-1)])]),_:1},8,["disabled"])):(i(),p("div",$i)),e("div",wi,[a(t(T),{variant:"ghost",onClick:S},{default:n(()=>{var b,Y;return[r(d(t(u).currentStep.value===6&&(((b=t(u).progress.value)==null?void 0:b.status)==="completed"||((Y=t(u).progress.value)==null?void 0:Y.status)==="failed")?"关闭":"取消"),1)]}),_:1}),t(u).currentStep.value<5?(i(),A(t(T),{key:0,onClick:l[26]||(l[26]=b=>t(u).goNext()),disabled:!t(u).canProceed.value},{default:n(()=>[...l[96]||(l[96]=[r(" 下一步 ",-1)])]),_:1},8,["disabled"])):y("",!0),t(u).currentStep.value===5?(i(),A(t(T),{key:1,onClick:l[27]||(l[27]=b=>t(u).goNext())},{default:n(()=>[...l[97]||(l[97]=[r(" 开始传输 ",-1)])]),_:1})):y("",!0)])])]}),_:1})]),_:1},8,["open"]),a(pt,{open:w.value,"instance-options":t(u).connections.value.map(R=>({id:R.id,instance_name:R.name})),connections:t(u).connections.value,"transfer-summary":C.value,"onUpdate:open":l[28]||(l[28]=R=>w.value=R)},null,8,["open","instance-options","connections","transfer-summary"])],64))}}),Ci={class:"space-y-4"},Si={class:"flex items-center gap-3 flex-wrap"},Di={key:0,class:"text-center py-12 text-muted-foreground"},Ti={key:1,class:"text-center py-12 text-muted-foreground"},Ei={key:2,class:"space-y-3"},zi={class:"flex items-start justify-between gap-4"},Vi={class:"flex-1 min-w-0"},ji={class:"flex items-center gap-2 flex-wrap"},Li={class:"font-semibold text-sm truncate"},Ui={key:0,class:"text-xs text-muted-foreground mt-1 truncate"},Oi={class:"flex items-center gap-4 mt-2 text-xs text-muted-foreground"},Ii={class:"font-medium text-foreground"},Ri={class:"font-medium text-foreground"},Fi={key:0},Ni={key:1},Pi={key:2},Ai={class:"flex items-center gap-4 mt-1 text-xs text-muted-foreground"},Bi={key:0},Mi={key:1,class:"text-red-500"},qi={key:2},Qi={class:"flex items-center gap-1 shrink-0"},Wi={key:3,class:"flex items-center justify-between mt-4 pt-4 border-t"},Hi={class:"text-sm text-muted-foreground"},Ji={class:"flex items-center gap-2"},Ki={class:"text-sm text-muted-foreground px-2"},Gi={class:"text-sm text-muted-foreground py-2"},Yi={class:"font-medium text-foreground"},Xi={class:"text-sm text-muted-foreground py-2"},Zi={class:"font-medium text-foreground"},eu=ye({name:"DataTransferPanel",__name:"DataTransferPanel",props:{instanceOptions:{},connections:{}},setup(M,{expose:q}){const z=M,u=k([]),w=k(!1),O=k(""),S=k("all"),H=k([]),N=k(1),C=k(10),o=k(0),l=k(!1),R=k(null),X=k(!1),ne=k(null),G=k(""),W=k(!1),F=k(!1),I=k(null),P=k(""),V=k(!1),m=k(null),E=k(""),j=k(!1);let $=null;const Z=oe(()=>u.value),h=oe(()=>Math.ceil(o.value/C.value));function ie(D){D<1||D>h.value||(N.value=D,te())}async function te(){w.value=!0;try{const D=new URLSearchParams({page:String(N.value),page_size:String(C.value)});O.value.trim()&&D.set("q",O.value.trim());const g=await fetch(`/api/resource-ops/dbspace/transfer-configs?${D}`);if(!g.ok)throw new Error("加载配置列表失败");const v=await g.json();u.value=v.items||[],o.value=v.total||u.value.length,console.log("[DataTransferPanel] Loaded configs:",{items:u.value.length,total:o.value,page:N.value,pageSize:C.value,totalPages:h.value})}catch(D){console.error("Failed to load transfer configs:",D)}finally{w.value=!1}}Re([O,S],()=>{N.value=1,te()});async function ue(){try{const D=await fetch("/api/db-platform/connections?page=1&page_size=200");if(!D.ok){console.error("加载连接列表失败");return}const g=await D.json();H.value=(g.items||[]).map(v=>({...v,instance_name:v.name,db_type:v.engine||v.db_type}))}catch(D){console.error("Failed to load connections:",D)}}function _e(){console.log("[DataTransferPanel] openCreateDialog called"),console.log("[DataTransferPanel] Current showConfigDialog:",l.value),R.value=null,l.value=!0,console.log("[DataTransferPanel] After set showConfigDialog:",l.value)}function ge(D){R.value=D,l.value=!0}function ke(){console.log("[DataTransferPanel] Config saved, closing dialog"),l.value=!1,R.value=null,te()}function pe(D){I.value=D.id,P.value=D.name,F.value=!0}
8async function ce(){if(I.value)try{console.log("[DataTransferPanel] Deleting config ID:",I.value);const D=await fetch(`/api/resource-ops/dbspace/transfer-configs/${I.value}`,{method:"DELETE"});if(!D.ok){const v=await D.json().catch(()=>({}));throw console.error("[DataTransferPanel] Delete failed:",{status:D.status,statusText:D.statusText,error:v}),new Error(v.detail||`删除失败 (HTTP ${D.status})`)}const g=await D.json();console.log("[DataTransferPanel] Delete success:",g),F.value=!1,I.value=null,te()}catch(D){console.error("Failed to delete config:",D),alert(`删除失败: ${D.message||D}`)}}function be(D){m.value=D.id,E.value=D.name,V.value=!0}async function fe(){if(!m.value)return;const D=m.value;j.value=!0;try{if(!(await fetch(`/api/resource-ops/dbspace/transfer-configs/${D}/execute`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({trigger_type:"manual",initiated_by:"current_user"})})).ok)throw new Error("执行失败");V.value=!1,m.value=null,await te(),b({id:D,name:E.value})}catch(g){console.error("Failed to execute config:",g),alert(`执行失败: ${g.message||g}`)}finally{j.value=!1}}async function xe(D){try{console.log("[DataTransferPanel] Duplicating config ID:",D.id);const g=await fetch(`/api/resource-ops/dbspace/transfer-configs/${D.id}`);if(!g.ok)throw new Error(`获取配置失败 (HTTP ${g.status})`);const v=await g.json();console.log("[DataTransferPanel] Fetched original config:",v);const s={...v,id:void 0,config_key:void 0,name:`${v.name} (Copy)`,is_active:!1,created_at:void 0,updated_at:void 0,total_executions:0,total_success:0,total_failed:0,last_execution_at:null,last_execution_status:null,last_execution_duration_ms:null};console.log("[DataTransferPanel] Prepared duplicated config:",s),R.value=s,l.value=!0,alert(`已加载「${v.name}」的副本数据,请修改后保存`)}catch(g){console.error("Failed to prepare duplicate config:",g),alert(`准备复制失败: ${g.message||g}`)}}function b(D){ne.value=D.id,G.value=D.name,X.value=!0}function Y(D){var v;const g=H.value.find(s=>s.id===D);return g?g.instance_name:((v=z.instanceOptions.find(s=>s.id===D))==null?void 0:v.instance_name)||`实例 ${D}`}function $e(D){return{full:"全量",schema_only:"仅结构",data_only:"仅数据",incremental:"增量"}[D]||D}function he(D){return{timestamp:"时间戳",primary_key:"主键递增",custom_where:"自定义条件",full:"全量"}[D]||D}function we(D){return D.schedule_enabled?D.schedule_type==="interval"?`每${D.interval_minutes}分钟`:D.schedule_type==="cron"?`Cron: ${D.cron_expression}`:"定时":"手动"}function me(D){return D.is_active?D.last_execution_status==="failed"?"bg-red-100 text-red-700":D.last_execution_status==="running"?"bg-blue-100 text-blue-700":D.last_execution_status==="success"||D.last_execution_status==="completed"?"bg-green-100 text-green-700":"bg-gray-100 text-gray-600":"bg-gray-100 text-gray-600"}Re(u,D=>
8{const g=D.some(v=>v.last_execution_status==="running");g&&!$?$=setInterval(te,5e3):!g&&$&&(clearInterval($),$=null)},{deep:!0});function de(){te()}return q({refreshData:de}),Oe(()=>{te(),ue()}),(D,g)=>(i(),A(t(Te),null,{default:n(()=>[a(t(qe),null,{default:n(()=>[a(t(Me),{class:"flex items-center gap-2 text-lg"},{default:n(()=>[a(K,{name:"refresh",size:20}),g[12]||(g[12]=r(" 数据传输配置 ",-1))]),_:1})]),_:1}),a(t(De),null,{default:n(()=>[e("div",Ci,[e("div",Si,[a(t(ee),{modelValue:O.value,"onUpdate:modelValue":g[0]||(g[0]=v=>O.value=v),placeholder:"搜索配置名称...",class:"w-64",onInput:te},null,8,["modelValue"]),a(t(Fe),{modelValue:S.value,"onUpdate:modelValue":[g[1]||(g[1]=v=>S.value=v),te]},{default:n(()=>[a(t(Ne),{class:"w-36"},{default:n(()=>[a(t(Pe))]),_:1}),a(t(Ae),null,{default:n(()=>[a(t(ve),{value:"all"},{default:n(()=>[...g[13]||(g[13]=[r("全部",-1)])]),_:1}),a(t(ve),{value:"active"},{default:n(()=>[...g[14]||(g[14]=[r("启用中",-1)])]),_:1}),a(t(ve),{value:"inactive"},{default:n(()=>[...g[15]||(g[15]=[r("已停用",-1)])]),_:1}),a(t(ve),{value:"scheduled"},{default:n(()=>[...g[16]||(g[16]=[r("定时任务",-1)])]),_:1})]),_:1})]),_:1},8,["modelValue"]),g[19]||(g[19]=e("div",{class:"flex-1"},null,-1)),a(t(T),{onClick:g[2]||(g[2]=v=>W.value=!0),size:"sm"},{default:n(()=>[a(K,{name:"refresh",size:16,class:"mr-1"}),g[17]||(g[17]=r(" 新建传输 ",-1))]),_:1}),a(t(T),{onClick:_e,variant:"outline",size:"sm"},{default:n(()=>[a(K,{name:"plus",size:16,class:"mr-1"}),g[18]||(g[18]=r(" 新建配置 ",-1))]),_:1})]),w.value?(i(),p("div",Di,"加载中...")):Z.value.length===0?(i(),p("div",Ti,[...g[20]||(g[20]=[e("p",{class:"text-lg mb-2"},"暂无数据传输配置",-1),e("p",{class:"text-sm"},"点击「新建配置」创建第一个同步任务",-1)])])):(i(),p("div",Ei,[(i(!0),p(B,null,Q(Z.value,v=>{var s;return i(),p("div",{key:v.id,class:"border rounded-lg p-4 hover:border-blue-300 dark:hover:border-blue-700 transition-colors"},[e("div",zi,[e("div",Vi,[e("div",ji,[e("h4",Li,d(v.name),1),a(t(ae),{variant:"outline",class:"text-xs font-mono"},{default:n(()=>[r(d(v.config_key),1)]),_:2},1024),e("span",{class:se(["inline-flex items-center px-2 py-0.5 rounded text-xs font-medium",me(v)])},d(v.is_active?v.last_execution_status||"未执行":"已停用"),3),v.schedule_enabled?(i(),A(t(ae),{key:0,variant:"secondary",class:"text-xs"},{default:n(()=>[r(d(we(v)),1)]),_:2},1024)):y("",!0),v.webhook_enabled?(i(),A(t(ae),{key:1,variant:"secondary",class:"text-xs"},{default:n(()=>[...g[21]||(g[21]=[r(" Webhook ",-1)])]),_:1})):y("",!0)]),v.description?(i(),p("p",Ui,d(v.description),1)):y("",!0),e("div",Oi,[e("span",null,[e("span",Ii,d(Y(v.source_instance_id)),1),g[22]||(g[22]=r(" → ",-1)),(i(!0),p(B,null,Q(v.target_instance_ids||[],(c,_)=>(i(),p("span",{key:c},[e("span",Ri,d(Y(c)),1),Number(_)<(v.target_instance_ids||[]).length-1?(i(),p("span",Fi,", ")):y("",!0)]))),128))]),e("span",null,d($e(v.sync_mode)),1),v.sync_mode==="incremental"&&v.default_incremental_strategy?(i(),A(t(ae),{key:0,variant:"outline",class:"text-xs"},{default:n(()=>[r(d(he(v.default_incremental_strategy)),1)]),_:2},1024)):y("",!0),v.database_name?(i(),p("span",Ni,"DB: "+d(v.database_name),1)):y("",!0),(s=v.tables)!=null&&s.length?(i(),p("span",Pi,"表: "+d(v.tables.length)+"个",1)):y("",!0)]),e("div",Ai,[e("span",null,"执行: "+d(v.total_executions)+"次",1),v.total_success?(i(),p("span",Bi,"成功: "+d(v.total_success),1)):y("",!0),v.total_failed?(i(),p("span",Mi,"失败: "+d(v.total_failed),1)):y("",!0),v.last_execution_at?(i(),p("span",qi," 最近: "+d(new Date(v.last_execution_at).toLocaleString("zh-CN")),1
8)):y("",!0)])]),e("div",Qi,[a(t(T),{variant:"ghost",size:"sm",onClick:c=>be(v),disabled:!v.is_active,title:"立即执行"},{default:n(()=>[a(K,{name:"play",size:14})]),_:1},8,["onClick","disabled"]),a(t(T),{variant:"ghost",size:"sm",onClick:c=>b(v),title:"执行历史"},{default:n(()=>[a(K,{name:"clock",size:14})]),_:1},8,["onClick"]),a(t(T),{variant:"ghost",size:"sm",onClick:c=>xe(v),title:"复制配置"},{default:n(()=>[a(K,{name:"copy",size:14})]),_:1},8,["onClick"]),a(t(T),{variant:"ghost",size:"sm",onClick:c=>ge(v),title:"编辑"},{default:n(()=>[a(K,{name:"edit",size:14})]),_:1},8,["onClick"]),a(t(T),{variant:"ghost",size:"sm",onClick:c=>pe(v),title:"删除",class:"text-red-500 hover:text-red-700"},{default:n(()=>[a(K,{name:"trash",size:14})]),_:1},8,["onClick"])])])])}),128))])),o.value>0?(i(),p("div",Wi,[e("div",Hi," 共 "+d(o.value)+" 条配置,每页 "+d(C.value)+" 条 ",1),e("div",Ji,[a(t(T),{variant:"outline",size:"sm",disabled:N.value===1,onClick:g[3]||(g[3]=v=>ie(N.value-1))},{default:n(()=>[...g[23]||(g[23]=[r(" 上一页 ",-1)])]),_:1},8,["disabled"]),e("span",Ki,d(N.value)+" / "+d(h.value),1),a(t(T),{variant:"outline",size:"sm",disabled:N.value===h.value||h.value===0,onClick:g[4]||(g[4]=v=>ie(N.value+1))},{default:n(()=>[...g[24]||(g[24]=[r(" 下一页 ",-1)])]),_:1},8,["disabled"])])])):y("",!0)])]),_:1}),W.value?(i(),A(hi,{key:0,onClose:g[5]||(g[5]=v=>{W.value=!1,te()})})):y("",!0),l.value?(i(),A(pt,{key:1,open:!0,"instance-options":M.instanceOptions,connections:H.value,"editing-config":R.value,onClose:g[6]||(g[6]=v=>{l.value=!1,R.value=null}),onSaved:ke},null,8,["instance-options","connections","editing-config"])):y("",!0),X.value?(i(),A(Lo,{key:2,"config-id":ne.value,"config-name":G.value,onClose:g[7]||(g[7]=v=>X.value=!1)},null,8,["config-id","config-name"])):y("",!0),a(t(Ee),{open:F.value,"onUpdate:open":g[9]||(g[9]=v=>F.value=v)},{default:n(()=>[a(t(ze),{class:"max-w-md"},{default:n(()=>[a(t(Ve),null,{default:n(()=>[a(t(je),null,{default:n(()=>[...g[25]||(g[25]=[r("确认删除",-1)])]),_:1})]),_:1}),e("p",Gi,[g[26]||(g[26]=r(" 确定要删除配置「",-1)),e("span",Yi,d(P.value),1),g[27]||(g[27]=r("」吗?此操作不可撤销。 ",-1))]),a(t(Be),null,{default:n(()=>[a(t(T),{variant:"outline",onClick:g[8]||(g[8]=v=>F.value=!1)},{default:n(()=>[...g[28]||(g[28]=[r("取消",-1)])]),_:1}),a(t(T),{variant:"destructive",onClick:ce},{default:n(()=>[...g[29]||(g[29]=[r("删除",-1)])]),_:1})]),_:1})]),_:1})]),_:1},8,["open"]),a(t(Ee),{open:V.value,"onUpdate:open":g[11]||(g[11]=v=>V.value=v)},{default:n(()=>[a(t(ze),{class:"max-w-md"},{default:n(()=>[a(t(Ve),null,{default:n(()=>[a(t(je),null,{default:n(()=>[...g[30]||(g[30]=[r("确认执行",-1)])]),_:1})]),_:1}),e("p",Xi,[g[31]||(g[31]=r(" 确定要立即执行配置「",-1)),e("span",Zi,d(E.value),1),g[32]||(g[32]=r("」的数据同步吗? ",-1))]),a(t(Be),null,{default:n(()=>[a(t(T),{variant:"outline",onClick:g[10]||(g[10]=v=>V.value=!1)},{default:n(()=>[...g[33]||(g[33]=[r("取消",-1)])]),_:1}),a(t(T),{onClick:fe,disabled:j.value},{default:n(()=>[r(d(j.value?"执行中...":"确认执行"),1)]),_:1},8,["disabled"])]),_:1})]),_:1})]),_:1},8,["open"])]),_:1}))}}),tu={class:"space-y-4 py-4"},su={class:"space-y-2"},au={class:"space-y-2"},nu={class:"space-y-2"},ou={class:"grid grid-cols-3 gap-2"},lu=["value"],ru={class:"text-sm"},iu={class:"space-y-2"},uu={class:"space-y-2"},du={class:"space-y-2"},cu=ye({__name:"PermissionRequestForm",props:{instanceOptions:{}},emits:["close","success"],setup(M,{emit:q}){const z=M,u=q,w=k({instance_id:null,requester:"",permission_type:[],database_name:"",tables:"",justification:""}),O=[{value:"SELECT",label:"SELECT (查询)"},{value:"INSERT",label:"INSERT (插入)"},{value:"UPDATE",label:"UPDATE (更新)"},{value:"DELETE",label:"DELETE (删除)"},{value:"DDL",label:"DDL (结构变更)"},{value:"ALL",label:"ALL (所有权限)"}];k((z.instanceOptions.length>0,""));function S(N){w.value.instance_id=N?Number(N):null}async function H(){if(!w.value.instance_id){alert("请选择数据库实例");return}if(!w.value.requester){alert("请填写申请人");return}if(w.value.permission_type.length===0){alert("请选择权限类型");return}if(!w.value.justification){alert("请填写申请理由");return}try{const N={instance_id:w.value.instance_id,requester:w.value.requester,permission_type:w.value.permission_type.join(","),database_name:w.value.database_name||null,tables:w.value.tables?w.value.tables.split(",").map(o=>o.trim()):null,justification:w.value.justification},C=await fetch("/api/resource-ops/dbspace/permission-requests",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(N)});if(!C.ok){const o=await C.json();throw new Error(o.detail||"创建失败")}u("success")}catch(N){console.error("Failed to create permission request:",N),alert(N.message||"创建权限申请失败")}}return(N,C)=>(i(),A(t(Ee),{open:!0,"onUpdate:open":C[6]||(C[6]=o=>u("close"))},{default:n(()=>[a(t(ze),{class:"max-w-2xl max-h-[90vh] overflow-y-auto"},{default:n(()=>[a(t(Ve),null,{default:n(()=>[a(t(je),null,{default:n(()=>[...C[7]||(C[7]=[r("新建权限申请",-1)])]),_:1})]),_:1}),e("div",tu,[e("div",su,[a(t(U),null,{default:n(()=>[...C[8]||(C[8]=[r("数据库实例 *",-1)])]),_:1}),a(t(Fe),{"model-value":w.value.instance_id!=null?String(w.value.instance_id):"","onUpdate:modelValue":S},{default:n(()=>[a(t(Ne),null,{default:n(()=>[a(t(Pe),{placeholder:"请选择数据库实例"})]),_:1}),a(t(Ae),null,{default:n(()=>[(i(!0),p(B,null,Q(M.instanceOptions,o=>(i(),A(t(ve),{key:o.id,value:String(o.id)},{default:n(()=>[r(d(o.instance_name)+" (ID: "+d(o.id)+") ",1)]),_:2},1032,["value"]))),128))]),_:1})]),_:1},8,["model-value"])]),e("div",au,[a(t(U),null,{default:n(()=>[...C[9]||(C[9]=[r("申请人 *",-1)])]),_:1}),a(t(ee),{modelValue:w.value.requester,"onUpdate:modelValue":C[0]||(C[0]=o=>w.value.requester=o),placeholder:"请输入申请人姓名"},null,8,["modelValue"])]),e("div",nu,[a(t(U),null,{default:n(()=>[...C[10]||(C[10]=[r("权限类型 *",-1)])]),_:1}),e("div",ou,[(i(),p(B,null,Q(O,o=>a(t(U),{key:o.value,class:"flex items-center gap-2 p-2 border rounded-lg cursor-pointer hover:bg-muted transition-colors"},{default:n(()=>[J(e("input",{type:"checkbox",value:o.value,"onUpdate:modelValue":C[1]||(C[1]=l=>w.value.permission_type=l),class:"w-4 h-4 rounded"},null,8,lu),[[re,w.value.permission_type]]),e("span",ru,d(o.label),1)]),_:2},1024)),64))])]),e("div",iu,[a(t(U),null,{default:n(()=>[...C[11]||(C[11]=[r("数据库名(可选)",-1)])]),_:1}),a(t(ee),{modelValue:w.value.database_name,"onUpdate:modelValue":C[2]||(C[2]=o=>w.value.database_name=o),placeholder:"留空表示所有数据库"},null,8,["modelValue"])]),e("div",uu,[a(t(U),null,{default:n(()=>[...C[12]||(C[12]=[r("表名(可选,逗号分隔)",-1)])]),_:1}),a(t(ee),{modelValue:w.value.tables,"onUpdate:modelValue":C[3]||(C[3]=o=>w.value.tables=o),placeholder:"e.g., users,orders"},null,8,["modelValue"])]),e("div",du,[a(t(U),null,{default:n(()=>[...C[13]||(C[13]=[r("申请理由 *",-1)])]),_:1}),a(t(Ge),{modelValue:w.value.justification,"onUpdate:modelValue":C[4]||(C[4]=o=>w.value.justification=o),rows:"4",placeholder:"请说明申请权限的原因和用途"},null,8,["modelValue"])])]),a(t(Be),null,{default:n(()=>[a(t(T),{variant:"outline",onClick:C[5]||(C[5]=o=>u("close"))},{default:n(()=>[...C[14]||(C[14]=[r("取消",-1)])]),_:1}),a(t(T),{onClick:H},{default:n(()=>[...C[15]||(C[15]=[r("提交申请",-1)])]),_:1})]),_:1})]),_:1})]),_:1}))}}),vu={class:"space-y-4"},pu={class:"flex gap-2"},fu={key:0,class:"text-center py-8 text-muted-foreground"},mu={key:1,class:"text-center py-8 text-muted-foreground"},_u={key:2,class:"space-y-2"},gu={class:"flex items-start justify-between mb-3"},bu={class:"font-semibold font-mono"},xu={class:"text-sm text-muted-foreground mt-1"},yu={class:"font-medium text-foreground"},ku={class:"grid grid-cols-2 gap-3 text-sm mb-3"},$u={class:"ml-2 font-medium"},wu={class:"ml-2 font-medium"},hu={key:0},Cu={class:"ml-2 font-medium"},Su={key:1},Du={class:"ml-2 font-medium"},Tu={class:"text-sm mb-3"},Eu={class:"mt-1"},zu={key:0,class:"text-xs text-muted-foreground bg-muted p-2 rounded-lg"},Vu={key:0},ju={key:1},Lu={key:1,class:"text-xs text-muted-foreground bg-destructive/5 border border-destructive/20 p-2 rounded-lg"},Uu={key:0},Ou={key:2,class:"flex gap-2 mt-3 pt-3 border-t"},Iu={class:"text-xs text-muted-foreground mt-2"},Ru={class:"space-y-4 py-4"},Fu={class:"space-y-2"},Nu={class:"space-y-2"},Pu={class:"space-y-2"},Au={class:"space-y-4 py-4"},Bu={class:"space-y-2"},Mu={class:"space-y-2"},qu=ye({__name:"PermissionRequestList",props:{instanceOptions:{}},emits:["refresh"],setup(M,{expose:q,emit:z}
8){const u=z,w=k(!1),O=k([]),S=k("all"),H=k(!1),N=k(!1),C=k(null),o=k({approver:"",expires_at:"",comments:""}),l=k({approver:"",comments:""});async function R(){w.value=!0;try{const V=new URLSearchParams({page:"1",page_size:"50"});S.value!=="all"&&V.set("status",S.value);const m=await fetch(`/api/resource-ops/dbspace/permission-requests?${V}`);if(!m.ok)throw new Error("加载失败");const E=await m.json();O.value=E.items||[]}catch(V){console.error("Failed to load permission requests:",V)}finally{w.value=!1}}function X(V){C.value=V,o.value={approver:"",expires_at:"",comments:""},H.value=!0}function ne(V){C.value=V,l.value={approver:"",comments:""},N.value=!0}async function G(){if(!o.value.approver){alert("请填写审批人");return}try{const V={approver:o.value.approver,comments:o.value.comments||null};if(o.value.expires_at&&(V.expires_at=o.value.expires_at),!(await fetch(`/api/resource-ops/dbspace/permission-requests/${C.value.id}/approve`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(V)})).ok)throw new Error("审批失败");H.value=!1,u("refresh"),await R()}catch(V){console.error("Failed to approve:",V),alert("审批失败")}}async function W(){if(!l.value.approver){alert("请填写审批人");return}if(!l.value.comments){alert("请填写拒绝原因");return}try{const V={approver:l.value.approver,comments:l.value.comments};if(!(await fetch(`/api/resource-ops/dbspace/permission-requests/${C.value.id}/reject`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(V)})).ok)throw new Error("拒绝失败");N.value=!1,u("refresh"),await R()}catch(V){console.error("Failed to reject:",V),alert("拒绝失败")}}function F(V){switch(V){case"pending":return"secondary";case"approved":return"default";case"rejected":return"destructive";default:return"outline"}}function I(V){switch(V){case"pending":return"待审批";case"approved":return"已通过";case"rejected":return"已拒绝";case"expired":return"已过期";default:return V}}function P(V){return V?new Date(V).toLocaleString("zh-CN"):"-"}return Oe(()=>{R()}),q({loadRequests:R}),(V,m)=>(i(),p("div",vu,[e("div",pu,[a(t(Fe),{modelValue:S.value,"onUpdate:modelValue":[m[0]||(m[0]=E=>S.value=E),R]},{default:n(()=>[a(t(Ne),{class:"w-40"},{default:n(()=>[a(t(Pe))]),_:1}),a(t(Ae),null,{default:n(()=>[a(t(ve),{value:"all"},{default:n(()=>[...m[10]||(m[10]=[r("全部状态",-1)])]),_:1}),a(t(ve),{value:"pending"},{default:n(()=>[...m[11]||(m[11]=[r("待审批",-1)])]),_:1}),a(t(ve),{value:"approved"},{default:n(()=>[...m[12]||(m[12]=[r("已通过",-1)])]),_:1}),a(t(ve),{value:"rejected"},{default:n(()=>[...m[13]||(m[13]=[r("已拒绝",-1)])]),_:1}),a(t(ve),{value:"expired"},{default:n(()=>[...m[14]||(m[14]=[r("已过期",-1)])]),_:1})]),_:1})]),_:1},8,["modelValue"])]),w.value?(i(),p("div",fu,"加载中...")):O.value.length===0?(i(),p("div",mu," 暂无权限申请记录 ")):(i(),p("div",_u,[(i(!0),p(B,null,Q(O.value,E=>(i(),A(t(Te),{key:E.id},{default:n(()=>[a(t(De),{class:"p-4"},{default:n(()=>[e("div",gu,[e("div",null,[e("h4",bu,d(E.request_key),1),e("p",xu,[m[15]||(m[15]=r(" 申请人: ",-1)),e("span",yu,d(E.requester),1)])]),a(t(ae),{variant:F(E.status)},{default:n(()=>[r(d(I(E.status)),1)]),_:2},1032,["variant"])]),e("div",ku,[e("div",null,[m[16]||(m[16]=e("span",{class:"text-muted-foreground"},"实例ID:",-1)),e("span",$u,d(E.instance_id),1)]),e("div",null,[m[17]||(m[17]=e("span",{class:"text-muted-foreground"},"权限类型:",-1)),e("span",wu,d(E.permission_type),1)]),E.database_name?(i(),p("div",hu,[m[18]||(m[18]=e("span",{class:"text-muted-foreground"},"数据库:",-1)),e("span",Cu,d(E.database_name),1)])):y("",!0),E.tables?(i(),p("div",Su,[m[19]||(m[19]=e("span",{class:"text-muted-foreground"},"表:",-1)),e("span",Du,d(E.tables.join(", ")),1)])):y("",!0)]),e("div",Tu,[m[20]||(m[20]=e("span",{class:"text-muted-foreground"},"申请理由:",-1)),e("p",Eu,d(E.justification),1)]),E.status==="approved"?(i(),p("div",zu,[r(" 审批人: "+d(E.approver)+" | 审批时间: "+d(P(E.approved_at))+" ",1),E.expires_at?(i(),p("span",Vu,"| 过期时间: "+d(P(E.expires_at)),1)):y("",!0),E.comments?(i(),p("span",ju,"| 备注: "+d(E.comments),1)):y("",!0)])):E.status==="rejected"?(i(),p("div",Lu,[r(" 审批人: "+d(E.approver)+" | 拒绝时间: "+d(P(E.approved_at))+" ",1),E.comments?(i(),p("span",Uu,"| 原因: "+d(E.comments),1)):y("",!0)])):y("",!0),E.status==="pending"?(i(),p("div",Ou,[a(t(T),{size:"sm",variant:"default",onClick:j=>X(E)},{default:n(()=>[...m[21]||(m[21]=[r("通过",-1)])]),_:1},8,["onClick"]),a(t(T),{size:"sm",variant:"destructive",onClick:j=>ne(E)},{default:n(()=>[...m[22]||(m[22]=[r("拒绝",-1)])]),_:1}
8,8,["onClick"])])):y("",!0),e("div",Iu," 申请时间: "+d(P(E.created_at)),1)]),_:2},1024)]),_:2},1024))),128))])),a(t(Ee),{open:H.value,"onUpdate:open":m[5]||(m[5]=E=>H.value=E)},{default:n(()=>[a(t(ze),null,{default:n(()=>[a(t(Ve),null,{default:n(()=>[a(t(je),null,{default:n(()=>[...m[23]||(m[23]=[r("审批通过",-1)])]),_:1})]),_:1}),e("div",Ru,[e("div",Fu,[a(t(U),null,{default:n(()=>[...m[24]||(m[24]=[r("审批人 *",-1)])]),_:1}),a(t(ee),{modelValue:o.value.approver,"onUpdate:modelValue":m[1]||(m[1]=E=>o.value.approver=E),placeholder:"请输入审批人姓名"},null,8,["modelValue"])]),e("div",Nu,[a(t(U),null,{default:n(()=>[...m[25]||(m[25]=[r("过期时间(可选)",-1)])]),_:1}),a(t(ee),{modelValue:o.value.expires_at,"onUpdate:modelValue":m[2]||(m[2]=E=>o.value.expires_at=E),type:"datetime-local"},null,8,["modelValue"])]),e("div",Pu,[a(t(U),null,{default:n(()=>[...m[26]||(m[26]=[r("备注",-1)])]),_:1}),a(t(Ge),{modelValue:o.value.comments,"onUpdate:modelValue":m[3]||(m[3]=E=>o.value.comments=E),rows:"3",placeholder:"可选备注信息"},null,8,["modelValue"])])]),a(t(Be),null,{default:n(()=>[a(t(T),{variant:"outline",onClick:m[4]||(m[4]=E=>H.value=!1)},{default:n(()=>[...m[27]||(m[27]=[r("取消",-1)])]),_:1}),a(t(T),{onClick:G},{default:n(()=>[...m[28]||(m[28]=[r("确认通过",-1)])]),_:1})]),_:1})]),_:1})]),_:1},8,["open"]),a(t(Ee),{open:N.value,"onUpdate:open":m[9]||(m[9]=E=>N.value=E)},{default:n(()=>[a(t(ze),null,{default:n(()=>[a(t(Ve),null,{default:n(()=>[a(t(je),null,{default:n(()=>[...m[29]||(m[29]=[r("拒绝申请",-1)])]),_:1})]),_:1}),e("div",Au,[e("div",Bu,[a(t(U),null,{default:n(()=>[...m[30]||(m[30]=[r("审批人 *",-1)])]),_:1}),a(t(ee),{modelValue:l.value.approver,"onUpdate:modelValue":m[6]||(m[6]=E=>l.value.approver=E),placeholder:"请输入审批人姓名"},null,8,["modelValue"])]),e("div",Mu,[a(t(U),null,{default:n(()=>[...m[31]||(m[31]=[r("拒绝原因 *",-1)])]),_:1}),a(t(Ge),{modelValue:l.value.comments,"onUpdate:modelValue":m[7]||(m[7]=E=>l.value.comments=E),rows:"3",placeholder:"请说明拒绝原因"},null,8,["modelValue"])])]),a(t(Be),null,{default:n(()=>[a(t(T),{variant:"outline",onClick:m[8]||(m[8]=E=>N.value=!1)},{default:n(()=>[...m[32]||(m[32]=[r("取消",-1)])]),_:1}),a(t(T),{variant:"destructive",onClick:W},{default:n(()=>[...m[33]||(m[33]=[r("确认拒绝",-1)])]),_:1})]),_:1})]),_:1})]),_:1},8,["open"])]))}}),Qu={class:"space-y-4"},Wu={class:"rounded-lg border bg-card p-6"},Hu=ye({name:"PermissionPanel",__name:"PermissionPanel",props:{instanceOptions:{}},setup(M){const q=k(!1);function z(){q.value=!1}return(u,w)=>(i(),A(t(Te),null,{default:n(()=>[a(t(qe),null,{default:n(()=>[a(t(Me),{class:"flex items-center gap-2 text-lg"},{default:n(()=>[a(K,{name:"settings",size:20}),w[2]||(w[2]=r(" 数据库权限管理 ",-1))]),_:1})]),_:1}),a(t(De),null,{default:n(()=>[e("div",Qu,[e("div",Wu,[w[4]||(w[4]=e("h3",{class:"mb-2 font-semibold"},"申请数据库权限",-1)),w[5]||(w[5]=e("p",{class:"mb-4 text-sm text-muted-foreground"}," 申请对数据库实例的访问权限,支持只读、读写等权限级别 ",-1)),a(t(T),{onClick:w[0]||(w[0]=O=>q.value=!0)},{default:n(()=>[a(K,{name:"plus",size:16,class:"mr-2"}),w[3]||(w[3]=r(" 申请权限 ",-1))]),_:1})]),a(qu,{"instance-options":M.instanceOptions},null,8,["instance-options"])])]),_:1}),q.value?(i(),A(cu,{key:0,"instance-options":M.instanceOptions,onClose:w[1]||(w[1]=O=>q.value=!1),onSuccess:z},null,8,["instance-options"])):y("",!0)]),_:1}))}}),Ju={class:"space-y-4"},Ku={class:"flex items-center gap-2 border-b border-border pb-2"},Gu={class:"min-h-[600px]"},vd=ye({name:"ResourceOpsDatabasePage",__name:"ResourceOpsDatabasePage",props:{locale:{}},emits:["focus-appsystem-architecture","focus-appsystem-dossier","focus-devops-project","focus-devops-environment","focus-devops-resource","open-account-detail"],setup(M,{emit:q}){const z=M,u=q,w=k("connections"),O=[{key:"connections",label:"连接管理",icon:"dashboard"},{key:"sql",label:"SQL工作台",icon:"edit"},{key:"transfers",label:"数据传输",icon:"refresh"},{key:"permissions",label:"权限管理",icon:"settings"}],S={connections:dt,sql:Ds,transfers:eu,permissions:Hu},H=oe(()=>S[w.value]||dt),N=oe(()=>{switch(w.value){case"connections":return{locale:z.locale};case"sql":return{};case"transfers":return{instanceOptions:o.value,connections:l.value};case"permissions":return{instanceOptions:o.value};default:return{}}}),C=oe(()=>{switch(w.value){case"connections":return{"focus-appsystem-architecture":F=>u("focus-appsystem-architecture",F),"focus-appsystem-dossier":F=>u("focus-appsystem-dossier",F),"focus-devops-project":F=>u("focus-devops-project",F),"focus-devops-environment":F=>u("focus-devops-environment",F),"focus-devops-resource":F=>u("focus-devops-resource",F),"connection-selected":W,"open-account-detail":F=>u("open-account-detail",F)};default:return{}}}),o=k([]),l=k([]),R=k(null),X=k(null);async function ne(){try{const F=await fetch("/api/resource-ops/dbspace/instances?page=1&page_size=100");if(!F.ok)throw new Error("加载实例列表失败");const I=await F.json();o.value=(I.items||[]).map(P=>({id:P.id,instance_name:P.instance_name}))}catch(F){console.error("Failed to load instance options:",F)}}async function G(){try{const F=await fetch("/api/db-platform/connections?page=1&page_size=200");if(!F.ok){console.error("加载连接列表失败");return}const I=await F.json();l.value=(I.items||[]).map(P=>({id:P.id,instance_name:P.name,db_type:P.engine||P.db_type,host:P.host,port:P.port}))}catch(F){console.error("Failed to load connections:",F)}}function W(F,I){R.value=F,X.value=I}return Oe(()=>{ne(),G()}),(F,I)=>(i(),p("div",Ju,[e("div",Ku,[(i(),p(B,null,Q(O,P=>a(t(T),{key:P.key,variant:w.value===P.key?"default":"ghost",size:"sm",onClick:V=>w.value=P.key,class:"gap-2"},{default:n(()=>[a(K,{name:P.icon,size:16},null,8,["name"]),r(" "+d(P.label),1)]),_:2},1032,["variant","onClick"])),64))]),e("div",Gu,[(i(),A(wt,null,[(i(),A(yt(H.value),kt({key:w.value},N.value,$t(C.value)),null,16))],1024))])]))}});
8export{vd as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.