fix(web): 设备绑定页『最后登录』修复 — 登录时间记录下沉到 App 登录本体

- device_profile.record_login(): 登录成功/失败均写 last_login (bound_at 首次绑定)
- HuyaAppPasswordLogin.login() 包装 _login_impl, GUI 批量/行内/CLI 全覆盖
  (此前只有 account_env CLI 路径写元数据, GUI 登录该列全为 '-')
- 修复 _enrich_profile 原地修改导致回写判断失效 (存量 hebe/guid32 被旧代码
  整体回写冲掉后无法自动补齐) — 改为返回新字典
- 存量 6 账号画像已全部补齐 hebe/guid32
This commit is contained in:
yml2213
2026-08-29 16:59:16 +08:00
parent 4f099cc196
commit 239ef91c56
2 changed files with 41 additions and 13 deletions
+30 -12
View File
@@ -78,6 +78,23 @@ def generate_profile(model_pick=None) -> dict:
}
def record_login(account: str, ok: bool, message: str = "") -> None:
"""记录该账号环境的一次登录结果 (最后登录时间/成败)。
幂等元数据: bound_at 只在首次出现时写入; 失败也记录 (设备绑定页要展示)。
供 app_login 登录流程调用, GUI 设备绑定页读取展示。
"""
import time as _time
db = _load_db()
rec = db.get(account)
if rec is None:
return # 尚无环境的账号 (纯 Cookie 导入) 不生成记录
now = int(_time.time())
rec.setdefault("bound_at", now)
rec["last_login"] = {"ok": bool(ok), "msg": str(message or "")[:120], "at": now}
_save_db(db)
def _load_db() -> dict:
if PRIMARY_PROFILE_DB.exists():
try:
@@ -100,34 +117,35 @@ def _save_db(db: dict) -> None:
pass
def _enrich_profile(profile: dict) -> dict:
"""补齐 dfp 一致性字段 (幂等): guid32 / Hebe_D1-D5。
def _enrich_profile(profile: dict) -> tuple[dict, bool]:
"""补齐 dfp 一致性字段 (幂等): guid32 / Hebe_D1-D5, 返回 (新画像, 是否有变更)
来源: R36 解密的真实 dfp 指纹 JSON 结构 (deviceinfo.guid + deviceinfo.Hebe_D1-D5)。
一号一设备: 每账号独立生成后终身不变, 供后续真实载荷构建与 GUI 设备绑定页展示。
注意: 返回新字典 (不原地改), 调用方据此判断是否需要回写。
"""
out = dict(profile)
changed = False
if not profile.get("guid32"):
profile["guid32"] = hashlib.sha256(os.urandom(16) + b"guid").hexdigest()
if not out.get("guid32"):
out["guid32"] = hashlib.sha256(os.urandom(16) + b"guid").hexdigest()
changed = True
hebe = profile.get("hebe") or {}
if len(hebe) < 5:
profile["hebe"] = {f"Hebe_D{i}": hashlib.sha256(os.urandom(16) + f"hebe{i}".encode()).hexdigest()
for i in range(1, 6)}
if len(out.get("hebe") or {}) < 5:
out["hebe"] = {f"Hebe_D{i}": hashlib.sha256(os.urandom(16) + f"hebe{i}".encode()).hexdigest()
for i in range(1, 6)}
changed = True
return profile if changed else profile
return out, changed
def get_profile(account: str, force_new: bool = False) -> dict:
"""按账号获取或创建画像(幂等:同账号复用同一套, 自动补齐缺失一致性字段)。"""
db = _load_db()
if not force_new and account in db:
enriched = _enrich_profile(db[account])
if enriched is not db[account]:
enriched, changed = _enrich_profile(db[account])
if changed:
db[account] = enriched
_save_db(db)
return enriched
p = _enrich_profile(generate_profile())
p, _ = _enrich_profile(generate_profile())
db[account] = p
_save_db(db)
return p