改动:新增厂商推送配置、设备 push_vendor/push_token 字段、device push-test 接口、心跳超时厂商直推发送逻辑和对应测试。 验证:python -m pytest tests/test_device_push.py tests/test_auth.py tests/test_health.py 通过。 --------- Co-authored-by: guke <guke@wonderable.ai> Co-authored-by: 左辰勇 <exinglang@gmail.com> Co-authored-by: lowmaster-chen <1119780489@qq.com> Reviewed-on: #118 Co-authored-by: Ghost <> Co-committed-by: Ghost <>
傻瓜比价 App 后端 — API 接口文档(索引)
Base URL:生产
https://app-api.shaguabijia.com;本地联调http://<开发机>:8770协议:HTTP / JSON,请求与响应体均application/json,字段统一 snake_case(⚠️ 例外:消息通知中心notifications族与厂商推送push族按 PRD 前端契约用 camelCase,见各自文档) 鉴权:需鉴权的接口在请求头带Authorization: Bearer <access_token><<<<<<< HEAD 最后更新:2026-07-14(新增 消息通知中心 3 端点(M1-M3,虚拟数据阶段)与 厂商推送测试 3 端点(P1-P3,荣耀/华为/小米/OPPO/vivo);上一次 2026-06-23 补全 device/internal/CPS 短链等整族端点) ======= 最后更新:2026-07-09(① 比价透传改「软鉴权 + trace_id 签发 + harvest 落库」(#112 尾声帧trace/epilogue一并补录);② 新端点:user/onboarding/reset(#114)、GET /internal/launch-confirm-samples(#91);③ 参数更新:提现族source分账(#82/#121)、wallet/account邀请奖励金余额、美团 feed/top-sales 按城市过滤(#116)、admin 调现金account目标账户(#95);④ Admin 索引补全到当前全量:新家族 roles(#117/#126)/coupon-data(#99)/device-liveness(#80)/event-logs(#83)/price-reports(#94)/CPS 运营台/提现审核族,及 feedbacks 采纳拒绝(#94/#105)、marquee 模式与真实条浏览(#122/#123)等。上一次 2026-07-03)origin/main 架构:
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 |
无 | 详情(rec tab 离线库 + 按城市过滤 #116) |
| 11 | POST /api/v1/meituan/referral-link |
无 | 详情 |
| 11a | POST /api/v1/meituan/top-sales |
无 | 详情(同城销量榜:离线库按销量降序 + 跨源去重 + 城市过滤 #116,不实时打美团) |
比价透传(前缀 /api/v1,透传 pricebot-backend;软鉴权 OptionalUser + 首帧签发 trace_id + harvest 落 comparison_record,2026-07 起不再是纯透传) |
|||
| 12 | POST /api/v1/intent/recognize |
软 | 详情(Phase 1 意图识别,单次,多数源;mint 帧建 running 行) |
| 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 步进;done 帧 harvest 写终态) |
| 13a | POST /api/v1/trace/finalize |
软 | 详情(比价 trace 收尾上云 + 夭折落库,终止/未识别拿 trace_url) |
| 13b | POST /api/v1/trace/epilogue |
软 | 详情(结果页尾声帧:App 结果页截图入 trace,纯透传不落库,#112) |
比价记录(前缀 /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;绑定注册即生效但不发奖,#113 起好友「比价并下单」才给邀请人发邀请奖励金,经 POST /order/report 触发) |
|||
| 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 | 详情(source 分账:coin_cash / invite_cash,#121) |
| 23 | GET /api/v1/wallet/withdraw/status |
Bearer | 详情 |
| 24 | GET /api/v1/wallet/withdraw-orders |
Bearer | 详情(可按 source 过滤) |
| 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 | 详情 |
任务(前缀 /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 | 详情 |
| 33a | GET /api/v1/ad/reward-result/{ad_session_id} |
Bearer | 详情(本次实发金币 + 本轮膨胀累计 round_coin,弹窗数字用它) |
| 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 删记录即触发重走) |
| 36c | POST /api/v1/user/onboarding/reset |
Bearer | 详情(重置本设备引导标记,下次登录重走,#114) |
| 37 | DELETE /api/v1/user |
Bearer | 详情 |
帮助与反馈(前缀 /api/v1/feedback) |
|||
| <<<<<<< HEAD | |||
| 38 | POST /api/v1/feedback |
Bearer | 详情 |
| 38a | GET /api/v1/feedback/config |
Bearer | 反馈页「加群二维码」卡配置(开关 + 二维码图 + 三行文案)(无单独文档) |
| 38b | GET /api/v1/feedback/records |
Bearer | 我的反馈历史(pending/adopted/rejected)(无单独文档) |
消息通知中心(前缀 /api/v1/notifications;⚠️ 本族对外 camelCase;虚拟数据阶段:内存 mock,重启复位) |
|||
| M1 | GET /api/v1/notifications |
Bearer | 详情(消息列表,分页;13 类型卡片字段 + sentAt/isRead;服务端已按时间倒序排好,不分组) |
| M2 | GET /api/v1/notifications/unread-count |
Bearer | 详情(未读总数,首页铃铛角标;>99 → "99+",0 → null 隐藏) |
| M3 | POST /api/v1/notifications/read |
Bearer | 详情(标记已读:{ids:[...]} 单条/多条 或 {all:true} 进通知中心全量清零;幂等) |
厂商推送测试(前缀 /api/v1/push;荣耀/华为/小米/OPPO/vivo 五通道联调三件套,同为 camelCase) |
|||
| P1 | GET /api/v1/push/vendors |
Bearer | 详情(5 厂商服务端凭据配置状态,缺哪些 .env 键一目了然) |
| P2 | GET /api/v1/push/templates |
Bearer | 详情(13 类通知的 push 标题/正文模板 + PRD 示例渲染效果) |
| P3 | POST /api/v1/push/test |
Bearer | 详情(测试发送:默认 mock 不真发;mock=false 真发;可联动插一条站内 mock 通知闭环验证已读) |
=======
| 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元) |
origin/main | 首页门面数据 / 客户端配置(前缀
/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 比) | | 40d |GET /api/v1/platform/huawei-review| 无 | 详情(华为审核开关:快速设置权限步能否被用户关闭;仅华为 ROM 客户端拉) | | 微信支付回调(前缀/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| 无 | 详情(微信网页授权回调;upsertcps_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) | | N7 |GET /internal/launch-confirm-samples| 内部密钥 | 详情(样本列表,供 pricebot distill 脚本聚合沉淀回静态规则,#91) | | 静态资源(StaticFiles 挂载,见下方/media静态服务) ||| | - |GET /media/avatars/<file>| 无 | 用户头像;返回二进制图片 | | - |GET /media/feedback/<file>| 无 | 反馈截图;返回二进制图片 | | 运营后台 Admin(独立子应用app/admin/,前缀/admin/api,独立进程 + 独立 admin JWT。鉴权列:admin=任意已登录管理员,operator/finance/super_admin=需对应角色;#117 起可见页由 admin_role 数据驱动,super_admin恒通过) ||| | A1 |POST /admin/api/auth/login·GET /auth/me| 无 / admin | 详情 / me(me 返回有效可见页pages) | | A2 |GET /admin/api/stats/overview| admin | 详情(大盘核心指标;#103 按 trace 聚合 + 京东收益 #90 + feed_scene 口径 #125) | | A3 |GET /admin/api/event-logs| admin | 详情(埋点日志检索,#83) | | A·用户:GET /users(筛选排序分页)、GET /users/{id}(360 详情)、GET /{id}/reward-stats+GET /{id}/coin-records(提现详情联查)、POST /{id}/status(封禁)、POST /{id}/debug-trace(调试链接权限)、POST /{id}/coins、POST /{id}/cash(#95account目标账户) ||| 列表 / 详情 / 状态+debug-trace / 金币 / 现金 | | A4 |GET /admin/api/wallet/coin-transactions/cash-transactions| admin | 金币 / 现金 | | A·提现审核台:GET /withdraws(列表)、/summary、/health-check(finance)、/ledger-check(#121 分账对账)、/{out_bill_no}(详情)、POST /reconcile、单笔refresh/approve/reject、批量bulk/refresh/bulk/approve/bulk/reject||| 列表 / 审核族 / 对账 / 查单 | | A·反馈:GET /feedbacks、/summary、POST /{id}/approve(采纳发币 #94)、/{id}/reject、/{id}/handle||| 列表 / 审核族 | | A5 |GET/PATCH/admin/api/feedback-config,POST/DELETE…/image| operator | 反馈页「加群二维码」卡配置(admin 侧;C 端读见 38a)(无单独文档,见app/admin/routers/feedback_qr.py) | | A·上报更低价:GET /price-reports、/summary、POST /{id}/approve|reject(#94) ||| 审核族 | | A6 |GET /admin/api/comparison-records(+/{id}详情) | admin | 比价记录检索(按 user/phone/店与商品名模糊搜 #117 筛;详情含 LLM 调用明细)(无单独文档,见app/admin/routers/comparison.py) | | A7 |GET /admin/api/coupon-data(+/user-records) | admin | 详情(领券数据看板,#99) | | A8 |GET /admin/api/device-liveness(+/stats) | admin | 详情(设备存活监控,#80) | | A9 |GET /onboarding/devices、POST /devices/{id}/reset、POST /reset-all| operator | 新手引导记录管理(按设备聚合/重置)(无单独文档,见app/admin/routers/onboarding.py) | | A·轮播:GET /marquee-seeds、/preview、/real-records(#123)、GET/PATCH/mode(#122,模式落app_config)、POST(+/bulk、/batch-delete、/batch-enable)、PATCH/DELETE/{seed_id}||| 详情 | | A10 |GET / PATCH /admin/api/dashboard-display| admin / operator | 详情(首页三统计配置) | | A11 |GET /admin/api/ad-coin-audit| admin | 详情(看广告金币公式复算对账,只读) | | A12 |GET /admin/api/ad-revenue-report| admin | 详情(广告收益报表:分页/场景/app_env筛 + DAU/ARPU #120;真实收益侧接穿山甲日表 #92) | | A13 |GET / PATCH /admin/api/ad-config| operator/finance | 广告配置(穿山甲 ID/验签密钥/各场景开关;C 端只读版见 40b)(无单独文档,见app/admin/routers/ad_config.py) | | A14 |GET /admin/api/config、PATCH /config/{key}| operator/finance | 运营可配置项(app_config:奖励常量/提现地板价等;#117 修系统配置下发)(无单独文档,见app/admin/routers/config.py) | | A16 |GET / PATCH /admin/api/huawei-review| operator/tech | 华为审核开关(快速设置权限步能否被用户关闭,落app_config.huawei_review;C 端只读版见 40d)(无单独文档,见app/admin/routers/huawei_review.py) | | A·管理员与角色(super_admin):GET/POST/admins、PATCH/DELETE/admins/{id}(#126 删除+pages_override)、GET/POST/roles、GET /roles/catalog、PATCH/DELETE/roles/{id}(#117/#126 自定义角色) ||| 列表 / 建 / 改+删 / 角色 | | A15 |GET /admin/api/audit-logs| admin | 详情 | | A·CPS 运营台:群/活动 CRUD、POST /referral-links、POST /orders/reconcile(美团+京东 #90)、GET /orders、/stats、群timeseries/daily/wx-users/day-users(#79) ||| 详情 | | - |GET /admin/api/health| 无 | admin 健康检查(无单独文档) |
⚠️ 美团三个接口当前无鉴权,且
referral-link的sid允许客户端传值覆盖默认渠道——见各接口"备注"。coupon/step透传到 pricebot-backend,仍不鉴权(device_id 区分设备,待补 JWT)。外卖比价透传族(intent/*、price/step、trace/finalize|epilogue)2026-07 起改软鉴权 OptionalUser:带 Bearer 则比价记录绑user_id,不带也放行;并由 app-server 首帧签发trace_id+ harvest 落comparison_record(见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必须为高熵随机串(生产严禁用默认值)。