feat: 设备池管理面板(新增/停用/删除/一键重连,调度数据源规范化入口)+ STF 设备管理增删桥接同步设备池(迁移期)
This commit is contained in:
+118
-6
@@ -1333,29 +1333,45 @@ def api_stf_devmgmt_status():
|
||||
@app.route("/api/stf/devmgmt/add", methods=["POST"])
|
||||
@admin_required
|
||||
def api_stf_devmgmt_add():
|
||||
"""STF 设备管理:添加设备(写入脚本 + 立即 connect)。"""
|
||||
"""STF 设备管理:添加设备(写入脚本 + 立即 connect)。
|
||||
|
||||
迁移期桥接:同步加入本地设备池(SQLite),保证新设备可被调度。
|
||||
阶段 3 摘除 STF 后此接口随设备池管理面板退役。
|
||||
"""
|
||||
ip = (request.json or {}).get("ip", "").strip()
|
||||
if not ip:
|
||||
return jsonify({"ok": False, "error": "请输入设备 IP"}), 400
|
||||
try:
|
||||
msgs = stf_device_mgmt.add_device(ip)
|
||||
return jsonify({"ok": True, "msgs": msgs})
|
||||
except StfDevError as e:
|
||||
return jsonify({"ok": False, "error": str(e)}), 502
|
||||
# 桥接:同步本地设备池(serial 统一 IP:5555)
|
||||
try:
|
||||
device_pool.add_device(f"{ip}:5555" if ":" not in ip else ip)
|
||||
except Exception as e:
|
||||
_log.warning(f"STF 添加设备桥接设备池失败: {e}")
|
||||
return jsonify({"ok": True, "msgs": msgs})
|
||||
|
||||
|
||||
@app.route("/api/stf/devmgmt/remove", methods=["POST"])
|
||||
@admin_required
|
||||
def api_stf_devmgmt_remove():
|
||||
"""STF 设备管理:移除设备(脚本删除 + disconnect)。"""
|
||||
"""STF 设备管理:移除设备(脚本删除 + disconnect)。
|
||||
|
||||
迁移期桥接:同步从本地设备池删除。阶段 3 此接口退役。
|
||||
"""
|
||||
ip = (request.json or {}).get("ip", "").strip()
|
||||
if not ip:
|
||||
return jsonify({"ok": False, "error": "请输入设备 IP"}), 400
|
||||
try:
|
||||
msgs = stf_device_mgmt.remove_device(ip)
|
||||
return jsonify({"ok": True, "msgs": msgs})
|
||||
except StfDevError as e:
|
||||
return jsonify({"ok": False, "error": str(e)}), 502
|
||||
try:
|
||||
device_pool.remove_device(f"{ip}:5555" if ":" not in ip else ip)
|
||||
except Exception:
|
||||
pass
|
||||
return jsonify({"ok": True, "msgs": msgs})
|
||||
|
||||
|
||||
def _app_ver_on_device(serial, pkg):
|
||||
@@ -1419,15 +1435,22 @@ def api_tools_appver():
|
||||
@app.route("/api/stf/devmgmt/delete", methods=["POST"])
|
||||
@admin_required
|
||||
def api_stf_devmgmt_delete():
|
||||
"""STF 设备管理:彻底删除(脚本移除 + disconnect + 清 STF 池记录)。"""
|
||||
"""STF 设备管理:彻底删除(脚本移除 + disconnect + 清 STF 池记录)。
|
||||
|
||||
迁移期桥接:同步从本地设备池删除。阶段 3 此接口退役。
|
||||
"""
|
||||
ip = (request.json or {}).get("ip", "").strip()
|
||||
if not ip:
|
||||
return jsonify({"ok": False, "error": "请输入设备 IP"}), 400
|
||||
try:
|
||||
msgs = stf_device_mgmt.delete_device(ip, stf=stf)
|
||||
return jsonify({"ok": True, "msgs": msgs})
|
||||
except StfDevError as e:
|
||||
return jsonify({"ok": False, "error": str(e)}), 502
|
||||
try:
|
||||
device_pool.remove_device(f"{ip}:5555" if ":" not in ip else ip)
|
||||
except Exception:
|
||||
pass
|
||||
return jsonify({"ok": True, "msgs": msgs})
|
||||
|
||||
|
||||
@app.route("/api/stf/devmgmt/reconnect", methods=["POST"])
|
||||
@@ -1441,6 +1464,95 @@ def api_stf_devmgmt_reconnect():
|
||||
return jsonify({"ok": False, "error": str(e)}), 502
|
||||
|
||||
|
||||
# ================== API:设备池管理(本地 SQLite 清单,新增设备的规范化入口) ==================
|
||||
@app.route("/api/devices/pool", methods=["GET"])
|
||||
@perm_required(PERM_DEVICES)
|
||||
def api_devices_pool_list():
|
||||
"""设备池清单(SQLite,含实时在线状态)。"""
|
||||
try:
|
||||
online = set(device_pool.list_online())
|
||||
except Exception:
|
||||
online = set()
|
||||
rows = device_pool.list_devices()
|
||||
for r in rows:
|
||||
r["online"] = r["serial"] in online
|
||||
return jsonify({"ok": True, "devices": rows})
|
||||
|
||||
|
||||
@app.route("/api/devices/pool/add", methods=["POST"])
|
||||
@perm_required(PERM_DEVICES)
|
||||
def api_devices_pool_add():
|
||||
"""添加/更新设备:{serial, name?, note?}。
|
||||
|
||||
IP:5555 设备添加后立即尝试 adb connect(不可达显示离线,不影响其他设备)。
|
||||
"""
|
||||
data = request.json or {}
|
||||
serial = (data.get("serial") or "").strip()
|
||||
if not serial:
|
||||
return jsonify({"ok": False, "error": "请输入设备 serial(如 100.100.10.20:5555)"}), 400
|
||||
is_new = device_pool.add_device(serial,
|
||||
name=(data.get("name") or "").strip(),
|
||||
note=(data.get("note") or "").strip())
|
||||
msg = "已添加" if is_new else "已更新"
|
||||
if ":" in serial:
|
||||
try:
|
||||
adb_connect(serial)
|
||||
except Exception:
|
||||
pass
|
||||
_log.info(f"设备池管理: {msg} {serial}")
|
||||
return jsonify({"ok": True, "msg": msg, "is_new": is_new})
|
||||
|
||||
|
||||
@app.route("/api/devices/pool/remove", methods=["POST"])
|
||||
@perm_required(PERM_DEVICES)
|
||||
def api_devices_pool_remove():
|
||||
"""从设备池删除(不再参与调度;不影响其他系统)。"""
|
||||
serial = (request.json or {}).get("serial", "").strip()
|
||||
if not serial:
|
||||
return jsonify({"ok": False, "error": "缺少 serial"}), 400
|
||||
ok = device_pool.remove_device(serial)
|
||||
if not ok:
|
||||
return jsonify({"ok": False, "error": "设备不存在"}), 404
|
||||
return jsonify({"ok": True, "msg": "已删除"})
|
||||
|
||||
|
||||
@app.route("/api/devices/pool/toggle", methods=["POST"])
|
||||
@perm_required(PERM_DEVICES)
|
||||
def api_devices_pool_toggle():
|
||||
"""启用/停用设备(停用后不参与调度)。"""
|
||||
data = request.json or {}
|
||||
serial = (data.get("serial") or "").strip()
|
||||
enabled = data.get("enabled")
|
||||
if not serial or enabled is None:
|
||||
return jsonify({"ok": False, "error": "缺少参数"}), 400
|
||||
ok = device_pool.set_enabled(serial, bool(enabled))
|
||||
if not ok:
|
||||
return jsonify({"ok": False, "error": "设备不存在"}), 404
|
||||
return jsonify({"ok": True, "msg": "已" + ("启用" if enabled else "停用")})
|
||||
|
||||
|
||||
@app.route("/api/devices/pool/reconnect", methods=["POST"])
|
||||
@perm_required(PERM_DEVICES)
|
||||
def api_devices_pool_reconnect():
|
||||
"""一键重连:并发 adb connect 池内全部 IP:5555 设备(后台执行,不阻塞)。"""
|
||||
def _run():
|
||||
try:
|
||||
serials = [s for s in device_pool.list_configured() if ":" in s]
|
||||
except Exception:
|
||||
return
|
||||
if not serials:
|
||||
return
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
with ThreadPoolExecutor(max_workers=10) as pool:
|
||||
futures = {pool.submit(adb_connect, s): s for s in serials}
|
||||
for _ in as_completed(futures):
|
||||
pass
|
||||
_log.info(f"设备池一键重连完成({len(serials)} 台)")
|
||||
import threading
|
||||
threading.Thread(target=_run, daemon=True).start()
|
||||
return jsonify({"ok": True, "msg": "重连已启动(后台并发,约 10-20 秒)"})
|
||||
|
||||
|
||||
@app.route("/api/stf/restart", methods=["POST"])
|
||||
@admin_required
|
||||
def api_stf_restart():
|
||||
|
||||
Reference in New Issue
Block a user