docs(r2): 写入 WCD 格式硬性规定并在阶段3/4 插入对应注意事项
依据 design-data-contract-v1.md 冻结版:designData 顶层 7 键白名单、 category.mask 必须保留、rotation/zIndex 本期持久化、贴纸 wxfile:// 允许暂存、 wordcloud 分组不得被 items 全量替换冲掉;阶段3 三个写入点与阶段4 缓存回写 各自插入红线提醒。 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+35
-3
@@ -42,6 +42,36 @@
|
||||
`productId` R2 不做存在性校验(R1 商品表可能未 seed);手机号只做非空字符串校验;
|
||||
越权 403 / 不存在 404(契约既定)。
|
||||
|
||||
### WCD 格式硬性规定(R2 全程适用,依据 `docs/design-data-contract-v1.md` 冻结版 2026-08-12)
|
||||
|
||||
> R2 是 `designData` 的**生产者**;R4 下单后把它打成 `.wcd` 包(Zip:`manifest.json` +
|
||||
> `document.json` + `assets/`)投递给词云平台还原整套画布。还原依赖三样东西全部在
|
||||
> designData 里:① 画布尺寸 ← `category.mask`;② 贴纸布局 ← `stickers[]`
|
||||
> (x/y/scale/width/height/rotation/zIndex);③ 贴纸图片字节 ← 每个贴纸的**持久 URL**。
|
||||
> R2 保存的每一份 designData 都要为这三样负责,否则 R4 打包直接失败或画布走样。
|
||||
|
||||
**结构规定(后端白名单已按此实现):**
|
||||
|
||||
1. designData 顶层只允许 **7 个键**:`version` / `category` / `background` / `wordcloud` /
|
||||
`stickers` / `imageSrc` / `imagePos`(后两个为旧版兼容)。多余顶层键 → 后端 400
|
||||
(forbidNonWhitelisted + service 白名单双重拦截)。
|
||||
2. `category` 只提交 `{ id, mask, tone? }`(阶段0 决策#2)。`mask` 是 WCD 画布尺寸来源,
|
||||
**禁止裁掉**——缺 mask 的数据 WCD 只能按产品默认尺寸兜底,画布会走样(契约约束#3)。
|
||||
3. `stickers[]` 内字段后端不深校验、原样透传。其中 `rotation` / `zIndex` 本期必须随 DIY
|
||||
保存持久化(契约决策#2 冻结,WCD 按 zIndex 排图层,约束#4;前端类型已具备);
|
||||
`edits`(brightness/hue/contrast/sketchSrc)同样透传,虽然本期不进 WCD document.json。
|
||||
4. 贴纸 `src` 允许暂存 `wxfile://` / `tmp` 本地路径——契约约束#1 明确允许
|
||||
(R4 在下单/派单前上传 COS 并回写 src)。**R2 任何环节禁止把它当脏数据清洗掉**。
|
||||
5. `wordcloud` 分组由 R4 词云生成后写入,R2 任何写入路径**不得丢弃**(约束#2):
|
||||
后端 PATCH 已做部分更新语义(不传 items 不清 designData);但前端 `updateDesign`
|
||||
是 items 全量替换——页面必须基于服务端最新 designData 合并改动后再整包提交。
|
||||
6. 状态机不受本契约影响:`ordered` 仍由 `orderId != null` 派生,前端只读(约束#6)。
|
||||
|
||||
**边界(本期不做,契约 §4):** 贴纸 edits/线稿不进 WCD `document.json`(仅记 `manifest.meta`);
|
||||
字体不随包携带;`.wcd` 只做「订单 → 词云平台」单向投递。
|
||||
|
||||
**涉及阶段:** 阶段 3(三个写入点)、阶段 4(缓存回写),注意事项已插入下文对应位置。
|
||||
|
||||
## 二、工作流程(按顺序)
|
||||
|
||||
### 原阶段 0 任务清单(存档)
|
||||
@@ -102,15 +132,17 @@
|
||||
|---|---|
|
||||
| `pages/address/index.tsx` | 增删改查、设默认全部走 API;401 由 request 层统一抛出并引导登录;API 失败降级读本地缓存并提示 |
|
||||
| `pages/designList/index.tsx` | 列表/筛选/批量删除走 API;状态筛选基于服务端返回的 `status` 计算,消灭魔法字符串 |
|
||||
| `pages/product/index.tsx`(加入清单) | `addDesign` 写 API(需登录),失败降级本地 |
|
||||
| `pages/diy/index.tsx`(保存 designData) | `updateDesign` 走 API;`designData.category` 裁剪为 `{id, mask, tone}`(决策#2);贴纸本地图路径允许暂存(R4 派单前才持久化,契约约束 #1) |
|
||||
| `pages/diy/stickerEdit/index.tsx` | 同上,保存贴纸改动走 API |
|
||||
| `pages/product/index.tsx`(加入清单) | `addDesign` 写 API(需登录),失败降级本地。此时尚无 designData,创建后保持 DRAFT |
|
||||
| `pages/diy/index.tsx`(保存 designData) | `updateDesign` 走 API;`designData.category` 裁剪为 `{id, mask, tone}`(决策#2);贴纸本地图路径允许暂存(R4 派单前才持久化,契约约束 #1)。**WCD 红线**:`category.mask` 必须保留;`stickers[].rotation/zIndex` 随保存持久化;items 是全量替换——提交前必须基于服务端最新 designData(含 R4 写入的 `wordcloud` 分组)合并改动后整包提交,不得只传改动片段(见「WCD 格式硬性规定」) |
|
||||
| `pages/diy/stickerEdit/index.tsx` | 同上,保存贴纸改动走 API;同样受 WCD 红线约束(合并后整包提交,rotation/zIndex 带全) |
|
||||
|
||||
### 阶段 4:本地 store 降级改造
|
||||
|
||||
`utils/store/address.ts`、`design.ts` 保留,但语义变为"离线兜底缓存":
|
||||
|
||||
- API 成功 → 把服务端数据写回本地缓存(下次冷启动先展示缓存再刷新);
|
||||
**designData 原样存储**:不得清洗 `wxfile://` 等本地贴纸路径、不得裁剪任何字段
|
||||
(WCD 硬性规定 #4/#5);
|
||||
- API 失败/断网 → 页面读缓存并可正常浏览,写操作提示失败;
|
||||
- 登录后首次进入:只读服务端,**不自动合并**本地旧数据(`smart_design_list_<openid>`
|
||||
与服务端并存的问题按路线文档风险节处理:忽略或提供一次性导入,默认忽略)。
|
||||
|
||||
Reference in New Issue
Block a user