通用

Q: 这套方案能跑在哪些规模?

  • 开发 / POC:一台 4C8G 单机 + docker compose 起依赖即可
  • 中小生产:3 节点(API、Worker、依赖各 1)支撑日均万级订单
  • 大型生产:API / Worker / 依赖分层水平扩展,瓶颈通常在 Puppeteer 吞吐

Q: 为什么后端选 Bun + Elysia 而不是 Java / Node + Express?

docs/项目总体设计.md 早期版本写的是 Java + SpringBoot,落地时改为 Bun + Elysia 主要因为:

  1. 启动 ≤ 1s、零编译、TS 原生
  2. Elysia 借 TypeBox 在路由层做”类型 + 校验”一体化,开发量比 Express 少
  3. 与前端 TS 团队共享语言/工具,单仓库 monorepo 跑得更顺
  4. 单进程合成 Job 与 HTTP 同源代码,分组部署只切配置不切技术栈

性能完全够用——瓶颈在 Puppeteer / MySQL,不在 Web 框架。

Q: 模板编辑器为什么选 Leafer 而不是 Konva / Fabric?

Leafer 在 2024–2025 期间生态活跃,原生支持 Vue 3、SSR 渲染(关键:Puppeteer 能跑同一份代码出图)、矢量节点丰富、性能在大量节点场景下优势明显。

Q: 一定要装 MinIO 吗?能不能直接用 OSS / S3 / COS?

可以。只要把 config.jsons3 段换成兼容的 endpoint + 密钥即可;前端的预签名上传链路天然适配 S3 协议。


模板与编辑器

Q: 同一个模板能否被多个相册引用?

可以。通过 album_templates 中间表,一张模板可被 N 个相册关联,并指定 relationType ∈ {inner, cover, back_cover} 与排序。

Q: 模板上线后改了,已下单未合成的订单受影响吗?

不受影响。order_template_submission_items.sceneJson 在提交时做了快照,合成 Job 优先用该快照,避免管理员改模板影响历史订单。

Q: 字体能不能让用户自己上传?

当前不支持。font_variants 是管理员维度的资源;如果业务必须开放给用户,建议沿用 userId 字段约定(0 全局,非 0 个人),并加上版权审核流程。


合成

Q: 一张图合成大概多久?

简单模板(背景 + 1 张图 + 1 行字)约 0.5–1s;复杂相册页(10+ 元素 + 多字体)约 1–3s。瓶颈是 Puppeteer 启动 Page + 字体加载,渲染本身很快。

Q: 我提交了 20 张图,能不能并行合成?

当前默认是按 submission 整单串行处理明细。如需并行:

  1. jobProcessorfor await 改成并行(带 p-limit 控并发)
  2. 给 Puppeteer 池配相应数量 Browser/Page
  3. 注意单机内存上限——Chromium 实例并不便宜

Q: 合成失败后怎么办?

  • item 级失败:failReason 写入失败原因,submission 整单标为 failed
  • 管理员在 pf-manage 单条重试,或修复后整单重提
  • 当前不自动重试,避免错误内容反复跑

Q: 想把合成产物输出成 PDF / TIFF / 高 DPI 怎么改?

utils/exportImg.ts 里有 PNG/PDF 两条路径;要加 TIFF 可在导出后用 sharp 转换。高 DPI 通过 Puppeteer 的 deviceScaleFactor 调大。


用户端

Q: 用户端能不能跨端编辑(手机端编了一半 PC 端继续)?

按设计文档当前版本暂不支持。已通过 pinia-persistedstate 把草稿持久化在 localStorage,但没有云端草稿同步。若要加,建议在 order_template_submissions 之外再加一张 submission_drafts 表。

Q: 上传单图能多大?

默认 200MB。受限于:

  • 浏览器内存(移动端尤其敏感)
  • MinIO multipart 部分尺寸
  • 反向代理 client_max_body_size

要支持更大文件,把这三处一起调。

Q: 人脸检测必须开吗?

否。只有模板节点显式声明 faceSafe: true 才会调 face-service;不开启的话整个 face-service 可以不部署,前端走普通自适应裁剪。


集成

Q: 怎么和现有电商主站打通?

参见 电商集成方案 的三种账号方案 + 订单同步 + 合成回调。最小集成只要打通账号 + 订单同步 + 回调三条边界。

Q: pf-manage 的账号和电商主站后台是同一套吗?

不建议合并。电商主站后台是面向运营全局的,pf-manage 仅服务”图模工坊”模块;权限粒度差别很大。若一定要 SSO,对接 POST /pf-manage/auth/exchange

Q: 用户的素材会不会泄露?

只要按部署建议把 MinIO 设为私有桶 + 预签名 URL,外部就拿不到任意素材;CDN 回源也建议走签名 URL。pf-service 内部不会把原图发到任何外部服务。


部署 & 运维

Q: Puppeteer 安装失败 / 启动报缺动态库?

常见缺:

  • Linux:libnss3 libatk-bridge2.0-0 libxcomposite1 libxdamage1 libxrandr2 libgbm1 libxkbcommon0 libpango-1.0-0 libcairo2
  • 用 Debian/Ubuntu 直接装 chromium 包并设 PUPPETEER_EXECUTABLE_PATH
  • 容器化时基础镜像选 Microsoft 的 mcr.microsoft.com/playwright 系列更省心

Q: 我把 config.composition.enabled = false 了,为什么提交还会变成 completed?

检查同一 DB 是否被其它进程的 pf-service 共享——其它进程 Job 仍在跑。生产建议显式拆分 API 与 Worker 进程组。

Q: 怎么看一条订单到底卡在哪?

1
2
3
4
5
6
7
8
9
-- 主表状态
SELECT id, order_no, status, created_at, updated_at
FROM order_template_submissions
WHERE order_no = '2025...';

-- 明细 + 失败原因
SELECT id, template_id, status, fail_reason
FROM order_template_submission_items
WHERE submission_id = ?;

或者直接在 pf-manage 的”合成提交”页打开详情。

Q: 数据备份怎么做?

  • MySQL:mysqldump 全量 + binlog 增量
  • MinIO:mc mirror 到异地桶
  • 模板的 sceneJson 都在 MySQL;MinIO 主要是素材/成品

二开

Q: 想加一个新前端(比如小程序)怎么对接?

后端接口都是 HTTP/JSON,鉴权 JWT,小程序端只要按 pf-app 的 API 调用范式接即可。/pf-app/* 前缀的接口是面向终端用户的,可以共用。

Q: 想把人脸服务换成识别二维码 / 文字行?

接口协议是稳定的:POST /api/face/detect 接受 imageUrl,返回归一化框 + score。换实现时保持响应字段、bump modelVersion,调用方零侵入。

Q: 模板能不能批量导入?

当前 pf-manage 只支持单张创建。如果你有现成的设计稿,可以写一个一次性脚本把 sceneJson 批量塞 templates 表,路径就在 apps/pf-service/src/db/seed.ts 旁边。


关于路线图与维护

  • 路线图见 Roadmap
  • 二开问题欢迎提 issue
  • 涉及商业部署 / 私有化交付请联系仓库主页留的联系方式