"""虎牙设备绑定:画像与指纹状态解绑。""" from fastapi import APIRouter from ._common import * router = APIRouter() @router.get("/device-bindings") def list_device_bindings( db: Session = Depends(get_db), current: User = Depends(get_current_user) ): """列出所有账号 ↔ 设备环境绑定 (画像 + 指纹状态 + 账号表三方合并)。""" if not any(user_has_permission(current, p) for p in _DEVICE_BINDINGS_PERMS_VIEW): raise HTTPException(status_code=403, detail="无虎牙账号查看权限") profiles = _load_profile_db() accounts = {a.username: a for a in db.query(HuyaAccount).all() if a.username} rows = [] for account, prof in sorted(profiles.items()): acct = accounts.get(account) state_dir = _fp_state_dir(account) last_login = prof.get("last_login") or {} rows.append( { "account": account, "vendor": prof.get("vendor", ""), "model": prof.get("model", ""), "screen": prof.get("screen", ""), "fingerprint_masked": _mask_hex(prof.get("fingerprint")), "guid32_masked": _mask_hex(prof.get("guid32")), "hebe_count": len(prof.get("hebe") or {}), "hdid32": prof.get("hdid", ""), # t1.t0 app 级常量, 非敏感 "has_hydevice_state": state_dir.exists(), "login_channel": (acct.login_channel if acct else "") or "", "account_status": (acct.status if acct else "") or "未入库", "bound_at": prof.get("bound_at"), "last_login_at": last_login.get("at"), "last_login_ok": last_login.get("ok"), } ) return {"items": rows, "total": len(rows)} @router.delete("/device-bindings/{account}") def delete_device_binding( account: str, db: Session = Depends(get_db), current: User = Depends(get_current_user), ): """解绑: 删除该账号的设备画像与 hydevice 指纹状态, 下次登录自动生成全新环境。""" _require_huya_perm(current, "huya:import") profiles = _load_profile_db() if account not in profiles: raise HTTPException(status_code=404, detail="该账号没有设备绑定记录") profiles.pop(account) _save_profile_db(profiles) state_dir = _fp_state_dir(account) removed_state = False if state_dir.exists(): shutil.rmtree(state_dir, ignore_errors=True) removed_state = True return { "ok": True, "account": account, "profile_removed": True, "fp_state_removed": removed_state, "message": "已解绑, 下次 App 协议登录将自动生成全新设备环境并重新注册", } @router.post("/device-bindings/batch-delete") def delete_device_bindings( req: HuyaDeviceBindingsBatchDeleteRequest, db: Session = Depends(get_db), current: User = Depends(get_current_user), ): """批量解绑: 一次删除多个账号的设备画像与指纹状态。""" _require_huya_perm(current, "huya:import") removed, missing = _unbind_device_accounts(req.accounts) if not removed: raise HTTPException(status_code=404, detail="所选账号均没有设备绑定记录") message = f"已批量解绑 {len(removed)} 个账号" if missing: message += f",{len(missing)} 个账号无绑定记录已跳过" message += ",下次 App 协议登录将自动生成全新设备环境并重新注册" return {"ok": True, "removed": removed, "missing": missing, "message": message}