chore(bug/qa): 归档测试清单、bug 报告与 QA 诊断脚本
- core/bug: 各轮电商项目测试清单 xlsx + 验证报告/套图提示词梳理 md - core/qa: consumption_summary / diag_login / diag_sessions / probe_usage 诊断脚本 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,143 @@
|
|||||||
|
# 平台套图(cover)提示词梳理 + 「没参考图片 / 参考不精准」真因
|
||||||
|
|
||||||
|
> 整理时间:2026-06-29 范围:图片生成 → 平台套图(mode=cover)
|
||||||
|
> 涉及代码:
|
||||||
|
> - 前端拼词:[core/frontend/src/routes/ai-tools.tsx](../frontend/src/routes/ai-tools.tsx)(`promptTemplate` + 平台名追加)
|
||||||
|
> - 后端真正发给模型的提示词:[core/backend/apps/ai/services.py](../backend/apps/ai/services.py) `build_platform_cover_prompt_refs()`(977 行)+ `run_standalone_image_task`(2194 行 cover 分支)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一句话结论
|
||||||
|
|
||||||
|
**10 个平台用的是同一套提示词,彼此之间唯一的区别只有结尾追加的一句「{平台名}平台头图版式」。**
|
||||||
|
代码里没有任何按平台区分尺寸、版式、画幅、调性的逻辑——抖音不会出 9:16 竖封、小红书不会出 3:4、淘宝/天猫不会强制 1:1 主图,全部是同一个模板换个平台名字而已。这就是「看起来没怎么按平台来」的根本原因。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 提示词是怎么拼出来的(两段拼接)
|
||||||
|
|
||||||
|
### 第 1 段:前端拼好的 base_prompt
|
||||||
|
|
||||||
|
打开页面时,按商品名预填一个模板(`platformCover.promptTemplate`):
|
||||||
|
|
||||||
|
```
|
||||||
|
{商品名},电商平台头图,统一视觉,主图特写
|
||||||
|
```
|
||||||
|
|
||||||
|
点「开始生成」时,对每个选中的平台各起一批,并在末尾追加平台名(ai-tools.tsx 第 1086~1089 行):
|
||||||
|
|
||||||
|
```
|
||||||
|
{商品名},电商平台头图,统一视觉,主图特写,{平台名}平台头图版式
|
||||||
|
```
|
||||||
|
|
||||||
|
> ⚠️ 平台之间的差异**仅此一处**。后端没有 platform 字段,平台信息全靠这句话表达。
|
||||||
|
|
||||||
|
### 第 2 段:后端把 base_prompt 包进固定模板(真正发给模型的词)
|
||||||
|
|
||||||
|
`build_platform_cover_prompt_refs()`(无模特、index=0 时):
|
||||||
|
|
||||||
|
```
|
||||||
|
参考图1是「{商品名}」的真实商品主图。 请基于该商品生成电商平台套图(主图 / 封面 / 详情排版),统一视觉风格; 商品的外形、品牌文字、配色、Logo、材质必须与参考图1高度一致,严禁改动或重新设计包装;干净背景、电商主图构图、真实质感。 本张:正面居中主图版式,商品占画面主体,纯净背景,经典电商主图构图。 {第1段的 base_prompt}
|
||||||
|
```
|
||||||
|
|
||||||
|
如果该批选了模特,则把中间替换为:
|
||||||
|
|
||||||
|
```
|
||||||
|
参考图1是「{商品名}」的真实商品主图。 参考图2是出镜模特。请生成参考图2中的这位模特展示参考图1中商品的电商平台套图(主图 / 封面 / 详情); 模特的五官、发型、肤色、身形必须与参考图2高度一致,不要换人; 商品的外形、品牌文字、配色、Logo、材质必须与参考图1高度一致,严禁改动或重新设计包装;干净背景、电商主图构图、真实质感。 本张:…… {第1段的 base_prompt}
|
||||||
|
```
|
||||||
|
|
||||||
|
末尾那句「本张:……」是**同一批 4 张图防雷同**用的,按张轮换(不区分平台):
|
||||||
|
|
||||||
|
| 第几张(index) | 版式指令 |
|
||||||
|
| --- | --- |
|
||||||
|
| 1 | 正面居中主图版式,商品占画面主体,纯净背景,经典电商主图构图 |
|
||||||
|
| 2 | 换一种排版——商品偏置 + 卖点文案分区,场景化背景,杂志感构图 |
|
||||||
|
| 3 | 特写细节版式,放大商品材质/做工,近景视角,突出质感 |
|
||||||
|
| 4 | 生活场景套图版式,商品置于真实使用情境,环境光,氛围感构图 |
|
||||||
|
| 5 | 多角度组合版式,商品换一个朝向/视角,几何分区背景,现代简约风 |
|
||||||
|
| 6 | 促销封面版式,留出标题/价签区,高对比配色,强视觉冲击构图 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 各平台完整提示词(以「南卡 Lite Pro 蓝牙耳机」、未选模特、第 1 张为例)
|
||||||
|
|
||||||
|
> 下面每条只有**最后一句的平台名**不同,前面完全一样。
|
||||||
|
|
||||||
|
### 抖音电商
|
||||||
|
```
|
||||||
|
参考图1是「南卡 Lite Pro 蓝牙耳机」的真实商品主图。 请基于该商品生成电商平台套图(主图 / 封面 / 详情排版),统一视觉风格; 商品的外形、品牌文字、配色、Logo、材质必须与参考图1高度一致,严禁改动或重新设计包装;干净背景、电商主图构图、真实质感。 本张:正面居中主图版式,商品占画面主体,纯净背景,经典电商主图构图。 南卡 Lite Pro 蓝牙耳机,电商平台头图,统一视觉,主图特写,抖音电商平台头图版式
|
||||||
|
```
|
||||||
|
|
||||||
|
### 淘宝
|
||||||
|
```
|
||||||
|
…(前略,同上)… 南卡 Lite Pro 蓝牙耳机,电商平台头图,统一视觉,主图特写,淘宝平台头图版式
|
||||||
|
```
|
||||||
|
|
||||||
|
### 天猫
|
||||||
|
```
|
||||||
|
…(前略,同上)… 南卡 Lite Pro 蓝牙耳机,电商平台头图,统一视觉,主图特写,天猫平台头图版式
|
||||||
|
```
|
||||||
|
|
||||||
|
### 京东
|
||||||
|
```
|
||||||
|
…(前略,同上)… 南卡 Lite Pro 蓝牙耳机,电商平台头图,统一视觉,主图特写,京东平台头图版式
|
||||||
|
```
|
||||||
|
|
||||||
|
### 拼多多
|
||||||
|
```
|
||||||
|
…(前略,同上)… 南卡 Lite Pro 蓝牙耳机,电商平台头图,统一视觉,主图特写,拼多多平台头图版式
|
||||||
|
```
|
||||||
|
|
||||||
|
### 小红书
|
||||||
|
```
|
||||||
|
…(前略,同上)… 南卡 Lite Pro 蓝牙耳机,电商平台头图,统一视觉,主图特写,小红书平台头图版式
|
||||||
|
```
|
||||||
|
|
||||||
|
### 快手
|
||||||
|
```
|
||||||
|
…(前略,同上)… 南卡 Lite Pro 蓝牙耳机,电商平台头图,统一视觉,主图特写,快手平台头图版式
|
||||||
|
```
|
||||||
|
|
||||||
|
### 视频号
|
||||||
|
```
|
||||||
|
…(前略,同上)… 南卡 Lite Pro 蓝牙耳机,电商平台头图,统一视觉,主图特写,视频号平台头图版式
|
||||||
|
```
|
||||||
|
|
||||||
|
### 亚马逊
|
||||||
|
```
|
||||||
|
…(前略,同上)… 南卡 Lite Pro 蓝牙耳机,电商平台头图,统一视觉,主图特写,亚马逊平台头图版式
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1688
|
||||||
|
```
|
||||||
|
…(前略,同上)… 南卡 Lite Pro 蓝牙耳机,电商平台头图,统一视觉,主图特写,1688平台头图版式
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 「好像没参考图片 / 参考了但不精准」的真因
|
||||||
|
|
||||||
|
参考图**确实有传**给模型(cover 分支 `edit_images = [product_url] (+ 模特图)`,2196 行),但精准度受三件事拖累:
|
||||||
|
|
||||||
|
1. **只传 1 张商品图,而且取的是「主图」**
|
||||||
|
cover 模式用 `_product_cover_url()`——优先 `cover_asset`,其次标记为主图的图,再次第一张。
|
||||||
|
- 只有单张参考,信息量本来就少;
|
||||||
|
- 更关键:这张主图**可能本身就是之前 AI 生成的图**(不是真实商品照),等于「拿 AI 图再喂 AI」,误差累积,越生成越走样。
|
||||||
|
- 对比模特上身图模式(mode=model)用的是 `_product_reference_urls(limit=3)`——最多 3 张、且**主动排除 AI 生成图**、优先真实上传图。cover 没用这套,所以参考质量天然更差。
|
||||||
|
|
||||||
|
2. **是否真"编辑参考图"取决于当前图像模型**
|
||||||
|
- 默认 `tokenssr:gpt-image-2` 支持 `image_edit`(多图参考编辑),会真照着参考图改 → 较准;
|
||||||
|
- 若落到火山 Seedream(无 image_edit),只能走「图生图」,**只松散借个色调、不锁主体** → 这就是典型的「看起来没参考我的图」。
|
||||||
|
|
||||||
|
3. **平台差异没进提示词,更没进尺寸**
|
||||||
|
平台名只是一句空泛的「XX平台头图版式」,模型并不知道抖音要竖屏短视频封面、淘宝/天猫要 1:1 白底主图、小红书要 3:4 种草图。画幅由用户选的 ratio 统一决定,不按平台变。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 建议改法(按性价比排序,供参考)
|
||||||
|
|
||||||
|
1. **cover 也改用 `_product_reference_urls(limit=3)`**(多张真实图、排除 AI 图)——最小改动、收益最大,直接提升还原度。
|
||||||
|
2. **给每个平台写真正差异化的版式/画幅模板**(建议做成 admin 可编辑的 `PromptTemplate`,key 如 `platform_cover_douyin`),把平台的推荐比例、版式、调性写进去,并按平台自动选 ratio。
|
||||||
|
3. **确认线上默认图像模型是支持 image_edit 的 gpt-image-2**,避免悄悄落到只会图生图的 Seedream。
|
||||||
|
|
||||||
|
> 注:1、3 属于「改完需部署才生效」;当前 admin 提示词页可改的只有后端那段固定模板(key=`platform_cover`,目前各平台共用,不区分平台)。
|
||||||
@@ -0,0 +1,998 @@
|
|||||||
|
# 平台套图线上提示词优化版
|
||||||
|
|
||||||
|
> 基于 `D:/feishudownload/平台套图提示词梳理.md` 和当前仓库代码整理。
|
||||||
|
> 目标不是重写一套全新生图系统,而是在现在线上拼词链路上做最小可落地升级。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 0. 结论
|
||||||
|
|
||||||
|
现在线上提示词的图片丰富度来源于 6 个 `本张` 轮换版式,这部分应该保留。
|
||||||
|
|
||||||
|
真正要改的是:
|
||||||
|
|
||||||
|
1. 删除 `详情 / 详情排版 / 详情套图`,平台套图只生成头图、主图、封面图候选。
|
||||||
|
2. 平台差异不能再靠末尾一句 `{平台名}平台套图版式`,需要把 `platform_id` 传到后端。
|
||||||
|
3. 后端 `build_platform_cover_prompt_refs()` 在固定模板里注入平台块、品类块、模型块、背景反差块、文案块,但所有块都必须遵守“头图低信息密度上限”。
|
||||||
|
4. cover 参考图不要只取 `_product_cover_url()` 单张主图,应改用 `_product_reference_urls(limit=3)`,真实上传图优先、排除 AI 图。
|
||||||
|
5. 普通客户不要选择模型;前端只暴露平台、张数、比例、是否真人上身、是否需要文案等业务选项,后端按 `slot_name / category / copy_policy / platform_id` 自动路由 Seedream 或 image2。
|
||||||
|
6. 图片比例必须由后端 size / 后处理裁切保证,不能只在 prompt 里写比例。当前 `4:5` 会 fallback 成 `1:1`,这是比例错误的直接原因。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 0.1 原 MD 逐条迁移对照
|
||||||
|
|
||||||
|
原文件 `D:/feishudownload/平台套图提示词梳理.md` 不是废弃材料,下面这些结论必须全部继承。本文件在原结论上做低信息密度和比例修正。
|
||||||
|
|
||||||
|
| 原 MD 内容 | 是否迁移 | 新文档处理方式 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 10 个平台只有最后一句平台名不同 | 已迁移 | 改为必须传 `platform_id` 到后端,不再靠 `{平台名}平台套图版式`。 |
|
||||||
|
| 前端 base_prompt 是平台套图入口第一段 | 已迁移并修正 | 保留前端入口,但删除 `详情排版`,默认词改为“平台商品头图”。 |
|
||||||
|
| 后端 `build_platform_cover_prompt_refs()` 是真正发给模型的固定模板 | 已迁移 | 仍以这个函数为主改造点,新增 `platform_id / index / count / model_route / selected_model / target_ratio` 参数,其中 `selected_model` 仅内部覆盖。 |
|
||||||
|
| 有模特时参考图2是出镜模特 | 已迁移 | 保留模特参考逻辑,但内衣上身图新增“不得被其他衣物遮挡”的强约束。 |
|
||||||
|
| 6 个 `本张` 轮换版式能防雷同 | 已迁移并降噪 | 保留 6 个视觉骨架,但新增“头图低信息密度上限”,防止变成详情页。 |
|
||||||
|
| 各平台完整提示词只是最后一句不同 | 已迁移 | 不再复制原来的 10 条重复 prompt,改为 `PLATFORM_COVER_BLOCKS` 平台块。 |
|
||||||
|
| cover 参考图确实有传,但只传 1 张主图 | 已迁移 | P0 改为 `_product_reference_urls(product, limit=3)`。 |
|
||||||
|
| 主图可能是 AI 生成图,误差会累积 | 已迁移 | 继续使用 `_product_reference_urls` 的“真实上传图优先、排除 AI 图”规则。 |
|
||||||
|
| 模特上身图模式已经用多图真实参考 | 已迁移 | cover 向 model 模式看齐,也使用多张真实商品参考。 |
|
||||||
|
| 是否真编辑参考图取决于模型能力 | 已补充 | 新增模型能力检查:支持 `image_edit` 的模型优先;Seedream 需要按图生图能力单独降级预期。 |
|
||||||
|
| Seedream 只松散借色调,不锁主体 | 已迁移 | 内衣/商品一致性中把 Seedream 作为单独分支处理,不承诺同等参考锁定能力。 |
|
||||||
|
| 平台差异没进提示词,也没进尺寸 | 已迁移并扩展 | 新增平台块 + 平台尺寸表 + `target_ratio` 最终比例校验。 |
|
||||||
|
| 建议 1:cover 改用 `_product_reference_urls(limit=3)` | 已迁移 | P0 第 4 条。 |
|
||||||
|
| 建议 2:每个平台写真正差异化模板,最好 admin 可编辑 | 已补充 | 新增 `platform_cover_{platform_id}` 模板 key 建议;配置缺失时 fallback 到内置平台块。 |
|
||||||
|
| 建议 3:确认默认图像模型支持 image_edit | 已补充 | 新增模型能力与 fallback 规则,避免悄悄落到只会图生图的模型。 |
|
||||||
|
| 注:当前 admin 只有共用 `platform_cover` | 已补充 | 新增 admin 配置迁移方案,从单一 key 拆到平台 key。 |
|
||||||
|
|
||||||
|
不再逐字复制原 MD 里的 10 条平台示例 prompt,因为那些示例的价值是证明“它们完全一样”。新的实现应保留这个诊断结论,而不是保留重复 prompt 本身。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 当前线上问题对应代码
|
||||||
|
|
||||||
|
### 1.1 前端默认提示词
|
||||||
|
|
||||||
|
当前代码:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// core/frontend/src/routes/ai-tools.tsx
|
||||||
|
promptTemplate: (title) => `${title},电商平台套图,统一视觉,主图 + 详情排版`
|
||||||
|
```
|
||||||
|
|
||||||
|
问题:
|
||||||
|
|
||||||
|
- `详情排版` 会把模型引到详情页、长图、营销页。
|
||||||
|
- `电商平台套图` 太宽泛,不等于平台头图。
|
||||||
|
|
||||||
|
建议改为:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
promptTemplate: (title) => `${title},平台商品头图,统一视觉,商品主体清晰`
|
||||||
|
```
|
||||||
|
|
||||||
|
页面文案也建议从:
|
||||||
|
|
||||||
|
```text
|
||||||
|
选择平台模板,一键生成主图 / 封面 / 详情套图。
|
||||||
|
```
|
||||||
|
|
||||||
|
改为:
|
||||||
|
|
||||||
|
```text
|
||||||
|
选择平台模板,一键生成平台商品头图。
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.2 前端平台拼词
|
||||||
|
|
||||||
|
当前代码:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// core/frontend/src/routes/ai-tools.tsx
|
||||||
|
void startBatch({
|
||||||
|
...base,
|
||||||
|
prompt: platName ? `${base.prompt},${platName}平台套图版式` : base.prompt,
|
||||||
|
platformIds: [pid]
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
问题:
|
||||||
|
|
||||||
|
- `platformIds` 只存在前端 batch 展示里,没有传给后端。
|
||||||
|
- 后端实际只能看到 prompt 里那句平台名。
|
||||||
|
- 另一个多商品入口只传 `platformIds`,甚至没有把平台名拼进 prompt,两个入口不一致。
|
||||||
|
|
||||||
|
建议:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
void startBatch({
|
||||||
|
...base,
|
||||||
|
prompt: base.prompt,
|
||||||
|
platformId: pid,
|
||||||
|
platformIds: [pid]
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
并在 `onGenerate / api.submitGenerateImage / GenerateImageView / enqueue_standalone_images / request_payload` 全链路新增:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
platform_id?: string
|
||||||
|
```
|
||||||
|
|
||||||
|
后端任务需要保存:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"platform_id": "taobao",
|
||||||
|
"platform_name": "淘宝"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
不要再把平台名作为用户提示词的一部分。
|
||||||
|
|
||||||
|
### 1.3 后端固定模板
|
||||||
|
|
||||||
|
当前代码:
|
||||||
|
|
||||||
|
```py
|
||||||
|
def build_platform_cover_prompt_refs(product, has_model: bool, base_prompt: str = "") -> str:
|
||||||
|
lines = [f"参考图1是「{name}」的真实商品主图。"]
|
||||||
|
if has_model:
|
||||||
|
lines += [
|
||||||
|
"参考图2是出镜模特。请生成参考图2中的这位模特展示参考图1中商品的电商平台套图(主图 / 封面 / 详情);",
|
||||||
|
"模特的五官、发型、肤色、身形必须与参考图2高度一致,不要换人;",
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
lines.append("请基于该商品生成电商平台套图(主图 / 封面 / 详情排版),统一视觉风格;")
|
||||||
|
```
|
||||||
|
|
||||||
|
建议改为:
|
||||||
|
|
||||||
|
```py
|
||||||
|
def build_platform_cover_prompt_refs(
|
||||||
|
product,
|
||||||
|
*,
|
||||||
|
has_model: bool,
|
||||||
|
base_prompt: str = "",
|
||||||
|
platform_id: str = "taobao",
|
||||||
|
index: int = 0,
|
||||||
|
count: int = 4,
|
||||||
|
model_route: str = "",
|
||||||
|
selected_model: str = "", # 仅内部调试/强制覆盖使用,普通客户不传
|
||||||
|
product_ref_count: int = 1,
|
||||||
|
) -> str:
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
其中:
|
||||||
|
|
||||||
|
- `platform_id` 用于选择平台提示词块。
|
||||||
|
- `index` 用于选择本张 slot。
|
||||||
|
- `count` 用于 4/8/12 张变体。
|
||||||
|
- `model_route` 是后端按 slot 自动算出的模型路由结果,用于 image2 / Seedream 分支。
|
||||||
|
- `selected_model` 只作为内部调试或后台强制覆盖字段,普通客户不应看到也不应传。
|
||||||
|
- `product_ref_count` 用于写 `参考图1~N`,避免多图参考时 prompt 仍写只有参考图1。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 参考图策略
|
||||||
|
|
||||||
|
当前 cover 使用:
|
||||||
|
|
||||||
|
```py
|
||||||
|
product_url = _product_cover_url(product)
|
||||||
|
edit_images = [product_url] + ([model_url] if model_url else [])
|
||||||
|
```
|
||||||
|
|
||||||
|
建议 cover 也改为:
|
||||||
|
|
||||||
|
```py
|
||||||
|
product_urls = _product_reference_urls(product, limit=3)
|
||||||
|
edit_images = product_urls + ([model_url] if model_url else [])
|
||||||
|
```
|
||||||
|
|
||||||
|
提示词写法:
|
||||||
|
|
||||||
|
```text
|
||||||
|
参考图1~{{product_ref_count}} 是同一件商品的真实商品参考图,用于锁定商品外观、颜色、材质、结构、Logo、品牌文字和比例。
|
||||||
|
这些参考图只锁定商品本体,不锁定原图里的床品、桌面、墙面、绿植、毛巾、窗帘、道具和拍摄光线。
|
||||||
|
```
|
||||||
|
|
||||||
|
如果后端能生成 `product_cutout_ref`,商品图、结构图、细节图优先传去背景商品参考图。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 保留线上 6 个版式骨架
|
||||||
|
|
||||||
|
不要废掉线上这 6 类,它们是现在图片丰富度比较好的原因。
|
||||||
|
|
||||||
|
但不要原样写成“所有平台通用”,而是作为 slot,再被平台/品类/模型翻译。
|
||||||
|
|
||||||
|
```text
|
||||||
|
slot_1_hero:
|
||||||
|
正面居中主图版式,商品占画面主体,纯净背景,经典电商主图构图。
|
||||||
|
|
||||||
|
slot_2_selling_layout:
|
||||||
|
商品偏置 + 卖点文案分区,场景化背景,杂志感构图。
|
||||||
|
|
||||||
|
slot_3_detail_closeup:
|
||||||
|
特写细节版式,放大商品材质/做工,近景视角,突出质感。
|
||||||
|
|
||||||
|
slot_4_lifestyle_scene:
|
||||||
|
生活场景套图版式,商品置于真实使用情境,环境光,氛围感构图。
|
||||||
|
|
||||||
|
slot_5_multi_angle:
|
||||||
|
多角度组合版式,商品换一个朝向/视角,几何分区背景,现代简约风。
|
||||||
|
|
||||||
|
slot_6_promo_cover:
|
||||||
|
促销封面版式,留出标题/价签区,高对比配色,强视觉冲击构图。
|
||||||
|
```
|
||||||
|
|
||||||
|
4 张时不要总取前 4 个固定模板。应按平台和品类挑 4 个最适合的角色。
|
||||||
|
|
||||||
|
重要修正:
|
||||||
|
|
||||||
|
```text
|
||||||
|
这 6 个版式只是“画面丰富度骨架”,不是信息密度许可。
|
||||||
|
平台头图不是详情页。默认 4 张里不要出现参数表、长卖点列表、复杂箭头结构图、密集图标、2x3 信息宫格。
|
||||||
|
结构说明和细节宫格只能作为 8 / 12 张里的轻量辅图,而且必须像单张商品轮播头图,不像详情页截图。
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3.1 头图低信息密度上限
|
||||||
|
|
||||||
|
所有平台、所有模型都必须遵守:
|
||||||
|
|
||||||
|
```text
|
||||||
|
一张头图只讲一个视觉任务。
|
||||||
|
画面第一优先级是商品/上身效果/使用场景,不是文字信息。
|
||||||
|
商品或模特主体占画面 60%-80%,文字和装饰不能抢主体。
|
||||||
|
```
|
||||||
|
|
||||||
|
允许的信息量:
|
||||||
|
|
||||||
|
```text
|
||||||
|
无文案图:0 个字。适合首图、上身图、挂拍、生活场景、细节摄影。
|
||||||
|
轻文案图:1 个短标题,最多 8 个汉字左右;可加 1-2 个极短标签。
|
||||||
|
活动图:1 个品牌名 + 1 条活动短语,活动条只占底部或角落,不铺满画面。
|
||||||
|
轻细节图:1-2 个局部特写,可有极短标签;不要做成详情页的 4 宫格说明。
|
||||||
|
```
|
||||||
|
|
||||||
|
禁止的信息量:
|
||||||
|
|
||||||
|
```text
|
||||||
|
不要参数表、规格表、长句卖点、三段式说明、大量箭头、密集图标、2x3/3x3 宫格、左右对比详情页。
|
||||||
|
不要一张图同时出现品牌区、活动条、价格区、图标卖点、编号卖点、结构箭头和细节标签。
|
||||||
|
不要为了平台感写很多文字;平台感主要靠背景、镜头、主体占比、轻量版式和调色。
|
||||||
|
```
|
||||||
|
|
||||||
|
4 张默认角色应收敛为:
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. 商品/上身主视觉:无文案。
|
||||||
|
2. 场景主视觉:挂拍、生活场景、手部整理、穿搭准备,无文案或 1 个极短标题。
|
||||||
|
3. 轻卖点封面:商品主体 + 1 个短标题 + 最多 2 个短标签。
|
||||||
|
4. 质感特写:材质/扣位/肩带/细节摄影,无文案或 1 个短标签。
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 平台提示词块
|
||||||
|
|
||||||
|
后端维护 `PLATFORM_COVER_BLOCKS`。
|
||||||
|
|
||||||
|
### 淘宝
|
||||||
|
|
||||||
|
```text
|
||||||
|
平台:淘宝。
|
||||||
|
画面像淘宝搜索货架和商品主图,移动端缩略图下商品一眼可识别。
|
||||||
|
常见结构:左上小品牌区、中央或偏右商品主体、底部活动条或底部轻卖点条、成人模特上身、挂拍、局部质感特写。
|
||||||
|
内衣类默认 4 张优先成人模特上身、挂拍/场景、轻卖点封面、质感特写;图标卖点、编号卖点、结构说明、细节宫格只作为 8/12 张轻量辅图,不进入默认 4 张。
|
||||||
|
背景干净但不能单调,允许浅灰棚拍、浅色墙面、试衣间背景、窗边挂拍、干净台面。
|
||||||
|
禁止生成详情页、长图、平台 UI、二维码、直播间界面、虚假价格和未提供折扣。
|
||||||
|
```
|
||||||
|
|
||||||
|
### 天猫
|
||||||
|
|
||||||
|
```text
|
||||||
|
平台:天猫。
|
||||||
|
画面像品牌旗舰店商品首图,品牌感、质感、留白、材质光影更重要。
|
||||||
|
常见结构:品牌主视觉、材质背景、精致展台、克制卖点区、少量品牌文案。
|
||||||
|
促销感弱于淘宝,不要大红大黄低价感,不要拼多多式强利益区。
|
||||||
|
```
|
||||||
|
|
||||||
|
### 京东
|
||||||
|
|
||||||
|
```text
|
||||||
|
平台:京东。
|
||||||
|
画面像京东商品主图,清晰、可信、理性、标准。
|
||||||
|
常见结构:白底/浅灰商品图、克制品质短标题、包装/配件/材质细节。
|
||||||
|
信息区要非常少,只允许 1 个短标题或 1-2 个短标签;不要参数表、功能说明长区、详情页式模块,不要小红书滤镜,不要强生活方式过度氛围。
|
||||||
|
```
|
||||||
|
|
||||||
|
### 拼多多
|
||||||
|
|
||||||
|
```text
|
||||||
|
平台:拼多多。
|
||||||
|
画面像拼多多商品主图或活动头图,主体大、信息直接、利益区明显。
|
||||||
|
可以有高对比活动区和大标题,但只讲一个利益点;不能编造价格、优惠、折扣、销量和平台补贴。
|
||||||
|
背景明亮,商品边缘清楚,不要复杂品牌大片感。
|
||||||
|
```
|
||||||
|
|
||||||
|
### 抖音电商
|
||||||
|
|
||||||
|
```text
|
||||||
|
平台:抖音电商。
|
||||||
|
画面像信息流商品封面和短视频电商封面,近景、强裁切、真实使用瞬间、动作感更强。
|
||||||
|
常见背景:衣橱、梳妆台、卧室、开箱、手部整理、拿取、穿搭准备。
|
||||||
|
文案更短,商品主体更大,适合快速停留。
|
||||||
|
不要生成抖音 UI、播放按钮、直播间贴片、字幕条,也不要套淘宝底部活动条。
|
||||||
|
```
|
||||||
|
|
||||||
|
### 小红书
|
||||||
|
|
||||||
|
```text
|
||||||
|
平台:小红书。
|
||||||
|
画面像生活方式笔记封面,自然光、真实体验、种草氛围。
|
||||||
|
常见背景:卧室、衣橱、梳妆台、桌面、浴室、旅行收纳、通勤准备。
|
||||||
|
标题像用户体验表达,少硬广、少参数表、少促销条。
|
||||||
|
```
|
||||||
|
|
||||||
|
### 快手
|
||||||
|
|
||||||
|
```text
|
||||||
|
平台:快手。
|
||||||
|
画面像快手小店商品图或直播前置封面素材,真实、直接、可信。
|
||||||
|
可以有桌面展示、手持展示、打包台、家中真实环境、开箱场景。
|
||||||
|
不要生成直播 UI、主播贴片和平台水印。
|
||||||
|
```
|
||||||
|
|
||||||
|
### 视频号
|
||||||
|
|
||||||
|
```text
|
||||||
|
平台:视频号/微信小店。
|
||||||
|
画面克制可信,适合社交分享和商品卡。
|
||||||
|
背景可用干净家居、礼赠、办公、生活空间、柔和自然光。
|
||||||
|
不要生成微信聊天界面、二维码、公众号 UI。
|
||||||
|
```
|
||||||
|
|
||||||
|
### 亚马逊
|
||||||
|
|
||||||
|
```text
|
||||||
|
平台:亚马逊。
|
||||||
|
第 1 张必须是 MAIN 合规图:纯白背景,只展示售卖商品本体,无文字、无道具、无边框、无水印,商品占画面主要区域。
|
||||||
|
第 2 张以后可以是 Lifestyle、Feature、Size、Detail、Package 辅图。
|
||||||
|
不要生成 Amazon 徽章、评分、排名、优惠和平台 UI。
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1688
|
||||||
|
|
||||||
|
```text
|
||||||
|
平台:1688。
|
||||||
|
画面像批发采购图,商品清楚,偏规格、材质、工艺、包装、供货信息。
|
||||||
|
背景可用白底、浅灰、工厂台面、仓储、包装台、材料/工艺背景。
|
||||||
|
头图仍然保持低信息密度,只允许 1 个短标题或 1-2 个短标签;不要做成规格表详情页。不要虚构工厂资质、库存、起订量、认证和价格。
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4.1 Admin PromptTemplate 拆分
|
||||||
|
|
||||||
|
原 MD 里提到:当前 admin 提示词页可改的只有后端共用模板 `platform_cover`,不区分平台。这一点要保留为开发改造项。
|
||||||
|
|
||||||
|
建议模板 key:
|
||||||
|
|
||||||
|
```text
|
||||||
|
platform_cover_base
|
||||||
|
platform_cover_taobao
|
||||||
|
platform_cover_tmall
|
||||||
|
platform_cover_jd
|
||||||
|
platform_cover_pdd
|
||||||
|
platform_cover_douyin
|
||||||
|
platform_cover_xhs
|
||||||
|
platform_cover_kuaishou
|
||||||
|
platform_cover_wechat
|
||||||
|
platform_cover_amazon
|
||||||
|
platform_cover_1688
|
||||||
|
```
|
||||||
|
|
||||||
|
读取规则:
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. 先读 platform_cover_base,放商品锁定、头图范围、低信息密度、通用负面约束。
|
||||||
|
2. 再读 platform_cover_{platform_id},放平台调性、默认比例、平台版式倾向。
|
||||||
|
3. 如果平台 key 不存在,fallback 到代码内置 PLATFORM_COVER_BLOCKS。
|
||||||
|
4. 不允许继续用一个 platform_cover 模板服务所有平台。
|
||||||
|
```
|
||||||
|
|
||||||
|
这样 UI 设计师后续可以在 admin 中单独微调淘宝、抖音、小红书等平台的提示词,不需要每次改代码。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4.2 模型能力检查
|
||||||
|
|
||||||
|
原 MD 里提到:是否真“编辑参考图”取决于当前图像模型。这是参考不精准的核心原因之一,需要作为任务创建前的能力检查。
|
||||||
|
|
||||||
|
规则:
|
||||||
|
|
||||||
|
```text
|
||||||
|
resolved_model = selected_model_override or model_route_result
|
||||||
|
|
||||||
|
if mode = cover and resolved_model supports image_edit:
|
||||||
|
使用多图参考 edit_images,商品外观锁定预期较高。
|
||||||
|
|
||||||
|
if mode = cover and resolved_model does not support image_edit:
|
||||||
|
明确标记 reference_lock_level = weak。
|
||||||
|
prompt 中仍传商品参考,但不能承诺严格编辑参考图。
|
||||||
|
需要更强商品锁定提示,并优先使用 product_cutout_ref。
|
||||||
|
|
||||||
|
if resolved_model = Seedream:
|
||||||
|
按图生图 / 参考图生成能力处理,商品外观可能只松散继承。
|
||||||
|
不要把 Seedream 和 gpt-image-2 写成同等参考锁定能力。
|
||||||
|
|
||||||
|
if resolved_model = gpt-image-2 / image2:
|
||||||
|
优先使用 image_edit 能力;若当前网关实际不支持 reference image,则必须在 debug metadata 标记 image_edit_unavailable。
|
||||||
|
```
|
||||||
|
|
||||||
|
任务 debug metadata 必须保存:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"model_route": "auto / seedream / image2 / overlay_text",
|
||||||
|
"resolved_model": "seedream / gpt-image-2 / image2",
|
||||||
|
"selected_model": "",
|
||||||
|
"model_route_reason": "slot_name + category + copy_policy",
|
||||||
|
"override_by_user": false,
|
||||||
|
"supports_image_edit": true,
|
||||||
|
"reference_lock_level": "strong / weak",
|
||||||
|
"product_ref_count": 3,
|
||||||
|
"used_real_uploaded_refs": true,
|
||||||
|
"used_ai_generated_cover_ref": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4.3 自动模型路由策略
|
||||||
|
|
||||||
|
实测结论:不要让普通客户手动选择 Seedream / image2。商家只关心平台、张数、比例、是否真人上身、是否需要文案;模型选择应由后端按图片角色自动决定。
|
||||||
|
|
||||||
|
后台可以保留 `selected_model` 作为调试开关,但线上默认使用 `model_route = auto`。
|
||||||
|
|
||||||
|
```text
|
||||||
|
默认模型分工:
|
||||||
|
|
||||||
|
Seedream:
|
||||||
|
- 适合内衣/服饰真人上身图。
|
||||||
|
- 适合淘宝感、卖货感、轻营销封面。
|
||||||
|
- 可以生成少量中文卖点,但仍必须限制在 allowed_copy_text。
|
||||||
|
|
||||||
|
image2:
|
||||||
|
- 适合无字商品摄影。
|
||||||
|
- 适合挂拍、平铺、收纳、材质、肩带、背扣、边缘走线等细节图。
|
||||||
|
- 对假品牌、假 Logo、信息图漂移更可控。
|
||||||
|
- 不建议直接生成成人内衣真人上身图。
|
||||||
|
|
||||||
|
overlay_text:
|
||||||
|
- 当文案必须准确时,模型只生成无字图,再由前端/后端叠字。
|
||||||
|
- 不依赖模型生成价格、折扣、品牌名、卖点短句或平台合规文案。
|
||||||
|
```
|
||||||
|
|
||||||
|
路由规则:
|
||||||
|
|
||||||
|
```text
|
||||||
|
if category in ["服饰内衣", "内衣", "泳衣", "贴身衣物"] and slot_name = clean_on_model_hero:
|
||||||
|
model_route = seedream
|
||||||
|
display_mode = on_model
|
||||||
|
copy_policy = none
|
||||||
|
|
||||||
|
if slot_name in ["product_hanging_scene", "flat_lay_lifestyle_scene", "texture_detail_photo", "package_or_material_context"]:
|
||||||
|
model_route = image2
|
||||||
|
copy_policy = none
|
||||||
|
|
||||||
|
if slot_name = light_selling_cover:
|
||||||
|
if copy_must_be_accurate = true:
|
||||||
|
model_route = image2 + overlay_text
|
||||||
|
copy_policy = none_for_model_then_overlay
|
||||||
|
else:
|
||||||
|
model_route = seedream
|
||||||
|
copy_policy = selling_point_copy
|
||||||
|
|
||||||
|
if platform_id = amazon and amazon_slot = MAIN:
|
||||||
|
model_route = image2
|
||||||
|
copy_policy = none
|
||||||
|
background = pure_white
|
||||||
|
|
||||||
|
if selected_model is provided by internal debug/admin:
|
||||||
|
selected_model can override model_route, but debug metadata must record override_by_user = true.
|
||||||
|
```
|
||||||
|
|
||||||
|
内衣默认 4 张推荐路由:
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. clean_on_model_hero → Seedream
|
||||||
|
成人模特直接穿着内衣,无文案。
|
||||||
|
|
||||||
|
2. product_hanging_scene → image2
|
||||||
|
挂拍/衣架/窗边/衣橱,无文案。
|
||||||
|
|
||||||
|
3. light_selling_cover → Seedream 或 image2 + overlay_text
|
||||||
|
若只要氛围卖点图,可用 Seedream 直接生成少量短文案;
|
||||||
|
若要求文字准确、可控、可改,必须用 image2 生成无字图后叠字。
|
||||||
|
|
||||||
|
4. texture_detail_photo → image2
|
||||||
|
面料、肩带、背扣、边缘走线等单个细节,无文案。
|
||||||
|
```
|
||||||
|
|
||||||
|
前端交互原则:
|
||||||
|
|
||||||
|
```text
|
||||||
|
普通客户不显示模型下拉框。
|
||||||
|
普通客户只选择:平台、图片数量、比例、是否真人上身、是否需要文案、视觉偏好。
|
||||||
|
高级调试/运营后台才显示模型覆盖选项。
|
||||||
|
```
|
||||||
|
|
||||||
|
混合模型成套感约束:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Seedream 和 image2 可以混合生成同一套图,但不能只靠 slot 自己发挥。
|
||||||
|
后端必须为同一批次生成 visual_system_guard,并注入每一张 prompt。
|
||||||
|
|
||||||
|
visual_system_guard 至少包含:
|
||||||
|
- 统一商品主色:商品颜色、材质、结构不能随模型改变。
|
||||||
|
- 统一背景色系:同一批次限定 1-2 个背景色族,例如冷灰 / 蓝灰 / 浅灰,不允许一张深灰商业棚拍、一张暖白生活大片差太远。
|
||||||
|
- 统一背景明度:默认中浅灰到浅灰,不要 Seedream 过深、image2 过白;除白底合规图外,不要纯白大底。
|
||||||
|
- 统一光线:柔和自然光或柔和棚拍二选一,同一批次不要混用夜景、强硬光、暖黄家居光和冷灰棚拍。
|
||||||
|
- 统一构图气质:高端淘宝轮播商品摄影,主体大、低信息密度、留白克制。
|
||||||
|
- 统一后处理:输出后可做轻量色温/亮度/对比度归一化,让不同模型看起来像同一品牌同一天拍摄。
|
||||||
|
|
||||||
|
若混合模型结果看起来不是一套,优先修 visual_system_guard 和后处理,不退回让客户手动选模型。
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 背景反差规则
|
||||||
|
|
||||||
|
新增后端字段:
|
||||||
|
|
||||||
|
```text
|
||||||
|
product_color_family = 从商品图或商品数据识别出的主色
|
||||||
|
background_contrast_guard = 根据主色生成的背景避让规则
|
||||||
|
```
|
||||||
|
|
||||||
|
直接写进 prompt:
|
||||||
|
|
||||||
|
```text
|
||||||
|
背景必须和商品主色形成清楚反差,不能让商品和背景同色相融。
|
||||||
|
浅色商品不要使用奶白、浅米、浅粉等近似大面积背景;优先使用冷灰、蓝灰、浅绿、浅薰衣草、自然木色、明确投影或边缘光。
|
||||||
|
黑色/深色商品不要使用黑色、深灰、深棕大背景;优先使用暖白、浅灰、肤色墙面、浅木色或日光窗边背景。
|
||||||
|
粉色/红色商品不要使用同色粉红或红色大背景;优先白、浅灰、浅绿、浅蓝、自然木色。
|
||||||
|
除亚马逊 MAIN 或明确白底 slot 外,不要把整组图片都做成白底/浅灰底。
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 内衣类模型分支
|
||||||
|
|
||||||
|
### 6.1 Seedream
|
||||||
|
|
||||||
|
Seedream 可以生成成人内衣上身图,但容易出现其他衣服污染。
|
||||||
|
|
||||||
|
Seedream 内衣上身图必须注入:
|
||||||
|
|
||||||
|
```text
|
||||||
|
这是真人试穿商品头图任务。
|
||||||
|
必须生成成人模特直接穿着参考商品图中的内衣,内衣是唯一服饰重点。
|
||||||
|
罩杯、肩带、下围、杯型、面料、颜色和关键版型必须完整可见,并与参考商品一致。
|
||||||
|
不要出现 T 恤、衬衫、吊带背心、运动上衣、连衣裙、制服、职业装、厚外套或任何遮挡内衣主体的第二件衣服。
|
||||||
|
不要把内衣穿在其他衣物外面,也不要在内衣下面加一层衣服。
|
||||||
|
最多允许轻薄开衫、薄纱或披肩松散搭在肩膀/手臂外侧,但不得盖住罩杯、肩带、下围和关键版型。
|
||||||
|
画面是正规电商服饰目录拍摄,成人、克制、商品展示向,非性感化,非挑逗姿势。
|
||||||
|
本张默认无文案,不要活动条、卖点图标和复杂模板。
|
||||||
|
镜头建议为脖颈以下到腰部/胯部以上的上半身商品目录构图,模特正面或轻微侧身,罩杯、肩带、下围和背带结构不能被裁切。
|
||||||
|
不要生成时尚大片、写真大片、暧昧姿势、夸张首饰、纹身、强烈夜店光、品牌水印、伪水印或角落签名。
|
||||||
|
```
|
||||||
|
|
||||||
|
Seedream 内衣 4 张推荐:
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. clean_on_model_hero:成人模特直接穿着内衣,干净上身主视觉,无文案。
|
||||||
|
2. hanging_or_lifestyle_scene:窗边挂拍、衣橱、手部整理或轻生活场景,无文案。
|
||||||
|
3. light_selling_cover:商品主体 + 1 个短标题 + 最多 2 个短标签,不出现真人。
|
||||||
|
4. texture_detail_photo:面料、肩带、扣位或边缘走线的质感特写,无文案或 1 个短标签。
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.2 image2
|
||||||
|
|
||||||
|
image2 更稳定,但成人内衣真人上身容易被安全策略拦截。
|
||||||
|
|
||||||
|
image2 内衣套图不能退化成 4 张相似浅色商品图。推荐角色:
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. product_hanging_scene:挂拍/衣架/窗边/衣橱,自然光,无文案。
|
||||||
|
2. flat_lay_lifestyle_scene:平铺或手部整理,桌面/收纳/旅行场景,无真人身体。
|
||||||
|
3. light_selling_cover:商品主体 + 1 个平台化短标题 + 最多 2 个短标签,文案来自 allowed_copy_text。
|
||||||
|
4. texture_detail_photo:单个材质/肩带/背扣/边缘走线特写,无文案或 1 个短标签。
|
||||||
|
5. soft_shape_display:隐形人台或立体轮廓,无真人皮肤,无复杂标签。
|
||||||
|
6. ghost_mannequin_shape_display:隐形人台或立体轮廓,无真人皮肤。
|
||||||
|
7. package_or_material_context:包装、材质、收纳、洗护或手感场景,不虚构配件。
|
||||||
|
```
|
||||||
|
|
||||||
|
4 张至少选择 4 个不同角色,但不能选择“结构说明图 + 细节宫格 + 卖点信息图”这种组合;默认组合应是挂拍、生活平铺、轻卖点封面、质感特写。
|
||||||
|
|
||||||
|
image2 实测会主动把“主图/卖点/信息图/模板”理解成多文字海报,所以 `copy_policy = none` 的 slot 不要使用这些词。应改写成“纯商品摄影、无文字、无标签、无图标、无排版模块、无海报感”。若需要文案,优先后期叠字,不依赖模型生成准确文字。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 文案生成规则
|
||||||
|
|
||||||
|
不要只照抄商品库卖点,也不要让模型自由编。
|
||||||
|
|
||||||
|
后端先生成 `copy_plan`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"product_display_name_for_prompt": "黑色夏薄款文胸",
|
||||||
|
"cover_headline": "夏日轻薄透气",
|
||||||
|
"cover_subpoints": ["清爽透气", "日常舒适", "穿着不闷"],
|
||||||
|
"allowed_copy_text": ["夏日轻薄透气", "清爽透气", "日常舒适", "穿着不闷"],
|
||||||
|
"copy_sources": {
|
||||||
|
"夏日轻薄透气": ["title: 夏薄款", "selling_points[0]: 透气"],
|
||||||
|
"清爽透气": ["selling_points[0]: 透气"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
允许:
|
||||||
|
|
||||||
|
- 把 `透气` 丰富成 `夏日透气不闷`、`清爽透气感`。
|
||||||
|
- 把标题里的类目/季节/款式和卖点合成短标题。
|
||||||
|
- 按平台语气调整表达。
|
||||||
|
|
||||||
|
禁止:
|
||||||
|
|
||||||
|
- 商品数据没有的价格、折扣、销量、排名、认证、百分比、杯型范围、尺码、明星同款。
|
||||||
|
- 把普通卖点扩成强功效或绝对承诺。
|
||||||
|
- 把完整 SEO 标题直接塞给生图模型。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7.1 图片比例修正
|
||||||
|
|
||||||
|
当前比例错误不是提示词问题,而是后端 size 映射问题。
|
||||||
|
|
||||||
|
当前代码:
|
||||||
|
|
||||||
|
```py
|
||||||
|
def _ratio_to_image_size(ratio: str) -> str:
|
||||||
|
return {
|
||||||
|
"1:1": "1024x1024",
|
||||||
|
"3:4": "1024x1536",
|
||||||
|
"9:16": "1024x1536",
|
||||||
|
"4:3": "1536x1024",
|
||||||
|
"16:9": "1536x864",
|
||||||
|
}.get((ratio or "").strip(), "1024x1024")
|
||||||
|
```
|
||||||
|
|
||||||
|
问题:
|
||||||
|
|
||||||
|
```text
|
||||||
|
平台套图前端默认 ratio = 4:5,但后端没有 4:5,所以 fallback 成 1024x1024。
|
||||||
|
3:4 和 9:16 都映射成 1024x1536,实际是 2:3,不是 3:4,也不是 9:16。
|
||||||
|
如果使用 YunQi gpt-image-2,网关只支持 1024x1024 / 1024x1536 / 1536x1024 这类固定 size,无法直接生成精确 4:5。
|
||||||
|
混合模型时原始输出尺寸会不一致:实测同一批 target_ratio = 1:1,Seedream 返回 1664x2496,image2 返回 1024x1024。
|
||||||
|
```
|
||||||
|
|
||||||
|
必须改:
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. 后端 request_payload 必须保存用户选择的 target_ratio。
|
||||||
|
2. 后端必须根据 platform_id + target_ratio 算出同批次唯一 target_export_size,例如 1:1 = 1200x1200,3:4 = 900x1200,4:5 = 960x1200。
|
||||||
|
3. 如果模型支持目标比例,就直接用最接近且不低于 target_export_size 的 size。
|
||||||
|
4. 如果模型只支持固定 size,就先生成最接近且覆盖目标画幅的尺寸,再做主体保护裁切或补边。
|
||||||
|
5. 所有模型返回的原图都必须进入同一个 normalize_output_image() 后处理,最终返回给用户的同一批图片必须是完全相同的 width x height,而不只是比例相同。
|
||||||
|
6. prompt 里可以写“1:1 方图构图 / 4:5 构图”,但不能依赖 prompt 保证最终像素比例或最终像素尺寸。
|
||||||
|
```
|
||||||
|
|
||||||
|
同批次导出契约:
|
||||||
|
|
||||||
|
```text
|
||||||
|
batch_target_ratio = 用户选择或 platform_default_ratio
|
||||||
|
batch_target_export_size = 后端根据 platform_id + target_ratio 决定
|
||||||
|
|
||||||
|
每张图生成后必须执行:
|
||||||
|
1. 读取 raw_width / raw_height。
|
||||||
|
2. 按 batch_target_ratio 做主体保护裁切或补边。
|
||||||
|
3. resize 到 batch_target_export_size。
|
||||||
|
4. 写入 normalized_width / normalized_height / crop_or_pad_method 到 debug metadata。
|
||||||
|
5. 返回给前端和素材库的只能是 normalized image,不返回 raw image。
|
||||||
|
```
|
||||||
|
|
||||||
|
normalize_output_image() 推荐策略:
|
||||||
|
|
||||||
|
```text
|
||||||
|
优先主体保护裁切:适合商品主体完整、背景足够的图。
|
||||||
|
主体会被裁掉时改用补边:使用同批次背景色 / 模糊延展 / 纯净浅灰补边,不改变商品本体。
|
||||||
|
禁止直接拉伸变形。
|
||||||
|
禁止同一批次有的图 1664x2496、有的图 1024x1024 直接进入素材库。
|
||||||
|
```
|
||||||
|
|
||||||
|
建议平台默认比例:
|
||||||
|
|
||||||
|
```text
|
||||||
|
淘宝 / 天猫 / 京东 / 拼多多 / 快手 / 视频号 / 1688:默认 1:1,适合商品上架主图。
|
||||||
|
亚马逊 MAIN:默认 1:1,纯白合规主图。
|
||||||
|
抖音电商:商品上架主图默认 1:1;鞋包服饰类可额外支持 3:4,但不是默认全平台 4:5。
|
||||||
|
小红书:商城商品主图默认 1:1;如果用户明确选择“笔记封面 / 种草封面”,再用 3:4。
|
||||||
|
不要把内容流封面比例直接当商品上架主图比例。
|
||||||
|
```
|
||||||
|
|
||||||
|
验收标准:
|
||||||
|
|
||||||
|
```text
|
||||||
|
用户选 1:1,最终图片像素比例必须是 1:1。
|
||||||
|
用户选 4:5,最终图片像素比例必须是 4:5,不能返回 1:1。
|
||||||
|
用户选 3:4,最终图片像素比例必须是 3:4,不能返回 2:3。
|
||||||
|
用户选 9:16,最终图片像素比例必须是 9:16,不能返回 2:3。
|
||||||
|
同一批平台套图的最终图片必须是完全相同的像素尺寸,例如全部 1200x1200,不能混用 1664x2496 和 1024x1024。
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7.2 各平台头图尺寸调研
|
||||||
|
|
||||||
|
这里的“头图尺寸”按用户可直接上架的商品主图 / 商品轮播图理解,不按短视频封面、笔记封面或店铺装修 banner 理解。
|
||||||
|
|
||||||
|
结论:
|
||||||
|
|
||||||
|
```text
|
||||||
|
大多数电商商品主图仍然以 1:1 方图为默认安全规格。
|
||||||
|
服饰、鞋包、内衣等展示类目常见 3:4 长图,但通常是类目/素材位扩展,不应替代所有平台默认比例。
|
||||||
|
小红书、抖音等内容平台的“内容封面”可以是 3:4、4:5 或 9:16,但“商品上架主图”仍要优先按商品图规则处理。
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.2.1 平台尺寸表
|
||||||
|
|
||||||
|
| platform_id | 平台 | 商品上架主图默认比例 | 常见/可选比例 | 建议最终导出尺寸 | 备注 |
|
||||||
|
| --- | --- | --- | --- | --- | --- |
|
||||||
|
| `taobao` | 淘宝 | `1:1` | 服饰/部分类目可用 `3:4` | `1:1` 用 `1200x1200` 或至少 `800x800`;`3:4` 用 `750x1000` 或更高等比 | 不要默认 4:5。平台头图首图仍优先方图;服饰/内衣可按用户或类目切到 3:4。 |
|
||||||
|
| `tmall` | 天猫 | `1:1` | 服饰/部分类目可用 `3:4` | `1:1` 用 `1200x1200` 或至少 `800x800`;`3:4` 用 `750x1000` 或更高等比 | 与淘宝类似,但视觉更品牌化。 |
|
||||||
|
| `jd` | 京东 | `1:1` | 可支持 `3:4` 长图 | 方图最终限制在平台可接受区间内,建议 `1200x1200`;长图可用 `750x1000` | 京东公开公告提到主图方图和长图均有尺寸范围,不要把京东做成内容流竖封。 |
|
||||||
|
| `pdd` | 拼多多 | `1:1` | 活动素材位可能有横版特殊图 | 商品轮播图建议 `800x800` 或 `1000x1000`,至少不低于 `480x480` | 商品主轮播图保守按方图;活动横图不是平台套图默认输出。 |
|
||||||
|
| `douyin` | 抖音电商 | `1:1` | 鞋包服饰类可用 `3:4`;内容流封面另算 | 方图至少 `600x600`,白底/场景建议 `800x800`;服饰 3:4 可用 `750x1000` | 商品上架主图不是短视频封面。只有用户明确要信息流封面时,才走 3:4/9:16。 |
|
||||||
|
| `xhs` | 小红书 | 商城商品主图优先 `1:1` | 店铺商品也常见 `3:4`;笔记封面推荐 `3:4` | 商城商品主图 `800x800` 或 `750x1000`;笔记封面可用 `1080x1440` / `1242x1660` | 如果目标是“商品上架”,默认 1:1;如果目标是“种草笔记封面”,才默认 3:4。 |
|
||||||
|
| `kuaishou` | 快手 | `1:1` | 可按类目支持 `3:4`,但不作为默认 | 建议 `800x800` 或更高方图 | 快手规则强调商品主图为 1:1,至少 3 张清晰主图。 |
|
||||||
|
| `wechat` | 视频号 / 微信小店 | `1:1` | 社交封面可另配竖版,但商品主图保守方图 | 建议 `800x800` 方图 | 公开资料未给稳定统一像素规格,具体以微信小店后台提示为准;系统默认不要 4:5。 |
|
||||||
|
| `amazon` | 亚马逊 | MAIN 图建议 `1:1` 方图输出 | 辅图可有生活方式/尺寸说明,但仍建议统一商品图比例 | MAIN 建议 `1600x1600`,至少最长边 `1000px`;平台接受最长边 `500-10000px` | MAIN 图必须纯白背景、无文案、无道具,商品填充约 85%。 |
|
||||||
|
| `1688` | 1688 | `1:1` 或近似方图 | B2B 信息图仍保持方图或近方图 | 建议 `750x750` / `800x800` / `1000x1000` | 1688/阿里系 B2B 主图倾向正方形或近正方形,不能默认竖封。 |
|
||||||
|
|
||||||
|
### 7.2.2 平台比例选择规则
|
||||||
|
|
||||||
|
```text
|
||||||
|
如果用户未手动选择比例:
|
||||||
|
使用 platform_default_ratio。
|
||||||
|
|
||||||
|
如果用户手动选择比例:
|
||||||
|
仍应尊重用户选择,但最终图片必须真实裁切/补边到该比例。
|
||||||
|
|
||||||
|
如果用户选择的平台默认不适合该比例:
|
||||||
|
前端可以给轻提示,例如“淘宝/京东/拼多多商品主图通常建议 1:1,当前选择 4:5 可能不适合直接上架”。
|
||||||
|
|
||||||
|
如果用户目标是“内容封面”而非“商品上架主图”:
|
||||||
|
抖音 / 小红书 / 快手 / 视频号可使用 3:4、4:5 或 9:16,但 prompt 中必须标记 cover_usage = content_feed_cover。
|
||||||
|
|
||||||
|
如果目标是“商品上架主图”:
|
||||||
|
不要默认使用 4:5。
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.2.3 建议配置
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const PLATFORM_RATIO_PRESETS = {
|
||||||
|
taobao: {
|
||||||
|
listingDefault: "1:1",
|
||||||
|
apparelOptional: "3:4",
|
||||||
|
finalSizes: { "1:1": "1200x1200", "3:4": "750x1000" }
|
||||||
|
},
|
||||||
|
tmall: {
|
||||||
|
listingDefault: "1:1",
|
||||||
|
apparelOptional: "3:4",
|
||||||
|
finalSizes: { "1:1": "1200x1200", "3:4": "750x1000" }
|
||||||
|
},
|
||||||
|
jd: {
|
||||||
|
listingDefault: "1:1",
|
||||||
|
optional: "3:4",
|
||||||
|
finalSizes: { "1:1": "1200x1200", "3:4": "750x1000" }
|
||||||
|
},
|
||||||
|
pdd: {
|
||||||
|
listingDefault: "1:1",
|
||||||
|
finalSizes: { "1:1": "1000x1000" }
|
||||||
|
},
|
||||||
|
douyin: {
|
||||||
|
listingDefault: "1:1",
|
||||||
|
apparelOptional: "3:4",
|
||||||
|
contentCoverOptional: "9:16",
|
||||||
|
finalSizes: { "1:1": "1000x1000", "3:4": "750x1000", "9:16": "1080x1920" }
|
||||||
|
},
|
||||||
|
xhs: {
|
||||||
|
listingDefault: "1:1",
|
||||||
|
shopOptional: "3:4",
|
||||||
|
noteCoverDefault: "3:4",
|
||||||
|
finalSizes: { "1:1": "1080x1080", "3:4": "1080x1440" }
|
||||||
|
},
|
||||||
|
kuaishou: {
|
||||||
|
listingDefault: "1:1",
|
||||||
|
finalSizes: { "1:1": "1000x1000" }
|
||||||
|
},
|
||||||
|
wechat: {
|
||||||
|
listingDefault: "1:1",
|
||||||
|
finalSizes: { "1:1": "1000x1000" }
|
||||||
|
},
|
||||||
|
amazon: {
|
||||||
|
listingDefault: "1:1",
|
||||||
|
finalSizes: { "1:1": "1600x1600" }
|
||||||
|
},
|
||||||
|
"1688": {
|
||||||
|
listingDefault: "1:1",
|
||||||
|
finalSizes: { "1:1": "1000x1000" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.2.4 对当前产品的直接修正
|
||||||
|
|
||||||
|
```text
|
||||||
|
平台套图页面不要再全局默认 4:5。
|
||||||
|
默认比例应改为“自动:按平台推荐”。
|
||||||
|
如果开发暂时不做自动比例,保守默认应改成 1:1,而不是 4:5。
|
||||||
|
比例选择器保留 1:1 / 3:4 / 4:5 / 9:16 / 16:9,但 4:5 不作为任何商品上架主图默认值。
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.2.5 尺寸来源与可信度
|
||||||
|
|
||||||
|
```text
|
||||||
|
官方公开规范优先,其次使用平台商家后台公告、平台学习中心、主流设计工具/服务商整理。
|
||||||
|
淘宝、天猫、拼多多、微信小店、小红书店铺等平台部分尺寸规则会按类目和后台版本变化,公开网页不一定完整;最终实现应保留后台配置能力。
|
||||||
|
```
|
||||||
|
|
||||||
|
参考链接:
|
||||||
|
|
||||||
|
- 抖音电商学习中心《商品主图发布规范》:https://school.jinritemai.com/doudian/web/article/aHean96XQDdv
|
||||||
|
- 抖音小店物料尺寸整理:https://www.canva.cn/learn/douyin-size/
|
||||||
|
- 京东主图尺寸放宽公告入口:https://mtt.m.jd.com/article/articleView/6bcf496d-ed86-46fe-9667-f0878bf97d35.action
|
||||||
|
- 快手电商《商品信息诊断规则》:https://edu.kwaixiaodian.com/rule/web/detail?id=yOOEScxkb9
|
||||||
|
- 微信小店商品素材准备 FAQ:https://e.qq.com/faq/wechat-store/product-listing/faq-spsj-002/
|
||||||
|
- Amazon Seller Central 商品图片指南:https://sellercentral.amazon.com/gp/help/external/G1881
|
||||||
|
- Amazon Handmade 图片要求最佳实践:https://sellercentral.amazon.com/help/hub/reference/external/GNRP6DDJV79DUHRD?mons_sel_locale=zh_CN
|
||||||
|
- 小红书店铺商品主图规则参考:https://www.sohu.com/a/784371738_121331647
|
||||||
|
- 小红书封面尺寸参考:https://www.canva.cn/sizes/little-red-book/
|
||||||
|
- 阿里巴巴商品图片规范参考:https://activity.alibaba.com/page/04cb5e7a.html
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. 后端主模板建议
|
||||||
|
|
||||||
|
```text
|
||||||
|
参考图1~{{product_ref_count}} 是「{{product_display_name_for_prompt}}」的真实商品参考图。
|
||||||
|
这些参考图用于锁定商品外观、颜色、材质、结构、Logo、品牌文字、比例和关键细节。
|
||||||
|
不要根据商品名称重新设计商品,不要生成相似款,不要改变商品品类。
|
||||||
|
|
||||||
|
只生成一张适合「{{platform_name}}」的商品头图/主图/封面图候选。
|
||||||
|
不要生成详情页、详情长图、多屏排版、店铺首页、平台 UI、直播间界面、二维码、水印或广告后台素材。
|
||||||
|
|
||||||
|
头图信息密度:
|
||||||
|
这是一张商品头图,不是商品详情页。画面第一优先级是商品主体/上身效果/使用场景。
|
||||||
|
商品或模特主体应占画面 60%-80%。除非本张 copy_policy 要求轻文案,否则不要出现文字。
|
||||||
|
如需文案,只允许 1 个短标题,最多再加 1-2 个极短标签;不要参数表、规格表、长句卖点、密集图标、复杂箭头、2x3/3x3 宫格或详情页式模块。
|
||||||
|
|
||||||
|
{{platform_prompt_block}}
|
||||||
|
|
||||||
|
本张是同一组平台头图中的第 {{image_index}} 张,共 {{count}} 张。
|
||||||
|
本张版式角色:{{slot_name}}
|
||||||
|
本张版式要求:{{slot_prompt_block}}
|
||||||
|
本张展示方式:{{display_mode}}
|
||||||
|
本张文案策略:{{copy_policy}}
|
||||||
|
本张模型路由:{{model_route}} / {{resolved_model}}(后端自动决定,非用户输入)
|
||||||
|
本张目标画幅:{{target_ratio}} 构图;最终像素尺寸由系统后处理统一为 {{target_export_size}},不要在画面内生成边框或留白模板。
|
||||||
|
|
||||||
|
同组视觉系统:
|
||||||
|
{{visual_system_guard}}
|
||||||
|
|
||||||
|
背景要求:
|
||||||
|
{{background_contrast_guard}}
|
||||||
|
参考图里的床品、桌面、墙面、绿植、毛巾、窗帘、道具和原始拍摄光线都不是锁定对象。
|
||||||
|
背景必须服从本张平台和 slot,不要复刻参考图背景。
|
||||||
|
|
||||||
|
商品数据:
|
||||||
|
品牌:{{brand}}
|
||||||
|
品类:{{category}}
|
||||||
|
商品卖点:{{selling_points}}
|
||||||
|
允许出现的文案:{{allowed_copy_text}}
|
||||||
|
|
||||||
|
文案限制:
|
||||||
|
若 copy_policy = none,画面不要出现任何文字。
|
||||||
|
若 copy_policy = selling_point_copy,只使用 allowed_copy_text 里的短文案,并且最多出现 1 个短标题 + 2 个短标签。
|
||||||
|
不要生成任何商品数据中不存在的品牌名、英文 Logo、角落签名、系列名、假水印或模型名;品牌为空或不确定时,画面不得出现品牌文字。
|
||||||
|
若画面必须有文字,只允许 1 个短标题或最多 2 个短标签;禁止把文案做成信息图、参数表、图标阵列或详情页模块。
|
||||||
|
不要生成商品数据没有的价格、折扣、销量、排名、认证、百分比、杯型范围、尺码或平台官方标识。
|
||||||
|
|
||||||
|
用户补充提示词:
|
||||||
|
{{base_prompt}}
|
||||||
|
用户提示词只影响氛围、构图、场景、光线和表达偏好;不能覆盖商品一致性、平台规则、slot 规则和合规限制。
|
||||||
|
|
||||||
|
画面质量:
|
||||||
|
商品主体清晰,移动端缩略图下仍能识别,商业级质感,真实可信,高分辨率。
|
||||||
|
同组图片必须像同一个品牌视觉系统,但每张在构图、背景、镜头距离、主体位置和信息重点上明显不同。
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 通用负面提示词
|
||||||
|
|
||||||
|
```text
|
||||||
|
不要生成详情页、详情长图、多屏排版、店铺页面、平台 UI、直播间界面、二维码、联系方式、水印、平台 Logo、官方认证标识、虚假角标。
|
||||||
|
|
||||||
|
不要根据商品名称重新生成商品,不要凭空设计新商品,不要改变参考商品图中的包装、Logo、颜色、材质、文字、图案、比例和关键细节,不要把商品生成成其他品类,不要擅自增加套装、配件或赠品。
|
||||||
|
|
||||||
|
不要生成商品数据中不存在的品牌名、英文 Logo、系列名、角落签名、模型名、AI 工具名、伪水印或装饰性商标。
|
||||||
|
|
||||||
|
不要生成商品数据中不存在的价格、优惠券、满减、折扣、限时活动、销量、排名、认证、功效承诺、医疗效果、绝对化用语或夸大宣传。
|
||||||
|
|
||||||
|
不要出现错别字、乱码、小字堆叠、不可读文字、大段文案、过度牛皮癣式排版。不要让文字遮挡商品主体。
|
||||||
|
|
||||||
|
不要生成 2x3 / 3x3 信息宫格、密集图标卖点、参数表、横向长条详情页、结构箭头堆叠或把多张详情页压缩进一张图。
|
||||||
|
|
||||||
|
不要让商品和背景同色相融。不要用与商品主色过于接近的大面积背景,不要让浅色商品贴在奶白/浅米/浅粉底上消失,不要让深色商品贴在深灰/黑色背景里丢失边缘。
|
||||||
|
|
||||||
|
若 display_mode = on_model 且商品为内衣、泳衣或贴身衣物,不要出现 T 恤、衬衫、吊带背心、运动上衣、连衣裙、制服、职业装、厚外套或任何遮挡内衣主体的第二件衣服。
|
||||||
|
|
||||||
|
不要让同组图片看起来像同一张图的重复版本。不要重复同一背景、同一构图、同一镜头距离、同一商品位置和同一信息重点。
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. 开发落地顺序
|
||||||
|
|
||||||
|
P0:
|
||||||
|
|
||||||
|
1. 前端默认 prompt 删除 `详情排版`。
|
||||||
|
2. API payload 新增 `platform_id`,后端 request_payload 保存 `platform_id`。
|
||||||
|
3. 后端保存 `target_ratio` 和 `target_export_size`,修正 `_ratio_to_image_size()`,所有模型原图必须经过 `normalize_output_image()` 裁切/补边/resize 到同一批次统一像素尺寸。
|
||||||
|
4. 后端 cover 参考图改为 `_product_reference_urls(product, limit=3)`。
|
||||||
|
5. `build_platform_cover_prompt_refs()` 接收 `platform_id/index/count/model_route/selected_model/product_ref_count/target_ratio`,其中 `selected_model` 仅用于内部调试覆盖。
|
||||||
|
6. 后端维护低信息密度版 `PLATFORM_COVER_BLOCKS` 和 `slot_prompt_block`。
|
||||||
|
7. 增加模型能力检查,保存 `supports_image_edit / reference_lock_level / product_ref_count`,避免把 Seedream 当成强参考编辑模型。
|
||||||
|
8. 新增 `model_route = auto`:按 `slot_name / category / copy_policy / platform_id` 自动选择 Seedream、image2 或 image2 + overlay_text;普通客户不显示模型选择。
|
||||||
|
9. 内衣类新增 Seedream / image2 模型分支,但默认 4 张不使用复杂结构说明图和详情宫格。
|
||||||
|
10. 加 `visual_system_guard`,混合模型同批次必须统一商品主色、背景色族、背景明度、光线和后处理。
|
||||||
|
11. 加 `background_contrast_guard`,避免商品融背景。
|
||||||
|
12. debug metadata 保存 `raw_width/raw_height/normalized_width/normalized_height/crop_or_pad_method`,方便排查尺寸问题。
|
||||||
|
|
||||||
|
P1:
|
||||||
|
|
||||||
|
1. 增加 `copy_plan` 生成,基于商品库卖点丰富文案。
|
||||||
|
2. 商品上传后生成/缓存 `product_cutout_ref`。
|
||||||
|
3. 将 prompt、platform_id、slot_name、copy_policy、background_contrast_guard 写入 debug metadata。
|
||||||
|
4. admin 提示词从单一 `platform_cover` 拆为 `platform_cover_base + platform_cover_{platform_id}`,支持设计师按平台微调。
|
||||||
|
5. 增加高级调试开关,允许内部人员覆盖 `selected_model`,但必须记录 `override_by_user = true` 和覆盖原因。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. 验收标准
|
||||||
|
|
||||||
|
必须通过:
|
||||||
|
|
||||||
|
1. 平台套图不再出现详情页、详情长图、多屏排版。
|
||||||
|
2. 默认 4 张都像头图:主体大、信息少、没有参数表/长卖点/复杂箭头/密集宫格。
|
||||||
|
3. 用户选择的比例必须被最终图片像素遵守,4:5 不能返回 1:1,3:4/9:16 不能返回 2:3。
|
||||||
|
4. 同一批平台套图最终返回的图片必须是完全相同的像素尺寸,不能混用 Seedream 原始尺寸和 image2 原始尺寸。
|
||||||
|
5. 同一平台 4 张图不是同一张图的轻微变体。
|
||||||
|
6. 淘宝、抖音、小红书、京东的背景、镜头和排版明显不同。
|
||||||
|
7. 内衣 Seedream 上身图不出现其他衣服遮挡内衣。
|
||||||
|
8. image2 内衣 4 张至少覆盖挂拍、生活平铺、轻卖点封面、质感特写等不同视觉角色。
|
||||||
|
9. 商品颜色不能和背景融在一起。
|
||||||
|
10. 商品形态、颜色、结构、Logo、材质不能被模型重新设计。
|
||||||
|
11. 文案可以基于卖点丰富,但不能编造价格、折扣、百分比、杯型范围、销量、认证。
|
||||||
|
12. `copy_policy = none` 的图片不得出现任何文字、假品牌、假 Logo、模型名、工具名、伪水印或角落签名。
|
||||||
|
13. image2 生成结果不得漂成信息图/详情页压缩图;Seedream 上身图不得漂成性感写真或裁切掉内衣关键结构。
|
||||||
|
14. 普通客户前台不出现 Seedream / image2 模型选择;默认 4 张内衣套图应按路由生成:上身图 Seedream,挂拍/平铺/细节 image2,准确文案走 overlay_text。
|
||||||
|
15. 混合模型同批次必须看起来像一套:商品颜色一致、背景色族一致、背景明度差异不过大、光线方向和后处理气质一致。
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,60 @@
|
|||||||
|
# 第7轮修复 · 本地验收结果
|
||||||
|
|
||||||
|
> 验收人:Claude Code(Playwright 真点)· 环境:本地 前端 :5173 + 后端 :8010(sqlite) · 账号:ZWQ(ZWQ-Test 团队 owner,10 商品)
|
||||||
|
> 日期:2026-06-29
|
||||||
|
|
||||||
|
图例:✅通过 · ⚠️部分/受限 · 🚀需后端部署本地无法验 · ⛔需付费生成未触发 · ❓本轮未做
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、实改代码 8 处
|
||||||
|
|
||||||
|
| # | 项 | 结果 | 证据 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| ZWQ-1 | 编辑删图真删除 + 刷新后悬停垃圾桶图标 | ✅ | 进编辑→主图 3 张,删 1 张→保存提示「商品已更新」→**整页刷新重进编辑,主图确为 2 张(真删持久化)**,且垃圾桶按钮仍在、hover 触发 |
|
||||||
|
| ZWQ-2② | 最近项目进度条 4 段 | ✅ | DOM 实测所有 `.prog` 均为 4 段 |
|
||||||
|
| ZWQ-2③ | 已完成项目末段绿色 | ✅ | 全绿(已完成)项目第 4 段=绿(66,195,102);橙色只作「当前进行阶段」标记,非完成项 |
|
||||||
|
| PMC-4 | 消息中心收件箱文字不错位 | ✅ | 收件箱卡片文字在框内对齐,右侧详情字段排版整齐 |
|
||||||
|
| PMC-5 | 费用预估 | ⚠️部分 | 预估随候选数线性变化(4张¥8 / 8张¥16,确定性显示);平台为单选;**「预估=实扣」一致性需真实付费生成才能确认,未触发** |
|
||||||
|
| PMC-10 | 多图失败错误上抛 | 🚀 | 需后端部署,本地不生效 |
|
||||||
|
| PMC-11 | 创建账户弹窗点遮罩不关闭 | ✅ | 点遮罩→弹窗保持打开;点取消→正常关闭 |
|
||||||
|
|
||||||
|
## 二、上轮已实现(本地=最新代码,复测确认)
|
||||||
|
|
||||||
|
| # | 项 | 结果 | 证据 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| YYX-1 | 提示词输入框加大 | ✅ | textarea 279×148px,多行 |
|
||||||
|
| YYX-3 | 选模型胶囊嵌入输入框左下 | ✅ | 「火山 Seedream ▾」胶囊在输入框内左下角 |
|
||||||
|
| YYX-4 | 搜索不丢平台数据/筛选/×清空 | ✅ | 搜「相机」商品列表过滤为 1 条,**右侧平台网格(淘宝/天猫/京东…)完整未丢**;筛选按钮在位 |
|
||||||
|
| YYX-6 | 折叠左侧栏 icon | ✅ | 点折叠→左栏收起只剩商品图片 |
|
||||||
|
| YYX-10 | 去掉白容器/分割线 | ✅ | 结果区直接空状态提示,无白盒包裹 |
|
||||||
|
| YYX-12 | 工作台「新建商品」弹抽屉 | ✅ | 停留 /dashboard 并弹出新建商品抽屉,未跳商品库 |
|
||||||
|
| YYX-13 | 卖点有「添加」按钮 | ✅ | 核心卖点字段输入框右侧有「添加」按钮 |
|
||||||
|
| YYX-5 | 重跑排底+滚动 | ⚠️受限 | 需已生成批次在工作区交互,本地无 worker 无法生成新批次 |
|
||||||
|
| YYX-7 | 批次气泡去重复「加入资产库」 | ⚠️受限 | 同上,需生成批次的气泡更多菜单 |
|
||||||
|
| YYX-9 | 筛选有内容时置顶提示栏 | ⚠️受限 | 任务类型/平台筛选未能在本地稳定触发筛选态,未复现提示栏 |
|
||||||
|
| YYX-11 | 样式复用组件/token | ⚠️代码层 | 视觉未见异常;属代码层,以 build 通过为准 |
|
||||||
|
| YYX-8 | 未读生成任务角标 | 🚀 | 数据源需后端部署 |
|
||||||
|
| PMC-1 | 失败一次后不再连续失败 | ⛔ | 需真实生成,本地无 worker 且会触发付费,未触发 |
|
||||||
|
| PMC-2/7 | 点创作后自动下滑 | ⛔ | 同上 |
|
||||||
|
| PMC-3 | image 模式点创作后清空输入框 | ⛔ | 同上 |
|
||||||
|
| PMC-8 | 删批次后不再弹「图片已生成」 | ⛔ | 同上 |
|
||||||
|
| PMC-9 | 多图差异化(seed/prompt) | ⛔ | 同上 |
|
||||||
|
|
||||||
|
## 三、本轮未做(不验)
|
||||||
|
|
||||||
|
YYX-2(真 logo)、ZWQ-2①(最近项目含图片项目)、PMC-6(点生成失败-后端)、PMC-10 语义(重跑复用不计费) —— 报告已标注本轮未做/待产品确认。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 结论
|
||||||
|
|
||||||
|
- **本地可验证的 11 项全部通过**(ZWQ-1/2②/2③、PMC-4/11、YYX-1/3/4/6/10/12/13)。其中 **ZWQ-1 做了删-存-刷新-重进 的完整持久化验证**,确认真删生效,是本轮最关键的修复。
|
||||||
|
- **PMC-5** 预估显示确定性正确,但「预估=实扣」需一次真实付费生成才能闭环。
|
||||||
|
- **🚀 部署项**(PMC-10、YYX-8 数据源)与 **⛔ 需付费生成的 PMC-1/2/7/3/8/9、YYX-5/7** 本地无法验证:本地不连集群 worker,且触发生成会真实扣费。建议这些项在测试/预发部署后用同一清单复测。
|
||||||
|
|
||||||
|
## 验收期间的数据改动(请知悉)
|
||||||
|
|
||||||
|
1. 为登录把 **ZWQ 账号密码重置为 `Test123456`**(本地 sqlite 测试库)。
|
||||||
|
2. ZWQ-1 验证时删除了 **SK-II 套装商品的 1 张主图**(3→2,本地库,可重新上传恢复)。
|
||||||
|
</content>
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
# 电商项目测试清单(7)—— 修复验证报告
|
||||||
|
|
||||||
|
> 给测试 Agent:本轮共处理 26 条。请按下表逐条复测。**注意:先确认你测的是最新部署**——上一轮大量功能已在代码里实现,但测试人员当时测的是旧部署导致误报,本轮同样有 16 条属于「代码早已实现,重新部署即可看到」,请在新部署上验证。
|
||||||
|
>
|
||||||
|
> 状态图例:✅已改代码 · ☑️代码已实现(重新部署验证) · 🚀需后端部署生效 · ❓待产品确认(本轮未做) · ⛔超出bug范围(本轮未做)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、需重点复测(实改代码 8 处)
|
||||||
|
|
||||||
|
| # | 模块 | 原问题 | 状态 | 复测步骤 | 预期结果 |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| ZWQ-1 | 商品库 | ①编辑商品删图弹"删除成功"但实际没删;②刷新重进编辑后悬停图片无垃圾桶图标 | ✅ | 进商品库→编辑某商品→悬停图片→点垃圾桶删除;再刷新页面重进编辑重复一次 | 删除真正生效(刷新后图片确实没了);刷新后悬停图片仍出现垃圾桶图标 |
|
||||||
|
| ZWQ-2② | 工作台 | 最近项目进度条 5 段,与视频项目的 4 段不一致 | ✅ | 工作台→最近项目,看进度条段数 | 进度条 4 段,与【视频项目】菜单一致 |
|
||||||
|
| ZWQ-2③ | 工作台 | 已完成项目第 4 段仍显示红色 | ✅ | 工作台→最近项目,找一个已完成的项目看末段颜色 | 已完成项目第 4 段显示绿色 |
|
||||||
|
| PMC-4 | 工作台 | 消息中心收件箱文字与 UI 框错位 | ✅ | 进消息中心→收件箱,看信息文字排版 | 文字与框对齐,不错位 |
|
||||||
|
| PMC-5 | 图片生成 | 生成前费用预估与生成后实扣有差别 | ✅ | 平台套图选多个平台生成→对比"预估费用"与实际扣款 | 预估 = 平台数 × 候选数 × 单价,与实扣一致(仅修预估展示,单价/扣费逻辑未动) |
|
||||||
|
| PMC-10 | 图片生成 | 多图生成失败时报错信息被吞,看不到真因 | 🚀 | 触发一次生图失败,看后端日志/错误提示 | 火山生图失败时错误体上抛,能看到真实失败原因(**需后端部署**) |
|
||||||
|
| PMC-11 | 团队 | 创建账户弹窗点窗口外区域就关闭 | ✅ | 团队管理→右上角【创建账户】→点弹窗外的遮罩区域 | 弹窗不关闭,须点取消/关闭按钮才关 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、代码已实现,请在新部署上验证(16 条)
|
||||||
|
|
||||||
|
> 这些上轮已实现但测的是旧部署。**只需在最新部署复测一遍确认即可,不应再报为 bug。**
|
||||||
|
|
||||||
|
| # | 模块 | 原问题 | 复测要点 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| PMC-1 | 图片生成 | 失败一次后后面都失败 | 故意失败一次后再正常生成,应能成功(并发锁已会复位) |
|
||||||
|
| PMC-2/7 | 图片生成 | 点创作后画面不自动下滑 | 点创作后列表自动滚动到最新内容,不用手动拖 |
|
||||||
|
| PMC-3 | 图片生成 | 点创作后输入框文字没清掉 | image 模式点创作后输入框自动清空 |
|
||||||
|
| PMC-8 | 图片生成 | 删除批次后右下角仍弹"图片已生成" | 生成中删除当前批次,之后不再弹"图片已生成" |
|
||||||
|
| PMC-9 | 图片生成 | 生成的图片文字内容雷同 | 前端未写死 seed、prompt 按 index 差异化;多图应有差异 |
|
||||||
|
| YYX-1 | 平台套图 | 提示词输入框太小 | 输入框已加大 |
|
||||||
|
| YYX-3 | 平台套图 | 选模型应作胶囊嵌入输入框靠左置底 | 选模型胶囊已嵌入提示词输入框内左下 |
|
||||||
|
| YYX-4 | 平台套图 | 搜索时左侧平台数据丢失/缺筛选/缺×清空 | 搜索不丢平台数据;搜索 icon 右有筛选按钮(按平台筛选悬浮弹窗);搜索框有×清空;筛选弹窗有清空按钮 |
|
||||||
|
| YYX-5 | 平台套图 | 重跑任务应排底+自动滚到新任务 | 重跑后新任务在最底部,面板自动滚到新任务位置 |
|
||||||
|
| YYX-6 | 平台套图 | 缺折叠左侧栏 icon | 有折叠 icon,点击收起左侧栏只显示商品图片 |
|
||||||
|
| YYX-7 | 平台套图 | "更多"里有重复的"加入资产库"入口 | 批次气泡里的重复入口已去掉,保留单图入库+主入口 |
|
||||||
|
| YYX-8 | 平台套图 | 缺未读生成任务数字胶囊 | 导航"图片生成"右显总未读数、商品预览图右下角显各自未读数(🚀数据源需后端部署) |
|
||||||
|
| YYX-9 | 平台套图 | 筛选有内容时缺置顶提示栏 | 筛选框有内容时工作台置顶提示栏,点"清空筛选"退出筛选视图 |
|
||||||
|
| YYX-10 | 平台套图 | 工作区白容器+分割线占地方 | 白色容器和分割线已去掉,图片显示区更大 |
|
||||||
|
| YYX-11 | 平台套图 | 样式未按规范复用组件 | 已复用现成组件、token 化样式 |
|
||||||
|
| YYX-12 | 工作台 | 点"新建商品"跳到商品库而非弹抽屉 | 工作台点"新建商品"直接弹出新建商品抽屉 |
|
||||||
|
| YYX-13 | 新建商品 | 卖点只能回车输入太隐晦 | 已有"添加卖点"按钮(YYX#G29 位置) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、本轮未做(需产品/负责人确认,不必复测)
|
||||||
|
|
||||||
|
| # | 模块 | 原问题 | 未做原因 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| YYX-2 | 平台套图 | 使用对应平台真 logo | ❓历史结论"真 logo 暂不做",本轮清单又列出,待确认是否要做(素材和组件已在位,要做改动不大) |
|
||||||
|
| ZWQ-2① | 工作台 | 最近项目应含图片项目 | ❓图片走 AITask/batch、视频走 Project,是两套数据模型,并入需后端新增聚合接口,属产品语义决策 |
|
||||||
|
| PMC-6 | 图片生成 | 点击生成图片失败 | 前端链路就绪,真因属后端出图,随 PMC-10 部署后一并验证 |
|
||||||
|
| PMC-10(语义) | 图片生成 | "重跑应复用原任务不另计费" | ⛔每次重跑=一次真 provider 调用+一次扣费,复用不计费需重设计扣费语义,超出 bug 范围;前端"排底+滚动"已实现 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、不在本轮范围(清单中标注的"暂不修复/功能如此",未列入)
|
||||||
|
|
||||||
|
ZWQ row8(演员库无删除)、row11(确认资产进故事板的提示判断)、row12(故事板敏感内容拦截,属内容审核非代码 bug)、row14(角色三视图防呆)——均按清单原标注「本次暂不修复 / 功能如此不用修复」处理。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**构建验证**:全量 `npm run build`(tsc -b && vite build)EXIT=0,1754 模块构建成功;后端 `volcano.py` AST 校验通过。
|
||||||
|
**部署提醒**:🚀 标记项(PMC-10、PMC-6、YYX-8 角标数据源及后端侧)必须重新部署后才能验证,本地不生效。
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
"""消费汇总:把 DB 里所有扣费/充值/退费流水按团队、按任务类型、按模型聚合。
|
||||||
|
跑法:cd core/backend && DJANGO_SETTINGS_MODULE=airshelf.settings.development .venv/bin/python ../qa/consumption_summary.py
|
||||||
|
"""
|
||||||
|
import os, sys
|
||||||
|
from collections import defaultdict
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "backend"))
|
||||||
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "airshelf.settings.development")
|
||||||
|
import django # noqa: E402
|
||||||
|
|
||||||
|
django.setup()
|
||||||
|
|
||||||
|
from django.db.models import Sum, Count # noqa: E402
|
||||||
|
from apps.billing.models import CreditLedger # noqa: E402
|
||||||
|
from apps.ai.models import AITask # noqa: E402
|
||||||
|
|
||||||
|
Z = Decimal("0")
|
||||||
|
|
||||||
|
print("=" * 60)
|
||||||
|
print("一、全平台流水汇总(内部额度,单位 CNY)")
|
||||||
|
print("=" * 60)
|
||||||
|
for row in (
|
||||||
|
CreditLedger.objects.values("ledger_type")
|
||||||
|
.annotate(total=Sum("amount"), n=Count("id"))
|
||||||
|
.order_by("ledger_type")
|
||||||
|
):
|
||||||
|
print(f" {row['ledger_type']:12} 笔数={row['n']:6} 合计={row['total'] or Z}")
|
||||||
|
|
||||||
|
charge_total = CreditLedger.objects.filter(ledger_type="charge").aggregate(s=Sum("amount"))["s"] or Z
|
||||||
|
recharge_total = CreditLedger.objects.filter(ledger_type="recharge").aggregate(s=Sum("amount"))["s"] or Z
|
||||||
|
refund_total = CreditLedger.objects.filter(ledger_type="refund").aggregate(s=Sum("amount"))["s"] or Z
|
||||||
|
print(f"\n >>> 实际消费(charge)总额 = {charge_total}")
|
||||||
|
print(f" >>> 充值(recharge)总额 = {recharge_total}")
|
||||||
|
print(f" >>> 退费(refund)总额 = {refund_total}")
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("二、按团队拆分消费(charge)")
|
||||||
|
print("=" * 60)
|
||||||
|
for row in (
|
||||||
|
CreditLedger.objects.filter(ledger_type="charge")
|
||||||
|
.values("team__name", "team_id")
|
||||||
|
.annotate(total=Sum("amount"), n=Count("id"))
|
||||||
|
.order_by("-total")
|
||||||
|
):
|
||||||
|
print(f" team={row['team__name']!r:24} 任务数={row['n']:5} 消费={row['total']}")
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("三、按任务类型拆分消费(charge 关联的 AITask.task_type)")
|
||||||
|
print("=" * 60)
|
||||||
|
agg = defaultdict(lambda: [0, Z]) # task_type -> [count, sum]
|
||||||
|
qs = (
|
||||||
|
CreditLedger.objects.filter(ledger_type="charge", task__isnull=False)
|
||||||
|
.select_related("task")
|
||||||
|
.values_list("task__task_type", "amount")
|
||||||
|
)
|
||||||
|
for tt, amt in qs:
|
||||||
|
agg[tt][0] += 1
|
||||||
|
agg[tt][1] += amt or Z
|
||||||
|
for tt, (n, s) in sorted(agg.items(), key=lambda kv: -kv[1][1]):
|
||||||
|
print(f" {tt:16} 次数={n:6} 消费={s}")
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("四、单价表(ModelConfig.unit_price = 平台每次固定收费,非三方实际成本)")
|
||||||
|
print("=" * 60)
|
||||||
|
from apps.ai.models import ModelConfig # noqa: E402
|
||||||
|
for mc in ModelConfig.objects.all().order_by("capability", "name"):
|
||||||
|
print(f" {mc.capability:8} {mc.provider.name}:{mc.name:30} 单价={mc.unit_price} status={mc.status}")
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("五、AITask 成本字段抽样(estimated_cost vs actual_cost)")
|
||||||
|
print("=" * 60)
|
||||||
|
print(f" task 总数={AITask.objects.count()} 成功={AITask.objects.filter(status='succeeded').count()} 失败={AITask.objects.filter(status='failed').count()}")
|
||||||
|
print(f" actual_cost 总和={AITask.objects.aggregate(s=Sum('actual_cost'))['s'] or Z}")
|
||||||
|
# 检查 response_payload 里有没有三方返回的 usage/token/费用
|
||||||
|
sample = AITask.objects.filter(status="succeeded").exclude(response_payload={}).first()
|
||||||
|
if sample:
|
||||||
|
keys = list(sample.response_payload.keys()) if isinstance(sample.response_payload, dict) else type(sample.response_payload)
|
||||||
|
print(f" response_payload 样本 keys = {keys}")
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import os, sys
|
||||||
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "backend"))
|
||||||
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "airshelf.settings.development")
|
||||||
|
import django; django.setup()
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
from apps.accounts.models import Team, TeamMember
|
||||||
|
|
||||||
|
U = get_user_model()
|
||||||
|
|
||||||
|
print("=" * 60)
|
||||||
|
print("一、用户整体状态分布")
|
||||||
|
print("=" * 60)
|
||||||
|
total = U.objects.count()
|
||||||
|
print(f" 用户总数 = {total}")
|
||||||
|
print(f" is_active=True = {U.objects.filter(is_active=True).count()}")
|
||||||
|
print(f" is_active=False = {U.objects.filter(is_active=False).count()} <-- Django 登录直接拒")
|
||||||
|
print(f" status=active = {U.objects.filter(status='active').count()}")
|
||||||
|
print(f" status=disabled = {U.objects.filter(status='disabled').count()} <-- is_disabled 拒登")
|
||||||
|
# 密码可用性
|
||||||
|
unusable = sum(1 for u in U.objects.all() if not u.has_usable_password())
|
||||||
|
print(f" 无可用密码(密码被清/损坏) = {unusable}")
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("二、团队状态")
|
||||||
|
print("=" * 60)
|
||||||
|
print(f" 团队总数 = {Team.objects.count()} active={Team.objects.filter(status='active').count()} disabled={Team.objects.filter(status='disabled').count()}")
|
||||||
|
for t in Team.objects.filter(status='disabled'):
|
||||||
|
print(f" 停用团队: {t.name} (id={t.id})")
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("三、ZWQ 相关账号详情")
|
||||||
|
print("=" * 60)
|
||||||
|
qs = U.objects.filter(username__icontains="zwq") | U.objects.filter(username__icontains="ZWQ")
|
||||||
|
qs = qs.distinct()
|
||||||
|
if not qs:
|
||||||
|
print(" 没找到 username 含 zwq 的用户,列出全部用户名供你认:")
|
||||||
|
for u in U.objects.all().order_by("username")[:60]:
|
||||||
|
print(f" {u.username}")
|
||||||
|
for u in qs:
|
||||||
|
print(f"\n username={u.username!r}")
|
||||||
|
print(f" is_active={u.is_active} status={u.status} has_usable_password={u.has_usable_password()}")
|
||||||
|
print(f" is_platform_admin={u.is_platform_admin} is_superuser={u.is_superuser}")
|
||||||
|
print(f" last_login={u.last_login} date_joined={u.date_joined}")
|
||||||
|
print(f" password_hash_prefix={u.password[:25]!r}")
|
||||||
|
mems = TeamMember.objects.filter(user=u).select_related("team")
|
||||||
|
for m in mems:
|
||||||
|
print(f" 团队成员: team={m.team.name!r} team_status={m.team.status} member_status={m.status} role={m.role}")
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import os, sys
|
||||||
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "backend"))
|
||||||
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "airshelf.settings.development")
|
||||||
|
import django; django.setup()
|
||||||
|
from apps.accounts.models import LoginSession
|
||||||
|
from rest_framework.authtoken.models import Token
|
||||||
|
|
||||||
|
print("=== 最近 30 条成功登录(LoginSession) ===")
|
||||||
|
for s in LoginSession.objects.select_related("user").order_by("-created_at")[:30]:
|
||||||
|
fields = {f.name: getattr(s, f.name) for f in s._meta.fields}
|
||||||
|
extra = {k: v for k, v in fields.items() if k not in ("id", "user", "created_at", "updated_at")}
|
||||||
|
print(f" {s.created_at:%Y-%m-%d %H:%M:%S} user={s.user.username:18} {extra}")
|
||||||
|
|
||||||
|
print(f"\n LoginSession 总数 = {LoginSession.objects.count()}")
|
||||||
|
print(f" 现存 Token(已登录会话) 数 = {Token.objects.count()}")
|
||||||
|
print("\n=== 现存 Token 的用户 + 签发时间 ===")
|
||||||
|
for t in Token.objects.select_related("user").order_by("-created")[:30]:
|
||||||
|
print(f" {t.created:%Y-%m-%d %H:%M:%S} {t.user.username}")
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import os, sys, json
|
||||||
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "backend"))
|
||||||
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "airshelf.settings.development")
|
||||||
|
import django; django.setup()
|
||||||
|
from apps.ai.models import AITask
|
||||||
|
|
||||||
|
for tt in ["product_image", "script_generation", "video_segment", "storyboard", "voiceover"]:
|
||||||
|
t = AITask.objects.filter(task_type=tt, status="succeeded").exclude(response_payload={}).first()
|
||||||
|
print("=" * 50, tt)
|
||||||
|
if not t:
|
||||||
|
print(" (无样本)"); continue
|
||||||
|
rp = t.response_payload if isinstance(t.response_payload, dict) else {}
|
||||||
|
usage = rp.get("usage")
|
||||||
|
print(" usage =", json.dumps(usage, ensure_ascii=False))
|
||||||
|
# 顶层除大字段外的 keys
|
||||||
|
print(" payload keys =", [k for k in rp.keys()])
|
||||||
Reference in New Issue
Block a user