fix(douyu): 修复未换绑成功时角色信息被待确认新角色污染 & 增加绑定接口明细日志

This commit is contained in:
yml2213
2026-08-02 13:18:56 +08:00
parent 4fab6ed0aa
commit de2e53748d
3 changed files with 180 additions and 27 deletions
+89 -18
View File
@@ -272,6 +272,7 @@ class DouyuBatchRunner:
f" need_role={1 if snap['need_bind_role'] else 0}"
f" wait={snap['change_role_wait_time'] if snap['change_role_wait_time'] is not None else '-'}"
f" can_change_time={snap['can_change_time'] if snap['can_change_time'] is not None else '-'}"
f" can={snap['can_change_role']}"
f"{pending_text}"
)
@@ -716,6 +717,10 @@ class DouyuBatchRunner:
self._push_log("warning", f"查询绑定信息失败 act={alias}: {exc}")
continue
info = {**info, "act_alias": alias}
self._push_log(
"info",
f"绑定信息 act={alias} {self._format_bind_summary(info)}",
)
results.append(info)
return results
@@ -882,7 +887,9 @@ class DouyuBatchRunner:
],
})
role_name = snapshot["role_name"]
self._apply_bind_info_to_account(account, bind_info, "game_queried")
# 待确认角色只回传前端展示,不写入账号表,避免“未换绑成功但角色信息已变新”
account.bind_status = "game_queried"
account.updated_at = datetime.now(timezone.utc)
self._push_log("success", f"识别到待确认角色: {role_name} (act={query_alias})")
self._update_task_progress(
db,
@@ -1127,6 +1134,15 @@ class DouyuBatchRunner:
before_snapshot = self._bind_snapshot(before)
role_name = before_snapshot["role_name"]
query_alias = str(before.get("act_alias") or "")
# 确认前“已生效绑定”角色(bound_act=1),确认失败/回查失败时写库用,避免待确认角色污染 game_name
before_bound = next(
(
info
for info in before_candidates
if self._is_bound_act(info) and str(info.get("role_name") or "").strip()
),
None,
)
self._push_log(
"info",
f"确认前状态 confirm_act={confirm_alias or '-'} hit={query_alias or '-'} "
@@ -1174,6 +1190,12 @@ class DouyuBatchRunner:
# 确认接口优先用配置的确认 alias;没有则回退到命中查询的 alias
use_confirm_alias = confirm_alias or query_alias
confirm_result = client.confirm_bind(use_confirm_alias)
confirm_raw = confirm_result.get("raw") or {}
self._push_log(
"info",
f"确认绑定接口返回 act={use_confirm_alias} "
f"error={confirm_raw.get('error')} msg={confirm_raw.get('msg') or '-'}",
)
try:
after_candidates = self._fetch_bind_info_candidates(client, query_aliases)
after = self._pick_bind_info(
@@ -1184,9 +1206,15 @@ class DouyuBatchRunner:
) if after_candidates else None
if after is None:
raise DouyuActivityError("确认后回查绑定信息失败")
self._push_log(
"info",
f"确认后回查 hit={after.get('act_alias') or '-'} "
f"{self._format_bind_summary(after)}",
)
except DouyuActivityError as exc:
# 确认接口已成功时,回查失败仍按确认成功处理,但保留错误信息。
self._apply_bind_info_to_account(account, before, "bind_confirmed")
# 写库优先确认前已生效绑定,避免待确认角色被误写入。
self._apply_bind_info_to_account(account, before_bound or before, "bind_confirmed")
self._mark_task(
db,
task,
@@ -1212,7 +1240,8 @@ class DouyuBatchRunner:
final_snapshot = after_snapshot if after_snapshot["role_name"] else before_snapshot
final_role_name = final_snapshot["role_name"] or role_name
if not after_snapshot["is_bound_act"]:
self._apply_bind_info_to_account(account, final_info, "game_queried")
# 确认未生效:保留确认前已生效绑定,不把待确认新角色写入账号表
self._apply_bind_info_to_account(account, before_bound or before, "game_queried")
self._mark_task(
db,
task,
@@ -1929,32 +1958,60 @@ class DouyuBatchRunner:
if not candidates:
self._mark_task(db, task, "failed", "查询绑定信息失败,请检查 Cookie 或 actAlias")
return
bind_info = self._pick_bind_info(
# 1) 优先“已生效绑定”角色(bound_act=1 且有角色名,通常是活动 alias)。
# 避免把扫码后未确认的新角色当成当前绑定结果。
bound_info = next(
(
info
for info in candidates
if self._is_bound_act(info) and str(info.get("role_name") or "").strip()
),
None,
)
# 2) 待确认角色(cjm 扫码后未确认;无已绑定时也用于首次绑定展示)
pending_info = self._pick_bind_info(
candidates,
prefer_pending=True,
prefer_aliases=query_aliases,
) or candidates[0]
snapshot = self._bind_snapshot(bind_info)
role_name = snapshot["role_name"]
source_alias = str(bind_info.get("act_alias") or "")
summary = f"act={source_alias or '-'} {self._format_bind_summary(bind_info)}"
pending_role = str(pending_info.get("role_name") or "").strip()
bound_role = str(bound_info.get("role_name") or "") if bound_info else ""
has_pending = bool(pending_role) and (pending_role != bound_role or not bound_info)
# 查询结果角色 = 已生效绑定;首次绑定(无绑定)时回退待确认角色
bind_info = bound_info if bound_info else (pending_info if has_pending else None)
snapshot = self._bind_snapshot(bind_info) if bind_info else {}
role_name = snapshot.get("role_name") or ""
is_bound = snapshot.get("is_bound_act", False)
source_alias = str((bind_info or {}).get("act_alias") or "")
summary = (
f"act={source_alias or '-'} {self._format_bind_summary(bind_info)}"
if bind_info
else "act=- role=-"
)
self._push_log(
"info",
"查询角色 "
f"aliases={','.join(query_aliases)} hit={source_alias or '-'} "
f"{self._format_bind_summary(bind_info)}",
f"aliases={','.join(query_aliases)} bound_hit={(bound_info or {}).get('act_alias') or '-'} "
f"pending_hit={pending_info.get('act_alias') or '-'} "
f"{self._format_bind_summary(bind_info) if bind_info else 'role=- bound_act=-'}",
)
self._apply_bind_info_to_account(account, bind_info, "game_queried" if role_name else "game_not_bound")
pending = bool(role_name) and not snapshot["is_bound_act"]
# 只有已生效绑定才写账号表;待确认角色不污染 game_name
if bind_info and is_bound:
self._apply_bind_info_to_account(account, bind_info, "game_queried")
else:
account.bind_status = "game_queried" if has_pending else "game_not_bound"
account.updated_at = datetime.now(timezone.utc)
result = {
"act_alias": source_alias,
"query_act_alias": source_alias,
"query_act_aliases": query_aliases,
**snapshot,
"bind_ready_for_confirm": pending,
"bind_confirmed": snapshot["is_bound_act"],
"bind_ready_for_confirm": has_pending,
"bind_confirmed": is_bound,
"bind_phase": (
"confirmed" if snapshot["is_bound_act"]
"confirmed" if is_bound
else ("role_ready" if role_name else "waiting_role")
),
"bind_summary": summary,
@@ -1967,10 +2024,18 @@ class DouyuBatchRunner:
for item in candidates
],
}
if not role_name:
# 已绑定角色之外另有待确认新角色时,单独字段展示,不覆盖 role_name
if has_pending and bound_info and pending_role != bound_role:
result["pending_role_name"] = pending_role
result["pending_area_name"] = str(pending_info.get("area_name") or "")
result["pending_plat_name"] = str(pending_info.get("plat_name") or "")
if not bind_info:
message = f"未获取到游戏名 | {summary}"
elif snapshot["is_bound_act"]:
message = f"当前已绑定: {role_name} | {summary}"
elif is_bound:
if has_pending and pending_role != bound_role:
message = f"当前已绑定: {bound_role},待确认: {pending_role} | {summary}"
else:
message = f"当前已绑定: {bound_role} | {summary}"
else:
message = f"待确认角色: {role_name} | {summary}"
self._mark_task(db, task, "success" if role_name else "failed", message, result)
@@ -2015,6 +2080,12 @@ class DouyuBatchRunner:
if not candidates:
self._mark_task(db, task, "failed", "查询绑定信息失败,请检查 Cookie 或 actAlias")
return
for item in candidates:
self._push_log(
"info",
f"查询换绑时间候选 act={item.get('act_alias') or '-'} "
f"{self._format_bind_summary(item)}",
)
# 换绑时间看“当前已绑定”活动态,不要优先 cjm(cjm 常无 changeRoleWaitTime
bind_info = self._pick_change_wait_bind_info(candidates, config) or candidates[0]
snapshot = self._bind_snapshot(bind_info)