5.7 KiB
5.7 KiB
R1 商品目录动态化(feat/r1-catalog)
Goal: 让首页、商品列表、沉浸式详情、商品详情四个页面改从后端商品/分类 API 取数,
前端不再直接依赖静态 productConfig.ts 作为线上数据源。
Architecture: 前端新增按域的 api/product.ts 与页面级加载状态;后端扩展 Product 表字段、
补齐 products/categories 查询能力、写入 5 个真实品类 seed;前后端通过 docs/api-contract-v1.md
冻结响应结构;静态 productConfig.ts 降级为离线兜底与图标映射,R1 合并验证前不删除。
Tech Stack: Taro 3.6 + React 18 + TypeScript;NestJS 11 + Prisma/PostgreSQL。
1. 本分支要开发的内容
前端 wechat_wc
| 文件 | 职责 |
|---|---|
src/types/index.ts 或 src/types/product.ts |
ProductCategory 与后端字段对齐,新增 subtitle/tone/story/scene/tags/specs/mask/originalPrice/leadTime/status |
src/utils/api/product.ts |
fetchProducts(params)、fetchProduct(id)、fetchCategories(),返回类型显式声明 |
src/hooks/useProducts.ts(新增) |
商品列表/详情加载、loading/error/retry、可选 60s 内存缓存 |
src/pages/index/index.tsx |
品类网格与搜索改走 API;成品轮播仍可静态,但价格/图片建议取商品数据 |
src/pages/shop/index.tsx |
商品网格改走 API,补加载骨架、空态、失败重试 |
src/pages/shop/detail/index.tsx |
按 id 拉详情,补 loading/error,保留沉浸式滚动动画 |
src/pages/product/index.tsx |
按 id 拉详情,addDesign 继续复用 store/design.ts |
src/utils/productConfig.ts |
保留为 seed 参考与离线兜底,不参与线上主流程 |
后端 wxmp_backend
| 模块 | 内容 |
|---|---|
prisma/schema.prisma |
Product 增加 subtitle/leadTime/originalPrice/tone/tags/specs/mask/story/scene/iconImg,其中 tone Int[]、specs Json、mask Json、tags String[] |
prisma/seed.ts |
写入 5 个真实品类(笔记本小/大、杯垫、笔盒、书灯),图片用 OSS URL,mask 与前端现有一致 |
products |
GET /api/products:分页、categoryId、keyword、status=ON_SALE;GET /api/products/:id:404 处理 |
categories |
GET /api/categories:稳定排序返回,暂做扁平结构 |
docs/api-contract-v1.md |
商品/分类接口、分页结构、Decimal 数字格式、错误码 |
词云项目 wordcloud
不参与本分支。
2. 设计注意事项
DO
- DO 前端只消费后端返回的
price,下单链路以后也不允许前端自算金额。 - DO 在 API 层把 Decimal 字符串规范成本地
number,页面组件里不做字符串拼接运算。 - DO 所有列表/详情页补齐 loading、空态、失败重试,失败时给出可操作文案。
- DO 图片加载失败使用
product.iconImg或四角星.svg兜底,单张图失败不阻塞页面。 - DO
mask、specs、tone等富字段作为后端 JSON 返回,前端类型用判别联合描述。 - DO 后端 seed 和前端
productConfig.ts使用同一套稳定的业务 ID(如notebook-small),方便前后端联调。 - DO 在 R1 分支内同步更新前端
types与 Swagger 文档,一个 PR 成对评审。 - DO 商品列表接口先给分页参数,前端第一版可以每次取全部,但接口结构要能扩展。
- DO 公共接口统一
auth:false,不要携带 token。 - DO 保持项目事件规范:所有点击使用
onTap,不使用onClick。
DON'T
- DON'T 直接删除
productConfig.ts,R1 合并前它仍是离线兜底和图标映射来源。 - DON'T 在页面里直接写
http.get('/api/products'),必须收口到api/product.ts。 - DON'T 在前端硬编码新的图片 CDN 地址,继续走
assetUrl与OSS_BASE_URL。 - DON'T 让前端根据
originalPrice自行计算促销逻辑,促销后续由后端字段统一表达。 - DON'T 依赖数据库插入顺序,列表必须有
sort/createdAt稳定排序。 - DON'T 在 seed 中用随机 cuid 造成不同环境商品 ID 漂移。
- DON'T 在 R1 里顺手改主题、TabBar、DIY 等无关文件。
- DON'T 把
description塞进 JSON 大字段混用,普通段落继续用字符串字段。
3. 补充内容(用户未列但建议纳入)
验收标准
- 前后端本地联调:首页/商品列表/沉浸式详情/商品详情四个页面数据来自 API,静态配置失效时页面有兜底而不会白屏。
- 后端
npm run build、前端npm run build:weapp通过。 - Swagger 中商品列表/详情/分类文档完整;前端类型与 Swagger 字段一一对应。
- seed 后数据库包含 5 个在售品类,图片 URL 可访问。
合并与依赖
- 分支名:前端与后端均为
feat/r1-catalog。 - 合并顺序:R1 是整个交易链路的前提,优先合入;R3 的服务端金额重算依赖本分支的商品表。
- 合入前跑一次后端接口 smoke:
GET /api/categories、GET /api/products、GET /api/products/:id。
风险
- OSS 图片域名若未配到微信后台
downloadFile合法域名,商品图会在真机白图,联调时先确认。 tone、mask等富字段若后端 JSON 序列化方式不统一,前端类型会悄悄失效,合入前要跑真实返回样例。- 首页成品轮播目前混用静态文案与商品数据,R1 建议只把“热门品类”切 API,轮播数据源单独决策。
测试要求
- 后端:至少补 products/categories 的 e2e(正常列表、空列表、404、keyword 过滤)。
- 前端:三个页面手测加载态、断网重试、空数据、关键词搜索无结果、图片 404 兜底。
- 不需要在 R1 引入自动化 UI 测试,保持手测清单即可。