146 Commits

Author SHA1 Message Date
seaislee1209
39667ff19c feat: v0.19.0 1080P 分辨率支持 — 完整前后端 + 严格计费准确性 + 47 测试
火山 Seedance 2.0 于 2026-04-16 上线 1080P 支持。本次实现前端 UI、
后端校验/计费、数据库迁移,并严格遵守三原则:
1. 禁止兜底/静默降级 — Fast+1080P 组合在 UI/store/serializer/view/计价
   五层防御,任一层穿透都 fail loud,不悄悄按 720P 扣费
2. 钱的计算绝对准确 — 前端预估公式与后端 estimate_tokens 完全一致
   `(输入时长+输出时长) × 宽 × 高 × fps / 1024`;实际扣费按火山返回
   total_tokens × 官方单价;预估端不维护最低 token 修正表
3. 不隐藏 bug — 无 `or '720p'` / `|| '720p'` 兜底;类型严格;异常暴露

## 后端(7 处 + 1 次迁移)

- models.py: QuotaConfig 加 base_token_price_1080p(51)/base_token_price_1080p_video(31);
  GenerationRecord.resolution 加 RESOLUTION_CHOICES 约束 + default='720p'
- migrations/0020: 含 RunPython data migration 回填历史 resolution='' → '720p'
- utils/billing.py:
  * RESOLUTION_MAP 加 1080P 六种宽高比(21:9 是 2206×946,不是 seedance 1.0 值)
  * get_resolution 去掉 tier 默认值,非法组合 raise KeyError 不静默降级
  * estimate_tokens 纯官方公式,加 input_video_duration 参数(公式完整)
- utils/airdrama_client.py: create_task 加 resolution 必填参数(无默认值)
- apps/generation/serializers.py:
  * VideoGenerateSerializer 加 resolution ChoiceField
  * aspect_ratio 改 ChoiceField 显式拒绝 adaptive
  * SystemSettingsSerializer 加 2 个 1080P 单价
- apps/generation/views.py:
  * _get_token_price 加 resolution 必填参数,Fast+1080P raise ValueError
  * _sum_video_duration 累加视频参考时长
  * video_generate_view 读 resolution、400 拒绝 Fast+1080P 组合、
    传给 get_resolution/estimate_tokens/_get_token_price/create_task/
    GenerationRecord.resolution(移除 L450 硬编码 '720p')
  * _settle_payment 按 record.resolution 取单价(1080P 结算按 1080P 价)
  * _serialize_task + 5 处手工序列化加 resolution 字段(无 `or '720p'`)
- apps/accounts/views.py: team 接口返回 token_price_1080p/_video

## 前端(10 处)

- types/index.ts: Resolution 类型;GenerationTask/BackendTask/Team/
  QuotaConfig/AssetVideo 加字段(全部必填,无 optional)
- store/inputBar.ts: resolution state;setModel/setResolution 双向拦截
  Fast+1080P 组合,toast 提示引导,不静默降级
- store/generation.ts: addTask/backendToFrontend/reEdit/regenerate 全链路
  携带 resolution;mapErrorMessage 改 '今日生成次数或团队余额不足'
- components/Toolbar.tsx:
  * 加分辨率选择器 Dropdown(位置:比例和时长之间)
  * modelItems/resolutionItems 双向 disabled(Fast 下 1080P 灰 / 1080P 下 Fast 灰)
  * estimatedTokens 对齐后端公式(含输入视频时长 + assetMentions 视频时长)
  * estimatedCost 按 resolution 选单价(Fast→fast_*、1080p→1080p_*、其他→基础)
  * tooltip 明示"实际费用以火山 API 返回的 token 数为准"
- components/Dropdown.tsx: 加 disabled 属性支持
- components/VideoDetailModal.tsx: 重新编辑恢复 resolution
- components/GenerationCard.tsx: 动态显示 task.resolution.toUpperCase()
- pages/SettingsPage.tsx: 加 2 个 1080P 单价输入框(独立分组)
- pages/AdminAssetsPage.tsx / TeamAssetsPage.tsx: 去 || '720p' 兜底
- lib/api.ts: videoApi.generate 参数 resolution 必填

## 测试(47 个用例)

### 后端(28 个)
- tests/test_1080p_billing.py(23): RESOLUTION_MAP 像素、estimate_tokens
  公式(含/不含输入视频、不做最低 token 修正)、_get_token_price 六种
  组合、Fast+1080P 抛异常、calculate_cost 对齐官方示例 4.97 / 12.39 元
- tests/test_1080p_api.py(5): video_generate_view 拒绝 Fast+1080P (400)
  + 拒绝 adaptive + 拒绝非法 resolution + 默认值兼容 + 合法组合通过

