a3a14b484a
改了什么:新增京东联盟订单查询客户端、cps_order 京东字段迁移、CPS 对账接口 platform=all/jd、数据大盘京东订单与佣金聚合。 为什么改:数据大盘需要展示京东 CPS 真实订单佣金,不再保持占位。 验证方式:python -m pytest tests\\test_admin_read.py::test_dashboard_overview tests\\test_cps_admin.py::test_jd_reconcile_updates_dashboard -q;本地真实拉取 2026-06-27 京东订单 3 行,页面显示京东有效 1 单/佣金 ¥0.13。 --------- Co-authored-by: lowmaster-chen <1119780489@qq.com> Reviewed-on: #90 Co-authored-by: chenshuobo <chenshuobo@wonderable.ai> Co-committed-by: chenshuobo <chenshuobo@wonderable.ai>
163 lines
5.7 KiB
Python
163 lines
5.7 KiB
Python
"""admin CPS 分发与对账 schemas。金额统一「分」(cents),前端 yuan() 展示。
|
|
|
|
平台:meituan(actId+sid 转链对账) / taobao(淘口令,只统计点击) / jd(链接 + 订单 API 对账)。
|
|
对账类字段对淘宝为 None → 前端显示 "-"(暂未对账)。
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field
|
|
|
|
|
|
# ───────────── 群 ─────────────
|
|
class CpsGroupOut(BaseModel):
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
sid: str | None = None # 仅美团群有
|
|
name: str
|
|
platforms: list[str] = Field(default_factory=list)
|
|
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)
|
|
# 该群发哪些平台,至少选一个
|
|
platforms: list[str] = Field(min_length=1)
|
|
# 仅当含 meituan 时需要(留空自动生成);纯淘宝/京东不填,后端置 None。
|
|
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)
|
|
platforms: list[str] | None = None
|
|
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)
|
|
|
|
|
|
# ───────────── 活动 ─────────────
|
|
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
|
|
payload: str | None = None # 淘宝淘口令 / 京东链接
|
|
image_url: str | None = None # 淘宝落地页图(绝对 URL)
|
|
status: str
|
|
remark: str | None = None
|
|
created_at: datetime
|
|
|
|
|
|
class CpsActivityCreate(BaseModel):
|
|
name: str = Field(min_length=1, max_length=128)
|
|
platform: str = Field(pattern=r"^(meituan|taobao|jd)$")
|
|
# 美团:act_id 或 product_view_sign 二选一
|
|
act_id: str | None = Field(default=None, max_length=64)
|
|
product_view_sign: str | None = Field(default=None, max_length=128)
|
|
# 淘宝:整段淘口令文本 / 京东:推广链接
|
|
payload: str | None = Field(default=None, max_length=4096)
|
|
# 淘宝落地页图(绝对/相对 URL;淘宝必填,由 router 校验)
|
|
image_url: str | None = Field(default=None, max_length=512)
|
|
remark: str | None = Field(default=None, max_length=256)
|
|
|
|
|
|
class CpsActivityUpdate(BaseModel):
|
|
"""编辑活动(PATCH):全字段可选,只更新传入的非 None 项;最终平台对应字段由 router 校验。"""
|
|
|
|
name: str | None = Field(default=None, min_length=1, max_length=128)
|
|
platform: str | None = Field(default=None, 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)
|
|
payload: str | None = Field(default=None, max_length=4096)
|
|
image_url: str | None = Field(default=None, max_length=512)
|
|
remark: str | None = Field(default=None, max_length=256)
|
|
status: str | None = Field(default=None, pattern=r"^(active|archived)$")
|
|
|
|
|
|
# ───────────── 生成链接(批量) ─────────────
|
|
class CpsReferralLinksRequest(BaseModel):
|
|
group_id: int
|
|
activity_ids: list[int] = Field(min_length=1)
|
|
|
|
|
|
class CpsReferralLinkItem(BaseModel):
|
|
activity_id: int
|
|
activity_name: str
|
|
platform: str
|
|
redirect_url: str # 我们的落地页 /c/{code}(发群用)
|
|
code: str
|
|
|
|
|
|
class CpsReferralLinksOut(BaseModel):
|
|
group_name: str
|
|
results: list[CpsReferralLinkItem]
|
|
|
|
|
|
# ───────────── 对账拉单 ─────────────
|
|
class CpsReconcileResult(BaseModel):
|
|
fetched: int
|
|
inserted: int
|
|
updated: int
|
|
pages: int
|
|
|
|
|
|
# ───────────── 订单明细 ─────────────
|
|
class CpsOrderOut(BaseModel):
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
platform: str = "meituan"
|
|
order_id: str
|
|
external_order_id: str | None = None
|
|
external_row_id: str | None = None
|
|
sid: str | None = None
|
|
act_id: str | None = None
|
|
pay_price_cents: int | None = None
|
|
commission_cents: int | None = None
|
|
estimated_commission_cents: int | None = None
|
|
actual_commission_cents: int | None = None
|
|
commission_rate: str | None = None
|
|
mt_status: str | None = None
|
|
jd_valid_code: str | None = None
|
|
invalid_reason: str | None = None
|
|
product_name: str | None = None
|
|
settle_month: str | None = None
|
|
pay_time: datetime | None = None
|
|
|
|
|
|
# ───────────── 统计 ─────────────
|
|
class CpsGroupStat(BaseModel):
|
|
group_id: int | None = None
|
|
sid: str | None = None
|
|
name: str
|
|
platforms: list[str] = Field(default_factory=list)
|
|
member_count: int | None = None
|
|
click_pv: int = 0
|
|
click_uv: int = 0
|
|
copy_pv: int = 0 # 淘宝"复制口令"次数
|
|
copy_uv: int = 0
|
|
# 对账类:淘宝/京东无法对账 → None(前端显示 "-");美团群为数值
|
|
order_count: int | None = None
|
|
settled_count: int | None = None
|
|
canceled_count: int | None = None
|
|
gmv_cents: int | None = None
|
|
est_commission_cents: int | None = None
|
|
settled_commission_cents: int | None = None
|
|
|
|
|
|
class CpsStatsOut(BaseModel):
|
|
groups: list[CpsGroupStat]
|
|
total_order_count: int
|
|
total_est_commission_cents: int
|
|
total_settled_commission_cents: int
|