aura-web/docs/points-mall-api.md

8.3 KiB
Raw Blame History

积分商城Points Mall接口需求说明

本文档用于对接 aura-web 的「积分商城」页面数据与兑换流程,供后端实现接口与数据表结构时参考。

页面结构对应的数据

页面 UI 由 4 个区域组成:

  1. 头部商品分类导航栏(横向)
  2. 公告栏
  3. banner 区 + 促销活动入口2 个入口卡片)
  4. 商品内容区(商品列表 + 搜索/排序/分页)

统一约定

  • BaseURLhttps://api.hoyidata.com/aura/v1
  • 鉴权沿用当前登录态Cookie / SessionAuthorization: Bearer <token>(以现有登录实现为准),接口需校验登录态
  • 图片字段:返回绝对 URL推荐 CDN 域名),前端不拼接
  • 时间字段建议统一使用毫秒时间戳number
  • 失败格式:沿用现有 aura 接口的错误格式HTTP Status + JSON message/error
  • GET /points-mall/overview 已废弃HTTP 410前端需按数据维度分别调用 /me、/categories、/announcements、/banners、/promo-entries

接口列表(前端必需)

1) 我的积分

GET /points-mall/me

Response

{
  "points": 1280,
  "level": "Lv.2",
  "totalSpentUSD": 0.174
}

2) 分类

GET /points-mall/categories

Response

[
  { "id": "all", "name": "全部", "sort": 0 },
  { "id": "digital", "name": "虚拟权益", "sort": 1 }
]

3) 公告

GET /points-mall/announcements

Response

[
  {
    "id": "a1",
    "title": "公告:积分规则升级中",
    "content": "本期暂不开放兑换,页面仅用于 UI 预览。",
    "linkUrl": "https://..."
  }
]

4) Banner

GET /points-mall/banners

Response

[
  {
    "id": "b1",
    "title": "限时上新",
    "subtitle": "Up to 25% Off",
    "imageUrl": "https://cdn.../banner.png",
    "linkUrl": "https://..."
  }
]

5) 促销入口

GET /points-mall/promo-entries

Response

[
  {
    "id": "p1",
    "title": "促销活动",
    "subtitle": "本周精选",
    "iconUrl": "https://cdn.../promo.png",
    "linkUrl": "https://..."
  },
  {
    "id": "p2",
    "title": "积分任务",
    "subtitle": "快速涨积分",
    "iconUrl": "https://cdn.../tasks.png",
    "linkUrl": "https://..."
  }
]

6) 商品列表(搜索/筛选/排序/分页)

GET /points-mall/products

Query

  • categoryId:可选(分类 ID不传代表全部
  • q:可选(搜索关键字;匹配 name/subtitle
  • sort:可选,默认 popular
    • popular:热度优先(建议按 sold 或近期兑换量)
    • newest:最新上架
    • price_asc:积分从低到高
    • price_desc:积分从高到低
  • page:可选,默认 1
  • pageSize:可选,默认 24

Response

{
  "page": 1,
  "pageSize": 24,
  "total": 120,
  "items": [
    {
      "id": "prd_001",
      "categoryId": "digital",
      "name": "Claude Pro 月卡",
      "subtitle": "兑换后获得激活码",
      "coverUrl": "https://cdn.../cover.png",
      "pointsPrice": 1999,
      "stock": 99,
      "sold": 12,
      "tags": ["热卖", "限时"]
    }
  ]
}

7) 商品详情

GET /points-mall/products/{productId}

Response建议

{
  "id": "prd_001",
  "categoryId": "digital",
  "name": "Claude Pro 月卡",
  "subtitle": "兑换后获得激活码",
  "coverUrl": "https://cdn.../cover.png",
  "imageUrls": ["https://cdn.../1.png", "https://cdn.../2.png"],
  "pointsPrice": 1999,
  "stock": 99,
  "sold": 12,
  "tags": ["热卖", "限时"],
  "description": "富文本/Markdown 均可,建议 Markdown",
  "type": "virtual",
  "delivery": {
    "mode": "code",
    "tips": "兑换成功后在【订单详情】查看兑换码"
  }
}

8) 创建兑换订单(扣积分)

POST /points-mall/orders

Request

{
  "productId": "prd_001",
  "quantity": 1
}

Response

{
  "orderId": "ord_001",
  "status": "paid",
  "pointsCost": 1999,
  "remainingPoints": 281
}

