Files
wxmp_backend/docs/R1-商品目录接口对接说明.md
T

4.2 KiB
Raw Blame History

R1 商品目录接口对接说明

提供方:成员 1R1 商品目录)

消费者:成员 2(设计清单)、成员 3(订单)、成员 4(设计/生产数据)

分支:feat/r1-catalog

本文档是 R1 向其他路线交付商品数据的简明使用说明。字段、路径与 api-contract-v1.md 第 3 节一致;发生冲突时以 API 契约为准。

1. 使用边界

  • 商品与分类查询都是公开接口,调用时必须传 auth: false,不依赖登录态。
  • 消费方只能读取在售商品;下架或不存在的商品详情返回 404
  • productId 是跨路线的稳定业务 ID,不能用数据库生成顺序、数组下标或展示名称替代。
  • price 是服务端权威价格。前端可展示,不能作为下单金额依据。

2. 稳定商品 ID

productId 商品
notebook-small 微雕笔记本(小)
notebook-large 微雕笔记本(大)
coaster 铜质杯垫
penbox 竹制笔盒
booklamp 书本型灯

每个商品都对应一个稳定分类 IDcat-<productId>,例如 cat-penbox

3. 查询接口

GET /api/categories

返回扁平分类数组,已按 sort 升序排列。

type CategoryDTO = {
  id: string
  name: string
  parentId?: string | null
  sort: number
}

GET /api/products

查询参数均可选:

{
  page?: number        // 默认 1
  pageSize?: number    // 默认 20,最大 100
  categoryId?: string
  keyword?: string     // 匹配名称、副标题、描述
}

响应 data

{
  list: ProductDTO[]
  total: number
  page: number
  pageSize: number
}

GET /api/products/:id

返回一个在售商品;商品不存在或不是 ON_SALE 时返回 404

type ProductDTO = {
  id: string
  name: string
  categoryId?: string
  price: number                 // 元,服务端已转为 number
  originalPrice?: number
  leadTime: string
  subtitle?: string
  description?: string
  story?: string
  scene?: string
  tags: string[]
  specs: [string, string][]
  tone: [number, number, number]
  mask: {
    shape: 'rect' | 'circle'
    width: number
    height: number
    borderRadius?: number
  }
  images: string[]
  iconImg?: string
  status: 'ON_SALE'
  sort: number
}

所有接口沿用统一响应包裹:{ code: 0, message: 'ok', data }

4. 前端调用方式

前端消费者统一从 R1 API 层调用,不能在页面直接拼 HTTP 请求:

import { fetchCategories, fetchProduct, fetchProducts } from '../../utils/api/product'

const { list } = await fetchProducts({ keyword: '笔记本', page: 1, pageSize: 20 })
const product = await fetchProduct('penbox')
const categories = await fetchCategories()

5. 给成员 2:设计清单

设计清单保存商品相关数据时使用:

{
  productId: product.id,
  productName: product.name,
  unitPrice: product.price,   // 仅展示/设计清单快照;不是订单结算依据
  count: quantity,
  designData: {
    category: { id: product.id, mask: product.mask, tone: product.tone },
  },
}

masktone 必须原样保留,供 R4 构造生产画布;不要把 productName 当作关联键。

6. 给成员 3:订单

R3 创建订单时,客户端请求只传:

{
  items: [{ productId: 'penbox', quantity: 1 }]
}

R3 服务端必须:

  1. productId 查询商品并确认 status === ON_SALE
  2. 以服务端 price 重算订单总价;
  3. productIdnamepricequantity 写进 OrderItem 快照;
  4. 忽略客户端传入的单价、商品名和总金额。

7. 给成员 4:设计与生产

R4 若需要从商品恢复画布尺寸或主题色,使用 ProductDTO.maskProductDTO.tone。 生产任务内保存的是设计快照;不要仅凭商品名称重新定位商品。

8. 联调前置条件

R1 合入或本地联调前,后端需要先执行数据库迁移与种子数据:

npm run prisma:migrate
npm run prisma:seed

最小 smoke 验收:

GET /api/categories
GET /api/products?page=1&pageSize=20
GET /api/products/penbox
GET /api/products/not-on-sale-or-missing  -> 404