RoutePage/web/admin.html
2026-09-15 02:00:21 +08:00

223 lines
9.1 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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="style.css">
</head>
<body class="admin-page">
<div class="console" id="console">
<!-- ================= 左侧深蓝可收缩侧栏 ================= -->
<aside class="console-nav">
<div class="console-brand">
<div class="logo">R</div>
<div class="cb-text"><b>管理控制台</b><i id="navUser"></i></div>
<button class="cnav-toggle" id="btnCollapseNav" title="收起 / 展开侧栏"></button>
</div>
<div class="cnav-item active" data-view="overview"><span class="ci">📊</span><span class="cl">概览</span></div>
<div class="cnav-item" data-view="users"><span class="ci">👥</span><span class="cl">用户管理</span></div>
<div class="cnav-item" data-view="topo"><span class="ci">🗺️</span><span class="cl">拓扑管理</span></div>
<div class="cnav-item" data-view="settings"><span class="ci">⚙️</span><span class="cl">网站设置</span></div>
<div class="cnav-item" data-view="logs"><span class="ci">📝</span><span class="cl">操作日志</span></div>
<div class="cnav-foot">
<div class="cnav-close" id="btnCloseAdmin"><span class="ci"></span><span class="cl">返回拓扑</span></div>
</div>
</aside>
<!-- ================= 右侧主区域 ================= -->
<main class="console-main">
<!-- 概览 -->
<section class="view" id="view-overview">
<div class="view-head"><h2>概览</h2></div>
<div class="cards" id="statCards"></div>
<div class="split">
<div class="panel">
<div class="panel-title">最近操作</div>
<div class="mini-list" id="recentLogs"></div>
</div>
<div class="panel">
<div class="panel-title">最近拓扑</div>
<div class="mini-list" id="recentTopos"></div>
</div>
</div>
</section>
<!-- 用户管理 -->
<section class="view" id="view-users" hidden>
<div class="view-head">
<h2>用户管理</h2>
<div class="view-tools">
<input class="search" id="userSearch" placeholder="搜索用户名 / 角色" spellcheck="false">
<button class="btn primary" id="btnNewUser"> 新建用户</button>
</div>
</div>
<div class="table-wrap">
<table class="grid">
<thead><tr>
<th>用户名</th><th>角色</th><th>状态</th><th>登录次数</th><th>最近登录</th><th>创建时间</th><th>操作</th>
</tr></thead>
<tbody id="userRows"></tbody>
</table>
</div>
<div class="pager" id="userPager"></div>
</section>
<!-- 拓扑管理 -->
<section class="view" id="view-topo" hidden>
<div class="view-head">
<h2>拓扑管理</h2>
<div class="view-tools">
<input class="search" id="topoSearch" placeholder="搜索拓扑名称" spellcheck="false">
<select class="search" id="topoOwner"></select>
<button class="btn" id="btnExportSelectedTopos">导出所选</button>
<button class="btn" id="btnExportAllTopos">导出全部</button>
<button class="btn danger" id="btnDeleteSelectedTopos">删除所选</button>
</div>
</div>
<div class="table-wrap">
<table class="grid">
<thead><tr>
<th class="col-chk"><input type="checkbox" id="topoSelectAll" title="全选本页"></th>
<th>名称</th><th>所有者</th><th>可见性</th><th>节点 / 连线</th><th>更新时间</th><th>操作</th>
</tr></thead>
<tbody id="topoRows"></tbody>
</table>
</div>
<div class="pager" id="topoPager"></div>
</section>
<!-- 网站设置 -->
<section class="view" id="view-settings" hidden>
<div class="view-head">
<h2>网站设置</h2>
<div class="view-tools">
<button class="btn primary" id="btnSaveSettings">保存设置</button>
</div>
</div>
<div class="settings-grid">
<div class="panel">
<div class="panel-title">品牌</div>
<label class="set-label">网站名称
<input class="search" id="setSiteName" type="text" placeholder="路由拓扑" spellcheck="false" maxlength="40">
</label>
<div class="set-label">网站 Logo</div>
<div class="logo-edit">
<div class="logo-preview" id="logoPreview">R</div>
<div class="logo-edit-side">
<input type="file" id="logoFile" accept="image/png,image/jpeg,image/gif,image/webp,image/svg+xml" hidden>
<div class="row-mini">
<button class="btn" id="btnPickLogo" type="button">选择图片</button>
<button class="btn" id="btnClearLogo" type="button">清除</button>
</div>
<div class="hint-sm">支持 PNG / JPG / GIF / WEBP / SVG,建议方形透明底,不超过 300KB。</div>
</div>
</div>
</div>
<div class="panel">
<div class="panel-title">注册与会话</div>
<label class="set-row">
<input type="checkbox" id="setAllowReg"> <span>开放访客自助注册</span>
</label>
<label class="set-label">会话有效期(天)
<input class="search" id="setTtl" type="number" min="1" max="365" step="1">
</label>
<div class="hint-sm">修改后,新登录的会话按该时长计算有效期(1 - 365 天)。</div>
</div>
</div>
</section>
<!-- 操作日志 -->
<section class="view" id="view-logs" hidden>
<div class="view-head">
<h2>操作日志</h2>
<div class="view-tools"><input class="search" id="logSearch" placeholder="搜索用户 / 动作 / 详情" spellcheck="false"></div>
</div>
<div class="table-wrap">
<table class="grid">
<thead><tr>
<th>时间</th><th>用户</th><th>动作</th><th>对象</th><th>详情</th><th>IP</th>
</tr></thead>
<tbody id="logRows"></tbody>
</table>
</div>
<div class="pager" id="logPager"></div>
</section>
</main>
</div>
<!-- ================= 新建用户 ================= -->
<div class="overlay" id="userOverlay" hidden>
<div class="dialog">
<div class="dlg-head"><h2 id="userDlgTitle">新建用户</h2><span class="dlg-close" id="btnCloseUser">×</span></div>
<label>用户名
<input id="uName" type="text" spellcheck="false" autocomplete="off" placeholder="2-32 位字母、数字、_ . -">
</label>
<label>密码
<input id="uPass" type="password" autocomplete="new-password" placeholder="至少 8 位,需含字母和数字">
</label>
<label>角色
<select id="uRole">
<option value="user">普通用户</option>
<option value="admin">管理员</option>
</select>
</label>
<div class="dlg-tip">新建用户首次登录后需强制修改密码</div>
<div class="dlg-err" id="userErr"></div>
<div class="dlg-actions">
<button class="btn" id="btnCancelUser" type="button">取消</button>
<button class="btn primary" id="btnSaveUser" type="button">创建</button>
</div>
</div>
</div>
<!-- ================= 重置用户密码 ================= -->
<div class="overlay" id="resetOverlay" hidden>
<div class="dialog">
<div class="dlg-head"><h2>重置用户密码</h2><span class="dlg-close" id="btnCloseReset">×</span></div>
<div class="dlg-tip" id="resetTip"></div>
<label>您的密码(管理员)
<input id="resetAdminPw" type="password" autocomplete="current-password" placeholder="请输入当前登录账号的密码">
</label>
<label>新密码
<input id="resetNewPw" type="password" autocomplete="new-password" placeholder="至少 8 位,需含字母和数字">
</label>
<label>确认新密码
<input id="resetNewPw2" type="password" autocomplete="new-password" placeholder="请再次输入新密码">
</label>
<label class="pwd-show"><input type="checkbox" id="resetShow"> 显示密码</label>
<div class="dlg-err" id="resetErr"></div>
<div class="dlg-actions">
<button class="btn" id="btnCancelReset" type="button">取消</button>
<button class="btn primary" id="btnDoReset" type="button">确认重置</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="toast" id="toast"></div>
<script src="admin.js"></script>
</body>
</html>