refactor: adb远程终端与Tailscale管理从维护页移至工具Tab(维护仅保留STF服务),设备列表共享缓存+复用esc

This commit is contained in:
2026-08-11 10:00:15 +08:00
parent 2f1003bf1f
commit 159649b6a0
2 changed files with 88 additions and 87 deletions
+61 -69
View File
@@ -501,75 +501,15 @@ select.form-control{cursor:pointer}
<!-- ========== Tab 7: 维护(仅管理员) ========== -->
<div id="tab-maintenance" class="tab-panel">
<div class="page-title">维护</div>
<div class="page-sub">管理员专用:STF 服务、adb 远程终端与 Tailscale 设备管理</div>
<div class="sub-tabs">
<button class="sub-tab active" data-sub="stf" onclick="showSubTab('maintenance','stf')">STF 服务</button>
<button class="sub-tab" data-sub="adb" onclick="showSubTab('maintenance','adb')">adb 远程终端</button>
<button class="sub-tab" data-sub="ts" onclick="showSubTab('maintenance','ts')">Tailscale 管理</button>
<div class="page-sub">管理员专用:STF 服务管理(adb 远程终端与 Tailscale 管理已移至"工具")</div>
<div class="toolbar">
<button class="btn btn-danger" onclick="restartStf()">一键重启 STF 容器</button>
<span id="stf-restart-status" class="text-muted"></span>
</div>
<!-- 子分栏 1:STF 服务 -->
<div class="sub-panel active" id="maintenance-sub-stf">
<div class="toolbar">
<button class="btn btn-danger" onclick="restartStf()">一键重启 STF 容器</button>
<span id="stf-restart-status" class="text-muted"></span>
</div>
<div class="help" style="margin-top:8px">
通过 SSH 到部署机执行 <code>docker restart</code>(目标与容器名可用环境变量
<code>STF_SSH_TARGET</code> / <code>STF_DOCKER_CONTAINER</code> 配置)。
影响:STF 约 30 秒不可用,期间设备占用状态重置;<b>有任务在运行时会被拒绝执行</b>。
</div>
</div>
<!-- 子分栏 2:adb 远程终端 -->
<div class="sub-panel" id="maintenance-sub-adb">
<div class="help">选中目标设备后,命令里的 <code>-s &lt;设备&gt;</code> 自动附加,直接写
<code>shell ls /sdcard</code> 即可。离线设备也可选,用"重连设备"恢复。
<b>禁止 kill-server / disconnect</b>(会中断 STF provider 的设备监控)。</div>
<div style="display:flex;gap:8px;margin:8px 0;align-items:center">
<label style="font-size:12px;color:var(--text-light)">目标设备</label>
<select id="adb-device" class="form-control" style="flex:1;max-width:340px;font-family:monospace"></select>
<button class="btn btn-xs" onclick="loadAdbDevices()" title="刷新设备列表">刷新</button>
</div>
<div style="display:flex;gap:8px;margin:8px 0">
<input type="text" id="adb-cmd-input" class="form-control" style="flex:1;font-family:monospace"
placeholder="shell ls /sdcard(选中设备后 -s 自动附加)"
onkeydown="if(event.key==='Enter')runAdbCmd()">
<button class="btn btn-primary" onclick="runAdbCmd()">执行</button>
</div>
<div style="display:flex;gap:6px;margin-bottom:8px;flex-wrap:wrap">
<button class="btn btn-xs" onclick="fillAdbCmd('adb devices')">adb devices</button>
<button class="btn btn-xs" onclick="fillAdbCmd('shell dumpsys window | grep mCurrentFocus')">前台App</button>
<button class="btn btn-xs" onclick="fillAdbCmd('shell ls /sdcard')">列文件</button>
<button class="btn btn-xs" onclick="fillAdbCmd('shell screencap -p /sdcard/shot.png')">截屏</button>
<button class="btn btn-xs" onclick="fillAdbCmd('shell pm list packages -3')">已装应用</button>
</div>
<div style="display:flex;gap:6px;margin-bottom:8px;flex-wrap:wrap">
<button class="btn btn-xs btn-danger" onclick="uninstallStfAgent()" title="卸载 jp.co.cyberagent.stf,STF 会在设备重连时重新推送">卸载 STF agent(卡死时用)</button>
<button class="btn btn-xs" onclick="reconnectAdbDevice()" title="重新 adb connect 该设备">重连设备</button>
<button class="btn btn-xs" onclick="checkStfAgent()" title="查看 jp.co.cyberagent.stf 是否已安装">检查 agent</button>
</div>
<pre id="adb-output" class="adb-console">(执行命令后输出显示在这里)</pre>
</div>
<!-- 子分栏 3:Tailscale 管理 -->
<div class="sub-panel" id="maintenance-sub-ts">
<div class="help" id="ts-hint"></div>
<div class="toolbar" style="margin:8px 0">
<button class="btn btn-primary" onclick="loadTailscaleDevices()">刷新设备</button>
<button class="btn" onclick="openTailscaleAuthKey()">生成接入 Auth Key</button>
<input class="form-control list-search" id="search-tailscale" placeholder="搜索主机名/名称/IP...">
<span id="ts-status" class="text-muted" style="margin-left:10px"></span>
</div>
<table class="table">
<thead><tr>
<th>主机名</th><th>显示名</th><th>IP</th><th>系统</th><th>在线</th><th>授权</th><th>密钥过期</th><th>操作</th>
</tr></thead>
<tbody id="tb-tailscale"><tr><td colspan="8" class="empty">点击"刷新设备"加载</td></tr></tbody>
</table>
<div class="list-pager" id="pager-tailscale"></div>
<div class="help">"设置IP"可修改设备 IPv4(会断开当前连接,平台 serial 随之变化,需同步 STF 设备池);"密钥不过期"= 关闭设备密钥验证,设备不会被定期踢下线;auth key 生成后只显示一次,请立即复制。</div>
<div class="help" style="margin-top:8px">
通过 SSH 到部署机执行 <code>docker restart</code>(目标与容器名可用环境变量
<code>STF_SSH_TARGET</code> / <code>STF_DOCKER_CONTAINER</code> 配置)。
影响:STF 约 30 秒不可用,期间设备占用状态重置;<b>有任务在运行时会被拒绝执行</b>。
</div>
</div>
@@ -580,12 +520,14 @@ select.form-control{cursor:pointer}
<div class="sub-tabs">
<button class="sub-tab active" data-sub="clipboard" onclick="showSubTab('tools','clipboard')">剪贴板注入</button>
<button class="sub-tab" data-sub="adb" onclick="showSubTab('tools','adb')">adb 远程终端</button>
<button class="sub-tab" data-sub="ts" onclick="showSubTab('tools','ts')">Tailscale 管理</button>
</div>
<!-- 子分栏 1:剪贴板注入 -->
<div class="sub-panel active" id="tools-sub-clipboard">
<div class="toolbar">
<button class="btn" onclick="loadToolsDevices()">刷新设备</button>
<button class="btn" onclick="loadToolsDevices(true)">刷新设备</button>
<span id="clip-status" class="text-muted"></span>
</div>
<div style="display:flex;gap:20px;flex-wrap:wrap">
@@ -618,6 +560,56 @@ select.form-control{cursor:pointer}
</table>
</div>
</div>
<!-- 子分栏 2:adb 远程终端 -->
<div class="sub-panel" id="tools-sub-adb">
<div class="help">选中目标设备后,命令里的 <code>-s &lt;设备&gt;</code> 自动附加,直接写
<code>shell ls /sdcard</code> 即可。离线设备也可选,用"重连设备"恢复。
<b>禁止 kill-server / disconnect</b>(会中断 STF provider 的设备监控)。</div>
<div style="display:flex;gap:8px;margin:8px 0;align-items:center">
<label style="font-size:12px;color:var(--text-light)">目标设备</label>
<select id="adb-device" class="form-control" style="flex:1;max-width:340px;font-family:monospace"></select>
<button class="btn btn-xs" onclick="loadAdbDevices(true)" title="刷新设备列表">刷新</button>
</div>
<div style="display:flex;gap:8px;margin:8px 0">
<input type="text" id="adb-cmd-input" class="form-control" style="flex:1;font-family:monospace"
placeholder="shell ls /sdcard(选中设备后 -s 自动附加)"
onkeydown="if(event.key==='Enter')runAdbCmd()">
<button class="btn btn-primary" onclick="runAdbCmd()">执行</button>
</div>
<div style="display:flex;gap:6px;margin-bottom:8px;flex-wrap:wrap">
<button class="btn btn-xs" onclick="fillAdbCmd('adb devices')">adb devices</button>
<button class="btn btn-xs" onclick="fillAdbCmd('shell dumpsys window | grep mCurrentFocus')">前台App</button>
<button class="btn btn-xs" onclick="fillAdbCmd('shell ls /sdcard')">列文件</button>
<button class="btn btn-xs" onclick="fillAdbCmd('shell screencap -p /sdcard/shot.png')">截屏</button>
<button class="btn btn-xs" onclick="fillAdbCmd('shell pm list packages -3')">已装应用</button>
</div>
<div style="display:flex;gap:6px;margin-bottom:8px;flex-wrap:wrap">
<button class="btn btn-xs btn-danger" onclick="uninstallStfAgent()" title="卸载 jp.co.cyberagent.stf,STF 会在设备重连时重新推送">卸载 STF agent(卡死时用)</button>
<button class="btn btn-xs" onclick="reconnectAdbDevice()" title="重新 adb connect 该设备">重连设备</button>
<button class="btn btn-xs" onclick="checkStfAgent()" title="查看 jp.co.cyberagent.stf 是否已安装">检查 agent</button>
</div>
<pre id="adb-output" class="adb-console">(执行命令后输出显示在这里)</pre>
</div>
<!-- 子分栏 3:Tailscale 管理 -->
<div class="sub-panel" id="tools-sub-ts">
<div class="help" id="ts-hint"></div>
<div class="toolbar" style="margin:8px 0">
<button class="btn btn-primary" onclick="loadTailscaleDevices()">刷新设备</button>
<button class="btn" onclick="openTailscaleAuthKey()">生成接入 Auth Key</button>
<input class="form-control list-search" id="search-tailscale" placeholder="搜索主机名/名称/IP...">
<span id="ts-status" class="text-muted" style="margin-left:10px"></span>
</div>
<table class="table">
<thead><tr>
<th>主机名</th><th>显示名</th><th>IP</th><th>系统</th><th>在线</th><th>授权</th><th>密钥过期</th><th>操作</th>
</tr></thead>
<tbody id="tb-tailscale"><tr><td colspan="8" class="empty">点击"刷新设备"加载</td></tr></tbody>
</table>
<div class="list-pager" id="pager-tailscale"></div>
<div class="help">"设置IP"可修改设备 IPv4(会断开当前连接,平台 serial 随之变化,需同步 STF 设备池);"密钥不过期"= 关闭设备密钥验证,设备不会被定期踢下线;auth key 生成后只显示一次,请立即复制。</div>
</div>
</div>
</div><!-- /.content -->