Files
syncdb/docs/prototype.html
曾志威 30385fc34b
continuous-integration/drone Build is failing
feat: initialize syncdb web service MVP
2026-09-06 14:06:16 +08:00

9 lines
11 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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>