Files
shaguabijia-app-server/docs/api/README.md
T
ouzhou da7ce69494 feat(ad): eCPM 上报接口 + 冷却策略解耦纯函数 + savings JSONB 跨库修复 (#8)
- 新增 POST /api/v1/ad/ecpm-report:激励视频展示后客户端上报本次 eCPM,落 ad_ecpm_record 做内部收益统计(model/repository/schema/alembic 迁移 + 接口文档)
- 看广告冷却策略抽到 app/core/ad_cooldown.py 纯函数;ad_reward.today_status 只取数据,换策略只改这一处
- savings.dishes 改 JSON().with_variant(JSONB,"postgresql"):SQLite 无 visit_JSONB 会让 create_all 编译崩,修复后测试套件恢复

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: OuYingJun1024 <1034284404@qq.com>
Reviewed-on: #8
Co-authored-by: ouzhou <ouzhou@wonderable.ai>
Co-committed-by: ouzhou <ouzhou@wonderable.ai>
2026-06-01 22:23:15 +08:00

11 KiB
Raw Blame History

傻瓜比价 App 后端 — API 接口文档(索引)

Base URL:生产 https://app-api.shaguabijia.com;本地联调 http://<开发机>:8770 协议:HTTP / JSON,请求与响应体均 application/json,字段统一 snake_case 鉴权:需鉴权的接口在请求头带 Authorization: Bearer <access_token> 最后更新:2026-05-31+ 比价战绩里程碑 12d/12e 架构: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 详情
9 POST /api/v1/meituan/coupons 详情
10 POST /api/v1/meituan/feed 详情
11 POST /api/v1/meituan/referral-link 详情
比价透传(前缀 /api/v1,外卖 MVP;与 coupon/step 同为透传 pricebot-backend
12 POST /api/v1/intent/recognize 详情
13 POST /api/v1/price/step 详情
比价记录(前缀 /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 详情
比价战绩里程碑(前缀 /api/v1/compare;福利页「记录比价战绩」,按成功比价数解锁逐档发金币)
12d GET /api/v1/compare/milestones Bearer 详情
12e POST /api/v1/compare/milestones/{milestone}/claim Bearer 详情
钱包 / 我的资产(前缀 /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 详情
签到(前缀 /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 详情
34 POST /api/v1/ad/test-grant Bearer 详情
35 POST /api/v1/ad/ecpm-report Bearer 详情
用户资料(前缀 /api/v1/user
35 PATCH /api/v1/user/profile Bearer 详情
36 POST /api/v1/user/avatar Bearer 详情
37 DELETE /api/v1/user Bearer 详情
帮助与反馈(前缀 /api/v1/feedback
38 POST /api/v1/feedback Bearer 详情
静态资源StaticFiles 挂载,见下方 /media 静态服务)
- GET /media/avatars/<file> 用户头像;返回二进制图片
- GET /media/feedback/<file> 反馈截图;返回二进制图片

⚠️ 美团三个接口当前无鉴权,且 referral-linksid 允许客户端传值覆盖默认渠道——见各接口"备注"。 coupon/step 及外卖比价的 intent/recognize / price/step 都透传到 pricebot-backend,MVP 阶段均不鉴权(device_id 透传,待补 JWT——见各接口详情)。 福利相关业务接口(wallet/signin/tasks/savings、ad/reward-status)均需 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 /docsSwagger UI)、GET /redoc;生产环境关闭。

游标分页约定

钱包流水 / 提现单 / 省钱明细等列表接口统一用游标分页:

  • 请求 query:limit(每页条数,1100,默认 20)、cursor(上一页返回的 next_cursor,首页不传)。
  • 响应:{ "items": [...], "next_cursor": <int|null> }next_cursor末条记录的 id;为 null 表示已到底,无更多数据。
  • itemsid 倒序(最新在前)。

复用数据结构

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 全部字段,额外多一个 userUserOut)。登录类接口成功时返回此结构。

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(券卡片,couponsfeeditems 元素)

字段 类型 说明
product_view_sign string 换链主键(传给 referral-link
platform int 1=外卖/到家, 2=到店
biz_line int | null 到店子类:1到餐 2到综 3酒店 4门票
name string 商品名
head_image_url string 头图
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)、iatexp
  • 携带:客户端对需鉴权接口自动加 Authorization: Bearer <access>(登录类接口跳过)。
  • 校验/me/logout:验签 → 验过期 → 验 typ=access → 查库确认用户存在且 status=active,任一不过 → 401。
  • 续期:access 过期触发 401 → 客户端用 refresh 调 /refresh 换新 token 对并重放原请求;refresh 也失效 → 清本地、跳登录。
  • 无状态:token 不落库,服务端无法主动吊销(logout 为占位),靠短 access 有效期限制泄露风险。JWT 密钥 JWT_SECRET_KEY 必须为高熵随机串(生产严禁用默认值)。