### 前端(19 个)
- test/unit/resolution1080p.test.ts(14): store 状态、双向拦截
  (1080P 下切 Fast 被阻止 model 不变、反向同样)、官方像素契约测试、
  价格示例对齐(720P 4.97 / 1080P 12.39)
- test/e2e/resolution-1080p.spec.ts(5): 真实浏览器验证默认 720P、
  Dropdown 双向置灰、tooltip 明示以火山为准

## 与官方文档对齐

- 参数:resolution (480p/720p/1080p 小写)、ratio、duration、generate_audio
- 像素:来自 docs/API文档/创建视频生成任务API.md Seedance 2.0 & 2.0 fast 列
- 单价:来自 docs/API文档/seedance模型价格.md (46/28/51/31/37/22)
- Fast 不支持 1080P:来自 docs/API文档/Seedance 2.0 1080P.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 19:06:45 +08:00
seaislee1209
624e12ae46 docs: v0.18.3 文档整理 + 新火山 API 文档 + changelog
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 5m38s
- 新增 4 个火山官方 API 文档(Seedance 2.0 1080P / seedance 模型价格 /
  seedance 2.0 系列教程 / 创建视频生成任务API)
- 归档 6 个过期文档到 docs/archive/(旧 Seedance API 邀测版 /
  旧 Assets API 邀测版 / celery 轮询修复 / design-review / prd / test-report)
- 新增 docs/todo/ 目录(提示词 AI 优化功能待办)
- changelog.md 补 v0.18.3 条目

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 18:03:49 +08:00
seaislee1209
dafdc8983f fix: v0.18.3 版权报错友好提示 + 图片删除即梦式连续重命名
Bug 1: 版权限制错误友好提示
- ERROR_MESSAGES 加 OutputVideoSensitiveContentDetected.PolicyViolation 映射
- 漫威等知名 IP 触发的版权拦截不再显示英文 raw error

Bug 2: 图片删除后同类型引用连续重命名(即梦逻辑)
- inputBar.ts::removeReference 重写:删除后同类型剩余引用按顺序 1/2/3 连续编号
- 用 DOMParser 同步更新 editorHtml 里对应 data-ref-id 的 @mention span textContent
- 缩略图区和提示词栏同步刷新,避免"两个图片2"命名冲突

验证
- 11 个 Vitest 单元测试覆盖图片/视频/音频删除、空 editorHtml、无 @mention、
  连续快速删除等边界场景
- 3 个 Playwright E2E 真实浏览器验证:上传 3 张图 → 删中间 → 再上传 → 编号不冲突

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 18:03:36 +08:00
seaislee1209
2281c64ee8 fix: 音频不能作为唯一参考素材 — 前端校验 + toast 提示
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 6m0s
Seedance API 不支持"纯音频"和"文本+音频"输入,必须搭配图片或视频。
- canSubmit() 校验同时检查 references 和 assetMentions
- Toolbar 点击禁用按钮时弹出 toast 提示原因

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 14:10:39 +08:00
zyc
41115faa16 add md
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 5m19s
2026-04-13 20:47:43 +08:00
seaislee1209
0b770340c8 fix: 修复资产页素材库引用不可查看 + 重新编辑素材泄漏
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 4m52s
1. AdminAssetsPage/TeamAssetsPage: asset:// 协议 URL 改用 thumb_url 显示缩略图
2. generation.ts reEdit/regenerate: 过滤 isAssetRef,素材库引用不混入 references 数组
3. PromptInput extractText: 实时同步 assetMentions store,删除 @标签后不再残留旧数据

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 18:33:08 +08:00
zyc
177a9c7dec feat: HTTP→HTTPS 自动跳转 — Traefik Middleware + CI/CD 部署补全
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 3m36s
- 新增 redirect-https-middleware.yaml (Traefik 301 永久重定向)
- ingress.yaml 添加 middleware annotation
- deploy.yaml 补充 cert-manager-issuer 和 redirect-middleware 的 kubectl apply

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 11:38:58 +08:00
zyc
a6a3928091 perf: kubectl 4s 超时 + 5 次重试,避免 K3s 内网抖动卡死部署
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 4m9s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 11:29:24 +08:00
zyc
ab1b00f94a feat: HTTP 自动跳转 HTTPS — Traefik Middleware + Ingress annotation
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 11:17:02 +08:00
seaislee1209
5972f45784 fix: 素材库引用缩略图烂图 + pollStatus 跨项目素材保护
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled
- MentionTag: onError fallback,缩略图加载失败显示视频/图片占位图标
- createMentionSpan/VideoDetailModal: img onError 隐藏烂图
- buildReferenceSnapshots: 素材库引用用 thumb_url 做 previewUrl
- isAssetRef 标记防止视频缩略图被 <video> 渲染、重编辑防重复
- pollStatus: 已 active 的素材跳过远程查询,防止跨项目素材被误删

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 11:11:12 +08:00
seaislee1209
db1bbfa1d4 Merge branch 'dev' of https://gitea.airlabs.art/zyc/video-shuoshan into dev
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled
2026-04-04 22:18:54 +08:00
seaislee1209
4b2dd9ef5e fix: 音频 ♫ 符号溢出到 prompt 文本 — 改用 CSS ::before 渲染
createMentionSpan 里音频的 ♫ 之前用 textContent 设置,
被 extractText() 的 el.textContent 读进了 prompt 纯文本,
导致 renderPromptWithMentions 匹配后留下额外的 ♫ 字符。

