fix: dashboard 微信状态检测识别等待扫码/会话失效, 不再误报已登录

This commit is contained in:
2026-08-08 01:30:19 +08:00
parent 8feed0092b
commit 6f9161cd93
+70 -1
View File
@@ -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(): def _docker_login_check():
"""Check docker logs for recent WeChat login. Returns datetime or None.""" """Check docker logs for recent WeChat login. Returns datetime or None."""
try: try:
@@ -648,6 +663,28 @@ def _augment_wechat_status(entry):
if last_logout: if last_logout:
logout_dt = datetime.strptime(last_logout, "%Y-%m-%d %H:%M:%S") 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 docker logs for recent login (catches fresh logins before webhook sees them)
# Check webhook log for login event # Check webhook log for login event
login_dt = None login_dt = None
@@ -657,8 +694,15 @@ def _augment_wechat_status(entry):
except ValueError: except ValueError:
pass pass
dlogin_dt = _docker_login_check() 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 # 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 entry["login_ok"] = False
h = round((now - logout_dt).total_seconds() / 3600, 1) h = round((now - logout_dt).total_seconds() / 3600, 1)
entry["message"] = "已掉线" if h < 1 else f"已掉线 {h:.0f}h" entry["message"] = "已掉线" if h < 1 else f"已掉线 {h:.0f}h"
@@ -1770,6 +1814,27 @@ def api_wechat_status():
except Exception as e: except Exception as e:
result["message"] = f"QR page fetch failed: {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) # 3. Check login status from webhook log (last WeChat send)
webhook_log = str(_GATEWAY_DIR / "linux" / "logs" / "webhook.log") webhook_log = str(_GATEWAY_DIR / "linux" / "logs" / "webhook.log")
try: try:
@@ -1821,6 +1886,10 @@ def api_wechat_status():
# Check docker logs for recent login # Check docker logs for recent login
dlogin_dt = _docker_login_check() 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 # Check webhook login event
login_dt = None login_dt = None
if result.get("last_login_at"): if result.get("last_login_at"):