新增斗鱼活动任务模块:绑定、宝典、鱼翅、积分、兑换等功能
- 新增 activity_client.py:封装斗鱼活动/兑换/充值/送礼接口 - 新增 cookie_utils.py:Cookie 解析与规范化工具 - 新增 douyu_service/douyu_runner:斗鱼任务服务层与批量执行器 - 新增 douyu 路由:任务类型查询、账号列表、配置管理、商品管理、批量任务、WebSocket 日志 - 新增 models/schemas:DouyuTask/DouyuConfig/DouyuGoodsSnapshot 模型,Account 扩展点数/鱼翅/绑定状态等字段 - 新增数据库迁移:斗鱼活动相关表与 accounts 字段补充 - 新增前端 DouyuTasksPage 任务操作台页面 - 兑换商品请求添加 sec-ch-ua 反检测头 - 兑换商品支持最多 8 次重试 + csrf_token 自动刷新 - 注册 douyu:task / douyu:config 权限点 - 侧边栏新增斗鱼分组与任务操作台菜单入口
This commit is contained in:
@@ -514,6 +514,134 @@ class HuyaRechargeGoodsOut(BaseModel):
|
||||
}
|
||||
|
||||
|
||||
# ---- 斗鱼活动任务 ----
|
||||
class DouyuConfigOut(BaseModel):
|
||||
manual_id: str = "G4KA4Qnz4LDp7"
|
||||
rid: str = "9263298"
|
||||
bind_act_alias: str = "20250213NQCYX"
|
||||
confirm_act_alias: str = "20260120QYOOB"
|
||||
legacy_act_alias: str = "cjm"
|
||||
room_id: str = "9263298"
|
||||
elite_amount: int = 3000
|
||||
gold_pay_type: int = 1
|
||||
gift_id: str = "23643"
|
||||
skin_id: str = "2942"
|
||||
updated_at: Optional[datetime] = None
|
||||
|
||||
@model_serializer
|
||||
def _serialize(self) -> dict[str, Any]:
|
||||
return {
|
||||
"manual_id": self.manual_id,
|
||||
"rid": self.rid,
|
||||
"bind_act_alias": self.bind_act_alias,
|
||||
"confirm_act_alias": self.confirm_act_alias,
|
||||
"legacy_act_alias": self.legacy_act_alias,
|
||||
"room_id": self.room_id,
|
||||
"elite_amount": self.elite_amount,
|
||||
"gold_pay_type": self.gold_pay_type,
|
||||
"gift_id": self.gift_id,
|
||||
"skin_id": self.skin_id,
|
||||
"updated_at": _ensure_tz(self.updated_at).isoformat() if self.updated_at else None,
|
||||
}
|
||||
|
||||
|
||||
class DouyuConfigUpdate(BaseModel):
|
||||
manual_id: Optional[str] = None
|
||||
rid: Optional[str] = None
|
||||
bind_act_alias: Optional[str] = None
|
||||
confirm_act_alias: Optional[str] = None
|
||||
legacy_act_alias: Optional[str] = None
|
||||
room_id: Optional[str] = None
|
||||
elite_amount: Optional[int] = Field(None, ge=1)
|
||||
gold_pay_type: Optional[int] = Field(None, ge=1, le=9)
|
||||
gift_id: Optional[str] = None
|
||||
skin_id: Optional[str] = None
|
||||
|
||||
|
||||
class DouyuTaskBatchRequest(BaseModel):
|
||||
account_ids: list[int]
|
||||
task_type: str
|
||||
concurrency: int = Field(3, ge=1, le=10)
|
||||
payload: dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class DouyuTaskOut(BaseModel):
|
||||
id: int
|
||||
batch_id: str
|
||||
account_id: int
|
||||
account_username: str = ""
|
||||
account_uid: str = ""
|
||||
account_nickname: str = ""
|
||||
task_type: str
|
||||
status: str
|
||||
message: str = ""
|
||||
result: Optional[dict[str, Any]] = None
|
||||
created_by: int
|
||||
created_at: Optional[datetime] = None
|
||||
finished_at: Optional[datetime] = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
@model_serializer
|
||||
def _serialize(self) -> dict[str, Any]:
|
||||
return {
|
||||
"id": self.id,
|
||||
"batch_id": self.batch_id,
|
||||
"account_id": self.account_id,
|
||||
"account_username": self.account_username,
|
||||
"account_uid": self.account_uid,
|
||||
"account_nickname": self.account_nickname,
|
||||
"task_type": self.task_type,
|
||||
"status": self.status,
|
||||
"message": self.message,
|
||||
"result": self.result,
|
||||
"created_by": self.created_by,
|
||||
"created_at": _ensure_tz(self.created_at).isoformat() if self.created_at else None,
|
||||
"finished_at": _ensure_tz(self.finished_at).isoformat() if self.finished_at else None,
|
||||
}
|
||||
|
||||
|
||||
class DouyuGoodsOut(BaseModel):
|
||||
id: int
|
||||
commodity_id: str
|
||||
name: str = ""
|
||||
score: Optional[int] = None
|
||||
status: str = ""
|
||||
raw: Optional[dict[str, Any]] = None
|
||||
updated_at: Optional[datetime] = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
@model_serializer
|
||||
def _serialize(self) -> dict[str, Any]:
|
||||
return {
|
||||
"id": self.id,
|
||||
"commodity_id": self.commodity_id,
|
||||
"name": self.name,
|
||||
"score": self.score,
|
||||
"status": self.status,
|
||||
"raw": self.raw,
|
||||
"updated_at": _ensure_tz(self.updated_at).isoformat() if self.updated_at else None,
|
||||
}
|
||||
|
||||
|
||||
class DouyuTaskAccountOut(BaseModel):
|
||||
id: int
|
||||
username: str
|
||||
uid: str = ""
|
||||
nickname: str = ""
|
||||
tag: str = ""
|
||||
points: Optional[int] = None
|
||||
game_name: str = ""
|
||||
game_channel: str = ""
|
||||
gold_balance: Optional[int] = None
|
||||
exchange_balance: Optional[int] = None
|
||||
bind_status: str = ""
|
||||
change_role_wait_time: Optional[int] = None
|
||||
assigned_to: Optional[int] = None
|
||||
assigned_username: Optional[str] = None
|
||||
|
||||
|
||||
# ---- 代理配置 ----
|
||||
class ProxyConfigOut(BaseModel):
|
||||
enabled: bool = False
|
||||
|
||||
Reference in New Issue
Block a user