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():
|
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"):
|
||||||
|
|||||||
Reference in New Issue
Block a user