Files
wechat_wc/docs/design-data-contract-v1.md
T
lhmin0604andClaude 395fa4116c docs(r2): 契约核对补充 + design-data-contract 增加 width/height 语义注记
- diy-fix-workflow:新增两份契约逐项核对总表
- design-data-contract-v1:stickers[].width/height/x/y 语义 = 画布显示像素
  (实现注记,非版本升级),历史数据读端按 mask 归一化兼容

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-12 18:53:07 +08:00

126 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 设计数据 → WCD 生产任务契约 v1
> 跨路线契约:**R2(数据生产者)与本路线 R4(WCD 打包消费者)共同遵守**。
> 冻结目的:R4 下单后要把设计清单以 `.wcd` 包投递到词云平台形成生产任务
> (见 `docs/routes/route-r4-upload-wordcloud.md` §3)。R4 能打包,取决于 R2
> 保存的 `designData` 携带哪些字段。本文档把这些字段**先定死**。
>
> 版本规则:字段只能新增 optional 字段;改名/改语义/改类型必须升版本并同步本文件。
## 1. 为什么需要本契约
词云平台用 `.wcd`Zip`manifest.json` + `document.json` + `assets/`)还原整套画布。
还原需要三样东西全部可用:
1. **画布尺寸 / 背景** ← 来自 `category.mask`
2. **贴纸布局**(位置、大小、旋转、层级)← 来自 `stickers[]`
3. **贴纸图片字节** ← 来自每个贴纸的**持久 URL**(COS)。
第 3 点是关键约束:如果贴纸图是 `wxfile://`/`tmp` 临时路径,后端打包时下载不到字节,
WCD 生产任务直接失败。因此本契约把"图片必须持久化"从 R2 的已知限制升级为**冻结约束**。
## 2. 冻结的 `designData` 结构(v1
与现有前端 `DesignItem.designData` 对齐,保留 `imageSrc/imagePos` 兼容旧版,**新增**如下字段:
```ts
/** 设计数据 v1 —— 支持 R4 WCD 生产任务打包 */
interface DesignDataV1 {
/** 结构版本,缺省按 v1 处理;旧数据可由后端/前端按版本迁移 */
version?: 1
/** 商品品类(已有)。mask 是画布尺寸来源,保存清单时必须保留 */
category?: {
id: string
mask: { shape: 'rect' | 'circle'; width: number; height: number; borderRadius?: number }
tone?: [number, number, number]
}
/** 底图(已有 imageSrc 语义的规范化):src 必须是持久 URL */
background?: {
src: string // COS 持久 URL;禁止 wxfile:// / tmp 临时路径
color?: string // 画布底色(缺省由 mask/主题决定)
pos?: { x: number; y: number; scale: number } // 兼容旧 imagePos
}
/**
* 词云信息(R4 在词云生成后写入;R2 保存/更新清单时原样保留这组字段,
* 后端 items JSON 白名单放行)。
*/
wordcloud?: {
jobId?: string // 生成该词云的 wxmp_backend 侧任务 id
imageUrl: string // 词云结果图持久 URL(COS)
names: string[] // 名单快照(≤200),生产/重建用,可为空
}
/** 贴纸列表(已有)。每个贴纸的 src 升级为持久 URL 约束 */
stickers?: Array<{
id: string
src: string // ★ 必须为 COS 持久 URLhttps),禁止 wxfile:// / tmp / 空
x: number
y: number
scale: number
width: number
height: number
rotation?: number // 已冻结(2026-08-12 决策#2):本期 DIY 持久化;无旋转则省略
zIndex?: number // 已冻结(2026-08-12 决策#2):图层顺序;WCD 按 zIndex 排列元素
isOverlapping?: boolean
edits?: {
brightness?: number // -100~100
hue?: number // -180~180
contrast?: number // -100~100
sketchSrc?: string
}
}>
}
```
关系说明:
- `DesignItem.designData`(前端类型文件 `src/types/index.ts`)与后端 `design-list.items[].designData`
(服务端 JSON)为**同一份**结构;前端类型以本契约为准,后端只做白名单校验不改业务 JSON。
- `imageSrc/imagePos` 保留为兼容旧版字段;新写入统一走 `background.src/pos`
WCD 打包器同时兜底读旧字段。
> **实现注记(2026-09-12DIY 修正,非版本升级)**`stickers[].width/height` 的语义为
> **画布显示像素**(坐标空间 = `category.mask` 的宽高),`x/y` 同为画布内坐标。
> 渲染、碰撞检测、WCD 打包三方按同一语义消费,打包时不再做像素换算。
> 历史数据中按「图片原始像素」写入的值(width > mask 宽高)由读取端按 mask 等比归一化兼容,
> 不做存量迁移。`addSticker` 时即归一化到画布空间(建议初始占 mask 短边 60%)。
## 3. 冻结约束(R2 需落地)
| # | 约束 | 说明 |
|---|---|---|
| 1 | **贴纸图持久化(R4 负责)** | 决策#4:**贴纸持久化由 R4 完成**。R2 允许保存/更新清单时贴纸 `src` 暂为本地路径(`wxfile://`/`tmp`);**R4 在下单/派单前**把本地图上传为 COS 持久 URL 并回写 `designData.stickers[].src`。WCD 打包只消费持久 URL。R2 需保证该字段可被 R4 回写 |
| 2 | **词云字段保留** | `designData.wordcloud` 由 R4 写入后,R2 的 PATCH/列表接口不得丢弃该分组 |
| 3 | **mask 必须存在** | `designData.category.mask` 是画布尺寸来源;缺 mask 的旧数据 WCD 打包按产品默认尺寸兜底 |
| 4 | **布局字段持久化** | 决策#2`rotation`/`zIndex` 本期由 DIY 随贴纸持久化(当前 `StickerItem` 缺 rotation,需补) |
| 5 | **白名单放行** | 后端 `design-list` 的 items JSON 白名单放行 `version/background/wordcloud/rotation/zIndex` 字段;单条 ≤1MB 上限以新结构复核(图片在远端 URL,JSON 本体仍应很小) |
| 6 | **状态映射不变** | `ordered` 继续由 `orderId != null` 派生,本契约不改变 R2 状态机 |
## 4. 边界(本期不做)
- 贴纸 `edits`(亮度/色相/对比度/`sketchSrc` 线稿)无法由词云平台 `.wcd`
`document.json` 表达,本期不随 WCD 携带;仅记录在 `manifest.meta`。若后续生产需要
线稿还原,需单独升 WCD 契约(wordcloud 侧支持后再谈)。
- 字体不随包携带(wordcloud 第一阶段不做字体打包)。
- `.wcd` 只做"订单 → wordcloud"单向投递;暂不做"词云平台 → 小程序"的反向导出。
## 5. 落地位置
| 文件 | 内容 |
|---|---|
| 前端类型 | `wechat_wc/src/types/index.ts``DesignItem.designData` 按本契约补齐字段 |
| 前端页面 | `diy`(保存 designData)、`checkout`(下单前确认 designData 完整) |
| 后端白名单 | `wxmp_backend/src/design-list/*` 的 items 校验放行新字段 |
| 契约发行 | `wxmp_backend/docs/api-contract-v1.md` §5 引用本文档 |
## 6. 决策记录(2026-08-12 冻结)
| 评审点 | 决策 |
|---|---|
| 1. `background`/`wordcloud` 命名 | **接受**,按 §2 结构冻结 |
| 2. `rotation`/`zIndex` 是否本期持久化 | **本期持久化**DIY 随贴纸保存(见约束 #4 |
| 3. 名单快照 `wordcloud.names` 是否必须 | **小程序可不必须**`names` 保持 optional,小程序可不带;R4 生成词云后按实际写入,生产侧不强依赖 |
| 4. 贴纸图持久化由谁触发 | **R4 负责**:下单/派单前把本地贴纸图上传为 COS 持久 URL 并回写 `src`(见约束 #1 |