RoutePage/web/index.html
2026-09-15 02:28:40 +08:00

237 lines
10 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>路由拓扑</title>
<link rel="stylesheet" href="web/style.css">
</head>
<body>
<div class="app">
<header class="topbar">
<div class="brand"><div class="logo" id="brandLogo">R</div><h1 id="brandName">路由拓扑</h1></div>
<div class="tb-group">
<button class="btn" id="btnUndo" disabled title="撤销上一次操作"><span class="lbl">撤销</span></button>
<button class="btn" id="btnAuto" title="自动整理布局"><span class="lbl">自动整理</span></button>
<button class="btn" id="btnFit" title="适应窗口"><span class="lbl">适应窗口</span></button>
</div>
<span class="sep"></span>
<div class="tb-group">
<button class="btn" id="btnImport" title="导入拓扑"><span class="lbl">导入</span></button>
<button class="btn" id="btnExport" title="导出拓扑"><span class="lbl">导出</span></button>
<button class="btn danger" id="btnClear" title="清空画布"><span class="lbl">清空</span></button>
</div>
<div class="topbar-right">
<span class="save-state" id="saveState"></span>
<button class="btn" id="btnShare" title="共享与协作" hidden><span class="lbl">共享</span></button>
<button class="btn primary" id="btnSave">保存</button>
<button class="btn" id="btnMyTopos">我的拓扑</button>
<div class="user-wrap">
<button class="btn" id="btnUser">登录</button>
</div>
</div>
<input type="file" id="fileInput" accept=".json,application/json" hidden>
</header>
<div class="banner" id="banner" hidden></div>
<main class="main">
<div class="canvas-wrap">
<svg id="svg" xmlns="http://www.w3.org/2000/svg">
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="10" refY="5"
markerWidth="6.5" markerHeight="6.5" orient="auto">
<path d="M 0 0.7 L 10 5 L 0 9.3 L 2.6 5 Z" fill="#94a3b8"/>
</marker>
</defs>
<g id="viewport"></g>
</svg>
<div class="hint">拖动空白平移 · 滚轮缩放 · 拖节点右侧蓝点连线 · 拖底部绿点加子节点 · 双击空白新建</div>
<div class="stats" id="stats"></div>
</div>
<aside class="inspector">
<div class="insp-empty" id="inspEmpty">
<b>未选中节点</b>
点击图中节点进行编辑
</div>
<div id="inspBody" hidden>
<div class="insp-section" data-sec="basic">
<div class="insp-sec-head"><span>基本信息</span><span class="insp-chevron"></span></div>
<div class="insp-sec-body">
<label>名称 / 地址
<input id="fLabel" type="text" placeholder="192.168.1.10 / dc.corp.local" spellcheck="false">
</label>
<label>类型
<select id="fType">
<option value="net">网段 (CIDR)</option>
<option value="host">主机 (IP)</option>
<option value="domain">域名</option>
<option value="other">其他</option>
</select>
</label>
<label>状态
<select id="fStatus"></select>
</label>
<label>端口 / 服务
<input id="fPorts" type="text" placeholder="22, 80, 445 / ssh、smb" spellcheck="false">
</label>
</div>
</div>
<div class="insp-section" data-sec="note">
<div class="insp-sec-head"><span>备注</span><span class="insp-chevron"></span></div>
<div class="insp-sec-body">
<label>备注
<textarea id="fNote" placeholder="凭据、漏洞、横向思路…"></textarea>
</label>
</div>
</div>
<div class="insp-section" data-sec="actions">
<div class="insp-sec-head"><span>操作</span><span class="insp-chevron"></span></div>
<div class="insp-sec-body">
<div class="btn-row">
<button class="btn" id="btnAddChild"> 子节点</button>
<button class="btn danger" id="btnDelete">删除节点</button>
</div>
</div>
</div>
<div class="meta" id="inspMeta"></div>
</div>
<div class="legend" id="legend"></div>
</aside>
</main>
</div>
<!-- ================= 登录 / 注册 ================= -->
<div class="overlay" id="loginOverlay" hidden>
<div class="dialog">
<div class="dlg-head"><h2 id="loginTitle">登录</h2><span class="dlg-close" id="btnCloseLogin">×</span></div>
<label>用户名
<input id="loginUser" type="text" spellcheck="false" autocomplete="username" placeholder="用户名">
</label>
<label>密码
<input id="loginPass" type="password" autocomplete="current-password" placeholder="密码">
</label>
<label id="loginPass2Wrap" hidden>确认密码
<input id="loginPass2" type="password" autocomplete="new-password" placeholder="请再次输入密码">
</label>
<label class="pwd-show"><input type="checkbox" id="loginShow"> 显示密码</label>
<div class="dlg-err" id="loginErr"></div>
<div class="dlg-actions">
<button class="btn primary" id="btnDoLogin">登录</button>
<button class="btn" id="btnRegister">注册新账号</button>
</div><br>
<div class="dlg-tip" id="loginTip">默认管理员 admin / admin123</div>
</div>
</div>
<!-- ================= 我的拓扑 ================= -->
<div class="overlay" id="topoOverlay" hidden>
<div class="dialog wide">
<div class="dlg-head"><h2>我的拓扑</h2><span class="dlg-close" id="btnCloseTopo">×</span></div>
<div class="new-row">
<input id="newTopoName" type="text" placeholder="新建拓扑名称,例如:某内网横向拓扑" spellcheck="false">
<select id="newTopoTemplate" title="选择初始化模板"></select>
<button class="btn primary" id="btnCreateTopo">新建</button>
</div>
<div class="seg" id="topoScope">
<button class="seg-btn active" type="button" data-scope="mine">我的拓扑</button>
<button class="seg-btn" type="button" data-scope="shared">共享拓扑</button>
<button class="seg-btn" type="button" data-scope="public">公开拓扑</button>
</div>
<div class="topo-list" id="topoList"></div>
</div>
</div>
<!-- ================= 共享与协作 ================= -->
<div class="overlay" id="shareOverlay" hidden>
<div class="dialog wide share-dialog">
<div class="dlg-head"><h2>共享与协作</h2><span class="dlg-close" id="btnCloseShare">×</span></div>
<div class="dlg-msg" id="shareMsg"></div>
<label class="set-row">
<input type="checkbox" id="shareMode"> <span>开启共享模式(允许以下成员 / 分组访问与协同编辑)</span>
</label>
<div class="share-cols">
<div class="share-col">
<div class="share-col-title">成员</div>
<input class="search" id="shareUserFilter" placeholder="搜索成员" spellcheck="false">
<div class="share-list" id="shareUserList"></div>
</div>
<div class="share-col">
<div class="share-col-title">分组</div>
<input class="search" id="shareGroupFilter" placeholder="搜索分组" spellcheck="false">
<div class="share-list" id="shareGroupList"></div>
</div>
</div>
<div class="dlg-err" id="shareErr"></div>
<div class="dlg-actions">
<button class="btn" id="btnCancelShare" type="button">取消</button>
<button class="btn primary" id="btnSaveShare" type="button">保存共享</button>
</div>
</div>
</div>
<!-- 管理员控制台已拆分为独立页面:web/admin.html -->
<!-- ================= 修改密码 ================= -->
<div class="overlay" id="pwdOverlay" hidden>
<div class="dialog">
<div class="dlg-head"><h2 id="pwdTitle">修改密码</h2><span class="dlg-close" id="btnClosePwd">×</span></div>
<div class="dlg-tip" id="pwdHintWrap" hidden>首次登录必须修改密码后才能继续使用</div>
<label>原密码<input id="pwdOld" type="password" autocomplete="current-password" placeholder="当前使用的密码"></label>
<label>新密码<input id="pwdNew" type="password" autocomplete="new-password" placeholder="至少 8 位,需含字母和数字"></label>
<label>确认新密码<input id="pwdNew2" type="password" autocomplete="new-password" placeholder="请再次输入新密码"></label>
<label class="pwd-show"><input type="checkbox" id="pwdShow"> 显示密码</label>
<div class="dlg-err" id="pwdErr"></div>
<div class="dlg-actions"><button class="btn primary" id="btnDoPwd">确认修改</button></div>
</div>
</div>
<!-- ================= 站内确认 / 输入弹窗 ================= -->
<div class="overlay" id="confirmOverlay" hidden>
<div class="dialog">
<div class="dlg-head"><h2 id="confirmTitle">请确认</h2><span class="dlg-close" id="confirmClose">×</span></div>
<div class="dlg-msg" id="confirmMsg"></div>
<label id="confirmFieldWrap" hidden><span id="confirmFieldLabel"></span>
<input id="confirmField" type="text" spellcheck="false" autocomplete="off">
</label>
<div class="dlg-err" id="confirmErr"></div>
<div class="dlg-actions">
<button class="btn" id="confirmCancel" type="button">取消</button>
<button class="btn primary" id="confirmOk" type="button">确定</button>
</div>
</div>
</div>
<!-- ================= 导出 / 导入 格式选择 ================= -->
<div class="overlay" id="formatOverlay" hidden>
<div class="dialog">
<div class="dlg-head"><h2 id="formatTitle">导出拓扑</h2><span class="dlg-close" id="btnCloseFormat">×</span></div>
<div class="dlg-msg" id="formatMsg"></div>
<div class="format-list" id="formatList"></div>
</div>
</div>
<!-- 用户菜单置于 body 直属并使用 fixed 定位,避免被顶部栏的 overflow / backdrop-filter 裁剪 -->
<div class="dropdown" id="userMenu" hidden>
<div class="dd-name" id="ddName"></div>
<div class="dd-item" id="ddWorkspace">我的工作台</div>
<div class="dd-item" id="ddPwd">修改密码</div>
<div class="dd-item" id="ddLogout">退出登录</div>
</div>
<!-- 右下角状态区:当前正在编辑的拓扑 + 在线协作(始终固定右下角) -->
<div class="corner-status" id="cornerStatus">
<div class="topo-current" id="topoCurrent">
<i class="tc-dot"></i><span class="tc-label">当前拓扑</span><span class="tc-name"></span>
</div>
<div class="collab-bar" id="collabBar" hidden></div>
</div>
<div class="toast" id="toast"></div>
<script src="web/app.js"></script>
</body>
</html>