docs/api目录文档分类和补全 --------- Co-authored-by: guke <guke@autohome.com.cn> Reviewed-on: #111
24 KiB
傻瓜比价 App 后端 — API 接口文档(索引)
Base URL:生产
https://app-api.shaguabijia.com;本地联调http://<开发机>:8770协议:HTTP / JSON,请求与响应体均application/json,字段统一 snake_case 鉴权:需鉴权的接口在请求头带Authorization: Bearer <access_token>最后更新:2026-07-03(补全缺失文档:ad/watch-report, wallet/transfer-auth 族, coupon/session+stats+completed-today+prompt 族, invite 族, user/onboarding, platform/flags+ad-config+app-version, intent/step+precoupon/step, analytics/events, order/report, report 族, feedback/config+records, trace/finalize。文档移至分类子目录,新增 mock 入参/出参示例) 架构:app/api/v1/只放很轻的接口层;穿山甲/微信支付/极光/短信/美团等 SDK 集成的重逻辑在app/integrations/,实现细节见 docs/integrations/。
接口总览
| # | 方法 + 路径 | 鉴权 | 详情 |
|---|---|---|---|
| 1 | GET /health |
无 | 详情 |
| 2 | POST /api/v1/auth/jverify-login |
无 | 详情 |
| 3 | POST /api/v1/auth/sms/send |
无 | 详情 |
| 4 | POST /api/v1/auth/sms/login |
无 | 详情 |
| 5 | POST /api/v1/auth/refresh |
无 | 详情 |
| 6 | GET /api/v1/auth/me |
Bearer | 详情 |
| 7 | POST /api/v1/auth/logout |
Bearer | 详情 |
| 8 | POST /api/v1/coupon/step |
无 | 详情(透传 pricebot + best-effort 写 coupon_* 三表) |
| 8a | POST /api/v1/coupon/prompt/shown |
无 | 详情(引导窗弹出即上报) |
| 8b | POST /api/v1/coupon/prompt/dismiss |
无 | 详情(用户拒绝/关闭引导窗) |
| 8c | GET /api/v1/coupon/prompt/should-show |
无 | 详情(切到外卖 App 时是否还应弹引导窗) |
| 8d | POST /api/v1/coupon/prompt/reset |
无 | 详情(重置今日引导窗 engagement,开发测频控用) |
| 8e | GET /api/v1/coupon/completed-today |
无 | 详情(这台设备今天是否已跑完整轮领券) |
| 8f | POST /api/v1/coupon/completed-today/reset |
无 | 详情(重置今日已完成,开发用) |
| 8g | GET /api/v1/coupon/stats |
Bearer | 详情(累计领券数,「我的」页战绩卡) |
| 8h | POST /api/v1/coupon/session |
无 | 详情(领券流水上报,admin 看板数据源) |
| 9 | POST /api/v1/meituan/coupons |
无 | 详情 |
| 10 | POST /api/v1/meituan/feed |
无 | 详情 |
| 11 | POST /api/v1/meituan/referral-link |
无 | 详情 |
| 11a | POST /api/v1/meituan/top-sales |
无 | 详情(销量榜:离线库 meituan_coupon 按销量降序 + 跨源去重,不实时打美团) |
比价透传(前缀 /api/v1,外卖 MVP;与 coupon/step 同为透传 pricebot-backend;下按 Phase 流程列,均不鉴权) |
|||
| 12 | POST /api/v1/intent/recognize |
无 | 详情(Phase 1 意图识别,单次,多数源) |
| 12a | POST /api/v1/intent/precoupon/step |
无 | 详情(Phase 0 意图识别前先用券,仅美团源) |
| 12b | POST /api/v1/intent/step |
无 | 详情(Phase 1 多帧意图识别,仅淘宝源,循环到 done) |
| 13 | POST /api/v1/price/step |
无 | 详情(Phase 2 步进) |
| 13a | POST /api/v1/trace/finalize |
无 | 详情(比价 trace 收尾上云,终止/未识别拿 trace_url) |
比价记录(前缀 /api/v1/compare;按用户落库,鉴权,区别于上面不鉴权的透传) |
|||
| 12a | POST /api/v1/compare/record |
Bearer | 详情 |
| 12b | GET /api/v1/compare/records |
Bearer | 详情 |
| 12c | GET /api/v1/compare/records/{id} |
Bearer | 详情 |
| 12e | GET /api/v1/compare/stats |
Bearer | 详情(「我的」页省钱战绩卡:完成比价数 + 累计发现可省) |
比价战绩里程碑(前缀 /api/v1/compare;福利页「记录比价战绩」,按成功比价数解锁逐档发金币) |
|||
| 12d | GET /api/v1/compare/milestones |
Bearer | 详情 |
| 12e | POST /api/v1/compare/milestones/{milestone}/claim |
Bearer | 详情 |
设备 / 无障碍存活监控(前缀 /api/v1/device;心跳超时检出 + 掉线召回,#65) |
|||
| D1 | POST /api/v1/device/register |
Bearer | 详情(注册设备/更新极光 push token) |
| D2 | POST /api/v1/device/heartbeat |
Bearer | 详情(无障碍服务存活心跳,心跳也能自注册) |
| D3 | GET /api/v1/device/liveness |
Bearer | 详情(进 App 查本机是否被判掉线过) |
| D4 | POST /api/v1/device/liveness/ack |
Bearer | 详情(确认已弹引导,清掉线告警) |
上报更低价(前缀 /api/v1/report;众包纠偏,人工审核发奖) |
|||
| R1 | POST /api/v1/report |
Bearer | 详情(提交上报更低价,multipart:比价记录ID+平台+价格+截图1-4张) |
| R2 | GET /api/v1/report/records |
Bearer | 详情(上报记录列表,?status=pending/approved/rejected 可选筛选) |
好友邀请(前缀 /api/v1/invite;注册即生效,双方各发 1 万金币) |
|||
| I1 | GET /api/v1/invite/me |
Bearer | 详情(我的邀请码+分享链接+已邀人数/已得金币) |
| I2 | GET /api/v1/invite/invitees |
Bearer | 详情(我邀请的人列表,limit/offset 分页) |
| I3 | POST /api/v1/invite/landing-track |
无 | 详情(落地页 dl.html 访问上报指纹,剪贴板归因兜底;浏览器无 token) |
| I4 | POST /api/v1/invite/bind |
Bearer | 详情(绑定邀请人;支持 clipboard/manual 邀请码+fingerprint 指纹反查三种归因) |
钱包 / 我的资产(前缀 /api/v1/wallet) |
|||
| 14 | GET /api/v1/wallet/account |
Bearer | 详情 |
| 15 | GET /api/v1/wallet/coin-transactions |
Bearer | 详情 |
| 16 | GET /api/v1/wallet/cash-transactions |
Bearer | 详情 |
| 17 | GET /api/v1/wallet/exchange-info |
无 | 详情 |
| 18 | POST /api/v1/wallet/exchange |
Bearer | 详情 |
| 19 | POST /api/v1/wallet/bind-wechat |
Bearer | 详情 |
| 20 | POST /api/v1/wallet/unbind-wechat |
Bearer | 详情 |
| 21 | GET /api/v1/wallet/withdraw-info |
Bearer | 详情 |
| 22 | POST /api/v1/wallet/withdraw |
Bearer | 详情 |
| 23 | GET /api/v1/wallet/withdraw/status |
Bearer | 详情 |
| 24 | GET /api/v1/wallet/withdraw-orders |
Bearer | 详情 |
| 24a | POST /api/v1/wallet/transfer-auth |
Bearer | 详情(开启免确认到账,申请授权,返回拉起微信授权页的 package) |
| 24b | GET /api/v1/wallet/transfer-auth/status |
Bearer | 详情(查免确认授权状态,从微信授权页返回后轮询) |
| 24c | POST /api/v1/wallet/transfer-auth/close |
Bearer | 详情(关闭免确认到账,解除授权) |
签到(前缀 /api/v1/signin) |
|||
| 25 | GET /api/v1/signin/status |
Bearer | 详情 |
| 26 | POST /api/v1/signin |
Bearer | 详情 |
| 26a | POST /api/v1/signin/boost |
Bearer | 详情 |
任务(前缀 /api/v1/tasks) |
|||
| 27 | GET /api/v1/tasks |
Bearer | 详情 |
| 28 | POST /api/v1/tasks/{task_key}/claim |
Bearer | 详情 |
省钱(前缀 /api/v1/savings) |
|||
| 29 | GET /api/v1/savings/summary |
Bearer | 详情 |
| 30 | GET /api/v1/savings/battle |
Bearer | 详情 |
| 31 | GET /api/v1/savings/records |
Bearer | 详情 |
看广告发奖(前缀 /api/v1/ad) |
|||
| 32 | GET /api/v1/ad/pangle-callback |
验签 | 详情 |
| 33 | GET /api/v1/ad/reward-status |
Bearer | 详情 |
| 34 | POST /api/v1/ad/test-grant |
Bearer | 详情 |
| 35 | POST /api/v1/ad/ecpm-report |
Bearer | 详情 |
| 35a | POST /api/v1/ad/feed-reward |
Bearer | 详情 |
| 35b | POST /api/v1/ad/reward-noshow |
Bearer | 详情(激励视频提前关闭/未发奖留痕,只记原因不发币) |
| 35c | GET /api/v1/ad/feed-reward/units |
Bearer | 详情(信息流广告今日已发份数/上限,配合 feed-reward 看进度) |
| 35d | POST /api/v1/ad/watch-report |
Bearer | 详情(上报激励视频观看时长,旧客户端兼容) |
用户资料(前缀 /api/v1/user) |
|||
| 35 | PATCH /api/v1/user/profile |
Bearer | 详情 |
| 36 | POST /api/v1/user/avatar |
Bearer | 详情 |
| 36a | POST /api/v1/user/onboarding/complete |
Bearer | 详情(标记新手引导完成,按 账号+device_id 幂等,跨卸载重装持久) |
| 36b | GET /api/v1/user/onboarding/status |
Bearer | 详情(查该 账号+设备 是否走过引导,运营在 admin 删记录即触发重走) |
| 37 | DELETE /api/v1/user |
Bearer | 详情 |
帮助与反馈(前缀 /api/v1/feedback) |
|||
| 38 | POST /api/v1/feedback |
Bearer | 详情 |
| 38a | GET /api/v1/feedback/config |
Bearer | 详情(反馈页「加群二维码」卡配置:开关+二维码图+三行文案) |
| 38b | GET /api/v1/feedback/records |
Bearer | 详情(我的反馈历史,pending/adopted/rejected) |
| 埋点 & 订单上报(前缀分散;全部 Bearer 除 analytics/events 不强制登录) | |||
| E1 | POST /api/v1/analytics/events |
无 | 详情(批量上报埋点事件,不强制登录,每批最多200条) |
| E2 | POST /api/v1/order/report |
Bearer | 详情(上报归因订单,比价后5分钟内点链接+支付金额与比价价相差≤1元) |
首页门面数据 / 客户端配置(前缀 /api/v1/platform;全平台展示数字 + 运营开关,全部不鉴权,登录前可读) |
|||
| 39 | GET /api/v1/platform/stats |
无 | 详情 |
| 40 | GET /api/v1/platform/savings-feed |
无 | 详情 |
| 40a | GET /api/v1/platform/flags |
无 | 详情(客户端运营 feature flag,比价/领券期广告开关等,拉取后缓存) |
| 40b | GET /api/v1/platform/ad-config |
无 | 详情(客户端拉广告配置:穿山甲 app_id+各位ID+各场景开关;不含验签密钥) |
| 40c | GET /api/v1/platform/app-version |
无 | 详情(最新 App 版本,OTA 检查更新;与本机 versionCode 比) |
微信支付回调(前缀 /api/v1/wxpay) |
|||
| W1 | POST /api/v1/wxpay/transfer-auth-notify |
无 | 免确认收款授权结果通知(一期 stub:仅应答 200 不验签不改账,授权状态靠主动查询兜底)(无单独文档) |
| CPS 群发短链落地(无前缀,挂域名根;公网不鉴权) | |||
| C1 | GET /c/{code} |
无 | 详情(短链落地:微信授权拿 openid + 记点击 + 302 跳/淘宝 H5 落地页) |
| C2 | POST /c/{code}/copy |
无 | 详情(淘宝落地页点「复制口令」记 copy) |
| C3 | GET /wx/oauth/cb |
无 | 详情(微信网页授权回调;upsert cps_wx_user + 种 cookie,include_in_schema=False) |
| C4 | GET /MP_verify_*.txt |
无 | 详情(微信「网页授权域名」归属校验文件,include_in_schema=False) |
内部回写端点(前缀 /internal;pricebot/发布流程→app-server,X-Internal-Secret 头,非客户端接口) |
|||
| N1 | POST /internal/price-observation |
内部密钥 | 详情(比价价格事实批量落 price_observation) |
| N2 | GET /internal/store-mapping/lookup |
内部密钥 | 详情(按源平台店名反查目标平台已沉淀店铺 id/deeplink) |
| N3 | POST /internal/store-mapping |
内部密钥 | 详情(跨平台店铺身份映射落 store_mapping) |
| N4 | POST /internal/store-mapping/invalidate |
内部密钥 | 详情(标记某平台 shopId 缓存 deeplink 失效) |
| N5 | POST /internal/launch-confirm-sample |
内部密钥 | 详情(启动确认窗兜底样本落 launch_confirm_sample) |
| N6 | POST /internal/app-version |
内部密钥 | 详情(发布流程写最新 App 版本,落 app_config) |
静态资源(StaticFiles 挂载,见下方 /media 静态服务) |
|||
| - | GET /media/avatars/<file> |
无 | 用户头像;返回二进制图片 |
| - | GET /media/feedback/<file> |
无 | 反馈截图;返回二进制图片 |
运营后台 Admin(独立子应用 app/admin/,前缀 /admin/api,独立进程 + 独立 admin JWT。鉴权列:admin=任意已登录管理员,operator/finance/super_admin=需对应角色(super_admin 恒通过)) |
|||
| A1 | POST /admin/api/auth/login |
无 | 详情 |
| A2 | GET /admin/api/auth/me |
admin | 详情 |
| A3 | GET /admin/api/stats/overview |
admin | 详情 |
| A4 | GET /admin/api/users |
admin | 详情 |
| A5 | GET /admin/api/users/{user_id} |
admin | 详情 |
| A6 | POST /admin/api/users/{user_id}/status |
operator | 详情 |
| A7 | POST /admin/api/users/{user_id}/coins |
finance | 详情 |
| A8 | POST /admin/api/users/{user_id}/cash |
finance | 详情 |
| A9 | GET /admin/api/wallet/coin-transactions |
admin | 详情 |
| A10 | GET /admin/api/wallet/cash-transactions |
admin | 详情 |
| A11 | GET /admin/api/withdraws |
admin | 详情 |
| A12 | POST /admin/api/withdraws/reconcile |
finance | 详情 |
| A13 | POST /admin/api/withdraws/{out_bill_no}/refresh |
finance | 详情 |
| A14 | GET /admin/api/feedbacks |
admin | 详情 |
| A15 | POST /admin/api/feedbacks/{feedback_id}/handle |
operator | 详情 |
| A16 | GET /admin/api/admins |
super_admin | 详情 |
| A17 | POST /admin/api/admins |
super_admin | 详情 |
| A18 | PATCH /admin/api/admins/{admin_id} |
super_admin | 详情 |
| A19 | GET /admin/api/audit-logs |
admin | 详情 |
| A20 | GET /admin/api/dashboard-display |
admin | 详情 |
| A21 | PATCH /admin/api/dashboard-display/{metric} |
operator | 详情 |
| A22 | GET /admin/api/marquee-seeds |
admin | 详情 |
| A23 | POST /admin/api/marquee-seeds |
operator | 详情 |
| A24 | PATCH /admin/api/marquee-seeds/{seed_id} |
operator | 详情 |
| A25 | DELETE /admin/api/marquee-seeds/{seed_id} |
operator | 详情 |
| A26 | POST /admin/api/marquee-seeds/bulk |
operator | 详情 |
| A27 | GET /admin/api/marquee-seeds/preview |
admin | 详情 |
| A28 | GET /admin/api/ad-coin-audit |
admin | 详情(看广告金币公式复算对账,只读) |
| A29 | GET /admin/api/ad-revenue-report |
admin | 详情(广告收益报表:按用户/日期/类型/应用/代码位 聚合 条数/收益/金币,只读) |
| - | GET /admin/api/health |
无 | admin 健康检查(无单独文档) |
⚠️ 美团三个接口当前无鉴权,且
referral-link的sid允许客户端传值覆盖默认渠道——见各接口"备注"。coupon/step及外卖比价的intent/recognize、intent/precoupon/step、intent/step、price/step、trace/finalize都透传到 pricebot-backend,MVP 阶段均不鉴权(device_id 透传,待补 JWT——见app/api/v1/compare.py)。 福利相关业务接口(wallet/signin/tasks/savings、ad/reward-status、ad/feed-reward)均需 Bearer;wallet/exchange-info是静态规则无鉴权;ad/pangle-callback不走 JWT、靠穿山甲验签;ad/test-grant仅本地联调(开关控制,生产 404)。 金额字段一律以分为单位(*_cents)。
通用约定
- 时间格式:ISO 8601 UTC(如
2026-05-27T12:34:56Z) - 错误响应:FastAPI 标准结构
{"detail": "<错误信息>"},配合语义化 HTTP 状态码:400业务参数错(如验证码不对)401未认证 / token 无效或过期 / 用户被禁(响应头带WWW-Authenticate: Bearer)403账号被禁用422请求体字段校验失败(FastAPI 自动校验,如手机号格式)429触发限流(短信发送过频)502上游调用失败(极光验证/解密失败、美团接口失败)
- 接口文档(交互式):
APP_ENV非 prod 时开放GET /docs(Swagger UI)、GET /redoc;生产环境关闭。
游标分页约定
钱包流水 / 提现单 / 省钱明细等列表接口统一用游标分页:
- 请求 query:
limit(每页条数,1–100,默认 20)、cursor(上一页返回的next_cursor,首页不传)。 - 响应:
{ "items": [...], "next_cursor": <int|null> }。next_cursor为末条记录的 id;为null表示已到底,无更多数据。 items按id倒序(最新在前)。
复用数据结构
TokenPair
| 字段 | 类型 | 说明 |
|---|---|---|
access_token |
string | 访问令牌,之后每个鉴权请求带 Authorization: Bearer <它> |
refresh_token |
string | 刷新令牌 |
token_type |
string | 固定 "Bearer" |
expires_in |
int | access 剩余秒数(默认 7200 = 2h) |
refresh_expires_in |
int | refresh 剩余秒数(默认 2592000 = 30d) |
TokenWithUser
继承 TokenPair 全部字段,额外多一个 user(UserOut)。登录类接口成功时返回此结构。
UserOut
| 字段 | 类型 | 说明 |
|---|---|---|
id |
int | 用户主键 |
phone |
string | 手机号(注销账号后变 deleted_<id> 占位释放唯一约束) |
nickname |
string | null | 昵称,经 PATCH /api/v1/user/profile 修改 |
avatar_url |
string | null | 头像相对 URL(/media/avatars/...),经 POST /api/v1/user/avatar 上传 |
register_channel |
string | 注册渠道:jverify / sms |
status |
string | active / disabled / deleted |
created_at |
datetime | 注册时间 |
last_login_at |
datetime | 最近登录时间 |
CouponCard(券卡片,coupons 与 feed 的 items 元素)
| 字段 | 类型 | 说明 |
|---|---|---|
product_view_sign |
string | 换链主键(传给 referral-link) |
platform |
int | 1=外卖/到家, 2=到店 |
biz_line |
int | null | 到店子类:1到餐 2到综 3酒店 4门票 |
name |
string | 商品名 |
head_image_url |
string | 头图;后端已统一拼缩放参数 @375w_375h_1e_1c.webp(美团 CDN 服务端缩到 124dp + 转 WebP,实测省 76–99%),客户端直接用 |
brand_name |
string | null | 品牌名 |
brand_logo_url |
string | null | 品牌 logo |
sell_price |
string | 现价 |
original_price |
string | 原价 |
discount_amount |
string | 优惠额 = 原价 − 现价 |
commission_rate |
string | 佣金比例,如 "1.4%" |
commission_amount |
string | null | 预估佣金(元) |
sale_volume |
string | null | 销量 |
poi_name |
string | null | 最近门店名 |
distance_text |
string | null | 格式化距离,如 "600m" / "1.5km" |
distance_meters |
float | null | 原始距离(米) |
available_poi_num |
int | null | 可用门店数 |
coupon_num |
int | null | 券张数 |
valid_days |
int | null | 券有效天数 |
price_label |
string | null | 如 "15天低价" |
rank_label |
string | null | 如 "2小时北京外卖销量榜第1名" |
rating_label |
string | null | 如 "4.6分" |
/media 静态服务
用户上传文件(头像/反馈截图)落盘到 settings.MEDIA_ROOT(默认 ./data/media/),由 FastAPI 的 StaticFiles 挂在 settings.MEDIA_URL_PREFIX(默认 /media)对外暴露:
GET /media/avatars/<file>— 用户头像(JPEG/PNG/WebP)GET /media/feedback/<file>— 反馈截图(同上)
生产建议:由 nginx 直接 serve MEDIA_ROOT 目录,绕过应用进程减少压力。
URL 格式:服务端返回相对路径(如 /media/avatars/u1_a4f2b3c8e9d2e0a1.jpg),客户端按自己的 BASE_URL 拼绝对地址——dev 下可能是 10.0.2.2/LAN IP/127.0.0.1,服务端不知道客户端怎么访问到自己。
文件名服务端随机生成 u<user_id>_<16 位 hex>.<ext>,杜绝路径穿越与覆盖。
附:鉴权与刷新机制
- 签发:登录成功后签发 access(HS256,2h) + refresh(30d),payload 含
sub(user_id)、typ(access/refresh)、iat、exp。 - 携带:客户端对需鉴权接口自动加
Authorization: Bearer <access>(登录类接口跳过)。 - 校验(
/me、/logout):验签 → 验过期 → 验typ=access→ 查库确认用户存在且status=active,任一不过 → 401。 - 续期:access 过期触发 401 → 客户端用 refresh 调
/refresh换新 token 对并重放原请求;refresh 也失效 → 清本地、跳登录。 - 无状态:token 不落库,服务端无法主动吊销(logout 为占位),靠短 access 有效期限制泄露风险。JWT 密钥
JWT_SECRET_KEY必须为高熵随机串(生产严禁用默认值)。