fa4127b9e5
Reviewed-on: #128
7.4 KiB
7.4 KiB
cps_order — CPS 对账订单(美团联盟 query_order 拉回的订单明细)
模型
app/models/cps_order.py· 仓库app/admin/repositories/cps.py(reconcile_orders/_map_order_fields/list_orders、统计group_stats) · 接口 adminPOST /admin/api/cps/orders/reconcile、GET /admin/api/cps/orders、GET /admin/api/cps/stats· ← 索引 · 总览
从联盟 API 按时间窗拉回、按 sid 归群的订单明细,是 CPS 群发漏斗的最下游"赚了多少佣金":用户点 cps_link(携群 cps_group 的 sid)下单后,联盟把订单连同 sid 回传,这里按 sid 归群做对账,与 cps_click 的点击量在 group_stats 汇成"点击→下单→佣金"漏斗。平台覆盖:初版仅美团(query_order);#90(2026-06-30)接入京东联盟订单(拉单进同一张表,platform='jd',配 jd_*/external_* 列,喂数据大盘);淘宝仍无对账 API,统计里对账字段显示 -。
用在哪 / 增删改查
- C/U(upsert):
POST /admin/api/cps/orders/reconcile(reconcile_orders,需finance角色)。调meituan.query_order(sid?, start_time, end_time, page, limit=100)分页拉单(max_pages=200防死循环),每条经_map_order_fields转字段,按order_idupsert:不存在则 insert,存在则逐字段覆盖(订单状态会随时间变 付款→完成→结算/退款,重复拉则更新)。返回{fetched, inserted, updated, pages}。order_id全局唯一即幂等键。 - R(读):
GET /admin/api/cps/orders(list_orders,游标分页,可按sid/mt_status过滤);统计group_stats拉全部订单按sid分桶,算order_count/gmv/est_commission/settled_commission等。 - D:无。
字段
字段对齐
query_order实测返回:金额(payPrice/profit)是「元」字符串 → 入库_yuan_to_cents转「分」(全站口径);时间(payTime/updateTime)是秒级时间戳 →_ts_to_dt转 tz-aware UTC。
| 列 | 类型 | 约束 / 默认 | 说明(取值 / join / 源字段) |
|---|---|---|---|
id |
Integer | PK, autoincrement | |
platform |
String(20) | index, NOT NULL, default meituan |
订单来源联盟:meituan / jd(#90)。统计/大盘按它分平台 |
order_id |
String(64) | UNIQUE, index, NOT NULL | 订单号(美团加密串 orderId;京东为联盟订单号)。upsert 幂等键 |
external_order_id |
String(128) | index, nullable | 平台原始订单号(#90,京东 orderId;美团 null) |
external_row_id |
String(128) | index, nullable | 平台订单行号(#90,京东一单多 sku 时区分行;美团 null) |
sid |
String(64) | index, nullable | 渠道追踪位 = 群 sid,源 sid。按它归群聚合;历史无 sid 订单为空 |
act_id |
String(64) | index, nullable | 活动物料 ID,源 actId(转字符串) |
biz_line |
Integer | nullable | 业务线,源 businessLine。1=外卖 |
trade_type |
Integer | nullable | 源 tradeType。1=cps 2=cpa |
pay_price_cents |
Integer | nullable | 付款金额(分),源 payPrice(元)。统计算 GMV |
commission_cents |
Integer | nullable | 预估佣金(分),源 profit(元)。统计算预估/已结算佣金 |
commission_rate |
String(16) | nullable | 佣金率,源 commissionRate。"300"=3%、"10"=0.1%(原样字符串,前端解释) |
refund_price_cents |
Integer | nullable | 退款金额(分),源 refundPrice(元) |
refund_profit_cents |
Integer | nullable | 退款佣金(分),源 refundProfit(元) |
estimated_commission_cents |
Integer | nullable | 预估佣金(分,#90 京东口径;美团用 commission_cents) |
actual_commission_cents |
Integer | nullable | 实际/结算佣金(分,#90 京东口径) |
mt_status |
String(8) | index, nullable | 美团订单状态,源 status:2付款 3完成 4取消 5风控 6结算;京东订单为 null |
jd_valid_code |
String(16) | index, nullable | 京东订单有效码(#90,联盟 validCode,判有效/无效/风控);美团订单为 null |
invalid_reason |
String(128) | nullable | 失效原因,源 invalidReason |
product_name |
String(512) | nullable | 商品名,源 productName(超 500 截断) |
settle_month |
String(16) | nullable | 结算月份(#90 京东) |
site_id / position_id / pid |
String(128) | nullable | 京东推广位维度(#90):站点/推广位/联盟 pid,归因用 |
pay_time |
DateTime(tz) | index, nullable | 付款时间,源 payTime(秒级 ts)。统计按时间窗过滤的就是它 |
mt_update_time |
DateTime(tz) | nullable | 美团侧更新时间,源 updateTime(秒级 ts) |
raw |
JSON / JSONB | NOT NULL, default {} |
query_order 单条原始 dataList,留底排查/补字段 |
first_seen |
DateTime(tz) | server_default now(), NOT NULL | 首次拉到入库时间(本地) |
updated_at |
DateTime(tz) | server_default now(), onupdate now() | 最近 upsert 时间(本地) |
关系 / Join Key
sid≈cps_group.sid(订单按 sid 归群,语义关联,无 ForeignKey)。group_stats即据此把订单挂到群行。- 与
cps_link/cps_click无直接列关联:下单链路是"美团短链(带 sid)→ 美团 App 下单",订单只回传sid、不回传我们的link.code或某次点击 id。所以点击与订单只能在群(sid)维度汇合,无法把单笔订单对到单次点击。 - 本表无
user_id:CPS 联盟订单是别人(被推广的微信群用户)在美团下的单,与本 App 的user表无关,纯渠道佣金对账,不归属本 App 用户。
索引与约束
- PK
id;UNIQUE+indexorder_id(uq_cps_order_order_id+ix_cps_order_order_id);indexsid、act_id、mt_status、pay_time。 - 无外键。
注意
- 状态决定佣金口径(
group_stats._order_agg):4取消/5风控不计佣金(_INVALID_STATUS);6结算才是佣金真正到账(_SETTLED_STATUS)。统计区分order_count(有效=非取消非风控)、settled_count(已结算)、canceled_count,佣金分est_commission(有效单预估)与settled_commission(结算单)。 - "未归群"独立行:
group_stats遍历完所有群后,对剩下的、有订单但sid不属任何现存群的 sid(历史遗留如wonderableai、或别处来源、或群被删),单列一行group_id=None、有对账无点击。所以本表sid可空/可孤立是设计内的,不是脏数据。 - 金额/时间统一转换的原因:
query_order返回金额是「元」字符串、时间是秒级 ts;_yuan_to_cents(Decimal 防浮点,"null"/空 → None)与_ts_to_dt(转 tz-aware UTC,前端按北京展示)在入库时归一,与全站"金额存分、时间存 tz-aware"口径对齐。raw整条留底,字段不够时不用重拉。 - upsert 而非 append:同一订单会被多次拉到(状态变化),按
order_id覆盖即可拿到最新状态;reconcile可重复跑(幂等)。 - 平台边界的演变:初版(
277f9b1)只服务美团;#90(2026-06-30)接入京东联盟拉单进同一张表(platform='jd'+external_*/jd_valid_code/estimated|actual_commission_cents等列,有效性按jd_valid_code判,喂 admin 数据大盘的京东收益)。淘宝仍无对账 API,统计对账列给None(前端显示-)。 - #119 修
pay_time缺失:早期美团拉单部分订单payTime空导致pay_time为 null → 大盘按时间窗过滤漏算美团收益;#119 起入库补齐/回填,时间窗统计以pay_time为准。