Files
wechat_wc/docs/r4-delivery-report.md
T

9.8 KiB
Raw Blame History

R4 交付报告(feat/r4-upload-wordcloud

日期:2026-08-13 | 范围:上传 / 词云生成 / 线稿 / 下单后 WCD 生产任务投递 涉及仓库:wechat_wc(小程序前端)、wxmp_backendNestJS 后端)、wordcloudFastAPI 词云平台)


1. 目标与架构

把「用户上传底图 + 名单 → 词云生成 → DIY 贴纸 → 下单」链路中的上传、词云、线稿全部接到真实后端, 并在下单后把订单对应的整套设计以 .wcd 包投递到词云平台形成生产任务

小程序 designData(贴纸持久化为 COS URL
  → POST /api/ordersdesignListId 关联,R3
  → POST /api/orders/:id/dispatch(幂等)
  → WordCloudService.buildWcdPackage(designData) → .wcdZip: manifest.json+document.json+assets/
  → POST {WORDCLOUD_API_URL}/api/jobs  wcd_fileMODE=WCD
  → 词云平台还原设计 + 合成生产 PNG → 后端轮询同步 CustomizationTask/WordCloudJob → 产物转存 COS

小程序只与 wxmp_backend 通信;WORDCLOUD_API_URL 未配置时返回结构化 not_configured,不做假成功。


2. 前端交付(wechat_wc / feat/r4-upload-wordcloud

模块 内容
src/types/index.ts DesignDataV1version/background/wordcloud)、StickerItemrotation/zIndex;新增 WordCloudJob/WordCloudStatus/CosCredentials/SketchResult/WordCloudDispatchStatus/WordCloudDispatchResult
src/utils/api/upload.ts getUploadCredentialsuploadToCos(预签名 PUT 直传)、sketchImagecreateWordCloudJobgetWordCloudJobgetWordCloudResultpersistDesignMedia(贴纸持久化,决策#4)、dispatchOrdermultipart 统一带 Bearer token、解析 {code,message,data} 信封
src/pages/wordcloud/index.tsx 去掉 setInterval+Math.random 假进度 → 真实「上传底图→建任务→轮询→取结果→保存相册」;新增生成失败/未配置提示块
src/pages/diy/stickerEdit/index.tsx your-api-domain.com 占位 → 走 sketchImagePOST /api/sketch),失败仍降级前端灰度
src/pages/diy/index.tsx handleComplete 保存前调用 persistDesignMedia:本地贴纸/底图 → COS 持久 URL 写回 designData
文档 docs/routes/route-r4-upload-wordcloud.mddocs/design-data-contract-v1.mdCLAUDE.md

验证:npm run build:weapp 通过。

3. 后端交付(wxmp_backend / feat/r4-upload-wordcloud

模块 内容
config wordcloud: { apiUrl, timeoutMs } 配置组 + Joi WORDCLOUD_API_URL/WORDCLOUD_TIMEOUT_MS(可选)
cos CosService:预签名 PUT URL 签发、服务端 putObject、公网 URL;未配置 → configured=false
upload GET /api/upload/credentials?key= 返回预签名 URL 并记录 Upload 归属(当前用户)
wordcloud POST /api/wordcloud/generatemultipart image+names → xlsx → 投递 /api/jobs)、GET /api/wordcloud/jobs/:id(归属校验+实时代理轮询)、GET /api/wordcloud/jobs/:id/result
wordcloud 派单 buildWcdPackagedesignData→.wcd,下载素材字节、sha256)、dispatchToWordcloud幂等、未配置→not_configured)、POST /api/orders/:id/dispatch
wordcloud 同步 onModuleInit 后台 30s 轮询进行中任务 → 成功时结果图转存 COS、同步 CustomizationTask→SUCCESS/resultUrl
sketch POST /api/sketchmultipart image,类型/大小校验 ≤10MB)→ 转存 COS 返回 URL
orders OrdersService.create 保存 designList 关联(R3 契约字段)

Prisma 迁移3 个):

迁移 内容
add_word_cloud_job WordCloudJob 模型 + WordCloudJobStatus 枚举
add_remote_job_id WordCloudJob.remoteJobIdwordcloud 外部 job_id
r4_order_design_and_dispatch Order.designListId+DesignList.ordersCustomizationTask.orderId/wordcloudJobId

验证:nest build 通过、prisma validate 通过、迁移已应用。

4. wordcloud 平台交付(wordcloud / feat/r4-wcd-job,仅工作区)

POST /api/jobs 新增可选 wcd_fileMODE=WCD):

  • 校验 format=wordcloud-canvasversion=1;素材按 SHA-256 去重注册(复用 /api/design-templates/import 逻辑);document.json 落库为生产设计。
  • 后台线程用 Pillow 把 CanvasDocument 合成扁平生产 PNG(背景 + 按 zIndex 叠贴纸)→ set_artifacts({png})queued/running/success,产物经 GET /api/jobs/{id}/files/png 可下载。
  • 对既有 .xlsx 名单模式完全向后兼容(纯新增可选字段)。

