Dev Spec v2 · ← 返回文档首页

02 系统设计

1. 模块

products/pixorder/
├── styles/        # 风格配置:提示词模板、所用网关任务、适用主体、可搭配的商品
├── sessions/      # 定制会话:上传 → 预览 → 挑选(匿名可用)
├── generate/      # 预览生成、补生成、重新生成(调用网关)
├── judge/         # 视觉打分与分流
├── restore/       # 老照片修复
├── printfile/     # 放大、裁切出血、DPI 检查、色彩空间
├── catalog/       # 商品目录(从代发平台同步)
├── orders/        # 订单、状态机、售后规则
├── fulfill/       # 代发适配器:printify / cn_pod(待定)
├── channels/      # 闲鱼卡密、Etsy(后期)
├── mockups/       # 商品效果图
└── api/

2. 两个核心对象

定制会话(design session):从上传到挑好图;可以是匿名的;不涉及钱。 订单(order):付款后产生;一个订单可以包含多个商品(例如电子版 + 帆布画)。

2.1 定制会话状态

created → uploaded → generating → ready ──(重新生成)──▶ generating
                          │
                          └─(连续 3 轮不合格)─▶ failed(提示换照片,不扣次数)
ready → selected → converted(已下单)
任何状态 7 天未转化 → expired(删除预览)

2.2 订单状态(按订单行分别推进)

订单行类型 状态
电子版 paid → rendering → delivered
实物 paid → rendering → submitted → in_production → shipped → delivered,另有 issue(售后)、refunded
  • rendering:放大并生成印刷文件(电子版则生成高清原图)
  • submitted:已调用代发接口下单
  • 状态白名单写死;非法转换抛异常;每次变更写 order_events

3. 数据库(schema pixorder)

CREATE TABLE pixorder.styles (
  id TEXT PRIMARY KEY,                     -- 'pet.renaissance_noble'
  subject TEXT NOT NULL,                   -- pet|human|old_photo|duo
  name JSONB NOT NULL,                     -- 多语言
  prompt_template TEXT NOT NULL,
  gateway_task TEXT NOT NULL,              -- 'pix.pet_portrait'
  judge_rubric TEXT NOT NULL,
  sample_keys TEXT[] NOT NULL,
  allowed_skus TEXT[] NOT NULL,
  regions TEXT[] NOT NULL,                 -- 在哪些区域上线
  fidelity_score REAL,                     -- 上线前保真度测试结果
  status TEXT NOT NULL                     -- draft|live|retired
);

CREATE TABLE pixorder.sessions (
  id TEXT PRIMARY KEY,
  user_id TEXT, anon_id TEXT,
  region TEXT NOT NULL,
  style_id TEXT REFERENCES pixorder.styles(id),
  subject TEXT NOT NULL,
  status TEXT NOT NULL,
  rerolls_free_left INT NOT NULL DEFAULT 2,
  rerolls_paid INT NOT NULL DEFAULT 0,
  selected_preview_id TEXT,
  consent_id TEXT,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  expires_at TIMESTAMPTZ NOT NULL
);

CREATE TABLE pixorder.uploads (
  id TEXT PRIMARY KEY, session_id TEXT NOT NULL,
  object_key TEXT NOT NULL, width INT, height INT,
  checks JSONB NOT NULL,                   -- {"blur":..., "subject":"dog", "nsfw":false}
  accepted BOOLEAN NOT NULL, reason TEXT
);

CREATE TABLE pixorder.previews (
  id TEXT PRIMARY KEY, session_id TEXT NOT NULL,
  round INT NOT NULL,                      -- 第几轮生成
  object_key TEXT NOT NULL,                -- 1024 级别的原图(不对外)
  preview_key TEXT NOT NULL,               -- 带水印的展示图
  model TEXT NOT NULL,
  judge JSONB NOT NULL,                    -- 视觉打分结果
  shown BOOLEAN NOT NULL                   -- 是否通过打分并展示给客户
);

CREATE TABLE pixorder.orders (
  id TEXT PRIMARY KEY, user_id TEXT NOT NULL, session_id TEXT NOT NULL,
  region TEXT NOT NULL, channel TEXT NOT NULL,     -- site|miniapp|xianyu|etsy
  currency TEXT NOT NULL, total_cents INT NOT NULL,
  gift JSONB,                              -- {"recipient":..., "message":..., "hide_price":true}
  ship_to_enc BYTEA,
  status TEXT NOT NULL,                    -- 汇总状态
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE pixorder.order_items (
  id TEXT PRIMARY KEY, order_id TEXT NOT NULL,
  kind TEXT NOT NULL,                      -- digital|physical
  sku TEXT NOT NULL, qty INT NOT NULL DEFAULT 1,
  price_cents INT NOT NULL, cost_cents INT,      -- 成本来自代发报价,用于算贡献毛利
  preview_id TEXT NOT NULL,
  file_key TEXT,                           -- 高清原图 / 印刷文件
  fulfiller TEXT, fulfiller_order_id TEXT, tracking JSONB,
  status TEXT NOT NULL
);

CREATE TABLE pixorder.order_events (
  id BIGSERIAL PRIMARY KEY, item_id TEXT NOT NULL,
  from_status TEXT, to_status TEXT NOT NULL, actor TEXT NOT NULL, note TEXT,
  at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE pixorder.catalog (
  sku TEXT PRIMARY KEY, region TEXT NOT NULL, fulfiller TEXT NOT NULL,
  fulfiller_product_ref JSONB NOT NULL,    -- 代发平台的商品、变体、供应商 ID
  name JSONB NOT NULL, print_w_px INT NOT NULL, print_h_px INT NOT NULL, bleed_px INT NOT NULL,
  base_cost_cents INT NOT NULL, ship_cost_cents JSONB NOT NULL,  -- 按国家
  price_cents INT NOT NULL, ship_countries TEXT[] NOT NULL,
  mockup_template TEXT NOT NULL, active BOOLEAN NOT NULL DEFAULT TRUE,
  synced_at TIMESTAMPTZ
);

CREATE TABLE pixorder.claims (             -- 售后
  id TEXT PRIMARY KEY, item_id TEXT NOT NULL, reason TEXT NOT NULL,
  photos TEXT[] NOT NULL, decision TEXT,   -- reprint|refund|exception
  decided_by TEXT NOT NULL,                -- rule|admin:<id>
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

4. 定价与贡献毛利

  • catalog.price_cents 由后台设置;同步到的成本上涨导致毛利率低于 35% 时,该 SKU 自动下架并告警
  • 每个订单行记录 cost_cents;日报按 SKU 统计贡献毛利 = 售价 − 代发成本 − 运费 − 支付费 − AI 成本

5. 定时任务

任务 频率 说明
catalog_sync 每天 从 Printify 同步商品、成本、运费
abandon_recall 每小时 生成了预览但 24 小时内没付款的会话 → 发召回邮件
fulfill_poll 每 30 分钟 兜底:拉取代发状态(主要靠回调)
purge 每小时 按生命周期删除照片和预览;印刷文件按 retain_until(签收后 45 天)删除,收到签收事件时更新该时间
sku_margin_watch 每天 毛利率检查