fix(cover): 模板缩略图渲染 + 自动生成封面404修复 #2053

Merged
auto-approve-bot merged 3 commits from fix/cover-thumb-and-404-20260926 into develop 2026-09-26 18:25:09 +08:00
Owner

修复内容

问题1:模板卡片不显示预览图

  • 之前写死渐变色+🖼️emoji,完全没用 thumbnail_url 字段
  • 新增 TemplateThumb 子组件:优先渲染 tpl.thumbnail_url(object-fit:cover),图片加载失败/无URL时回退到按模板 id 哈希的柔和渐变色占位
  • 选中态 ✓ 覆盖在图片上层

问题2:自动生成封面 404

根因:前端用魔法字符串 "default" 作为 template_id 发给后端,但后端模板库不存在 id=default 的记录,resolve_draft_plan_id(auto_create_default=False) 直接抛 404 "模板不存在"。

修复(前后端协同):

  1. 前端 useSharedCover:挂载时拉模板列表,初始 "default" 占位符自动解析为第一个系统模板的真实 id;用户未选模板时传空串给 API 层
  2. 前端 api/generation/cover.ts:templateId 为空或 "default" 时不传 template_id query 参数
  3. 后端 generation_cover.py:
    • template_id Query 改为可选(默认空串)
    • 移除强依赖 get_draft_plan_id(auto_create_default=False) 的 Depends
    • 函数体内手动 resolve:空串时 auto_create_default=True 自动兜底到用户默认模板;非空时走原校验逻辑
  4. useBatchCovers:批量一键生成同样不传 "default"
  5. Step6CoverSettings:透传原始 selectedTemplateId 给 useBatchCovers
  6. 保留 selectedTemplateId==="default" 的 UI 展示分支("默认模板"文案)用于首次挂载模板列表加载完成前的过渡态

验证

  • tsc --noEmit ✅
  • eslint --max-warnings=0 ✅
  • prettier ✅
  • vite build ✅
  • 后端 Python 语法检查 ✅
  • 未修改 CI 配置
## 修复内容 ### 问题1:模板卡片不显示预览图 - 之前写死渐变色+🖼️emoji,完全没用 thumbnail_url 字段 - 新增 TemplateThumb 子组件:优先渲染 tpl.thumbnail_url(object-fit:cover),图片加载失败/无URL时回退到按模板 id 哈希的柔和渐变色占位 - 选中态 ✓ 覆盖在图片上层 ### 问题2:自动生成封面 404 **根因**:前端用魔法字符串 `"default"` 作为 template_id 发给后端,但后端模板库不存在 id=`default` 的记录,`resolve_draft_plan_id(auto_create_default=False)` 直接抛 404 "模板不存在"。 修复(前后端协同): 1. **前端 useSharedCover**:挂载时拉模板列表,初始 `"default"` 占位符自动解析为第一个系统模板的真实 id;用户未选模板时传空串给 API 层 2. **前端 api/generation/cover.ts**:templateId 为空或 `"default"` 时不传 `template_id` query 参数 3. **后端 generation_cover.py**: - `template_id` Query 改为可选(默认空串) - 移除强依赖 `get_draft_plan_id(auto_create_default=False)` 的 Depends - 函数体内手动 resolve:空串时 `auto_create_default=True` 自动兜底到用户默认模板;非空时走原校验逻辑 4. **useBatchCovers**:批量一键生成同样不传 `"default"` 5. **Step6CoverSettings**:透传原始 selectedTemplateId 给 useBatchCovers 6. 保留 `selectedTemplateId==="default"` 的 UI 展示分支("默认模板"文案)用于首次挂载模板列表加载完成前的过渡态 ## 验证 - tsc --noEmit ✅ - eslint --max-warnings=0 ✅ - prettier ✅ - vite build ✅ - 后端 Python 语法检查 ✅ - 未修改 CI 配置
xiaoxia added 1 commit 2026-09-26 16:13:14 +08:00
fix(cover): 模板缩略图渲染 + 自动生成封面404修复
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 1s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 1m4s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 1m47s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m57s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 1m54s
CI/CD Pipeline / Unit Tests (pull_request) Failing after 2m12s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 2m17s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m35s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 2m43s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 3m2s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m7s
AI Code Review / AI Code Review (pull_request) Successful in 6m35s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 8m12s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Failing after 9m12s
CI/CD Pipeline / CI Gate (pull_request) Failing after 0s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 6m14s
0a6473e5d7
问题1:模板卡片不显示预览图
- 之前写死渐变色+🖼️emoji,完全没用 thumbnail_url 字段
- 新增 TemplateThumb 子组件:优先渲染 tpl.thumbnail_url(object-fit:cover),
  图片加载失败或无URL时回退到按模板id哈希的柔和渐变色占位
- 选中态✓覆盖在图片上层

问题2:自动生成封面 POST /generation/generate-cover 返回404
根因:前端用魔法字符串 "default" 作为 template_id 发给后端,但后端
模板库中不存在 id="default" 的记录,resolve_draft_plan_id 返回404。

修复:
1. 前端 useSharedCover:挂载时拉模板列表,把初始 "default" 占位符自动
   解析为第一个系统模板的真实id;用户未选模板时传空串给API层
