Files
shaguabijia-app-server/docs/api/compare-record-report.md
T
OuYingJun1024 1c61f231a0 feat(compare): comparison_results 增加 coupon_saved(平台红包优惠额)
- schema ComparisonResultIn 显式声明 coupon_saved(否则 model_dump 丢字段)
- 上报→落库→读出贯通, 加 passthrough 测试(目标带值/源平台 null)
- 更新 api/database 文档

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 22:05:00 +08:00

4.0 KiB
Raw Blame History

POST /api/v1/compare/record — 上报一次比价结果(幂等)

所属:比价记录组(前缀 /api/v1/compare | 鉴权:Bearer | ← 返回 API 索引

比价 done 帧后,客户端用带 JWT 的通道上报一条比价结果,落 comparison_record 表,作为「我的比价记录」数据源 + 用户级行为画像。

⚠️ 与不鉴权的透传端点 /api/v1/price/step 不同:那是转发壳,本接口按用户维度落库,必须鉴权。 本轮只做 server 端;客户端在 done 帧后调本接口的改动另起一轮(见 待办与技术债.md P1)。

入参(JSON body

字段刻意对齐 pricebot 协议(02_api_protocol.mdcalibration + done.params),客户端把 Phase1 的 calibration 和 done 帧 params 零翻译映射上来即可。

字段 类型 必填 默认 说明
trace_id string pricebot 侧 trace_id。幂等键:同用户同 trace_id 重复上报覆盖、返回同一 id
business_type string food food(外卖,当前唯一接通) / ecom(电商) / coupon(领券)
device_id string | null null 设备号
store_name string | null null 店铺名(外卖,来自 calibration.result
source_platform_id string | null null 源平台代号,如 taobao_flash
source_platform_name string | null null 源平台中文名
source_package string | null null 源平台 Android 包名
source_price float | null null 源平台到手价(
items Item[] [] 下单菜品,{name, qty, specs?}
comparison_results Result[] [] 逐平台对比,见下表(price 单位
skipped_dish_count int | null null 目标平台未找到、跳过的菜品数
skipped_dish_names string[] [] 被跳过的菜名
total_dish_count int | null null 原始菜品总数
information string | null null done 帧文案(成功摘要 / 失败具体原因),持久化为列并在列表/详情返回,前端失败时当原因展示
status string | null null success / failed不传则服务端派生

Item{ name: string, qty: int=1, specs: string[]\|null }

Resultcomparison_results 元素){ platform_id, platform_name, package, price(元,float\|null), is_source(bool), rank(int\|null), coupon_saved(元,float\|null) }

  • coupon_saved:该平台本单平台主优惠额(元)——美团红包 / 淘宝平台红包 / 京东优惠券·百亿补贴,只取那一笔,不含配送费减免/共减总额。仅外卖目标平台带值,源平台/没用为 null,前端记录页据此展示**「已优惠 ¥X」**(null 不展示)。

服务端派生(客户端不用算)

comparison_results 派生并落结构化列:

  • best_*:取最便宜的一家(按 rank 升序、再按 price),写 best_platform_id/name/best_price_cents
  • source_price_cents:优先用 source_price,缺失则取 comparison_resultsis_source=true 行的价
  • saved_amount_cents = 源价 最优价(可为 0 / 负:源平台本来就最便宜)
  • is_source_best:最便宜的一家是否为源平台(= 这次没省到)
  • status(未显式传时):存在「非源且有价」的结果 → success,否则 → failed
  • 金额一律 round(元 × 100)

comparison_results / items / skipped_dish_names 原样存 JSON;完整上报 body 另存 raw_payload(详情接口可取回)。

出参

响应 200{ "id": int }(写入或已存在记录的 id

错误

  • 401 未鉴权
  • 422trace_id 或字段类型不符

说明

失败的比价(done 帧只有源/空 comparison_results)也会落一条 status=failed——「越详细越好」,是否在 UI 展示由前端过滤。