fix: STF未就绪设备纳入维护终端列表(adb可达但agent启动失败,标记stf_not_ready)+ 卸载/检查agent自动先connect

This commit is contained in:
2026-08-17 11:02:43 +08:00
parent e48eeef49b
commit c111cb9a5e
3 changed files with 26 additions and 8 deletions
+13 -4
View File
@@ -29,7 +29,7 @@ async function loadToolsDevices(force){
return; return;
} }
wrap.innerHTML = _clipDevices.map(d=>{ wrap.innerHTML = _clipDevices.map(d=>{
const st = d.state==='stf' ? 'STF池' : (d.state==='device' ? '已连接' : d.state); const st = d.state==='stf' ? 'STF池' : (d.state==='device' ? '已连接' : (d.state==='stf_not_ready' ? 'STF未就绪' : d.state));
const stCls = (d.state==='device'||d.state==='stf') ? 'label-success' : 'label-warning'; const stCls = (d.state==='device'||d.state==='stf') ? 'label-success' : 'label-warning';
return '<label data-serial="'+esc(d.serial)+'">' return '<label data-serial="'+esc(d.serial)+'">'
+'<input type="checkbox" value="'+esc(d.serial)+'"'+( _clipSelected.has(d.serial)?' checked':'')+' onchange="toggleClipDevice(this)">' +'<input type="checkbox" value="'+esc(d.serial)+'"'+( _clipSelected.has(d.serial)?' checked':'')+' onchange="toggleClipDevice(this)">'
@@ -222,7 +222,7 @@ async function loadAdbDevices(force){
const list=await _fetchAdbDevices(force); const list=await _fetchAdbDevices(force);
if(list===null)return; if(list===null)return;
const cur=sel.value; const cur=sel.value;
const stateTxt={device:'在线',offline:'离线',stf:'STF池(未连接)'}; const stateTxt={device:'在线',offline:'离线',stf:'STF池(未连接)',stf_not_ready:'STF未就绪'};
const opts=['<option value="">(不指定设备)</option>'].concat( const opts=['<option value="">(不指定设备)</option>'].concat(
list.map(d=> list.map(d=>
'<option value="'+esc(d.serial)+'">'+esc(d.serial)+' ('+(stateTxt[d.state]||d.state)+')</option>' '<option value="'+esc(d.serial)+'">'+esc(d.serial)+' ('+(stateTxt[d.state]||d.state)+')</option>'
@@ -251,11 +251,20 @@ async function runAdbCmd(){
cmd=_attachDevice(cmd); cmd=_attachDevice(cmd);
await _runAdbFull('adb '+cmd); await _runAdbFull('adb '+cmd);
} }
// 修复类命令:目标为 IP:port 时先 adb connect(已连接自动跳过),
// 否则设备不在本机 adb server 里会报 "device not found"(STF 未就绪的设备尤其如此)。
async function _runAdbRepair(full){
const serial=_selectedSerial();
if(serial && serial.indexOf(':')>=0){
await _runAdbFull('adb connect '+serial);
}
await _runAdbFull(full);
}
function uninstallStfAgent(){ function uninstallStfAgent(){
const serial=_selectedSerial(); const serial=_selectedSerial();
if(!serial){showToast('请先选择目标设备','error');return;} if(!serial){showToast('请先选择目标设备','error');return;}
if(!confirm('确定卸载 '+serial+' 上的 STF agent(jp.co.cyberagent.stf)?\n\n卸载后 STF 会在设备重连时自动重新推送安装。'))return; if(!confirm('确定卸载 '+serial+' 上的 STF agent(jp.co.cyberagent.stf)?\n\n卸载后 STF 会在设备重连时自动重新推送安装。'))return;
_runAdbFull('adb -s '+serial+' uninstall jp.co.cyberagent.stf'); _runAdbRepair('adb -s '+serial+' uninstall jp.co.cyberagent.stf');
} }
function reconnectAdbDevice(){ function reconnectAdbDevice(){
const serial=_selectedSerial(); const serial=_selectedSerial();
@@ -265,7 +274,7 @@ function reconnectAdbDevice(){
function checkStfAgent(){ function checkStfAgent(){
const serial=_selectedSerial(); const serial=_selectedSerial();
if(!serial){showToast('请先选择目标设备','error');return;} if(!serial){showToast('请先选择目标设备','error');return;}
_runAdbFull('adb -s '+serial+' shell pm list packages | grep cyberagent'); _runAdbRepair('adb -s '+serial+' shell pm list packages | grep cyberagent');
} }
async function restartStf(){ async function restartStf(){
if(!confirm('确定重启 STF 容器?\n\n影响:STF 约 30 秒不可用,期间所有设备占用状态重置,正在执行的任务会受影响。\n\n确认继续吗?'))return; if(!confirm('确定重启 STF 容器?\n\n影响:STF 约 30 秒不可用,期间所有设备占用状态重置,正在执行的任务会受影响。\n\n确认继续吗?'))return;
+2 -2
View File
@@ -546,9 +546,9 @@ select.form-control{cursor:pointer}
<button class="btn btn-xs" onclick="fillAdbCmd('tcpip 5555')" title="USB 设备开启网络调试(重启设备后失效,需重新执行)">tcpip 5555 转网络调试</button> <button class="btn btn-xs" onclick="fillAdbCmd('tcpip 5555')" title="USB 设备开启网络调试(重启设备后失效,需重新执行)">tcpip 5555 转网络调试</button>
</div> </div>
<div style="display:flex;gap:6px;margin-bottom:8px;flex-wrap:wrap"> <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 btn-danger" onclick="uninstallStfAgent()" title="自动先 adb connect 再卸载 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="reconnectAdbDevice()" title="重新 adb connect 该设备">重连设备</button>
<button class="btn btn-xs" onclick="checkStfAgent()" title="查看 jp.co.cyberagent.stf 是否已安装">检查 agent</button> <button class="btn btn-xs" onclick="checkStfAgent()" title="自动先 adb connect 再查看 jp.co.cyberagent.stf 是否已安装">检查 agent</button>
</div> </div>
<pre id="adb-output" class="adb-console">(执行命令后输出显示在这里)</pre> <pre id="adb-output" class="adb-console">(执行命令后输出显示在这里)</pre>
</div> </div>
+11 -2
View File
@@ -1065,6 +1065,9 @@ def _merged_device_list():
"""本地 adb(含 USB)+ STF 在线设备池的合并列表([{serial, state}])。 """本地 adb(含 USB)+ STF 在线设备池的合并列表([{serial, state}])。
供维护终端/剪贴板注入/应用版本管理等设备选择场景共用。 供维护终端/剪贴板注入/应用版本管理等设备选择场景共用。
STF 里 adb 可达但 agent 未就绪的设备(手机端 agent 启动失败)也列入,
标记 stf_not_ready——这种设备恰恰需要用维护终端卸载/重装 agent 修复,
不列出来就永远无法修复(死循环)。
""" """
states = {} states = {}
out = _adb("devices") out = _adb("devices")
@@ -1075,8 +1078,13 @@ def _merged_device_list():
try: try:
for d in stf.list_all_devices(): for d in stf.list_all_devices():
serial = d.get("serial", "") serial = d.get("serial", "")
if serial and d.get("present") and d.get("ready") and serial not in states: if not serial or serial in states:
continue
if d.get("present") and d.get("ready"):
states[serial] = "stf" states[serial] = "stf"
elif d.get("present") and not d.get("ready"):
# adb 可达但 STF agent 未就绪(启动失败/未安装):列入供修复
states[serial] = "stf_not_ready"
except Exception: except Exception:
pass pass
return [{"serial": s, "state": st} for s, st in sorted(states.items())] return [{"serial": s, "state": st} for s, st in sorted(states.items())]
@@ -1085,7 +1093,8 @@ def _merged_device_list():
@app.route("/api/adb/devices") @app.route("/api/adb/devices")
@admin_required @admin_required
def api_adb_devices(): def api_adb_devices():
"""维护终端设备列表(仅管理员):本地 adb 已连接 + STF 在线设备池。 """维护终端设备列表(仅管理员):本地 adb 已连接 + STF 在线设备池
(含 agent 未就绪的待修复设备,state=stf_not_ready)。
供终端设备选择器使用——选中后自动附加 `-s <serial>`, 供终端设备选择器使用——选中后自动附加 `-s <serial>`,
离线/未连接的设备也可选,配合"重连设备"按钮恢复。 离线/未连接的设备也可选,配合"重连设备"按钮恢复。