Files
ozon-seller-kit/docs/v2.1/backend-structure.md

162 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# V2.1 后端代码结构盘点(server/)
> 状态:现状盘点(2026-08-28,鉴权移除后)
> 用途:一眼看清后端有哪些代码、各自处理什么逻辑、哪些在用哪些冻结。做后端改动前先读本文。
> 契约细节另见 [`api.md`](./api.md)。
---
## 1. 总览
共 5270 行 Python。分层:`api/`(HTTP 路由)→ `services/`(业务逻辑)→ `models/`(ORM 表);`schemas/`(Pydantic 契约)、`core/`(AES 加解密)、`config/`(配置)、`migrations/`(Alembic)。
状态标注:✅ 在用 · 🧊 冻结(保留不维护)· 🗑 残留(可删)。
```
server/
├── main.py 【72·入口】
│ ├── FastAPI app + CORS + startup create_all(幂等建表,生产以 Alembic 为准)
│ ├── 挂载 12 个路由器(auth 已移除)
│ ├── /media 静态托管 data/media/(本地图片)
│ └── / 挂载 web/(v1 工具台,冻结)
│
├── api/ ──────────────────────────── 路由层(HTTP 接口,冻结链路已移至 legacy/)
│ ├── materials.py 【267 ✅核心】(原 collection.py,与 /api/materials 路径对齐)
│ │ ├── POST /api/materials 插件采集上报入库(建/复用商品 + 文本解析 + 图片队列下载转存)
│ │ ├── POST /api/materials/bytes 直接上传图片字节(试算页「上传图片」)
│ │ ├── GET /api/products/{id}/fingerprints 素材去重指纹
│ │ └── GET /api/collected 按 platform+itemId 查重(扩展防重复上报)
│ ├── products.py 【178 ✅核心】
│ │ ├── GET·POST /api/products 商品列表 / 新建
│ │ ├── GET·PATCH·DELETE /api/products/{id} 详情 / 自动保存 / 删除(软删 archived | 硬删)
│ │ └── POST /api/products/{id}/copy 复制为新变体(重置货号/图片防冲突)
│ ├── suite.py 【✅核心·Phase B】
│ │ ├── POST /api/suite/plan DeepSeek 出图方案规划(同步,数秒级)
│ │ ├── POST /api/suite/generate 一键生成:方案展开→持久化子任务→Worker 生图→回写 generated 素材
│ │ ├── GET /api/suites/{id} 任务状态轮询(前端 3s 一次)/ cancel / retry
│ │ ├── GET /api/products/{id}/suites 恢复商品活动任务
│ │ ├── GET /api/suites/{id}/zip 生成结果打包下载(中文文件名)
│ │ └── POST /api/suite/image-edit 单张 AI 生图(试算页每图按钮,append=true 回写素材)
│ ├── export.py 【121 ✅】POST /api/export/images 采集图片打包 ZIP(标题/分组/SKU规格 文件夹结构)
│ ├── proxy.py 【54 ✅】 GET /api/proxy-image?url= 图片防盗链代理(带站点 Referer 代下)
│ ├── fx.py 【13 ✅】 GET /api/fx 汇率(FloatRates→俄央行→er-api 三级回退 + 区间校验)
│ ├── ai.py 【~30 ✅】 GET /api/ai/models、POST /api/ai/copy 俄文文案生成(试算页 03 区块)
│ ├── image.py 【~12 保留】POST /api/image/edit 万相 wanx2.1 图像编辑(智能修图页专用)
│ ├── shops.py 【118 🧊冻结】店铺 CRUD + 连通测试(发布链路配套,AES 加密凭证)
│ ├── categories.py 【117 🧊冻结】Ozon 类目树/属性/字典值代理
│ ├── publish.py 【179 🧊冻结】Ozon ImportProductsV3 直传 + 任务轮询
│ └── ozon.py 【5 🧊冻结】空占位(远期直传重启时用)
│
├── services/ ──────────────────────── 业务逻辑层
│ ├── generator.py 【✅核心】生图 provider(doubao / tongyi / rightapi / pcore)
│ │ + 可恢复的 submit/poll 推进器 + 参考图解析
│ │ (variant 精确匹配 SKU 图 → 回退 main 首张;≤2 张转 data-URI)
│ ├── planner.py 【227 ✅核心】DeepSeek 出图方案规划器
│ │ (单行 JSON 解析 / kind 白名单 / count 钳 0-3 / 幻觉 SKU 丢弃绑定 / 截断修复)
│ ├── prompts/ 【✅核心】生图提示词引擎(按模型家族分发)
│ │ ├── __init__.py (provider, model) → 家族路由 + build_prompt / build_context / type_name
│ │ ├── common.py 10 种图类型 builder(white_bg/lifestyle/…)+ 5 套风格 + 图内文案语言规范
│ │ ├── alibaba.py 通义系「主体参考」语义(doubao 复用):商品逐像素一致,只改背景/角度
│ │ ├── gpt.py gpt-image-2「edits 保真」语义:以参考图为准,禁止按文案重造商品
│ │ ├── google.py nano-banana「主体保持」语义:一句话钉死主体 + 自然语言指令
│ │ └── doubao.py 豆包(复用 alibaba)
│ ├── jobs.py 【✅核心】持久化任务仓库、租约领取、取消/失败重试、任务视图
│ ├── job_worker.py【✅核心】独立 Worker:逐图提交/轮询外部模型、落图与回写素材
│ ├── tasks.py 【兼容】旧内存任务执行器,活跃 API 不再使用
│ ├── watermark.py 【122 ✅】Pillow 水印合成(图片徽章/文字,右下角,失败回退原图)
│ ├── deepseek.py 【182 ✅】DeepSeek chat 封装(俄文文案 + 出图规划共用;JSON 容错解析)
│ ├── models_catalog.py【84 ✅】读 config/models.yaml(俄文文案模型白名单:快/省、质量两档)
│ ├── storage.py 【117 ✅】存储抽象:Local(data/media/,/media 托管)+ Qiniu(七牛,生产)
│ │ + local_path(stored_url→本地路径,ZIP 打包用)+ download_bytes(带 Referer 代下)
│ ├── fx.py 【58 ✅】多源汇率 + [5,25] 区间脏数据校验(v1 移植)
│ ├── image_edit.py【185 保留】wanx2.1-imageedit 多模型图像编辑(智能修图页后端)
│ └── suite_service.py【~95 ✅】套图业务逻辑(api 层下沉):texts_to_raw / 模型白名单校验 /
│ append_generated_asset(generated 回写 + asset_counts 累加)
│
├── legacy/ ────────────────────────── 🧊 冻结代码(Ozon API 直传链路,接口仍挂载但不再投入)
│ ├── api/ shops(店铺 CRUD+连通测试)/ categories(类目字典代理)/
│ │ publish(ImportProductsV3 直传)/ ozon(空占位)
│ ├── services/ ozon_client(Seller API 薄封装)/ publish(请求体组装+必填校验)
│ ├── models/ shop / publish_task / category(字典缓存三表)
│ └── schemas/ shop
│
│
├── schemas/ ────────────────────────── Pydantic 契约(请求/响应模型)
│ ├── suite.py 【160 ✅】SuitePlanRequest / SuiteGenerateRequest / SuiteOut /
│ │ ImageEditSingleRequest(product_id + append → 回写)/ WatermarkOptions / 模型白名单
│ ├── collection.py 【✅】MaterialsRequest(camelCase:source.itemId / groupKey / variantName,对齐扩展)
│ ├── product.py 【102 ✅】列表 / 详情 / 部分更新(自动保存)
│ ├── copy.py 【✅】俄文文案(titles_ru/zh、description、tags、usage)
│ ├── image_edit.py 【125 保留】智能修图(模型白名单 / function / 强度)
│ └── (shop 已移至 legacy/schemas/;auth.py 残留已删除)
│
├── models/ ─────────────────────────── SQLAlchemy ORM(表结构)
│ ├── product.py products 商品主表(Ozon 字段 + raw/pricing/copy 三个 JSON 扩展)
│ ├── asset.py product_assets 素材表(group_key: main/sku/detail/generated/upload/…;stored_url;dedupe_key)
│ ├── user.py users(预留空置;鉴权移除后暂无用途,表已在库)
│ ├── enums.py stage 状态机(collected→editing→ready→…→archived)等枚举
│ └── types.py JSON/JSONB 兼容类型
│
├── core/security.py 【保留】店铺凭证 AES-GCM 加解密(shops/categories/publish 使用)
│ 鉴权(JWT/APP_TOKEN)已按 V2.1 决策移除,加账户体系时在此重引
├── db.py 【50】async engine + session 工厂(SQLite 开发 / PostgreSQL 生产)
├── config/
│ ├── settings.py 【94】pydantic-settings:database_url / DEEPSEEK·DASHSCOPE·ARK·RIGHTAPI 密钥 /
│ │ image_provider / request_timeout(300s) / poll_max_wait(600s) / 存储与水印配置
│ └── models.yaml 俄文文案模型白名单(deepseek-v4-flash 默认 / deepseek-v4-pro)
└── migrations/ Alembic(2 个版本:initial_v2_schema、add_shop_id_to_products)
```
---
## 2. 接口一览(20 个端点,全部无鉴权)
| 分组 | 端点 | 用途 | 消费方 |
|---|---|---|---|
| **采集上报** | POST /api/materials | 采集结果入库(返回 product_id) | extensions/collector「上报商品」 |
| | POST /api/materials/bytes | 上传图片字节(FormData) | 试算页「上传图片」 |
| | GET /api/collected?platform=&itemId= | 采集前查重 | 扩展面板 |
| | GET /api/products/{id}/fingerprints | 素材去重指纹 | 扩展 |
| **商品库** | GET·POST /api/products | 列表 / 新建 | 采集箱、登记表导出 |
| | GET·PATCH·DELETE /api/products/{id} | 详情 / 自动保存 / 删除 | 试算页、编辑页 |
| | POST /api/products/{id}/copy | 复制为新变体 | 采集箱 |
| | GET /api/products/{id}/assets | 素材列表 | 试算页 04 区块 |
| **套图生图** | POST /api/suite/plan | DeepSeek 出图方案 | 试算页「AI 智能规划」 |
| | POST /api/suite/generate | 提交套图任务(返回 suite_id) | 试算页「一键生图」 |
| | GET /api/suites/{id} | 任务状态轮询 | 试算页进度条 |
| | GET /api/suites/{id}/zip | 结果打包下载 | 试算页「导出 ZIP」 |
| | POST /api/suite/image-edit | 单张 AI 生图(可回写素材) | 试算页每图「AI 生图」 |
| **辅助** | GET /api/fx | 汇率 | 试算页计价 |
| | GET /api/ai/models · POST /api/ai/copy | 文案模型 / 生成 | 试算页 03 区块 |
| | POST /api/export/images | 采集图片 ZIP | 试算页「下载采集图片」 |
| | GET /api/proxy-image | 防盗链代理 | 前端图片回退 |
| | POST /api/image/edit | 万相图像编辑 | 智能修图页 |
| | GET /api/health | 健康检查 | 运维 |
| **🧊冻结** | /api/shops/* · /api/categories/* · /api/publish/* · /api/ozon/* | Ozon 直传链路(代码在 legacy/,接口仍挂载) | 无(保留代码) |
---
## 3. 核心数据流
```
extensions/collector 采集
→ POST /api/materials(collection.py 落库 products + 排队下载图片 → storage 落盘)
→ 试算页 /trial/{id}(studio)
├─ 01/02/03 编辑 → PATCH /api/products/{id} 自动保存(raw/pricing/copy JSON)
├─ 04 生图:POST /api/suite/plan(planner+deepseek)→ POST /api/suite/generate
│ → background_jobs / items → 独立 Worker → generator(prompts 家族 → provider API → watermark → storage)
│ → 每张成功回写 product_assets(generated) → 前端轮询 GET /api/suites/{id} + 刷新素材
└─ 05 登记(localStorage)→ 导出 CSV / 组合码(纯前端)
```
## 4. 已知特性与注意事项
| 项 | 说明 |
|---|---|
| 生图任务依赖独立 Worker | `start.command` 已自动启动 `python server/worker.py`;手动启动 uvicorn 时也必须启动 Worker |
| 外部任务恢复 | Pcore、RightAPI、通义万相的 provider task id 会保存到数据库,重启后继续轮询原任务;同步 provider 无外部 id 时只能重试 |
| 全部接口无鉴权 | V2.1 决策:先功能后鉴权;重新引入时从 `deps.py` + 路由依赖层加 |
| 残留可删 | `schemas/auth.py`(无引用);`api/ozon.py`(空占位,随冻结链路保留) |
| 密钥 | `.env`:DEEPSEEK_API_KEY(规划+文案)、RIGHTAPI_API_KEY(gpt/nano 生图)、DASHSCOPE_API_KEY(通义)、ARK_API_KEY(豆包,可选) |
| 前端契约 | 试算页 `studio/src/services/suite.ts` 与 `schemas/suite.py` 逐字段对齐(联调已验证) |