fix(douyu): 确认绑定回查按已生效绑定判定并支持同步延迟等待 & 失败提示优化为待绑定账号换绑限制文案 & 前端居中弹窗提示

This commit is contained in:
yml2213
2026-08-02 13:37:15 +08:00
parent de2e53748d
commit 1b06694c66
2 changed files with 142 additions and 38 deletions
+82 -37
View File
@@ -33,6 +33,8 @@ DOUYU_PAYMENT_POLL_SECONDS = 600
DOUYU_PAYMENT_POLL_INTERVAL = 5
DOUYU_GIFT_POINTS_REFRESH_TIMES = 3
DOUYU_GIFT_POINTS_REFRESH_INTERVAL = 2
DOUYU_CONFIRM_EFFECT_POLL_TIMES = 3
DOUYU_CONFIRM_EFFECT_POLL_INTERVAL = 3
class DouyuBatchRunner:
@@ -1189,30 +1191,98 @@ class DouyuBatchRunner:
# 确认接口优先用配置的确认 alias;没有则回退到命中查询的 alias
use_confirm_alias = confirm_alias or query_alias
confirm_result = client.confirm_bind(use_confirm_alias)
try:
confirm_result = client.confirm_bind(use_confirm_alias)
except DouyuActivityError as exc:
confirm_msg = str(exc)
self._push_log("warning", f"确认绑定接口失败: {confirm_msg}")
# 待绑定游戏账号侧换绑限制(未到换绑时间等)导致确认失败:保留原绑定并给出明确提示
self._apply_bind_info_to_account(account, before_bound or before, "game_queried")
self._mark_task(
db,
task,
"failed",
f"待绑定游戏账号({role_name or '-'})未到换绑时间(不是斗鱼/虎牙账号),请重新换账号扫码绑定",
{
"act_alias": use_confirm_alias,
"query_act_alias": query_alias,
"query_act_aliases": query_aliases,
"before_bind_info": before,
**before_snapshot,
"confirm_error": confirm_msg,
"bind_ready_for_confirm": True,
"bind_confirmed": False,
"bind_phase": "confirm_failed",
},
)
return
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 '-'}",
)
def _pick_bound_after(candidates: list[dict]) -> dict | None:
"""确认后回查:只认已生效绑定(bound_act=1)。
cjm 的角色名恒有且 bound_act 恒为 0,若按 alias 顺序挑选会永远
判定“确认未生效”,必须按 bound_act=1 判定确认结果。
"""
return next(
(
info
for info in candidates
if self._is_bound_act(info) and str(info.get("role_name") or "").strip()
),
None,
)
try:
after_candidates = self._fetch_bind_info_candidates(client, query_aliases)
after = self._pick_bind_info(
after_candidates,
baseline_role_name="",
baseline_is_bound_act=False,
prefer_pending=False,
) if after_candidates else None
if after is None:
if not after_candidates:
raise DouyuActivityError("确认后回查绑定信息失败")
after = _pick_bound_after(after_candidates)
# 已生效绑定存在同步延迟:确认接口已成功但未生效时短轮询等待
if after is None:
for _ in range(DOUYU_CONFIRM_EFFECT_POLL_TIMES):
if self._stop.wait(DOUYU_CONFIRM_EFFECT_POLL_INTERVAL):
break
after_candidates = self._fetch_bind_info_candidates(client, query_aliases)
if not after_candidates:
break
after = _pick_bound_after(after_candidates)
if after is not None:
break
if after is None:
# 已生效绑定始终未出现:确认未生效(或同步延迟超时),保留原绑定
self._apply_bind_info_to_account(account, before_bound or before, "game_queried")
self._mark_task(
db,
task,
"failed",
f"待绑定游戏账号({role_name or '-'})未到换绑时间(不是斗鱼/虎牙账号),请重新换账号扫码绑定",
{
"act_alias": use_confirm_alias,
"query_act_alias": query_alias,
"query_act_aliases": query_aliases,
"before_bind_info": before,
"confirm": confirm_result,
"after_bind_info": None,
**before_snapshot,
"bind_ready_for_confirm": True,
"bind_confirmed": False,
"bind_phase": "confirm_failed",
"confirm_wait_error": "确认后短轮询未等到已生效绑定",
},
)
return
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_bound or before, "bind_confirmed")
self._mark_task(
@@ -1236,33 +1306,8 @@ class DouyuBatchRunner:
return
after_snapshot = self._bind_snapshot(after)
final_info = after if after_snapshot["role_name"] else before
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, before_bound or before, "game_queried")
self._mark_task(
db,
task,
"failed",
f"确认绑定未生效: {final_role_name}",
{
"act_alias": use_confirm_alias,
"query_act_alias": after.get("act_alias") or query_alias,
"query_act_aliases": query_aliases,
"before_bind_info": before,
"confirm": confirm_result,
**final_snapshot,
"bind_ready_for_confirm": True,
"bind_confirmed": False,
"bind_phase": "confirm_failed",
"after_bind_info": after,
},
)
return
self._apply_bind_info_to_account(account, final_info, "bind_confirmed")
final_role_name = after_snapshot["role_name"] or role_name
self._apply_bind_info_to_account(account, after, "bind_confirmed")
self._mark_task(
db,
task,
@@ -1275,7 +1320,7 @@ class DouyuBatchRunner:
"before_bind_info": before,
"confirm": confirm_result,
"after_bind_info": after,
**final_snapshot,
**after_snapshot,
"bind_ready_for_confirm": True,
"bind_confirmed": True,
"bind_phase": "confirmed",