"""admin CPS 分发与对账 schemas。金额统一「分」(cents),前端 yuan() 展示。""" from __future__ import annotations from datetime import datetime from pydantic import BaseModel, ConfigDict, Field # ───────────── 群(sid) ───────────── class CpsGroupOut(BaseModel): model_config = ConfigDict(from_attributes=True) id: int sid: str name: str member_count: int | None = None status: str remark: str | None = None created_at: datetime class CpsGroupCreate(BaseModel): name: str = Field(min_length=1, max_length=128) # 留空 → 后端自动生成 g;填写则必须字母+数字(美团 sid 限制)。 sid: str | None = Field(default=None, max_length=64, pattern=r"^[A-Za-z0-9]+$") member_count: int | None = Field(default=None, ge=0) remark: str | None = Field(default=None, max_length=256) class CpsGroupUpdate(BaseModel): name: str | None = Field(default=None, min_length=1, max_length=128) member_count: int | None = Field(default=None, ge=0) status: str | None = Field(default=None, pattern=r"^(active|archived)$") remark: str | None = Field(default=None, max_length=256) # ───────────── 活动(actId) ───────────── class CpsActivityOut(BaseModel): model_config = ConfigDict(from_attributes=True) id: int platform: str name: str act_id: str | None = None product_view_sign: str | None = None status: str remark: str | None = None created_at: datetime class CpsActivityCreate(BaseModel): name: str = Field(min_length=1, max_length=128) platform: str = Field(default="meituan", pattern=r"^(meituan|taobao|jd)$") act_id: str | None = Field(default=None, max_length=64) product_view_sign: str | None = Field(default=None, max_length=128) remark: str | None = Field(default=None, max_length=256) # ───────────── 转链 ───────────── class CpsReferralLinkRequest(BaseModel): group_id: int activity_id: int # 链接类型:1长链 2短链 3deeplink。默认短链(微信可打开)+deeplink。 link_types: list[int] = Field(default_factory=lambda: [2, 3]) class CpsReferralLinkOut(BaseModel): redirect_url: str # ★ 我们的群发短链(/c/{code}),发群就用这个,点击经我们统计 code: str sid: str group_name: str activity_name: str target_url: str # 实际 302 跳转的美团短链 link_map: dict[str, str] # 美团原始 1长链/2短链/3deeplink(参考/备用) # ───────────── 对账拉单 ───────────── class CpsReconcileResult(BaseModel): fetched: int # 本次美团返回的订单条数 inserted: int # 新入库 updated: int # 已存在→更新状态/佣金 pages: int # 翻了几页 # ───────────── 订单明细 ───────────── class CpsOrderOut(BaseModel): model_config = ConfigDict(from_attributes=True) id: int order_id: str sid: str | None = None act_id: str | None = None pay_price_cents: int | None = None commission_cents: int | None = None commission_rate: str | None = None mt_status: str | None = None invalid_reason: str | None = None product_name: str | None = None pay_time: datetime | None = None # ───────────── 统计 ───────────── class CpsGroupStat(BaseModel): group_id: int | None = None # None = 未归群的 sid(历史/其它来源) sid: str | None = None name: str member_count: int | None = None click_pv: int = 0 # 点击总次数 click_uv: int = 0 # 独立点击(按 ip+ua 近似去重) order_count: int # 有效订单数(不含取消/风控) settled_count: int # 已结算单数 canceled_count: int # 取消+风控单数 gmv_cents: int # 成交额(有效单 payPrice 合计) est_commission_cents: int # 预估佣金(有效单 profit 合计) settled_commission_cents: int # 已结算佣金 class CpsStatsOut(BaseModel): groups: list[CpsGroupStat] total_order_count: int total_est_commission_cents: int total_settled_commission_cents: int