fix: dashboard 微信状态检测识别等待扫码/会话失效, 不再误报已登录
This commit is contained in:
@@ -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"):
|
||||
|
||||
Reference in New Issue
Block a user