9.8 KiB
9.8 KiB
R4 交付报告(feat/r4-upload-wordcloud)
日期:2026-08-13 | 范围:上传 / 词云生成 / 线稿 / 下单后 WCD 生产任务投递 涉及仓库:
wechat_wc(小程序前端)、wxmp_backend(NestJS 后端)、wordcloud(FastAPI 词云平台)
1. 目标与架构
把「用户上传底图 + 名单 → 词云生成 → DIY 贴纸 → 下单」链路中的上传、词云、线稿全部接到真实后端,
并在下单后把订单对应的整套设计以 .wcd 包投递到词云平台形成生产任务。
小程序 designData(贴纸持久化为 COS URL)
→ POST /api/orders(designListId 关联,R3)
→ POST /api/orders/:id/dispatch(幂等)
→ WordCloudService.buildWcdPackage(designData) → .wcd(Zip: manifest.json+document.json+assets/)
→ POST {WORDCLOUD_API_URL}/api/jobs wcd_file(MODE=WCD)
→ 词云平台还原设计 + 合成生产 PNG → 后端轮询同步 CustomizationTask/WordCloudJob → 产物转存 COS
小程序只与 wxmp_backend 通信;WORDCLOUD_API_URL 未配置时返回结构化 not_configured,不做假成功。
2. 前端交付(wechat_wc / feat/r4-upload-wordcloud)
| 模块 | 内容 |
|---|---|
src/types/index.ts |
DesignDataV1(version/background/wordcloud)、StickerItem 补 rotation/zIndex;新增 WordCloudJob/WordCloudStatus/CosCredentials/SketchResult/WordCloudDispatchStatus/WordCloudDispatchResult |
src/utils/api/upload.ts |
getUploadCredentials、uploadToCos(预签名 PUT 直传)、sketchImage、createWordCloudJob、getWordCloudJob、getWordCloudResult、persistDesignMedia(贴纸持久化,决策#4)、dispatchOrder;multipart 统一带 Bearer token、解析 {code,message,data} 信封 |
src/pages/wordcloud/index.tsx |
去掉 setInterval+Math.random 假进度 → 真实「上传底图→建任务→轮询→取结果→保存相册」;新增生成失败/未配置提示块 |
src/pages/diy/stickerEdit/index.tsx |
删 your-api-domain.com 占位 → 走 sketchImage(POST /api/sketch),失败仍降级前端灰度 |
src/pages/diy/index.tsx |
handleComplete 保存前调用 persistDesignMedia:本地贴纸/底图 → COS 持久 URL 写回 designData |
| 文档 | docs/routes/route-r4-upload-wordcloud.md、docs/design-data-contract-v1.md、CLAUDE.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/generate(multipart image+names → xlsx → 投递 /api/jobs)、GET /api/wordcloud/jobs/:id(归属校验+实时代理轮询)、GET /api/wordcloud/jobs/:id/result |
wordcloud 派单 |
buildWcdPackage(designData→.wcd,下载素材字节、sha256)、dispatchToWordcloud(幂等、未配置→not_configured)、POST /api/orders/:id/dispatch |
wordcloud 同步 |
onModuleInit 后台 30s 轮询进行中任务 → 成功时结果图转存 COS、同步 CustomizationTask→SUCCESS/resultUrl |
sketch |
POST /api/sketch(multipart image,类型/大小校验 ≤10MB)→ 转存 COS 返回 URL |
orders |
OrdersService.create 保存 designList 关联(R3 契约字段) |
Prisma 迁移(3 个):
| 迁移 | 内容 |
|---|---|
add_word_cloud_job |
WordCloudJob 模型 + WordCloudJobStatus 枚举 |
add_remote_job_id |
WordCloudJob.remoteJobId(wordcloud 外部 job_id) |
r4_order_design_and_dispatch |
Order.designListId+DesignList.orders;CustomizationTask.orderId/wordcloudJobId |
验证:nest build 通过、prisma validate 通过、迁移已应用。
4. wordcloud 平台交付(wordcloud / feat/r4-wcd-job,仅工作区)
POST /api/jobs 新增可选 wcd_file(MODE=WCD):
- 校验
format=wordcloud-canvas、version=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.json,list_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=0,0 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. 注意事项(上线前必读)
- 微信后台域名:小程序
downloadFile/uploadFile合法域名需加入 COS 桶域名(https://wordcloudwechat.cos.ap-guangzhou.myqcloud.com)与后端域名(https://wxbackend.tokenleaping.com);否则真机上传/下载失败。 - COS:
wordcloudwechat桶需公共读;COS_*密钥只存后端 env。直传用预签名 URL,小程序不持永久密钥。 - wordcloud 部署:
WORDCLOUD_API_URL指向真实部署实例;联调前锁定一个版本(它正在大量变更)。wcd_file实现需 wordcloud 侧合入其分支(当前在工作区)。 - 贴纸持久化依赖:
buildWcdPackage只消费持久 URL;若 designData 里的贴纸仍是本地/临时路径会被跳过。前端保存时已调用persistDesignMedia,但必须在 COS 已配置下才生效。 - 任务同步:当前用服务内 30s 后台轮询推进状态(未依赖 Redis/BullMQ queue);生产量大时可换 queue processor(占位仍在
src/queue/)。 - 安全:所有 wordcloud 任务查询带 userId 归属校验;未配置时结构化返回,不做假成功;名单 ≤200、底图 ≤10MB、任务超时清理。
- 测试环境:跑 wordcloud 测试需安装
pandas/pytest。
8. 对接需求
| 对接方 | 需求 |
|---|---|
| R2(设计清单) | designData 按 docs/design-data-contract-v1.md 冻结:放行 version/background/wordcloud/rotation/zIndex;category.mask 必须保留;贴纸图 src 由 R4 持久化(R2 允许保存时暂为本地路径)。4 项决策已冻结(见契约 §6) |
| R3(订单) | 创建订单时传 designListId(OrdersService.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 队列做任务同步;加任务超时清理、单账号频率限制。