Files
live-hub-py/web/backend/routers/huya/devices.py
T
yml2213andCursor e81119117f feat(huya): 多选登录改单线程队列并拆分路由与工作台
默认同时只登一个号,失败两次跳下一个,号间留间隔,结束后可一键重试失败账号。
顺带拆分虎牙路由与斗鱼工作台页面,并补齐 raw_cookie 重建入口。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-10 11:31:50 +08:00

88 lines
3.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""虎牙设备绑定:画像与指纹状态解绑。"""
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}