Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 26 additions & 10 deletions mobile/damai_app/orchestrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,29 @@ def _set_run_outcome(self, outcome):
"""Record the terminal outcome for the latest run attempt."""
self._last_run_outcome = outcome

def _report_pending_order_dialog(self):
"""检测到「未支付订单弹窗」时的统一上报(真话优先,U-10 同源)。

probe_only 从不提交任何订单,此弹窗必然是账号里预先存在的占单(非本次
安全探测产生)。旧实现无论何种模式都记 ``order_pending_payment`` →
「抢票成功:检测到未支付订单」,会误导安全探测用户以为 probe 下了单
(2026-07-11 真机实测)。据实分流,返回 True 语义不变:
- probe_only:``preexisting_pending_order`` —— 只做探测提醒,不称成功;
- 正式/开发模式:``order_pending_payment`` —— 本轮流程占单,沿用原语义。
"""
if self.config.probe_only:
self._set_run_outcome("preexisting_pending_order")
logger.info(
"探测提醒:账号存在未支付订单(非本次安全探测产生),"
"如需可自行前往订单页处理;本次探测未做任何提交"
)
else:
self._set_run_outcome("order_pending_payment")
logger.info(
"检测到未支付订单弹窗(已占单待支付),请立即前往订单页完成支付"
)
return True

def _execution_mode_key(self):
"""Return the current execution mode key."""
if self.config.probe_only:
Expand Down Expand Up @@ -232,6 +255,7 @@ def _log_success_outcome(self, retry_prefix=""):
"validation_ready": "开发验证成功:已到订单确认页,未提交订单",
"order_submitted": "抢票成功:已提交订单",
"order_pending_payment": "抢票成功:检测到未支付订单,请立即前往支付完成下单",
"preexisting_pending_order": "探测提醒:账号存在未支付订单(非本次探测产生),本次未做任何提交",
"order_flow_completed": "抢票流程完成:已执行提交,等待后续结果确认",
}
logger.info(
Expand Down Expand Up @@ -760,11 +784,7 @@ def run_ticket_grabbing(self, initial_page_probe=None):
return False

if page_probe["state"] == "pending_order_dialog":
self._set_run_outcome("order_pending_payment")
logger.info(
"检测到未支付订单弹窗(已占单待支付),请立即前往订单页完成支付"
)
return True
return self._report_pending_order_dialog()

if page_probe["state"] not in {
"detail_page",
Expand All @@ -779,11 +799,7 @@ def run_ticket_grabbing(self, initial_page_probe=None):
return False
page_probe = self.probe_current_page()
if page_probe["state"] == "pending_order_dialog":
self._set_run_outcome("order_pending_payment")
logger.info(
"检测到未支付订单弹窗(已占单待支付),请立即前往订单页完成支付"
)
return True
return self._report_pending_order_dialog()
else:
logger.warning("当前不在演出详情页,请先手动打开目标演出详情页")
return False
Expand Down
6 changes: 1 addition & 5 deletions mobile/damai_app/recovery_strategies.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,11 +351,7 @@ def _fast_retry_from_current_state(self):
result = self._submit_order_fast(submit_selectors)
return self._finalize_submit_result(result)
elif state == "pending_order_dialog":
self._set_run_outcome("order_pending_payment")
logger.info(
"检测到未支付订单弹窗(已占单待支付),请立即前往订单页完成支付"
)
return True
return self._report_pending_order_dialog()
else:
if self.config.auto_navigate:
return (
Expand Down
39 changes: 39 additions & 0 deletions tests/unit/test_mobile_damai_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -1588,6 +1588,45 @@ def test_run_ticket_grabbing_returns_success_when_pending_order_dialog_detected_
assert result is True
assert bot._last_run_outcome == "order_pending_payment"

def test_run_ticket_grabbing_probe_mode_pending_order_is_not_grab_success(self, bot):
# 2026-07-11 真机回归:probe_only 从不提交,遇到预先存在的未支付订单弹窗
# 必须据实上报(preexisting_pending_order),绝不能记「抢票成功」——否则
# 安全探测用户会误以为 probe 下了单(信任问题,U-10 同源)。
bot.config.probe_only = True
bot.config.if_commit_order = False
with patch.object(bot, "dismiss_startup_popups"):
with patch.object(bot, "check_session_valid", return_value=True):
with patch.object(
bot,
"probe_current_page",
return_value={
"state": "pending_order_dialog",
"purchase_button": False,
"price_container": False,
"quantity_picker": False,
"submit_button": False,
"reservation_mode": False,
"pending_order_dialog": True,
},
):
result = bot.run_ticket_grabbing()

assert result is True
assert bot._last_run_outcome == "preexisting_pending_order"

def test_log_success_outcome_preexisting_pending_order_not_grab_success(
self, bot, caplog
):
# 成功日志映射也不得对该 outcome 说「抢票成功」
import logging as _logging

bot._set_run_outcome("preexisting_pending_order")
with caplog.at_level(_logging.INFO):
bot._log_success_outcome("快速重试成功:")
joined = " ".join(r.message for r in caplog.records)
assert "抢票成功" not in joined
assert "未支付订单" in joined

def test_run_ticket_grabbing_rush_mode_skips_detail_prepare_and_reprobe_when_no_sell_time(
self, bot
):
Expand Down
Loading