改用 CSS ::before content 渲染,不参与 textContent,
prompt 里不再有多余的 ♫。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 22:17:07 +08:00
zyc
3bc8b78507 perf: docker cleanup 保留基础镜像缓存,只清 dangling 镜像
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 4m4s
2026-04-04 21:54:11 +08:00
seaislee1209
5da67435b2 fix: v0.18.1 用户测试 8 项 Bug 修复
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled
- MutationObserver 立刻同步 editorHtml(删 @ 标签后时长/数量立即重置)
- parseAssetMentionsFromDOM 从 DOM 实时读取(不用 stale state)
- renderPromptWithMentions 支持音频 ♫ + 视频首帧 + assetType
- rebuildMentionSpans 按 label 长度降序匹配(防子串冲突)
- 删除素材后 group 缩略图优先找图片/视频(不用音频 URL)
- 素材组整组删除功能(后端 DELETE + 前端按钮)
- Celery poll 架构重构(一次性任务 + recover_stuck_tasks 统一驱动)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 21:06:02 +08:00
zyc
d73175b101 fix: kubectl 装到 /usr/bin 避开 /usr/local/bin 的 bind mount
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m16s
2026-04-04 20:28:05 +08:00
zyc
f37c38d38b fix: kubectl 安装前先删旧目录避免 mv 覆盖目录报错
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled
2026-04-04 20:25:52 +08:00
zyc
4cf9a0a4bb perf: 轮询调度间隔从30秒改为10秒
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled
2026-04-04 20:21:25 +08:00
zyc
127ed9659d Merge remote-tracking branch 'origin/dev' into dev
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled
2026-04-04 20:16:15 +08:00
zyc
ded5c4c44f fix bug 2026-04-04 20:13:23 +08:00
seaislee1209
ba33c35dd8 add test
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 4m13s
2026-04-04 19:38:36 +08:00
zyc
6353d2ec4f feat: rename /assets route to /user-assets
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled
2026-04-04 19:29:31 +08:00
seaislee1209
f1a7ad8a2f fix: nginx /assets 路由 403 修复 — 静态缓存改为正则匹配文件扩展名
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 4m32s
/assets/ location 会拦截 SPA 路由 /assets(资产页),导致刷新 403。
改为正则匹配 /assets/*.{js,css,png,...},只缓存实际静态文件,
不影响 SPA fallback 到 index.html。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 19:16:38 +08:00
seaislee1209
9a6d95a69d fix: v0.18.0 商业级加固 — 并发安全、流式上传、错误反馈、类型修复
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 3m13s
- TOS 流式上传 upload_from_file_path(避免大文件 OOM)
- 视频生成完成后下载一次复用(TOS 上传 + 首帧提取)
- 并发安全:group thumbnail 用 select_for_update 原子更新
- 跨团队校验:_resolve_asset_group_all 加 group__team 过滤
- 异常信息脱敏:文件上传失败不再泄露内部异常
- SSRF 防护:download_to_temp 校验 URL scheme
- poll lock 终态释放:cache.delete 在 record.save 后调用
- duration=null 语义区分:ffprobe 失败存 None 非 0
- 前端 duration 未知 toast 警告:素材时长未确定时提示用户
- 搜索 API 失败 toast:素材搜索失败时反馈用户
- 视频保存降级标记:临时 URL 降级时设 error_message
- TypeScript 类型修复:AssetItem/AssetSearchResult.duration 改为 number|null
- rebuildMentionSpans 补完 assetId/assetType/assetName/duration 属性
- paste DOMPurify 白名单补完新 data attributes
- resolved_url NameError 修复:非素材库视频/音频引用用 url
- process_asset_media group 删除保护
- download_to_temp 改为 public API
- 清理前端死代码

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 18:49:08 +08:00
zyc
61bcb9576f add git guide
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 3m55s
2026-04-04 18:26:05 +08:00
seaislee1209
2e72c82116 Merge branch 'dev' of https://gitea.airlabs.art/zyc/video-shuoshan into dev
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 4m39s
2026-04-04 17:36:39 +08:00
seaislee1209
da9a1413c3 v0.18.0 素材库多类型支持 + @ 引用改为单素材
对齐火山 API 文档(Asset URI 小写、HEIC/HEIF、DeleteAsset)
素材库支持视频/音频上传(按类型分三区显示、前端校验、拖拽上传)
@ 引用从素材组改为单个素材(搜索返回具体素材、即时数量/时长检查)
ffmpeg 视频封面帧提取 + 音频时长读取(Celery 异步)
生产级安全修复(跨团队校验、异常信息脱敏、下载大小限制)
2026-04-04 17:36:35 +08:00
zyc
95bdb0a6e8 fix: USE_TZ=False 统一使用北京时间,修复 recover_stuck_tasks 时区比较错误
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 3m3s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 17:10:55 +08:00
zyc
1e76052c64 fix: 用 printf 写 kubeconfig 防止多行内容被 echo 截断
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 24s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 16:17:34 +08:00
zyc
622491c3d0 chore: 触发构建验证 runner host 网络修复
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 16:07:44 +08:00
zyc
a8ffd6417a feat: add Docker cleanup step to CI pipeline
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled
Automatically prune unused containers, images and build cache after
each CI run to prevent disk space exhaustion on the runner.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 15:46:52 +08:00
zyc
43fe1b8909 fix: 将 kubectl secret 创建也纳入重试循环,修复重试未生效的问题
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 6s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 15:15:01 +08:00
zyc
2365824313 fix: CI 全链路添加 3 次重试(build/push/kubectl/deploy)防止网络抖动
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 5m43s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 14:37:28 +08:00
zyc
1ff985d64f fix: Deploy to K3s 添加 3 次重试,防止内网抖动导致构建失败
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 6s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 14:35:31 +08:00
zyc
05097d58f9 perf: gunicorn 启用 gevent 异步模式,并发从 2 提升到 400
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 13s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 14:33:58 +08:00
zyc
ca6f2a0346 fix: 添加 Redis 分布式锁防止 poll_video_task 重复派发
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 6m17s
recover_stuck_tasks 在 API 超时 >3 分钟时可能重复派发同一任务,
导致重复扣费风险。通过 cache.add 实现互斥锁保护。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 14:21:38 +08:00
zyc
55c26fb1f5 Merge branch 'dev' of https://gitea.airlabs.art/zyc/video-shuoshan into dev
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 6s
2026-04-04 14:12:09 +08:00
zyc
49e06fd3c4 fix 镜像原 2026-04-04 14:11:39 +08:00
seaislee1209
9bca1bc20f feat: v0.17.0 对齐火山 API 文档 + 素材库多类型支持 + 删除功能
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 27s
- Asset URI 大小写修复(Asset:// → asset://)
- HEIC/HEIF 图片格式支持
- 素材删除功能(DeleteAsset API + 前端 hover 删除按钮)
- 素材库支持视频/音频上传(asset_type 字段 + 后端类型检测)
- 素材组详情页按类型分三区(肖像/视频/音频)+ 红字提示
- @ 引用全发(组内所有 active 素材按类型发送)
- 前端素材库上传校验(validateAssetFile 全套校验)
- Failed 素材 hover 显示错误原因
- 正在生成的视频可点重新编辑

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 14:07:38 +08:00
zyc
befd7c8d49 add sql prod
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled
2026-04-04 14:04:53 +08:00
zyc
f85a3d69d0 fix: kubectl 自动安装兜底 + 阿里云镜像源
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 5m5s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 13:54:49 +08:00
zyc
ffbd7cf016 add prod 镜像仓
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 12s
2026-04-04 13:52:43 +08:00
zyc
6c9fddf5fe 更新测试文档
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 9m20s
2026-04-04 13:36:23 +08:00
seaislee1209
ee7cdec9e3 add docs
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 5s
2026-04-04 13:27:13 +08:00
zyc
70725894bd pull test
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 12s
2026-04-04 13:21:57 +08:00
zyc
aff37ee4a8 chore: verify DaoCloud mirror build
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 5s
2026-04-04 13:15:40 +08:00
zyc
a7a9fdf4fe fix: use DaoCloud mirror for base images to avoid Docker Hub timeout
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 25s
2026-04-04 13:14:20 +08:00
zyc
ec5622534f chore: verify docker cache hit
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 19s
2026-04-04 13:11:48 +08:00
zyc
4175474149 chore: rebuild after clearing docker cache
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 3m23s
2026-04-04 13:06:44 +08:00
zyc
8c31e7e36a chore: trigger rebuild with updated docker mirrors
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 5s
2026-04-04 13:05:50 +08:00
zyc
d01301433c chore: rebuild after docker mirror fix
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 20s
2026-04-04 13:04:08 +08:00