125 lines
6.5 KiB
Markdown
125 lines
6.5 KiB
Markdown
# R2 收货地址 + 设计清单(feat/r2-address-design)
|
||
|
||
**Goal:** 把收货地址和设计清单从本地 Storage 切换到后端 CRUD,完成字段契约、接口权限、
|
||
默认地址事务、设计数据 JSON 与状态映射,让 R3 的订单闭环可以直接消费这两组能力。
|
||
|
||
**Architecture:** 前端 `api/address.ts`、`api/design.ts` 负责 HTTP 契约,本地
|
||
`store/address.ts`、`store/design.ts` 在联调期保留为兜底;后端补齐 addresses 与 design-list
|
||
的完整 CRUD、事务与本人数据校验;`checkout` 页归 R3 所有,R2 只定义接口不修改该页面。
|
||
|
||
**Tech Stack:** Taro 3.6 + React 18 + TypeScript;NestJS 11 + Prisma/PostgreSQL。
|
||
|
||
## 1. 本分支要开发的内容
|
||
|
||
### 前端 `wechat_wc`
|
||
|
||
| 文件 | 职责 |
|
||
|---|---|
|
||
| `src/utils/api/address.ts` | `fetchAddresses/createAddress/updateAddress/deleteAddress/setDefaultAddress`,负责 `region[]` 与 `province/city/district` 双向转换 |
|
||
| `src/utils/api/design.ts` | `fetchDesignList/createDesign/updateDesign/deleteDesigns` |
|
||
| `src/pages/address/index.tsx` | 列表、新增、编辑、删除、设为默认全部走 API;保留表单校验与区域 Picker |
|
||
| `src/pages/designList/index.tsx` | 列表、状态筛选、批量删除走 API;保留 LoginGuard |
|
||
| `src/types/index.ts` | AddressItem/DesignItem 与后端结构对齐,新增服务端 id、状态码、时间字段 |
|
||
| `src/utils/store/address.ts`、`design.ts` | 降级为“本地缓存/离线兜底”,API 调用成功后同步刷新 |
|
||
|
||
### 后端 `wxmp_backend`
|
||
|
||
| 模块 | 内容 |
|
||
|---|---|
|
||
| `addresses` | `GET/POST /api/addresses`、`PATCH /api/addresses/:id`、`PATCH /api/addresses/:id/default`、`DELETE /api/addresses/:id`;全部带 userId 归属校验 |
|
||
| `addresses` 事务 | 设置默认时事务内先清旧默认再设新默认;删除默认地址后自动指定最新一条为默认 |
|
||
| `design-list` | `GET/POST /api/design-list`、`PATCH /api/design-list/:id`、`DELETE /api/design-list/:id`、批量删除 |
|
||
| `design-list` 校验 | `items` JSON 结构与大小校验、状态机转换、本人专属查询 |
|
||
| `docs/api-contract-v1.md` | 地址字段映射、设计清单状态枚举、错误码 |
|
||
|
||
### 词云项目 `wordcloud`
|
||
|
||
不参与本分支,但 `designData` 中的本地贴纸图片路径问题会影响后续 R4,见风险一节。
|
||
|
||
## 2. 状态映射(必须先定死)
|
||
|
||
后端 `DesignListStatus` 目前是 `DRAFT/SUBMITTED/PROCESSING/DONE`,前端是
|
||
`undesigned/designing/ordered`。R2 不要在两边各造一套值,建议按显示语义映射:
|
||
|
||
| 前端显示 | 后端状态 | 前端状态码 |
|
||
|---|---|---|
|
||
| 待设计 | DRAFT | `undesigned` |
|
||
| 设计中 | SUBMITTED | `designing` |
|
||
| 生产中 | PROCESSING | `processing` |
|
||
| 已下单 | DONE | `ordered` |
|
||
|
||
“已下单”不要用独立状态表达,改为 `orderId != null` 派生;前端只显示,不提交这个状态。
|
||
状态码收口到 `docs/api-contract-v1.md`,后端校验状态迁移,前端不传自由字符串。
|
||
|
||
## 3. 字段契约
|
||
|
||
### 地址
|
||
|
||
后端 `province/city/district/detail` 对应前端 `region: [province, city, district] + detail`。
|
||
转换只放在 `api/address.ts`,页面和 store 不得散落第二次转换。
|
||
|
||
### 设计数据
|
||
|
||
`DesignList.items` 是服务端 JSON,前端提交结构建议与当前 `DesignItem.designData` 对齐:
|
||
|
||
```ts
|
||
interface DesignData {
|
||
stickers?: StickerItem[]
|
||
category?: ProductCategory
|
||
imageSrc?: string
|
||
imagePos?: { x: number; y: number; scale: number }
|
||
}
|
||
```
|
||
|
||
服务端只做白名单字段校验,不修改业务 JSON 内容;单条设计数据建议限制在 1MB 以内。
|
||
|
||
## 4. 设计注意事项
|
||
|
||
### DO
|
||
|
||
- DO 地址的增删改查和默认切换全部要求登录态,401 时引导去个人中心登录。
|
||
- DO 所有按 id 操作的服务端路由同时带 `userId` 条件,404 与 403 区分清楚。
|
||
- DO 默认地址切换与删除补偿放在同一个 Prisma transaction 里。
|
||
- DO 前端继续沿用户已熟悉的表单校验,但最终校验提示以后端返回为准。
|
||
- DO 设计清单状态通过后端枚举返回,前端状态筛选基于返回的 `status` 计算。
|
||
- DO 批量删除设计条目提供单个接口或循环调用时保证部分失败可恢复;推荐后端一次批量删除。
|
||
- DO 本地 store 只在 API 失败时做降级读取,成功写回后以服务端数据为准。
|
||
|
||
### DON'T
|
||
|
||
- DON'T 把前端 `region` 数组原样 POST 给后端,后端契约是四个独立地址字段。
|
||
- DON'T 让前端直接写 `isDefault` 的两条规则,默认地址唯一性由后端事务保证。
|
||
- DON'T 在路由/service 层漏掉归属校验;这是本分支最容易出的越权洞。
|
||
- DON'T 新增前端自造状态 `ordered` 之外的字符串,状态值必须在契约文档里可枚举。
|
||
- DON'T 在本分支修改 `checkout/index.tsx`,地址选择器与下单集成留给 R3。
|
||
- DON'T 把 `wxfile://` 临时贴纸路径当作可持久化 URL 直接入库,R4 之前它只是本地预览。
|
||
- DON'T 用设计清单字段承载订单状态,`orderId` 派生展示即可。
|
||
|
||
## 5. 补充内容
|
||
|
||
### 验收标准
|
||
|
||
- 地址页与设计清单页在登录态下增删改查、默认切换、批量删除全部走真实后端并刷新。
|
||
- 后端所有变更接口带本人校验,越权访问返回 403,不存在资源返回 404。
|
||
- 默认地址永远唯一;删除默认地址后列表自动产生新的默认地址。
|
||
- 前端构建与后端构建通过;Swagger 涵盖地址与设计清单全部接口。
|
||
- 状态映射表在 `docs/api-contract-v1.md` 中落地,前端页面不再出现魔法字符串状态。
|
||
|
||
### 合并与依赖
|
||
|
||
- 分支名:前端与后端均为 `feat/r2-address-design`。
|
||
- R2 依赖已有登录体系(已完成),不依赖 R1;可与 R1 并行开发。
|
||
- checkout 对地址 API 的调用在 R3 接入,R2 只需保证接口稳定即可。
|
||
|
||
### 风险
|
||
|
||
- 设计数据中的贴纸是本地临时路径,一旦真机重启或清理缓存,旧设计预览会裂图;在 R4 上传能力完成前,文档明确这是已知限制。
|
||
- 旧版本本地 `smart_design_list_<openid>` 数据与后端数据可能并存,首次切换登录时避免双写冲突;可做一次性“导入本地清单”或直接忽略旧数据。
|
||
- 批量删除接口若后端未实现,前端循环删除会遇到部分失败,联调时先约定失败语义。
|
||
|
||
### 测试要求
|
||
|
||
- 后端:地址 CRUD、默认地址唯一性事务、越权访问、设计清单状态迁移、超大 JSON 拒绝。
|
||
- 前端:地址新增/编辑/删除/默认切换、设计清单筛选/批量删除、断网降级提示、401 引导登录。
|
||
|