feat: 斗鱼外部单协作台账与店铺实时同步

This commit is contained in:
yml2213
2026-10-20 20:11:35 +08:00
parent c778ae9a09
commit 71574908ff
18 changed files with 6187 additions and 4 deletions
+166
View File
@@ -514,6 +514,172 @@ class DouyuEsportsGoodsSnapshot(Base):
)
class DouyuCollabShop(Base):
"""斗鱼外部单协作的店铺字典(新建单时点选,历史文本自动登记)。"""
__tablename__ = "douyu_collab_shops"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
name: Mapped[str] = mapped_column(
String(64), unique=True, nullable=False, index=True
)
sort_order: Mapped[int] = mapped_column(Integer, default=0, server_default="0")
is_active: Mapped[bool] = mapped_column(
Boolean, default=True, server_default="1", index=True
)
remark: Mapped[str] = mapped_column(String(255), default="", server_default="")
created_by: Mapped[int | None] = mapped_column(
ForeignKey("users.id"), nullable=True
)
updated_by: Mapped[int | None] = mapped_column(
ForeignKey("users.id"), nullable=True
)
created_at: Mapped[datetime] = mapped_column(UTCDateTime, default=_utcnow)
updated_at: Mapped[datetime] = mapped_column(
UTCDateTime, default=_utcnow, onupdate=_utcnow
)
class DouyuExternalOrder(Base):
"""斗鱼外部单协作台账(一行 = 一单 = 一个内部斗鱼账号)。
和虎牙外部 CK 台账的关键区别:**不复制 CK**。协作单只存 ``account_id``
(可空,账号删除后置空)与用户名/UID 快照,任何查询都实时读
``accounts.cookie``。账号 CK 更新后,协作单自动使用最新凭据。
"""
__tablename__ = "douyu_external_orders"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
order_no: Mapped[str] = mapped_column(
String(64), unique=True, nullable=False, index=True
)
shop: Mapped[str] = mapped_column(
String(64), default="", server_default="", index=True
)
owner_id: Mapped[int | None] = mapped_column(
ForeignKey("users.id"), nullable=True, index=True
)
# ---- 内部斗鱼账号(CK 不落本表)----
account_id: Mapped[int | None] = mapped_column(
ForeignKey("accounts.id", ondelete="SET NULL"), nullable=True, index=True
)
account_username: Mapped[str] = mapped_column(
String(128), default="", server_default="", index=True
)
account_uid: Mapped[str] = mapped_column(String(32), default="", server_default="")
account_nickname: Mapped[str] = mapped_column(
String(128), default="", server_default=""
)
# ---- 绑定角色只读快照(来自 memberthird/tencent/bindInfo)----
bind_game_account: Mapped[str] = mapped_column(
String(128), default="", server_default=""
)
bind_game_role: Mapped[str] = mapped_column(
String(128), default="", server_default=""
)
bind_game_channel: Mapped[str] = mapped_column(
String(128), default="", server_default=""
)
bind_snapshot_at: Mapped[datetime | None] = mapped_column(
UTCDateTime, nullable=True
)
# ---- 订单资料 ----
home_images: Mapped[list | None] = mapped_column(JSON, nullable=True)
gift_name: Mapped[str] = mapped_column(String(128), default="", server_default="")
commodity_id: Mapped[str] = mapped_column(String(64), default="", server_default="")
required_points: Mapped[int | None] = mapped_column(Integer, nullable=True)
remark: Mapped[str] = mapped_column(String(512), default="", server_default="")
# ---- 业务进度 ----
status: Mapped[str] = mapped_column(
String(16), default="incomplete", server_default="incomplete", index=True
)
recharged_at: Mapped[datetime | None] = mapped_column(UTCDateTime, nullable=True)
scripted_at: Mapped[datetime | None] = mapped_column(UTCDateTime, nullable=True)
done_at: Mapped[datetime | None] = mapped_column(UTCDateTime, nullable=True)
void_reason: Mapped[str] = mapped_column(String(256), default="", server_default="")
# ---- 鱼翅 / 积分 / 核账快照 ----
fish_fin_balance: Mapped[int | None] = mapped_column(Integer, nullable=True)
points_balance: Mapped[int | None] = mapped_column(Integer, nullable=True)
points_required_total: Mapped[int | None] = mapped_column(Integer, nullable=True)
points_surplus: Mapped[int | None] = mapped_column(Integer, nullable=True)
points_threshold: Mapped[int | None] = mapped_column(Integer, nullable=True)
points_checked_at: Mapped[datetime | None] = mapped_column(
UTCDateTime, nullable=True
)
points_check_reason: Mapped[str] = mapped_column(
String(16), default="", server_default=""
)
points_check_message: Mapped[str] = mapped_column(
String(512), default="", server_default=""
)
points_check_detail: Mapped[dict | None] = mapped_column(JSON, nullable=True)
# ---- 归档 ----
archived_at: Mapped[datetime | None] = mapped_column(
UTCDateTime, nullable=True, index=True
)
archived_by: Mapped[int | None] = mapped_column(
ForeignKey("users.id"), nullable=True
)
archive_reason: Mapped[str] = mapped_column(
String(256), default="", server_default=""
)
created_by: Mapped[int | None] = mapped_column(
ForeignKey("users.id"), nullable=True, index=True
)
updated_by: Mapped[int | None] = mapped_column(
ForeignKey("users.id"), nullable=True
)
version: Mapped[int] = mapped_column(Integer, default=0, server_default="0")
created_at: Mapped[datetime] = mapped_column(UTCDateTime, default=_utcnow)
updated_at: Mapped[datetime] = mapped_column(
UTCDateTime, default=_utcnow, onupdate=_utcnow, index=True
)
class DouyuExternalOrderMetric(Base):
"""斗鱼协作单的鱼翅/积分/兑换记录快照(只追加,不存 CK)。"""
__tablename__ = "douyu_external_order_metrics"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
order_id: Mapped[int] = mapped_column(
ForeignKey("douyu_external_orders.id", ondelete="CASCADE"), index=True
)
order_no: Mapped[str] = mapped_column(String(64), default="", server_default="")
account_id: Mapped[int | None] = mapped_column(Integer, nullable=True, index=True)
account_username: Mapped[str] = mapped_column(
String(128), default="", server_default=""
)
fish_fin_balance: Mapped[int | None] = mapped_column(Integer, nullable=True)
points_balance: Mapped[int | None] = mapped_column(Integer, nullable=True)
points_required_total: Mapped[int | None] = mapped_column(Integer, nullable=True)
points_surplus: Mapped[int | None] = mapped_column(Integer, nullable=True)
records_total: Mapped[int] = mapped_column(Integer, default=0, server_default="0")
records_matched: Mapped[int] = mapped_column(Integer, default=0, server_default="0")
verdict: Mapped[str] = mapped_column(
String(16), default="unknown", server_default="unknown", index=True
)
message: Mapped[str] = mapped_column(String(512), default="", server_default="")
source: Mapped[str] = mapped_column(
String(16), default="manual", server_default="manual"
)
raw: Mapped[dict | None] = mapped_column(JSON, nullable=True)
created_by: Mapped[int | None] = mapped_column(
ForeignKey("users.id"), nullable=True
)
created_at: Mapped[datetime] = mapped_column(
UTCDateTime, default=_utcnow, index=True
)
class HuyaAccount(Base):
"""虎牙账号"""