From 0fe2a2fc5fc45f0f249582386b3796fb34e91245 Mon Sep 17 00:00:00 2001 From: butubb <1422726308@qq.com> Date: Fri, 7 Aug 2026 15:08:36 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E7=94=BB=E9=9D=A2=E6=88=AA=E5=9B=BE=E3=80=81=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=A4=8D=E9=80=89=E6=A1=86/=E6=8E=92=E5=BA=8F/=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E5=81=9C=E6=AD=A2=EF=BC=8C=E4=BF=AE=E5=A4=8D=E7=AB=AF?= =?UTF-8?q?=E5=8F=A3=E7=BB=91=E5=AE=9A=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.py | 4 +- core/adb_helper.py | 29 ++++ data/users.db | Bin 36864 -> 36864 bytes scripts/fix_web.bat | 2 +- start_web.bat | 4 +- templates/admin/monitor.html | 300 +++++++++++++++++++++++++++++++---- web_server.py | 71 ++++++--- 7 files changed, 355 insertions(+), 55 deletions(-) diff --git a/config.py b/config.py index 4d87155..513b5cd 100644 --- a/config.py +++ b/config.py @@ -27,7 +27,9 @@ else: # ================== Web 后台 ================== WEB_HOST = "0.0.0.0" -WEB_PORT = 5050 +# 端口必须避开 Windows 动态端口范围(本机被改成 1024-15000,默认 49152-65535) +# 用 18050 处于动态范围之外,不会被出站连接随机占用,避免 WinError 10013 +WEB_PORT = 18050 # ================== 数据目录 ================== # 持久化数据(分组、任务计划)存放目录 diff --git a/core/adb_helper.py b/core/adb_helper.py index 301e9b2..b177be7 100644 --- a/core/adb_helper.py +++ b/core/adb_helper.py @@ -124,6 +124,35 @@ def adb_disconnect(remote_adb_url): pass +def screenshot(serial, timeout=5): + """获取设备当前画面截图(PNG bytes)。 + + 用 `adb exec-out -s shell screencap -p`,只读操作, + 不抢占 u2 的 atx-agent 通道,任务运行中调用安全。 + 返回 (ok, png_bytes_or_errmsg)。 + """ + if not serial: + return False, "缺少 serial" + # 先尝试连一下(任务运行中设备已 connect,这里是幂等的) + if not adb_connect_light(serial): + return False, "adb connect 失败" + try: + r = subprocess.run( + [ADB_PATH, "-s", serial, "exec-out", "screencap", "-p"], + capture_output=True, timeout=timeout, + ) + # PNG 文件头:\x89PNG + if r.stdout and r.stdout[:4] == b"\x89PNG": + return True, r.stdout + # 失败时 stdout 可能为空,看 stderr + err = (r.stderr or b"").decode("utf-8", errors="replace").strip() + return False, err or "截图失败(设备可能离线)" + except subprocess.TimeoutExpired: + return False, "截图超时" + except Exception as e: + return False, str(e) + + def identify_device(serial, duration=3): """让设备响铃以供识别(直连 serial,不经过 STF)。 diff --git a/data/users.db b/data/users.db index 0aed34242e2f3544916704e7490af12d0a378dc1..05ea73c93f2e1b728d4876b680889d592e298481 100644 GIT binary patch delta 26 icmZozz|^pSX@WGP@I)DBM&XSK6XO|8H-C!fGXMZ_nh1da delta 28 kcmZozz|^pSX@WGP&_o$$Mxl)f6XPcv#PMwY8_#S20EOWRb^rhX diff --git a/scripts/fix_web.bat b/scripts/fix_web.bat index d38d28c..f658794 100644 --- a/scripts/fix_web.bat +++ b/scripts/fix_web.bat @@ -52,6 +52,6 @@ echo ============================================ echo Fix complete! Now: echo 1. Close ALL browser windows and reopen echo 2. Run: python web_server.py -echo 3. Open: http://127.0.0.1:5050/ +echo 3. Open: http://127.0.0.1:18050/ echo ============================================ pause diff --git a/start_web.bat b/start_web.bat index fe9ef1c..f321a01 100644 --- a/start_web.bat +++ b/start_web.bat @@ -23,8 +23,8 @@ if %errorlevel% neq 0 ( echo ============================================ echo 管理后台已启动(局域网可访问) -echo 本机访问: http://127.0.0.1:5050/ -echo 局域网访问: http://本机IP:5050/ +echo 本机访问: http://127.0.0.1:18050/ +echo 局域网访问: http://本机IP:18050/ echo 默认账号: admin / admin123 echo 按 Ctrl+C 停止 echo ============================================ diff --git a/templates/admin/monitor.html b/templates/admin/monitor.html index 1f07832..388511e 100644 --- a/templates/admin/monitor.html +++ b/templates/admin/monitor.html @@ -143,6 +143,27 @@ select.form-control{cursor:pointer} .toast.show{display:block} .toast-success{background:#dcfce7;color:#166534;border:1px solid #86efac} .toast-error{background:#fee2e2;color:#991b1b;border:1px solid #fca5a5} + +/* 截图弹窗 */ +.shot-modal{max-width:none;width:min(440px,95vw)} +.shot-modal .modal-body{text-align:center;padding:14px} +.shot-img{max-width:100%;max-height:calc(100vh - 240px);width:auto;height:auto;border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,.15);background:#1e293b;min-height:200px;display:block;margin:0 auto} +.shot-loading{color:var(--text-light);padding:60px 0;font-size:13px} +.shot-err{color:var(--danger);padding:40px 0;font-size:13px;white-space:pre-wrap;word-break:break-all} +.shot-info{font-size:12px;color:var(--text-muted);margin-top:10px} +.shot-toolbar{display:flex;gap:8px;justify-content:center;align-items:center;margin-top:12px;flex-wrap:wrap} +.shot-toolbar .auto-label{font-size:12px;color:var(--text-muted);display:flex;align-items:center;gap:4px} +.shot-toolbar .auto-label input{width:14px;height:14px} + +/* 表头排序 */ +.table thead th.sortable{cursor:pointer;user-select:none;white-space:nowrap} +.table thead th.sortable:hover{background:#e2e8f0} +.table thead th.sortable::after{content:" ⇅";color:#cbd5e1;font-weight:400;font-size:11px} +.table thead th.sortable.sort-asc::after{content:" ↑";color:var(--primary);font-weight:700} +.table thead th.sortable.sort-desc::after{content:" ↓";color:var(--primary);font-weight:700} +.table tbody tr.row-checked td{background:#eff6ff} +.table .col-cb{width:36px;text-align:center} +.table .col-cb input{width:14px;height:14px;cursor:pointer;vertical-align:middle} @@ -176,15 +197,25 @@ select.form-control{cursor:pointer}
设备列表
+ - · 每 5 秒自动刷新 · + · 每 5 秒自动刷新 · · 未选中
- - + + + + + + + + + + +
设备型号STF任务状态前台App进度当前任务当前动作最近错误操作设备型号STF任务状态前台App进度当前任务当前动作最近错误操作
@@ -289,7 +320,7 @@ select.form-control{cursor:pointer}