关键规则

  • 需要幂等:建议支持 Idempotency-Key header避免重复扣积分
  • 校验库存与用户积分
  • 虚拟商品/实物商品可共用该接口,但实物商品需要补充收货信息(可扩展字段)

9) 订单列表 / 订单详情

GET /points-mall/orders

Query建议

  • page / pageSize
  • status:可选

GET /points-mall/orders/{orderId}

Response建议

{
  "id": "ord_001",
  "status": "paid",
  "createdAt": 1730000000000,
  "product": {
    "id": "prd_001",
    "name": "Claude Pro 月卡",
    "coverUrl": "https://cdn.../cover.png"
  },
  "quantity": 1,
  "pointsCost": 1999,
  "delivery": {
    "mode": "code",
    "code": "XXXX-YYYY-ZZZZ"
  }
}

10) 积分流水(可选,但强烈建议)

用于解释积分变动与对账。

GET /points-mall/me/points-ledger

Query建议

  • page / pageSize

Response建议

{
  "page": 1,
  "pageSize": 20,
  "total": 300,
  "items": [
    {
      "id": "pl_001",
      "createdAt": 1730000000000,
      "change": -1999,
      "balance": 281,
      "reason": "兑换 Claude Pro 月卡",
      "bizType": "points_mall_order",
      "bizId": "ord_001"
    }
  ]
}

数据表结构建议(后端实现参考)

说明:下述为建议表结构,字段类型可按现有数据库规范调整;建议均包含 created_at / updated_at 与必要索引。

1) points_mall_categories(分类)

  • idPK, string/uuid
  • namevarchar
  • sortint
  • enabledbool

索引:

  • enabled, sort

2) points_mall_announcements(公告)

  • idPK
  • titlevarchar
  • contenttext
  • link_urlvarchar, nullable
  • start_atbigint, nullable
  • end_atbigint, nullable
  • enabledbool
  • sortint

索引:

  • enabled, sort
  • start_at, end_at

3) points_mall_bannersbanner

  • idPK
  • titlevarchar
  • subtitlevarchar, nullable
  • image_urlvarchar
  • link_urlvarchar, nullable
  • start_atbigint, nullable
  • end_atbigint, nullable
  • enabledbool
  • sortint

索引:

  • enabled, sort
  • start_at, end_at

4) points_mall_promo_entries(促销入口)

  • idPK
  • titlevarchar
  • subtitlevarchar, nullable
  • icon_urlvarchar, nullable
  • link_urlvarchar, nullable
  • enabledbool
  • sortint

索引:

  • enabled, sort

5) points_mall_products(商品)

  • idPK
  • category_idFK -> categories.id
  • namevarchar
  • subtitlevarchar, nullable
  • descriptiontext / markdown
  • cover_urlvarchar
  • image_urlsjson/text数组
  • typeenum: virtual | physical
  • points_priceint
  • stockint
  • soldint累计兑换量或可由订单聚合
  • tagsjson/text数组
  • enabledbool
  • start_atbigint, nullable
  • end_atbigint, nullable
  • sortint

索引:

  • enabled, start_at, end_at
  • category_id, enabled, sort
  • 搜索:name/subtitle 建议全文索引或 LIKE视数据库而定

6) points_mall_orders(订单)

  • idPK
  • user_idFK
  • product_idFK
  • quantityint
  • points_costint
  • statusenum: created | paid | delivered | canceled | refunded
  • delivery_modeenum: code | shipping
  • delivery_payloadjson虚拟码/物流信息等)
  • idempotency_keyvarchar, nullable建议唯一索引 + user_id 组合)

索引:

  • user_id, created_at desc
  • status, created_at desc
  • user_id, idempotency_key(唯一)

7) points_ledger(积分流水)

  • idPK
  • user_idFK
  • changeint正负
  • balanceint
  • reasonvarchar
  • biz_typevarchar
  • biz_idvarchar

索引:

  • user_id, created_at desc
  • biz_type, biz_id

前端实现已对齐的字段

前端已按以下字段读取:

  • 分类:id/name/sort
  • 公告:title/content/linkUrl
  • bannertitle/subtitle/imageUrl/linkUrl
  • 促销入口:title/subtitle/iconUrl/linkUrl
  • 商品列表:id/categoryId/name/subtitle/coverUrl/pointsPrice/stock/sold/tags

如后端字段命名需要用 snake_case可在接口层做映射但建议直接使用上述 camelCase减少前端 mapping。