From 6f9161cd9335c721bb296d398f6a1e572a076fe6 Mon Sep 17 00:00:00 2001 From: mohe Date: Sat, 8 Aug 2026 01:30:19 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20dashboard=20=E5=BE=AE=E4=BF=A1=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E6=A3=80=E6=B5=8B=E8=AF=86=E5=88=AB=E7=AD=89=E5=BE=85?= =?UTF-8?q?=E6=89=AB=E7=A0=81/=E4=BC=9A=E8=AF=9D=E5=A4=B1=E6=95=88,=20?= =?UTF-8?q?=E4=B8=8D=E5=86=8D=E8=AF=AF=E6=8A=A5=E5=B7=B2=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gateway/scripts/dashboard.py | 71 +++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/gateway/scripts/dashboard.py b/gateway/scripts/dashboard.py index 3b9384b..efab076 100644 --- a/gateway/scripts/dashboard.py +++ b/gateway/scripts/dashboard.py @@ -565,6 +565,21 @@ PLATFORM_SERVICES = [ ] +def _docker_session_failed(): + """Check docker logs for recent loginCheck errors (WeChat session expired silently).""" + try: + dr = subprocess.run( + ["docker", "logs", "wxBotWebhook", "--since", "15m"], + capture_output=True, text=True, timeout=5 + ) + logs = dr.stdout + dr.stderr + err_lines = [l for l in logs.split("\n") if "loginCheck" in l and "Error" in l] + return len(err_lines) >= 3 + except Exception: + return False + return False + + def _docker_login_check(): """Check docker logs for recent WeChat login. Returns datetime or None.""" try: @@ -648,6 +663,28 @@ def _augment_wechat_status(entry): if last_logout: logout_dt = datetime.strptime(last_logout, "%Y-%m-%d %H:%M:%S") + # ═══ 新增: 检测"正在等待扫码"状态 ═══ + # 如果 docker 日志最近显示二维码, 说明未登录等待扫码, 优先判定 + try: + _dr = subprocess.run( + ["docker", "logs", "wxBotWebhook", "--since", "5m"], + capture_output=True, text=True, timeout=5 + ) + _dlogs = _dr.stdout + _dr.stderr + _showing_qr = ("扫描以下二维码" in _dlogs) or ("Access the URL to login" in _dlogs) + _login_err = _dlogs.count("loginCheck") >= 2 + except Exception: + _showing_qr = False + _login_err = False + if _showing_qr or _login_err: + entry["login_ok"] = False + entry["status"] = "logged_out" + entry["message"] = "等待扫码登录" if _showing_qr else "会话失效(loginCheck错误)" + entry["qr_url"] = entry.get("qr_url") or "" + _done_flag = True + else: + _done_flag = False + # Check docker logs for recent login (catches fresh logins before webhook sees them) # Check webhook log for login event login_dt = None @@ -657,8 +694,15 @@ def _augment_wechat_status(entry): except ValueError: pass dlogin_dt = _docker_login_check() + # Session-failed: loginCheck errors = WeChat session expired silently + if _docker_session_failed(): + entry["login_ok"] = False + entry["message"] = "会话失效(loginCheck错误)" + entry["status"] = "logged_out" # Logout is the most authoritative signal: if logout happened after the last login, session is dead - if logout_dt and login_dt and logout_dt > login_dt: + if _done_flag: + pass + elif logout_dt and login_dt and logout_dt > login_dt: entry["login_ok"] = False h = round((now - logout_dt).total_seconds() / 3600, 1) entry["message"] = "已掉线" if h < 1 else f"已掉线 {h:.0f}h" @@ -1770,6 +1814,27 @@ def api_wechat_status(): except Exception as e: result["message"] = f"QR page fetch failed: {e}" + # 3a. 优先检测: docker 日志是否正在显示登录二维码 (未登录等待扫码) + try: + _dr = subprocess.run( + ["docker", "logs", "wxBotWebhook", "--since", "5m"], + capture_output=True, text=True, timeout=5 + ) + _dlogs = _dr.stdout + _dr.stderr + _showing_qr = ("扫描以下二维码" in _dlogs) or ("Access the URL to login" in _dlogs) + _login_err = _dlogs.count("loginCheck") >= 2 + except Exception: + _showing_qr = False + _login_err = False + if _showing_qr: + result["online"] = False + result["message"] = "等待扫码登录" + return jsonify(result) + if _login_err: + result["online"] = False + result["message"] = "会话失效(loginCheck错误)" + return jsonify(result) + # 3. Check login status from webhook log (last WeChat send) webhook_log = str(_GATEWAY_DIR / "linux" / "logs" / "webhook.log") try: @@ -1821,6 +1886,10 @@ def api_wechat_status(): # Check docker logs for recent login dlogin_dt = _docker_login_check() + # Session-failed: loginCheck errors = WeChat session expired silently + if _docker_session_failed(): + result["online"] = False + result["message"] = "会话失效(loginCheck错误)" # Check webhook login event login_dt = None if result.get("last_login_at"):