9 lines
11 KiB
HTML
9 lines
11 KiB
HTML
<!doctype html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>syncdb · 数据同步控制台</title>
|
||
<style>
|
||
:root{--bg:#f5f7fb;--panel:#fff;--ink:#172033;--muted:#7c879b;--line:#e7ebf2;--blue:#3867ff;--blue2:#edf1ff;--green:#19a974;--orange:#d98920;--red:#df5b66;--shadow:0 12px 34px #263b6812}*{box-sizing:border-box}body{margin:0;background:var(--bg);font:14px/1.5 Inter,Segoe UI,Microsoft YaHei,sans-serif;color:var(--ink)}button{border:0;font:inherit;cursor:pointer}.app{display:flex;min-height:100vh}.side{width:232px;background:#121a2b;color:#aeb8cb;padding:25px 16px}.logo{color:#fff;font-size:21px;font-weight:800;letter-spacing:.3px;padding:0 13px 34px}.logo span{color:#6e8cff}.nav{padding:12px 14px;border-radius:10px;margin:5px 0;cursor:pointer}.nav.active,.nav:hover{background:#263454;color:#fff}.nav i{display:inline-block;width:25px;color:#829cff;font-style:normal}.section{font-size:11px;text-transform:uppercase;letter-spacing:1.5px;color:#64708a;padding:23px 14px 8px}.main{flex:1;padding:26px 36px;max-width:1500px}.top{display:flex;justify-content:space-between;align-items:center;margin-bottom:27px}.crumb{color:var(--muted);font-size:13px}.title{font-size:26px;font-weight:750;margin:5px 0}.actions{display:flex;gap:10px;align-items:center}.btn{padding:10px 15px;border-radius:9px;background:#fff;border:1px solid var(--line);color:#526078}.btn.primary{background:var(--blue);border-color:var(--blue);color:#fff}.user{width:35px;height:35px;background:#dbe3ff;color:#3154d2;border-radius:50%;display:grid;place-items:center;font-weight:700}.grid{display:grid;grid-template-columns:repeat(4,1fr);gap:17px;margin-bottom:22px}.card{background:var(--panel);border:1px solid var(--line);border-radius:13px;padding:19px;box-shadow:var(--shadow)}.metric{display:flex;justify-content:space-between}.metric small{color:var(--muted)}.metric strong{display:block;font-size:27px;margin-top:7px}.ico{width:42px;height:42px;border-radius:11px;background:var(--blue2);display:grid;place-items:center;color:var(--blue);font-size:18px}.delta{font-size:12px;color:var(--green);margin-top:11px}.cols{display:grid;grid-template-columns:1.3fr .7fr;gap:20px}.cardhead{display:flex;justify-content:space-between;align-items:center;margin-bottom:17px}.cardhead h3{font-size:16px;margin:0}.link{color:var(--blue);cursor:pointer}.table{width:100%;border-collapse:collapse}.table th{text-align:left;color:var(--muted);font-size:12px;font-weight:500;padding:9px 8px;border-bottom:1px solid var(--line)}.table td{padding:14px 8px;border-bottom:1px solid #f0f2f6}.status{padding:5px 9px;border-radius:20px;font-size:12px}.ok{background:#e6f7ef;color:#108a5b}.run{background:#e9efff;color:#3961dd}.warn{background:#fff3df;color:#b66b10}.bar{height:7px;background:#edf0f5;border-radius:9px;overflow:hidden}.bar b{height:100%;display:block;background:var(--blue);border-radius:9px}.donut{width:150px;height:150px;border-radius:50%;background:conic-gradient(var(--blue) 0 68%,#8fc3ff 68% 84%,#ffd27b 84% 93%,#e8ebf1 93%);margin:8px auto;display:grid;place-items:center}.donut:after{content:'68%';background:#fff;width:100px;height:100px;border-radius:50%;display:grid;place-items:center;font-size:22px;font-weight:700}.legend{display:flex;justify-content:space-around;color:var(--muted);font-size:12px}.dot{display:inline-block;width:7px;height:7px;border-radius:50%;margin-right:5px;background:var(--blue)}.modal{display:none;position:fixed;inset:0;background:#101a2b66;place-items:center}.modal.open{display:grid}.dialog{background:#fff;width:570px;border-radius:16px;padding:26px;box-shadow:0 20px 60px #0003}.dialog h2{margin:0 0 20px}.form{display:grid;grid-template-columns:1fr 1fr;gap:14px}.field label{display:block;color:var(--muted);font-size:12px;margin-bottom:6px}.field input,.field select{width:100%;padding:10px;border:1px solid var(--line);border-radius:8px;background:#fff}.full{grid-column:1/-1}.dialogfoot{display:flex;justify-content:flex-end;gap:9px;margin-top:24px}
|
||
</style></head>
|
||
<body><div class="app"><aside class="side"><div class="logo">sync<span>db</span></div><div class="nav active" onclick="show('仪表盘',this)"><i>◈</i>仪表盘</div><div class="nav" onclick="show('数据源',this)"><i>◉</i>数据源</div><div class="nav" onclick="show('同步任务',this)"><i>↻</i>同步任务</div><div class="nav" onclick="show('SQL 导出',this)"><i>⇩</i>SQL 导出</div><div class="nav" onclick="show('Binlog / SQL',this)"><i>⌁</i>Binlog / SQL</div><div class="section">系统</div><div class="nav"><i>⚙</i>设置</div><div class="nav"><i>?</i>帮助文档</div></aside><main class="main"><div class="top"><div><div class="crumb">工作台 / <span id="page">仪表盘</span></div><div class="title" id="title">同步概览</div></div><div class="actions"><button class="btn" onclick="toast('暂无新的通知')">● 通知</button><button class="btn primary" onclick="openModal()">+ 新建同步任务</button><div class="user">Z</div></div></div><section class="grid"><div class="card metric"><div><small>数据源</small><strong>12</strong><div class="delta">↑ 2 本月新增</div></div><div class="ico">⌘</div></div><div class="card metric"><div><small>同步任务</small><strong>24</strong><div class="delta">↑ 8.4% 活跃任务</div></div><div class="ico">↻</div></div><div class="card metric"><div><small>本月同步记录</small><strong>1.28M</strong><div class="delta">↑ 18.2% 较上月</div></div><div class="ico">▣</div></div><div class="card metric"><div><small>成功率</small><strong>98.6%</strong><div class="delta">↑ 1.2% 较上月</div></div><div class="ico">✓</div></div></section><section class="cols"><div class="card"><div class="cardhead"><h3>最近同步任务</h3><span class="link">查看全部 →</span></div><table class="table"><thead><tr><th>任务名称</th><th>数据流向</th><th>进度</th><th>状态</th></tr></thead><tbody><tr><td><b>测试环境用户刷新</b><br><small style="color:var(--muted)">刚刚</small></td><td>MySQL <span style="color:#aab2c1">→</span> MySQL</td><td style="width:170px"><div class="bar"><b style="width:72%"></b></div><small>72%</small></td><td><span class="status run">执行中</span></td></tr><tr><td><b>订单数据归档</b><br><small style="color:var(--muted)">今天 10:32</small></td><td>MongoDB <span style="color:#aab2c1">→</span> MongoDB</td><td><div class="bar"><b style="width:100%;background:var(--green)"></b></div><small>100%</small></td><td><span class="status ok">已完成</span></td></tr><tr><td><b>用户中心迁移</b><br><small style="color:var(--muted)">昨天 18:20</small></td><td>MySQL <span style="color:#aab2c1">→</span> MongoDB</td><td><div class="bar"><b style="width:100%;background:var(--red)"></b></div><small>100%</small></td><td><span class="status warn">部分失败</span></td></tr><tr><td><b>报表库增量同步</b><br><small style="color:var(--muted)">昨天 16:05</small></td><td>MySQL <span style="color:#aab2c1">→</span> MySQL</td><td><div class="bar"><b style="width:100%;background:var(--green)"></b></div><small>100%</small></td><td><span class="status ok">已完成</span></td></tr></tbody></table></div><div class="card"><div class="cardhead"><h3>同步成功率</h3><span class="link">近 30 天⌄</span></div><div class="donut"></div><div class="legend"><span><i class="dot"></i>成功 68%</span><span><i class="dot" style="background:#8fc3ff"></i>跳过 16%</span><span><i class="dot" style="background:#ffd27b"></i>失败 9%</span></div></div></section><section class="card" style="margin-top:20px"><div class="cardhead"><h3>SQL 导出文件</h3><span class="link" onclick="toast('打开全部导出记录')">查看全部 →</span></div><table class="table"><thead><tr><th>文件名</th><th>内容</th><th>大小</th><th>生成时间</th><th>操作</th></tr></thead><tbody><tr><td>syncdb-export-20260906-001.tar.gz</td><td>users, orders · 结构+数据</td><td>248 MB</td><td>今天 09:48</td><td><button class="btn" onclick="toast('开始下载压缩包')">⇩ 下载</button></td></tr></tbody></table></section><section class="card" style="margin-top:20px"><div class="cardhead"><h3>最近执行 SQL</h3><span class="link" onclick="toast('打开 SQL 审计')">查看全部 →</span></div><table class="table"><thead><tr><th>执行时间</th><th>任务</th><th>SQL 类型</th><th>耗时</th><th>状态</th></tr></thead><tbody><tr><td>今天 10:42:18</td><td>测试环境用户刷新</td><td>INSERT · users</td><td>86 ms</td><td><span class="status ok">成功</span></td></tr><tr><td>今天 10:41:56</td><td>订单数据归档</td><td>UPDATE · orders</td><td>124 ms</td><td><span class="status ok">成功</span></td></tr><tr><td>今天 10:40:12</td><td>用户中心迁移</td><td>UPSERT · users</td><td>—</td><td><span class="status warn">失败</span></td></tr></tbody></table></section><section class="card" style="margin-top:20px"><div class="cardhead"><h3>MySQL Binlog 事件</h3><span class="link" onclick="toast('Binlog 过滤器已打开')">筛选条件 →</span></div><table class="table"><thead><tr><th>时间</th><th>文件 / 位置</th><th>对象</th><th>事件</th><th>变更</th></tr></thead><tbody><tr><td>10:42:19</td><td>mysql-bin.000018 : 92831</td><td>app.users</td><td><span class="status run">WRITE_ROWS</span></td><td>id=1024 · 已脱敏</td></tr><tr><td>10:42:17</td><td>mysql-bin.000018 : 92104</td><td>app.orders</td><td><span class="status warn">UPDATE_ROWS</span></td><td>id=8831 · 3 fields</td></tr></tbody></table></section></main></div><div class="modal" id="modal"><div class="dialog"><h2>新建同步任务</h2><div class="form"><div class="field full"><label>任务名称</label><input value="测试环境数据刷新"></div><div class="field"><label>源数据源</label><select><option>开发 MySQL · dev-db</option><option>生产 MongoDB · prod-mongo</option></select></div><div class="field"><label>目标数据源</label><select><option>测试 MySQL · test-db</option><option>开发 MongoDB · dev-mongo</option></select></div><div class="field"><label>同步模式</label><select><option>全量同步</option><option>增量同步</option></select></div><div class="field"><label>冲突策略</label><select><option>Upsert</option><option>Skip</option><option>Fail</option></select></div><div class="field full"><label>同步对象</label><input placeholder="选择表或集合,例如 users, orders"></div></div><div class="dialogfoot"><button class="btn" onclick="closeModal()">取消</button><button class="btn primary" onclick="closeModal();toast('任务已创建,等待执行')">创建任务</button></div></div></div><script>function openModal(){document.getElementById('modal').classList.add('open')}function closeModal(){document.getElementById('modal').classList.remove('open')}function toast(t){let x=document.createElement('div');x.textContent=t;x.style='position:fixed;right:30px;bottom:30px;background:#172033;color:#fff;padding:12px 18px;border-radius:9px;box-shadow:0 8px 30px #0003';document.body.appendChild(x);setTimeout(()=>x.remove(),2200)}function show(p,e){document.querySelectorAll('.nav').forEach(n=>n.classList.remove('active'));e.classList.add('active');document.getElementById('page').textContent=p;document.getElementById('title').textContent=p==='仪表盘'?'同步概览':p}</script></body></html> |