Files
2026-06-10 16:51:18 +08:00

137 lines
4.3 KiB
HTML

<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>NetStable 测速监控</title>
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<header class="topbar">
<div>
<h1>NetStable</h1>
<p>浏览器到服务器上传下载实时测速</p>
</div>
<div id="serverState" class="state idle">空闲</div>
</header>
<main class="layout">
<section class="panel control-panel">
<h2>开始测试</h2>
<form id="testForm" class="form">
<label>
<span>目标 IP / 域名(可带端口)</span>
<input id="target" name="target" autocomplete="off" required>
</label>
<label>
<span>延迟探测 URL</span>
<input id="httpUrl" name="httpUrl" placeholder="可选,例如 https://example.com/">
</label>
<div class="grid-2">
<fieldset class="choice-field">
<span>每阶段时长(秒)</span>
<div class="segmented-control" role="radiogroup" aria-label="每阶段时长">
<label>
<input name="durationSeconds" type="radio" value="15">
<span>15s</span>
</label>
<label>
<input name="durationSeconds" type="radio" value="30" checked>
<span>30s</span>
</label>
</div>
</fieldset>
<label>
<span>超时(毫秒)</span>
<input id="timeoutMillis" name="timeoutMillis" type="number" min="100" max="30000" value="3000">
</label>
</div>
<div class="action-row">
<button id="startButton" type="submit">开始实时测试</button>
<button id="stopButton" class="stop-button" type="button" hidden>停止测试</button>
</div>
</form>
<div class="command-panel" aria-label="CLI 一键测试命令">
<div class="command-title">
<span>CLI 一键下载测试命令</span>
<button id="copyCommandButton" class="secondary-button" type="button">复制</button>
</div>
<code id="cliCommand" class="command-text"></code>
</div>
<p id="notice" class="notice"></p>
</section>
<section class="metrics" aria-label="实时指标">
<div class="metric">
<span>稳定评分</span>
<strong id="score">--</strong>
</div>
<div class="metric">
<span>下载速度</span>
<strong id="downloadSpeed">--</strong>
</div>
<div class="metric">
<span>上传速度</span>
<strong id="uploadSpeed">--</strong>
</div>
<div class="metric">
<span>平均延迟</span>
<strong id="latencyMetric">--</strong>
</div>
<div class="metric">
<span>辅助连接</span>
<strong id="connectionState">连接中</strong>
</div>
<div class="metric limit-metric">
<span>理论最高限值</span>
<strong id="bandwidthLimit">加载中</strong>
</div>
</section>
<section class="panel chart-panel">
<div class="section-title">
<h2>实时曲线</h2>
<span id="sampleCount">0 个样本</span>
</div>
<canvas id="liveChart" width="900" height="300"></canvas>
<div id="eventLog" class="event-log"></div>
</section>
<section class="panel chart-panel">
<div class="section-title">
<h2>历史时序图</h2>
<span>按测试开始时间排序</span>
</div>
<canvas id="historyChart" width="900" height="300"></canvas>
</section>
<section class="panel records-panel">
<div class="section-title">
<h2>所有测试记录</h2>
<button id="refreshButton" type="button">刷新</button>
</div>
<div class="table-wrap">
<table>
<thead>
<tr>
<th>时间</th>
<th>脱敏 IP</th>
<th>地区 / 运营商</th>
<th>目标</th>
<th>评分</th>
<th>下载</th>
<th>上传</th>
<th>延迟</th>
<th>样本</th>
</tr>
</thead>
<tbody id="recordsBody"></tbody>
</table>
</div>
</section>
</main>
<script src="/app.js"></script>
</body>
</html>