feat(douyu): support elite handbook lock orders
This commit is contained in:
@@ -2686,6 +2686,99 @@ class DouyuBatchRunner:
|
||||
points = result["points"]
|
||||
self._mark_task(db, task, "success", f"积分: {points if points is not None else '-'}", result)
|
||||
|
||||
def _execute_lock_goods(self, db: Session, task: DouyuTask, account: Account, cookie: str, config: dict):
|
||||
payload = self._task_payload(task)
|
||||
commodity_id = str(payload.get("commodity_id") or payload.get("commodityId") or "").strip()
|
||||
if not commodity_id:
|
||||
self._mark_task(db, task, "failed", "请选择锁定商品")
|
||||
return
|
||||
try:
|
||||
num = int(payload.get("num") or 1)
|
||||
except (TypeError, ValueError):
|
||||
num = 1
|
||||
client = self._client(cookie)
|
||||
result = client.create_exchange_order(
|
||||
manual_id=str(config["manual_id"]),
|
||||
rid=str(config["rid"]),
|
||||
commodity_id=commodity_id,
|
||||
num=max(1, num),
|
||||
)
|
||||
goods = (
|
||||
db.query(DouyuGoodsSnapshot)
|
||||
.filter(DouyuGoodsSnapshot.commodity_id == commodity_id)
|
||||
.first()
|
||||
)
|
||||
account.bind_status = "goods_locked"
|
||||
account.updated_at = datetime.now(timezone.utc)
|
||||
expire_seconds = result.get("expire_seconds")
|
||||
expire_text = f",{expire_seconds} 秒内有效" if expire_seconds else ""
|
||||
self._mark_task(
|
||||
db,
|
||||
task,
|
||||
"success",
|
||||
f"锁单成功: {(goods.name if goods else '') or commodity_id}(订单 {result['order_id']}{expire_text})",
|
||||
{
|
||||
"goods": goods.raw if goods else None,
|
||||
"game_name": account.game_name or "",
|
||||
"game_channel": account.game_channel or "",
|
||||
"account_name": account.nickname or account.username or account.uid or f"#{account.id}",
|
||||
**result,
|
||||
},
|
||||
)
|
||||
|
||||
def _execute_pay_locked_order(
|
||||
self,
|
||||
db: Session,
|
||||
task: DouyuTask,
|
||||
account: Account,
|
||||
cookie: str,
|
||||
config: dict,
|
||||
):
|
||||
payload = self._task_payload(task)
|
||||
order_id = str(payload.get("order_id") or payload.get("orderId") or "").strip()
|
||||
commodity_id = str(payload.get("commodity_id") or payload.get("commodityId") or "").strip()
|
||||
if not order_id:
|
||||
self._mark_task(db, task, "failed", "锁单订单号不能为空")
|
||||
return
|
||||
client = self._client(cookie)
|
||||
payment = client.pay_exchange_order(
|
||||
manual_id=str(config["manual_id"]),
|
||||
order_id=order_id,
|
||||
)
|
||||
goods = None
|
||||
if commodity_id:
|
||||
goods = (
|
||||
db.query(DouyuGoodsSnapshot)
|
||||
.filter(DouyuGoodsSnapshot.commodity_id == commodity_id)
|
||||
.first()
|
||||
)
|
||||
account.bind_status = "goods_exchanged"
|
||||
account.updated_at = datetime.now(timezone.utc)
|
||||
result = {
|
||||
"commodity_id": commodity_id,
|
||||
"order_id": order_id,
|
||||
"exchange_id": payment["exchange_id"],
|
||||
"commodity_image": payment["commodity_image"],
|
||||
"exchange_num": payment["exchange_num"],
|
||||
"payment": payment,
|
||||
"goods": goods.raw if goods else None,
|
||||
"game_name": account.game_name or "",
|
||||
"game_channel": account.game_channel or "",
|
||||
"account_name": account.nickname or account.username or account.uid or f"#{account.id}",
|
||||
}
|
||||
try:
|
||||
ctn = client.acf_ccn(refresh_subscribe=False)
|
||||
result.update(self._refresh_account_points(client, account, cookie, ctn=ctn))
|
||||
except Exception as exc:
|
||||
self._push_log("warning", f"支付锁单后刷新积分失败: {exc}")
|
||||
self._mark_task(
|
||||
db,
|
||||
task,
|
||||
"success",
|
||||
f"锁单支付成功: {(goods.name if goods else '') or commodity_id or order_id}",
|
||||
result,
|
||||
)
|
||||
|
||||
def _execute_exchange_goods(self, db: Session, task: DouyuTask, account: Account, cookie: str, config: dict):
|
||||
import time as time_mod
|
||||
payload = self._task_payload(task)
|
||||
@@ -2694,40 +2787,52 @@ class DouyuBatchRunner:
|
||||
self._mark_task(db, task, "failed", "请选择兑换商品")
|
||||
return
|
||||
client = self._client(cookie)
|
||||
ctn = client.acf_ccn(refresh_subscribe=False)
|
||||
result = None
|
||||
locked = client.create_exchange_order(
|
||||
manual_id=str(config["manual_id"]),
|
||||
rid=str(config["rid"]),
|
||||
commodity_id=commodity_id,
|
||||
num=1,
|
||||
)
|
||||
payment = None
|
||||
last_error = ""
|
||||
for attempt in range(8 + 1):
|
||||
if self._stop.is_set():
|
||||
self._mark_task(db, task, "stopped", "任务已停止")
|
||||
self._mark_task(db, task, "stopped", "任务已停止,商品锁单仍可能有效", locked)
|
||||
return
|
||||
try:
|
||||
result = client.exchange_goods(
|
||||
payment = client.pay_exchange_order(
|
||||
manual_id=str(config["manual_id"]),
|
||||
rid=str(config["rid"]),
|
||||
commodity_id=commodity_id,
|
||||
ctn=ctn,
|
||||
order_id=locked["order_id"],
|
||||
)
|
||||
break
|
||||
except DouyuActivityError as exc:
|
||||
last_error = str(exc)
|
||||
if attempt >= 8:
|
||||
self._mark_task(db, task, "failed", f"兑换失败(已重试{attempt}次): {last_error}")
|
||||
self._mark_task(
|
||||
db,
|
||||
task,
|
||||
"failed",
|
||||
f"锁单 {locked['order_id']} 支付失败(已重试{attempt}次): {last_error}",
|
||||
{"commodity_id": commodity_id, "lock_order": locked, **locked},
|
||||
)
|
||||
return
|
||||
error_lower = last_error.lower()
|
||||
if any(kw in error_lower for kw in ("无效", "太快", "csrf")):
|
||||
self._push_log("info", f" 重试 {attempt + 1}/8: {last_error},刷新 csrf_token...")
|
||||
try:
|
||||
token = client.csrf_token()
|
||||
self._push_log("debug", f" csrf_token 已刷新: {token[:12]}...")
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
self._push_log("info", f" 重试 {attempt + 1}/8: {last_error}")
|
||||
self._push_log(
|
||||
"info",
|
||||
f" 锁单 {locked['order_id']} 支付重试 {attempt + 1}/8: {last_error}",
|
||||
)
|
||||
time_mod.sleep(0.3)
|
||||
if result is None:
|
||||
if payment is None:
|
||||
self._mark_task(db, task, "failed", f"兑换失败: {last_error}")
|
||||
return
|
||||
result = {
|
||||
"commodity_id": commodity_id,
|
||||
"order_id": locked["order_id"],
|
||||
"exchange_id": payment["exchange_id"],
|
||||
"commodity_image": payment["commodity_image"] or locked["commodity_image"],
|
||||
"exchange_num": payment["exchange_num"],
|
||||
"lock_order": locked,
|
||||
"payment": payment,
|
||||
}
|
||||
goods = (
|
||||
db.query(DouyuGoodsSnapshot)
|
||||
.filter(DouyuGoodsSnapshot.commodity_id == commodity_id)
|
||||
@@ -2738,6 +2843,7 @@ class DouyuBatchRunner:
|
||||
# 兑换成功后自动刷新积分,更新账号最新积分信息(失败不阻断兑换成功)
|
||||
points_refresh = None
|
||||
try:
|
||||
ctn = client.acf_ccn(refresh_subscribe=False)
|
||||
points_refresh = self._refresh_account_points(client, account, cookie, ctn=ctn)
|
||||
except Exception as exc:
|
||||
self._push_log("warning", f"兑换后刷新积分失败: {exc}")
|
||||
@@ -3077,6 +3183,8 @@ class DouyuBatchRunner:
|
||||
"create_gold_qr": self._execute_create_gold_qr,
|
||||
"donate_elite_gift": self._execute_donate_elite_gift,
|
||||
"query_points": self._execute_query_points,
|
||||
"lock_goods": self._execute_lock_goods,
|
||||
"pay_locked_order": self._execute_pay_locked_order,
|
||||
"exchange_goods": self._execute_exchange_goods,
|
||||
"exchange_esports_goods": self._execute_exchange_esports_goods,
|
||||
"query_game_name": self._execute_query_game_name,
|
||||
|
||||
Reference in New Issue
Block a user