增加兑换
This commit is contained in:
@@ -15,7 +15,7 @@ from sqlalchemy.orm import Session, joinedload
|
||||
from core.douyu import DouyuActivityClient, DouyuActivityError
|
||||
|
||||
from ..database import SessionLocal
|
||||
from ..models import Account, DouyuGoodsSnapshot, DouyuTask
|
||||
from ..models import Account, DouyuEsportsGoodsSnapshot, DouyuGoodsSnapshot, DouyuTask
|
||||
from .douyu_service import (
|
||||
DOUYU_CONFIG_FIELDS,
|
||||
account_uid,
|
||||
@@ -382,6 +382,27 @@ class DouyuBatchRunner:
|
||||
row.updated_at = now
|
||||
db.commit()
|
||||
|
||||
def _upsert_esports_goods(self, db: Session, goods: list[dict]) -> None:
|
||||
now = datetime.now(timezone.utc)
|
||||
for raw in goods:
|
||||
commodity_id = str(raw.get("commodityId") or raw.get("commodity_id") or "")
|
||||
if not commodity_id:
|
||||
continue
|
||||
row = (
|
||||
db.query(DouyuEsportsGoodsSnapshot)
|
||||
.filter(DouyuEsportsGoodsSnapshot.commodity_id == commodity_id)
|
||||
.first()
|
||||
)
|
||||
if row is None:
|
||||
row = DouyuEsportsGoodsSnapshot(commodity_id=commodity_id)
|
||||
db.add(row)
|
||||
row.name = str(raw.get("commodityName") or raw.get("name") or "")
|
||||
row.score = self._to_int(raw.get("score"))
|
||||
row.status = str(raw.get("status") or "")
|
||||
row.raw = raw
|
||||
row.updated_at = now
|
||||
db.commit()
|
||||
|
||||
def _config_info(self, db: Session) -> dict:
|
||||
config = ensure_douyu_config(db)
|
||||
return {field: douyu_config_value(field, getattr(config, field, None)) for field in DOUYU_CONFIG_FIELDS}
|
||||
@@ -921,6 +942,32 @@ class DouyuBatchRunner:
|
||||
account.updated_at = datetime.now(timezone.utc)
|
||||
self._mark_task(db, task, "success", f"已刷新商品 {len(goods)} 个", {"goods_count": len(goods), "goods": goods})
|
||||
|
||||
def _execute_refresh_esports_goods(
|
||||
self,
|
||||
db: Session,
|
||||
task: DouyuTask,
|
||||
account: Account,
|
||||
cookie: str,
|
||||
config: dict,
|
||||
):
|
||||
"""刷新电竞手册皮肤商城快照。"""
|
||||
client = self._client(cookie)
|
||||
result = client.list_esports_goods(
|
||||
manual_id=str(config["esports_manual_id"]),
|
||||
rid=str(config["room_id"]),
|
||||
)
|
||||
goods = result["goods"]
|
||||
self._upsert_esports_goods(db, goods)
|
||||
account.esports_bind_status = "esports_goods_refreshed"
|
||||
account.updated_at = datetime.now(timezone.utc)
|
||||
self._mark_task(
|
||||
db,
|
||||
task,
|
||||
"success",
|
||||
f"已刷新电竞皮肤 {len(goods)} 个",
|
||||
{"goods_count": len(goods), "esports_store_score": result["score"], "goods": goods},
|
||||
)
|
||||
|
||||
def _execute_get_bind_qr(self, db: Session, task: DouyuTask, account: Account, cookie: str, config: dict):
|
||||
client = self._client(cookie)
|
||||
qr_act_alias = self._bind_qr_act_alias(config)
|
||||
@@ -1492,6 +1539,147 @@ class DouyuBatchRunner:
|
||||
result,
|
||||
)
|
||||
|
||||
def _execute_query_esports_points(
|
||||
self,
|
||||
db: Session,
|
||||
task: DouyuTask,
|
||||
account: Account,
|
||||
cookie: str,
|
||||
config: dict,
|
||||
):
|
||||
"""查询电竞手册积分。"""
|
||||
manual_id = str(config.get("esports_manual_id") or "").strip()
|
||||
if not manual_id:
|
||||
self._mark_task(db, task, "failed", "请先配置电竞手册 manualID")
|
||||
return
|
||||
client = self._client(cookie)
|
||||
result = self._refresh_esports_handbook(client, account, manual_id=manual_id)
|
||||
account.esports_bind_status = "esports_points_queried"
|
||||
account.updated_at = datetime.now(timezone.utc)
|
||||
points = result["esports_points"]
|
||||
self._mark_task(db, task, "success", f"电竞积分: {points if points is not None else '-'}", result)
|
||||
|
||||
def _execute_donate_esports_gift(
|
||||
self,
|
||||
db: Session,
|
||||
task: DouyuTask,
|
||||
account: Account,
|
||||
cookie: str,
|
||||
config: dict,
|
||||
*,
|
||||
gift_name: str,
|
||||
config_gift_id_key: str,
|
||||
config_skin_id_key: str,
|
||||
):
|
||||
"""赠送电竞手册任务礼物并刷新独立积分。"""
|
||||
payload = self._task_payload(task)
|
||||
try:
|
||||
gift_count = max(1, int(payload.get("gift_count") or payload.get("count") or 1))
|
||||
except (TypeError, ValueError):
|
||||
self._mark_task(db, task, "failed", "赠送数量必须是正整数")
|
||||
return
|
||||
|
||||
manual_id = str(config.get("esports_manual_id") or "").strip()
|
||||
gift_id = str(payload.get("gift_id") or config.get(config_gift_id_key) or "").strip()
|
||||
skin_id = str(payload.get("skin_id") or config.get(config_skin_id_key) or "").strip()
|
||||
room_id = str(payload.get("room_id") or config.get("room_id") or "").strip()
|
||||
if not manual_id or not gift_id or not skin_id or not room_id:
|
||||
self._mark_task(db, task, "failed", "请先完整配置电竞手册、房间和礼物参数")
|
||||
return
|
||||
|
||||
client = self._client(cookie)
|
||||
baseline_points = account.esports_points
|
||||
try:
|
||||
baseline = self._refresh_esports_handbook(client, account, manual_id=manual_id)
|
||||
baseline_points = baseline["esports_points"]
|
||||
db.commit()
|
||||
except Exception as exc:
|
||||
self._push_log("warning", f"赠送{gift_name}前刷新电竞积分失败: {exc}")
|
||||
|
||||
result = client.donate_esports_gift(
|
||||
gift_name=gift_name,
|
||||
gift_count=gift_count,
|
||||
room_id=room_id,
|
||||
gift_id=gift_id,
|
||||
skin_id=skin_id,
|
||||
)
|
||||
result.update(
|
||||
{
|
||||
"gift_name": gift_name,
|
||||
"gift_id": gift_id,
|
||||
"skin_id": skin_id,
|
||||
"gift_count": gift_count,
|
||||
"esports_points_baseline": baseline_points,
|
||||
}
|
||||
)
|
||||
refresh_errors = []
|
||||
try:
|
||||
result.update(self._refresh_account_gold_balance(client, account))
|
||||
except Exception as exc:
|
||||
refresh_errors.append(f"鱼翅余额: {exc}")
|
||||
try:
|
||||
points_result = self._refresh_esports_handbook(client, account, manual_id=manual_id)
|
||||
result.update(points_result)
|
||||
result["esports_points_after_gift"] = points_result["esports_points"]
|
||||
result["esports_points_changed"] = (
|
||||
baseline_points is not None
|
||||
and points_result["esports_points"] is not None
|
||||
and points_result["esports_points"] != baseline_points
|
||||
)
|
||||
except Exception as exc:
|
||||
refresh_errors.append(f"电竞积分: {exc}")
|
||||
if refresh_errors:
|
||||
result["refresh_errors"] = refresh_errors
|
||||
|
||||
account.esports_bind_status = "esports_gift_donated"
|
||||
account.updated_at = datetime.now(timezone.utc)
|
||||
message = f"赠送{gift_name}成功: {gift_count}"
|
||||
if account.gold_balance is not None:
|
||||
message += f",鱼翅余额: {account.gold_balance}"
|
||||
if account.esports_points is not None:
|
||||
message += f",电竞积分: {account.esports_points}"
|
||||
self._mark_task(db, task, "success", message, result)
|
||||
|
||||
def _execute_donate_esports_chicken_gift(
|
||||
self,
|
||||
db: Session,
|
||||
task: DouyuTask,
|
||||
account: Account,
|
||||
cookie: str,
|
||||
config: dict,
|
||||
):
|
||||
"""赠送冠军鸡腿。"""
|
||||
self._execute_donate_esports_gift(
|
||||
db,
|
||||
task,
|
||||
account,
|
||||
cookie,
|
||||
config,
|
||||
gift_name="冠军鸡腿",
|
||||
config_gift_id_key="esports_chicken_gift_id",
|
||||
config_skin_id_key="esports_chicken_skin_id",
|
||||
)
|
||||
|
||||
def _execute_donate_esports_firework_gift(
|
||||
self,
|
||||
db: Session,
|
||||
task: DouyuTask,
|
||||
account: Account,
|
||||
cookie: str,
|
||||
config: dict,
|
||||
):
|
||||
"""赠送冠军烟花。"""
|
||||
self._execute_donate_esports_gift(
|
||||
db,
|
||||
task,
|
||||
account,
|
||||
cookie,
|
||||
config,
|
||||
gift_name="冠军烟花",
|
||||
config_gift_id_key="esports_firework_gift_id",
|
||||
config_skin_id_key="esports_firework_skin_id",
|
||||
)
|
||||
|
||||
def _execute_create_gold_qr(self, db: Session, task: DouyuTask, account: Account, cookie: str, config: dict):
|
||||
payload = self._task_payload(task)
|
||||
amount = int(payload.get("amount") or payload.get("gold_amount") or 1)
|
||||
@@ -1650,6 +1838,71 @@ class DouyuBatchRunner:
|
||||
{"goods": goods.raw if goods else None, **result},
|
||||
)
|
||||
|
||||
def _execute_exchange_esports_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:
|
||||
quantity = max(1, int(payload.get("quantity") or payload.get("num") or 1))
|
||||
except (TypeError, ValueError):
|
||||
self._mark_task(db, task, "failed", "兑换数量必须是正整数")
|
||||
return
|
||||
|
||||
manual_id = str(config.get("esports_manual_id") or "").strip()
|
||||
room_id = str(config.get("room_id") or "").strip()
|
||||
if not manual_id or not room_id:
|
||||
self._mark_task(db, task, "failed", "请先配置电竞手册 manualID 和房间 ID")
|
||||
return
|
||||
|
||||
client = self._client(cookie)
|
||||
baseline_points = account.esports_points
|
||||
try:
|
||||
baseline = self._refresh_esports_handbook(client, account, manual_id=manual_id)
|
||||
baseline_points = baseline["esports_points"]
|
||||
db.commit()
|
||||
except Exception as exc:
|
||||
self._push_log("warning", f"兑换电竞皮肤前刷新积分失败: {exc}")
|
||||
|
||||
result = client.exchange_esports_goods(
|
||||
manual_id=manual_id,
|
||||
rid=room_id,
|
||||
commodity_id=commodity_id,
|
||||
quantity=quantity,
|
||||
)
|
||||
goods = (
|
||||
db.query(DouyuEsportsGoodsSnapshot)
|
||||
.filter(DouyuEsportsGoodsSnapshot.commodity_id == commodity_id)
|
||||
.first()
|
||||
)
|
||||
result["goods"] = goods.raw if goods else None
|
||||
result["esports_points_baseline"] = baseline_points
|
||||
try:
|
||||
points_result = self._refresh_esports_handbook(client, account, manual_id=manual_id)
|
||||
result.update(points_result)
|
||||
result["esports_points_after_exchange"] = points_result["esports_points"]
|
||||
except Exception as exc:
|
||||
result["esports_points_refresh_error"] = str(exc)
|
||||
|
||||
account.esports_bind_status = "esports_goods_exchanged"
|
||||
account.updated_at = datetime.now(timezone.utc)
|
||||
name = (goods.name if goods else "") or commodity_id
|
||||
message = f"兑换电竞皮肤成功: {name}"
|
||||
if quantity > 1:
|
||||
message += f" x{quantity}"
|
||||
if account.esports_points is not None:
|
||||
message += f",电竞积分: {account.esports_points}"
|
||||
self._mark_task(db, task, "success", message, result)
|
||||
|
||||
def _execute_query_game_name(self, db: Session, task: DouyuTask, account: Account, cookie: str, config: dict):
|
||||
client = self._client(cookie)
|
||||
query_aliases = self._query_bind_act_aliases(config)
|
||||
@@ -1870,6 +2123,7 @@ class DouyuBatchRunner:
|
||||
|
||||
handler = {
|
||||
"refresh_goods": self._execute_refresh_goods,
|
||||
"refresh_esports_goods": self._execute_refresh_esports_goods,
|
||||
"get_bind_qr": self._execute_get_bind_qr,
|
||||
"confirm_bind": self._execute_confirm_bind,
|
||||
"create_elite_qr": self._execute_create_elite_qr,
|
||||
@@ -1878,10 +2132,14 @@ class DouyuBatchRunner:
|
||||
"query_esports_game_name": self._execute_query_esports_game_name,
|
||||
"confirm_esports_bind": self._execute_confirm_esports_bind,
|
||||
"create_esports_qr": self._execute_create_esports_qr,
|
||||
"query_esports_points": self._execute_query_esports_points,
|
||||
"donate_esports_chicken_gift": self._execute_donate_esports_chicken_gift,
|
||||
"donate_esports_firework_gift": self._execute_donate_esports_firework_gift,
|
||||
"create_gold_qr": self._execute_create_gold_qr,
|
||||
"donate_elite_gift": self._execute_donate_elite_gift,
|
||||
"query_points": self._execute_query_points,
|
||||
"exchange_goods": self._execute_exchange_goods,
|
||||
"exchange_esports_goods": self._execute_exchange_esports_goods,
|
||||
"query_game_name": self._execute_query_game_name,
|
||||
"query_change_bind_time": self._execute_query_change_bind_time,
|
||||
"query_limited_goods": self._execute_query_limited_goods,
|
||||
|
||||
Reference in New Issue
Block a user