生产订单列表(补充,回应需求"wordcloud 侧订单列表"):

  • _create_wcd_job 从 WCD 的 manifest.meta.orderNo(或 order-{orderNo} 命名)登记生产订单到 service_orders/(新增存储目录 + _order_dir/_read_order/_write_order 辅助)。
  • 新增 GET /api/orders(生产订单列表,回填对应 job 最新状态)与 GET /api/orders/{order_no}(详情),便于 wordcloud/运营侧查看下方单的生产任务。
  • 注意order 目录含 order.jsonlist_orders 需直接遍历 ORDERS_DIR(不能复用只认 meta/template/project.json_list_dirs)。

验证:py_compile 通过;用 venv FastAPI 真实调用 _create_wcd_job + 轮询任务 + list_orders/get_order + 产物访问,端到端通过(订单登记、状态=success、产物 PNG 可访问)。未提交——该仓库 app.py 有他人大量在途改动且无远程,改动留在 feat/r4-wcd-job 工作区,由 wordcloud 维护者合入其分支后提交。

5. 配置(后端 .env

# ── 词云平台 ──
WORDCLOUD_API_URL=          # 词云服务地址;留空 → 派单返回 not_configured
WORDCLOUD_TIMEOUT_MS=30000
# ── COS ──
COS_SECRET_ID=
COS_SECRET_KEY=
COS_BUCKET=wordcloudwechat
COS_REGION=ap-guangzhou

6. 验证情况

结果
wechat_wc npm run build:weapp 通过(多次)
wxmp_backend nest build 通过(EXIT=00 error
wxmp_backend prisma validate + 迁移应用 通过
wordcloud app.py py_compile 通过
wordcloud WCD/订单列表端到端 用 venv FastAPI(0.136.3) 真实调用:建 WCD job → success → GET /api/orders 登记订单 → 产物 PNG 可访问
wordcloud pytest ⚠️ 系统 python 缺 pandas/pytest(项目 venv 未装),完整测试需团队环境

诚实说明:COS 与 wordcloud 的本地 env 均为空,运行期未做真实端到端联调(见 §7 注意事项)。

7. 注意事项(上线前必读)

  1. 微信后台域名:小程序 downloadFile/uploadFile 合法域名需加入 COS 桶域名(https://wordcloudwechat.cos.ap-guangzhou.myqcloud.com)与后端域名(https://wxbackend.tokenleaping.com);否则真机上传/下载失败。
  2. COSwordcloudwechat 桶需公共读;COS_* 密钥只存后端 env。直传用预签名 URL,小程序不持永久密钥。
  3. wordcloud 部署WORDCLOUD_API_URL 指向真实部署实例;联调前锁定一个版本(它正在大量变更)。wcd_file 实现需 wordcloud 侧合入其分支(当前在工作区)。
  4. 贴纸持久化依赖buildWcdPackage 只消费持久 URL;若 designData 里的贴纸仍是本地/临时路径会被跳过。前端保存时已调用 persistDesignMedia,但必须在 COS 已配置下才生效。
  5. 任务同步:当前用服务内 30s 后台轮询推进状态(未依赖 Redis/BullMQ queue);生产量大时可换 queue processor(占位仍在 src/queue/)。
  6. 安全:所有 wordcloud 任务查询带 userId 归属校验;未配置时结构化返回,不做假成功;名单 ≤200、底图 ≤10MB、任务超时清理。
  7. 测试环境:跑 wordcloud 测试需安装 pandas/pytest

8. 对接需求

对接方 需求
R2(设计清单) designDatadocs/design-data-contract-v1.md 冻结:放行 version/background/wordcloud/rotation/zIndexcategory.mask 必须保留;贴纸图 src 由 R4 持久化(R2 允许保存时暂为本地路径)。4 项决策已冻结(见契约 §6)
R3(订单) 创建订单时传 designListIdOrdersService.create 已支持存储);订单进入 PROCESSING 时可自动触发 POST /api/orders/:id/dispatch;支付未配置期用该端点做联调/运营触发
wordcloud 团队 合入 feat/r4-wcd-job 工作区的 create_job wcd_file 改动 + 订单列表(GET /api/orders;对外部署;契约 v1.1 已冻结(wxmp_backend/docs/wordcloud-contract.md);新订单列表为运营侧查看,wxmp_backend 不消费
运维 配置 COS_*WORDCLOUD_API_URL;微信后台加域名;跑一次迁移 prisma migrate deploy
前端(R4 自身) 词云页/线稿页联调需后端接口真实可用;下单后派单状态展示挂在 R3 的订单详情页

9. 分支与提交

仓库 分支 提交
wechat_wc feat/r4-upload-wordcloud docs(契约/路线/CLAUDE.md) → 前端类型/api/词云页/线稿 → 贴纸持久化+dispatch
wxmp_backend feat/r4-upload-wordcloud docs(契约) → config → WordCloudJob+适配器 → COS → WCD 派单 → sketch/Upload/同步 → jobs/:id/result
wordcloud feat/r4-wcd-job 工作区改动(未提交,无远程)

远端 master/main 全程复查:无新提交需合并,分支已随开发保持同步。

10. 剩余 / 交接

  • wordcloud 侧 wcd_file 合入其分支 + 部署锁定版本 → 端到端联调(下单 → WCD 生产 PNG)。
  • R3 完成后接入"订单进 PROCESSING 自动派单"与订单详情派单状态展示。
  • 生产化:换 Redis/BullMQ 队列做任务同步;加任务超时清理、单账号频率限制。