Files
wechat_wc/docs/design-data-contract-v1.md
T
lhmin0604andClaude b109451e29 docs(r2): 交接文档复核更新——DIY 修正批次新事实 + 契约核对结论
- README:新增修正批次落地事实(草稿随时 PATCH、SUBMITTED 触发点、
  edits 落库与消费、width/height 语义、x/y 允许超界、onShow 同步通病)、
  契约核对结论与已知偏差(wxfile:// 以冻结决策为准)
- r2-workflow:决策#6 注记 SUBMITTED 触发点提前
- design-data-contract:实现注记明确 x/y 允许超出画布边界(钳制已撤销)

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

6.9 KiB
Raw Blame History

设计数据 → WCD 生产任务契约 v1

跨路线契约:R2(数据生产者)与本路线 R4(WCD 打包消费者)共同遵守。 冻结目的:R4 下单后要把设计清单以 .wcd 包投递到词云平台形成生产任务 (见 docs/routes/route-r4-upload-wordcloud.md §3)。R4 能打包,取决于 R2 保存的 designData 携带哪些字段。本文档把这些字段先定死

版本规则:字段只能新增 optional 字段;改名/改语义/改类型必须升版本并同步本文件。

1. 为什么需要本契约

词云平台用 .wcdZipmanifest.json + document.json + assets/)还原整套画布。 还原需要三样东西全部可用:

  1. 画布尺寸 / 背景 ← 来自 category.mask
  2. 贴纸布局(位置、大小、旋转、层级)← 来自 stickers[]
  3. 贴纸图片字节 ← 来自每个贴纸的持久 URLCOS)。

第 3 点是关键约束:如果贴纸图是 wxfile:///tmp 临时路径,后端打包时下载不到字节, WCD 生产任务直接失败。因此本契约把"图片必须持久化"从 R2 的已知限制升级为冻结约束

2. 冻结的 designData 结构(v1

与现有前端 DesignItem.designData 对齐,保留 imageSrc/imagePos 兼容旧版,新增如下字段:

/** 设计数据 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-12,DIY 修正,非版本升级)stickers[].width/height 的语义为 画布显示像素(坐标空间 = category.mask 的宽高),x/y 使用画布坐标空间 (原点 = mask 左上角;允许超出画布边界——2026-09-12 需求确认:贴纸可拖出画布 自由摆放,渲染端裁切显示,WCD 打包按原值还原,不做钳制)。 渲染、碰撞检测、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 布局字段持久化 决策#2rotation/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.tsDesignItem.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