2. 前端 api/generation/cover.ts:templateId 为空或 "default" 时不传
   template_id query 参数(而非传 "default")
3. 后端 generation_cover.py:
   - template_id Query 改为可选(默认空串)
   - 移除原来强依赖 get_draft_plan_id(auto_create_default=False) 的 Depends
   - 在函数体内手动 resolve:空串时 auto_create_default=True 自动兜底到
     用户默认模板;非空时走原校验逻辑
4. useBatchCovers:批量一键生成同样不传 "default"
5. Step6CoverSettings:透传原始 selectedTemplateId 给 useBatchCovers
6. 保留 selectedTemplateId==="default" 的UI展示分支("默认模板"文案)
   用于首次挂载模板列表加载完成前的过渡态

验证:
- tsc --noEmit ✅
- eslint --max-warnings=0 ✅
- prettier ✅
- vite build ✅
- 后端 Python 语法检查 ✅
- 未修改 CI 配置

🚀 预览环境已部署

项目 详情
PR号 #2053
预览链接 https://pr-2053.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #2053 | | 预览链接 | [https://pr-2053.preview.xiaoxiajianji.com](https://pr-2053.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
xiaoxia added 1 commit 2026-09-26 18:16:40 +08:00
fix(cover): 修复 #2053 单测失败 — plan_id 直接返回以兼容测试直接调用
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 1s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 1s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Unit Tests (pull_request) Has been cancelled
CI/CD Pipeline / Build Production API Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Style (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Security (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Has been cancelled
CI/CD Pipeline / PR Build API Image (pull_request) Has been cancelled
CI/CD Pipeline / PR Build Web Image (pull_request) Has been cancelled
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Frontend Lint (pull_request) Has been cancelled
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been cancelled
AI Code Review / AI Code Review (pull_request) Has been cancelled
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been cancelled
PR Automation / Auto Approve on CI Green (pull_request) Has been cancelled
Preview Deploy / Deploy Preview Environment (pull_request) Has been cancelled
a989670d83
CI 报错 17 个用例失败:
  ValidationError: GenerateCoverResponse.plan_id Input should be a valid string
  input_value=<MagicMock id='...'>

原因:上一版把 plan_id 参数默认值改为 "" 后,在函数体内用 resolve_draft_plan_id
的返回值覆盖了 plan_id。单测直接调用函数时虽然显式传入了 plan_id="plan-x",
但 resolve_draft_plan_id 未被 mock,会把 services=(mock_tpl, mock_plan) 中的
MagicMock 当作 tpl_svc 调用并返回 MagicMock,最终覆盖传入的字符串。

修复:在函数体内加判断 if not plan_id: 才走 resolve_draft_plan_id;单测显式
传入 plan_id 字符串时直接用,HTTP 调用默认空串才触发模板解析。
同时把两处函数内 from-import 提升到模块顶层 import resolve_draft_plan_id,
并在 templates_editor/dependencies.py 新增 get_draft_plan_id_optional 依赖
(供其他端点复用,本次未实际引用但保留供将来使用)。

PR Build API Image 的失败是 CI 基础设施 DNS 解析超时
(xiaoxia-registry.cn-hangzhou.cr.aliyuncs.com i/o timeout),
与代码无关,push 后重试即可。
xiaoxia added 1 commit 2026-09-26 18:18:51 +08:00
revert(backend): 撤回 #2053 后端改动,让前端PR先合入
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 8s
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 1m27s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m23s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 1m43s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 1m36s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 2m21s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 4m16s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 4m54s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 5m17s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 0s
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 4m29s
AI Code Review / AI Code Review (pull_request) Successful in 6m43s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 33s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 34s
6becc7beca
按方案1拆分:撤回 generation_cover.py 的 template_id 可选改动和
dependencies.py 的 get_draft_plan_id_optional 新增依赖。PR#2053 现在只包含
前端修复(模板缩略图渲染 + 不传 "default" 魔法字符串 + 真实模板id解析)。

后端改动(让 /generate-cover 支持 template_id 为空自动兜底默认模板)后续
会在独立 PR 中跟进,配合单测更新一起合。

前端已处理的向后兼容:
- api/generation/cover.ts: templateId 为空或 'default' 时不传 template_id
  参数。当前后端 template_id 是必填 Query,会返回 422 Validation Error,
  这比之前传 'default' 返回 404 '模板不存在' 更明确;
- useSharedCover 挂载时会自动拉模板列表把 'default' 占位符解析为第一个
  系统模板的真实 id,因此绝大多数正常路径(选过模板/默认系统模板)不会
  触发空 template_id 分支;
- useBatchCovers 同样使用解析后的真实模板 id 或空串,空串情况只发生在
  用户删除全部模板后的极端兜底场景,届时用户会看到 422 错误提示需要
  新建模板,属于可接受的退化行为。
auto-approve-bot approved these changes 2026-09-26 18:20:40 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
auto-approve-bot approved these changes 2026-09-26 18:20:40 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
auto-approve-bot merged commit a5075624f8 into develop 2026-09-26 18:25:09 +08:00
auto-approve-bot deleted branch fix/cover-thumb-and-404-20260926 2026-09-26 18:25:11 +08:00

🗑️ 预览环境已清理

PR #2053 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #2053 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Sign in to join this conversation.