Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 2m0s
- 全新 Landing Page:Canvas 极光动画(5色光球 + additive blending + blur 融合) - 暗角/胶片颗粒/渐变遮罩 4 层视觉架构 - 鼠标推动光球交互(lerp 缓动)+ 呼吸效果 - 登录弹窗(磨砂玻璃 backdrop-filter blur)替代独立登录页 - Air Spark 全屏毛玻璃弹窗 + 音乐彩蛋(SVG 音波 + BGM) - 品牌名 AIRFLOW STUDIO / AI VISUAL NARRATIVE + Space Grotesk 字体 - 路由重构:/ → LandingPage, /login → 自动弹登录框 - 自适应视频播放器比例修复(读取 videoWidth/videoHeight) - adaptive 英文显示改为中文「自适应」 - 首页音乐泄漏修复(组件卸载时 pause+reset) - 登录弹窗添加「目前仅限受邀创作者体验」提示 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
21 KiB
21 KiB
需求变更日志 (Changelog)
按日期倒序记录每次需求变更。每条记录在开发完成、测试验收通过后归档。
2026-03-16 — v0.9.1: 首页 + 播放器修复
状态: ✅ 已完成 | 验收: ✅ 通过(本地验证)
变更内容
- 首页音乐泄漏修复 — 登录跳转
/app后 BGM 继续播放,添加组件卸载时 pause + reset - 自适应视频播放器比例修复 —
adaptive比例视频在详情弹窗中固定 16:9 容器,改为读取视频固有videoWidth/videoHeight自适应缩放 - 自适应比例中文化 — 视频详情弹窗、生成卡片标签、详情 tooltip 中
adaptive改为显示「自适应」 - 登录弹窗提示语 — 登录按钮下方添加「目前仅限受邀创作者体验」提示
变更文件
| 文件 | 改动 |
|---|---|
web/src/pages/LandingPage.tsx |
添加 useEffect 清理:组件卸载时暂停音乐 |
web/src/components/VideoDetailModal.tsx |
adaptive 比例读取视频固有尺寸 + 显示中文「自适应」 |
web/src/components/GenerationCard.tsx |
两处 aspectRatio 显示改为中文「自适应」 |
web/src/components/LoginModal.tsx |
添加受邀创作者提示文字 |
web/src/components/LoginModal.module.css |
新增 .hint 样式 |
2026-03-16 — v0.9.0: 品牌首页(Landing Page)
状态: ✅ 已完成 | 验收: ✅ 通过(本地验证)
变更内容
- 5 层极光首页 — 全新单屏 Landing Page,Canvas 实现有机流动极光背景(暗角→胶片颗粒→极光光球→渐变遮罩→内容层)
- 品牌标识 — 标题 "AIRFLOW STUDIO" + 副标题 "AI VISUAL NARRATIVE",Space Grotesk 字体(300/400/500)
- 双入口按钮 — Air Drama(品牌青色高亮)/ Air Spark(幽灵按钮),中文副标题移至按钮下方独立小字
- 登录弹窗 — 点击 Air Drama 原地弹出登录 Modal(磨砂玻璃背景 + backdrop-filter: blur),替代独立登录页跳转
- Air Spark 全屏提示 — 毛玻璃遮罩 + 戏剧性大字 "别急,土豆🥔正在 coding 中",点击任意位置关闭
- 鼠标极光交互 — 鼠标靠近光球时轻推偏移(28px),lerp 缓动跟踪,离开后缓慢回归
- 极光呼吸感 — 5 个光球各自不同位置/大小/亮度/呼吸频率,避免均匀蓝块,保持明暗对比
- 彩蛋文字 — 底部 "Every frame was once just air." opacity 0.06,hover 2s 过渡到 0.25
- 音乐彩蛋 — 右下角 SVG 音波图标,点击播放/暂停 BGM,竖线从中心向两端扩展跳动(JS 随机高度 + CSS transition)
- 路由重构 —
/→ LandingPage,/login→ LandingPage + 自动弹登录框,/app→ VideoGenerationPage - Logo 替换 — 全站 5 处 Logo 替换为品牌 Logo(favicon、侧栏、管理后台、团队管理、登录弹窗)
变更文件
| 文件 | 改动 |
|---|---|
web/src/components/AuroraCanvas.tsx |
新建:Canvas 极光 + 胶片颗粒 + 暗角 + 鼠标交互 |
web/src/components/LoginModal.tsx |
新建:登录弹窗组件 |
web/src/components/LoginModal.module.css |
新建:磨砂玻璃弹窗样式 |
web/src/pages/LandingPage.tsx |
重写:5 层架构 + 双按钮 + Air Spark 遮罩 + 音乐彩蛋 |
web/src/pages/LandingPage.module.css |
重写:全新首页样式 |
web/src/App.tsx |
路由重构:/login → <LandingPage autoLogin /> |
web/index.html |
添加 Space Grotesk 字体 + favicon |
web/src/components/Sidebar.tsx |
Logo 替换 + 导航 / → /app |
web/src/pages/AdminLayout.tsx |
Logo 替换 + 返回链接 /app |
web/src/pages/TeamAdminLayout.tsx |
Logo 替换 + 返回链接 /app |
web/src/pages/ProfilePage.tsx |
返回链接 / → /app |
web/src/components/ProtectedRoute.tsx |
未认证重定向 /login |
web/public/favicon.png |
新增:品牌 favicon |
web/public/bgm.mp3 |
新增:首页背景音乐 |
web/src/assets/logo_32.png |
新增:小尺寸 Logo |
web/src/assets/logo_128.png |
新增:中尺寸 Logo |
web/src/assets/logo_512.png |
新增:大尺寸 Logo |
触发原因
- 系统之前只有登录页,缺少品牌展示首页
- 需要对标 Runway/Pika 等 AI 视频平台的首页质感
- 两个子产品(Air Drama / Air Spark)需要统一入口
备注
- 旧 LoginPage.tsx 保留未删除,作为备用
- 极光效果使用 Canvas +
globalCompositeOperation: 'lighter'+ CSSfilter: blur(50px) - 移动端自动降级 Canvas 分辨率(0.5x DPR)
2026-03-16 — v0.8.5: 安全加固(CRITICAL + HIGH 修复)
状态: ✅ 已完成 | 验收: 待线上验证
变更内容
- C1/C2: 密钥硬编码清除 —
settings.py移除数据库密码和 SECRET_KEY 默认值,backend-deployment.yaml中 DB_PASSWORD/DB_HOST/DB_USER/DJANGO_SECRET_KEY 改为 K8s Secret 引用 - H1: DEBUG 默认改 False — 防止生产环境遗漏配置时暴露调试信息
- H2: 登录限流 — DRF
ScopedRateThrottle实现login: 5/min,全局匿名 30/min、认证用户 120/min - H4: Django Admin 限制 — 仅在
DEBUG=True时注册/admin/URL - H6: XSS 防护 — 安装 DOMPurify,
PromptInput.tsx的innerHTML赋值前进行 HTML 消毒 - H7: ALLOWED_HOSTS 收紧 — 从
"*"改为video-huoshan-api.airlabs.art,localhost - H9: Nginx 安全头 —
server_tokens off+ X-Frame-Options/X-Content-Type-Options/X-XSS-Protection/Referrer-Policy/Permissions-Policy - M1: 密码策略加强 — 最小 8 位 + 常见密码检测 + 纯数字密码检测
- M5: Django 安全头 — 生产环境启用 XSS Filter/Content-Type-Nosniff/X-Frame-Options/SSL Proxy Header
- L1: 登录 POST-only — 移除 GET 方法支持
变更文件
| 文件 | 改动 |
|---|---|
backend/config/settings.py |
SECRET_KEY/DB 默认值清除、DEBUG 默认 False、密码策略加强、DRF 限流配置、生产安全头 |
backend/config/urls.py |
Django Admin 仅 DEBUG 模式注册 |
backend/apps/accounts/views.py |
登录 POST-only + LoginRateThrottle |
k8s/backend-deployment.yaml |
DB/SECRET_KEY 改为 secretKeyRef、ALLOWED_HOSTS 收紧 |
web/nginx.conf |
server_tokens off + 5 个安全响应头 |
web/src/components/PromptInput.tsx |
DOMPurify 消毒 innerHTML |
web/package.json |
新增 dompurify 依赖 |
2026-03-16 — v0.8.4: 管理员操作审计日志
状态: ✅ 已完成 | 验收: ✅ 通过(本地测试)
变更内容
- AdminAuditLog 模型 — 新增审计日志 Model,记录操作人、操作类型(12 种)、目标、变更前后值(JSONField)、IP 地址、时间
log_admin_action()辅助函数 — 统一的审计日志写入接口,自动获取操作人和客户端 IP- 12 处 view 埋点 — 所有管理员 mutation 操作均记录审计日志:
- 创建类:团队创建、团队管理员创建、用户创建、成员创建
- 修改类:团队更新、团队充值、设置秒数池、用户额度更新、系统设置更新、成员额度更新
- 状态类:用户状态切换、成员状态切换
- 日志查询 API —
GET /api/v1/admin/logs,支持按操作类型、操作人、日期范围筛选 + 分页 - 前端日志页面 —
/admin/logs操作日志页,含筛选栏(操作类型下拉、操作人搜索、日期范围)、变更详情展示(旧值 → 新值)、分页 - 侧栏导航 — AdminLayout 新增"操作日志"菜单项
变更文件
| 文件 | 改动 |
|---|---|
backend/apps/accounts/models.py |
新增 AdminAuditLog 模型 + log_admin_action 函数 |
backend/apps/accounts/migrations/0005_adminauditlog.py |
新增迁移 |
backend/apps/generation/views.py |
12 处埋点 + admin_audit_logs_view 新端点 |
backend/apps/generation/urls.py |
新增 admin/logs 路由 |
web/src/types/index.ts |
新增 AuditLog 接口 |
web/src/lib/api.ts |
新增 getAuditLogs 方法 |
web/src/pages/AuditLogsPage.tsx |
新建日志页面 |
web/src/pages/AuditLogsPage.module.css |
新建日志页面样式 |
web/src/pages/AdminLayout.tsx |
侧栏新增"操作日志" |
web/src/App.tsx |
新增 /admin/logs 路由 |
新增 API
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/admin/logs |
审计日志查询(支持 action/operator/start_date/end_date 筛选) |
触发原因
- 充值、修改秒数等操作直接对应金钱,填错无法追溯
- 需要记录谁在什么时候做了什么操作、改了什么值
2026-03-16 — v0.8.3: 团队详情弹窗重构 + 修改秒数功能
状态: ✅ 已完成 | 验收: 待测试
变更内容
- 团队详情:抽屉→弹窗 — 右侧抽屉改为居中弹窗(Modal),遵循 VideoDetailModal 设计规范:毛玻璃背景
backdrop-filter: blur(24px)、border-radius: 16px、入场动画、精致的关闭按钮 - 弹窗尺寸优化 — 宽度 1080px、最小高度 70vh,桌面端大气不小气
- 字号提升 — 统计卡片标签
#8b8ea812px、数值#f1f0ff18px、成员表 14px(对齐 VideoDetailModal 规范) - 修改秒数池功能 — 团队详情"总秒数池"卡片旁新增编辑按钮,支持直接设置
total_seconds_pool值(后端校验不能低于已消耗秒数、不能为负) - member_count 修复 — 后端团队详情 API 漏返回
member_count字段,已补上
变更文件
| 文件 | 改动 |
|---|---|
web/src/pages/TeamsPage.tsx |
抽屉→弹窗结构、修改秒数池 UI + handler |
web/src/pages/TeamsPage.module.css |
全部 Team Detail Modal 样式重写(VideoDetailModal 规范) |
web/src/lib/api.ts |
新增 setTeamPool API 方法 |
backend/apps/generation/views.py |
新增 admin_team_set_pool_view、团队详情补返 member_count |
backend/apps/generation/urls.py |
新增 admin/teams/<id>/set-pool 路由 |
新增 API
| Method | Endpoint | Description |
|---|---|---|
| PUT | /api/v1/admin/teams/<id>/set-pool |
直接设置团队总秒数池 |
触发原因
- 团队详情使用右侧抽屉形式,信息拥挤、不符合暗色主题规范
- 充值秒数填错后无法修改,而这些秒数直接对应金钱
- 成员数卡片值为空(后端遗漏字段)
2026-03-16 — v0.8.2: 管理后台 UI 修复(4 项)+ 失败原因展示
状态: ✅ 已完成 | 验收: 待测试
变更内容
- DatePicker 日历透明修复 —
.dropdown背景从半透明var(--color-bg-card)改为不透明#16161e+backdrop-filter - 自定义 Select 组件 — 替换原生
<select>白色下拉面板,暗色主题 + 动画 + click-outside 关闭(RecordsPage 1 处、UsersPage 2 处) - 公告横幅美化 — 渐变背景 + 左侧强调色竖条 + CSS 跑马灯滚动(hover 暂停)+ 淡出遮罩
- Toast 全局化 —
<Toast />从 VideoGenerationPage 移至 App.tsx 根级,管理后台页面(如设置页保存)可正常显示提示 - 失败原因 tooltip — 消费记录表中失败状态悬浮显示
error_message;CSV 导出增加"失败原因"列;后端 admin_records API 返回error_message字段
变更文件
| 文件 | 改动 |
|---|---|
web/src/components/DatePicker.module.css |
.dropdown 背景改为不透明 |
web/src/components/Select.tsx |
新建自定义暗色 Select 组件 |
web/src/components/Select.module.css |
新建 Select 样式 |
web/src/pages/RecordsPage.tsx |
替换原生 select + 失败原因 tooltip + CSV 导出 |
web/src/pages/RecordsPage.module.css |
新增 errorTooltip 样式 |
web/src/pages/UsersPage.tsx |
替换 2 处原生 select |
web/src/components/AnnouncementBanner.tsx |
跑马灯结构 |
web/src/components/AnnouncementBanner.module.css |
渐变背景 + 滚动动画 |
web/src/App.tsx |
全局 <Toast /> |
web/src/components/VideoGenerationPage.tsx |
移除局部 <Toast /> |
web/src/types/index.ts |
AdminRecord 增加 error_message |
backend/apps/generation/views.py |
admin_records 返回 error_message |
触发原因
- DatePicker / Select 下拉面板与暗色主题不协调
- 公告横幅样式简陋
- 管理后台保存设置无反馈
- 失败记录无法查看具体原因
2026-03-15 — v0.8.1: Seedance API 友好错误提示 + Mock 数据清理
状态: ✅ 已完成 | 验收: ✅ 通过(本地端到端测试)
变更内容
- Seedance API 友好错误提示 —
seedance_client.py新增SeedanceAPIError异常类 +ERROR_MESSAGES错误码映射表,API 报错时返回中文友好提示(如"参考图片中检测到真实人脸")而非原始英文错误 - views.py 错误传递优化 —
video_generate_view异常处理识别SeedanceAPIError,将user_message存入error_message字段,前端直接展示具体原因 - 移除前端 Mock 数据 —
generation.ts删除 DEV 环境下的 7 个硬编码 mock 任务,消除页面加载时的 404 轮询错误
变更文件
| 文件 | 改动 |
|---|---|
backend/utils/seedance_client.py |
新增 SeedanceAPIError 异常类 + ERROR_MESSAGES 映射 + create_task 错误解析 |
backend/apps/generation/views.py |
异常处理区分 SeedanceAPIError,存储友好错误信息 |
web/src/store/generation.ts |
删除 DEV mock 数据(7 个假任务),消除 404 轮询 |
触发原因
- 本地测试上传含真人面部的图片,Seedance 返回 400 但前端只显示"生成失败,请重试",用户无法理解失败原因
- DEV 环境 mock 数据的假 taskId 触发持续 404 轮询错误
备注
- 已覆盖错误码:隐私人脸、敏感图片/视频、参数无效、频率超限、余额不足
- 未匹配的错误码会直接展示 API 原始 message
2026-03-15 — v0.8.0: Seedance API 全流程修复 + TOS 视频持久化
状态: ✅ 已完成 | 验收: ✅ 通过(本地端到端测试)
变更内容
- 音频引用支持 — 后端 content_items 构建新增
audio类型分支,Seedance API 可接收音频参考素材 - 视频 TOS 持久化 — Seedance 返回的临时 URL(24h 有效)自动下载并上传到 TOS,生成永久 CDN 链接;失败时降级使用临时 URL
- 移除硬编码密钥 — ARK_API_KEY 默认值从测试 key 改为空字符串,避免生产环境误用
- 渐进式轮询 — 前端轮询从固定 3 分钟改为渐进式:前 2 分钟每 10s → 2-5 分钟每 30s → 5 分钟后每 60s
- TOS 新桶配置 — 切换到独立桶
airdrama-media(cn-beijing),TOS 配置默认值更新 - K8s Secret 注入 — TOS_ACCESS_KEY / TOS_SECRET_KEY 通过 K8s Secret 注入,CI/CD 自动创建
- CI/CD 密钥同步 — deploy.yaml 新增 TOS 密钥到 kubectl secret 创建命令
变更文件
| 文件 | 改动 |
|---|---|
backend/apps/generation/views.py |
新增 audio content_item 分支 + 完成时 TOS 持久化逻辑 |
backend/utils/tos_client.py |
新增 upload_from_url() — 从 URL 下载并上传到 TOS |
backend/config/settings.py |
TOS 桶/区域/端点改为 airdrama-media (cn-beijing);ARK_API_KEY 默认值清空 |
web/src/store/generation.ts |
setInterval → setTimeout 渐进式轮询 |
k8s/backend-deployment.yaml |
新增 6 个 TOS 环境变量(AK/SK from Secret) |
.gitea/workflows/deploy.yaml |
kubectl secret 新增 TOS_ACCESS_KEY / TOS_SECRET_KEY |
触发原因
- Seedance API 文档审查发现:音频引用未传递、视频 URL 24h 过期、密钥硬编码
- 需要独立 TOS 桶存放生成视频(原桶为同事的阿里云 OSS)
备注
- 本地测试通过:文生视频 "一只猫在阳光下伸懒腰" → 87,300 tokens → 永久 TOS URL
- Seedance 2.0 定价:不含视频输入 46 元/百万 tokens,含视频输入 28 元/百万 tokens
- 资源包 5,000,000 tokens,约可生成 57 个 4 秒 720p 视频
2026-03-13 — 异常上报体系优化 + 轮询策略调整
状态: ✅ 已完成 | 验收: ✅ 通过
变更内容
- LogCenterMiddleware — 新增 Django 中间件,捕获 DRF 之外的异常(导入错误、中间件异常、URL 解析失败),上报日志中台
- custom_exception_handler 优化 — 未处理异常返回 JSON
{'error': '...'}而非 HTML 500 - 轮询间隔调整 — 前端视频生成任务轮询从 5 秒改为 3 分钟(Seedance 生成耗时 2-5 分钟)
- CLAUDE.md 更新 — 增量开发指南从 "Autonomous Skill" 修正为 "agent-auto"
变更文件
| 文件 | 改动 |
|---|---|
backend/utils/log_center.py |
新增 LogCenterMiddleware + 优化 custom_exception_handler |
backend/config/settings.py |
MIDDLEWARE 列表首位加入中间件 |
web/src/store/generation.ts |
轮询间隔 5000ms → 180000ms |
CLAUDE.md |
增量开发指南更新 |
触发原因
- 线上
/api/v1/video/tasks返回 500,日志中台未收到错误上报 - 视频生成轮询过于频繁,增加后端负载
2026-03-13 — Phase 4: TOS 存储 + Seedance API 集成
状态: ✅ 已完成 | 验收: ✅ 通过
变更内容
- TOS 文件上传 — 火山引擎 TOS(S3 兼容)上传,
POST /api/v1/media/upload - Seedance API 对接 — 火山方舟 Seedance 视频生成 API,异步 create_task + query_task
- 数据库持久化 — GenerationRecord 新增 ark_task_id、result_url、error_message、reference_urls
- 前端重写 — generation store 完全重写:TOS 上传 → API 调用 → 轮询 → 展示结果
- 页面刷新持久化 —
loadTasks()从数据库加载历史任务
新增/变更 API
| 端点 | 方法 | 说明 |
|---|---|---|
/api/v1/media/upload |
POST | 上传文件到 TOS |
/api/v1/video/generate |
POST | 创建 Seedance 任务(改写) |
/api/v1/video/tasks |
GET | 用户任务列表(新增) |
/api/v1/video/tasks/<uuid> |
GET | 单任务状态轮询(新增) |
变更文件
| 文件 | 改动 |
|---|---|
backend/utils/tos_client.py |
新增:TOS 上传客户端 |
backend/utils/seedance_client.py |
新增:Seedance API 客户端 |
backend/config/settings.py |
TOS + ARK 配置 |
backend/apps/generation/models.py |
4 个新字段 |
backend/apps/generation/views.py |
3 个新端点 + 重写 generate |
backend/apps/generation/urls.py |
3 条新路由 |
backend/apps/generation/serializers.py |
references 字段 |
backend/requirements.txt |
tos>=2.7, requests>=2.31 |
web/src/store/generation.ts |
完全重写 |
web/src/types/index.ts |
BackendTask 接口 |
web/src/lib/api.ts |
mediaApi + videoApi |
web/src/components/VideoGenerationPage.tsx |
loadTasks on mount |
web/src/components/GenerationCard.tsx |
视频播放器 + 错误态 |
2026-03-13 — 测试隔离 + Mock 数据清理
状态: ✅ 已完成 | 验收: ✅ 通过
变更内容
- 测试 DB 隔离 —
TESTING=true环境变量切换到test_db.sqlite3,Playwright 自动启动测试后端 - 移除 Mock 数据兜底 — DashboardPage 图表仅显示真实数据,无 mock fallback
触发原因
- E2E 测试会污染开发数据库
- Dashboard 应展示真实数据而非虚假 Mock
2026-03-12 — Phase 3: 秒数计量 + 管理后台重做 + 个人中心
状态: ✅ 已完成 | 验收: ✅ 通过(agent-auto 自动测试)
变更内容
- 计量单位变更 — 所有「调用次数」改为「生成秒数」(daily_seconds_limit / monthly_seconds_limit)
- 管理后台重做 — Sidebar 多页面布局,4 个子路由:
/admin/dashboard— 仪表盘 + ECharts 折线图 + 排行柱状图/admin/users— 用户管理(分页、搜索、配额编辑、启用/禁用)/admin/records— 消费记录(时间筛选、导出 CSV)/admin/settings— 系统设置 + 公告管理
- 用户个人中心 (
/profile) — ECharts 环形进度条 + Sparkline + 消费记录 - 8 个新 API 端点 — admin: stats/users/users/:id/quota/status/records + profile: overview/records
设计规范
- 深色主题(Linear/Vercel 风格)
- ECharts + echarts-for-react
- Arco Design 组件库优先
2026-03-12 — Phase 2: 后端 + 用户认证 + 管理面板
状态: ✅ 已完成 | 验收: ✅ 通过(agent-auto 自动测试)
变更内容
- Django 后端 — Django 4.2 + DRF + MySQL 云数据库
- JWT 认证 — SimpleJWT + 前端 Token 自动刷新
- 用户系统 — 登录
/login+ 注册/register - 管理后台 — 基础仪表盘 + 用户配额管理
- 9 个新 API 端点 — 认证 4 个 + 管理 3 个 + 已有接口认证 2 个
2025 — Phase 1: 核心视频生成 UI
状态: ✅ 已完成 | 验收: ✅ 通过(92 单元测试 + 14 E2E 测试)
变更内容
- 视频生成页 — 全能参考/首尾帧双模式
- InputBar — contentEditable 富文本 + @ mention
- 深色主题 UI —
#0a0a0f背景 + Arco Design - 状态管理 — Zustand store
模板(新增变更请复制此模板)
## YYYY-MM-DD — 变更标题
**状态**: 🔲 开发中 / ✅ 已完成 | **验收**: 🔲 待验收 / ✅ 通过 / ❌ 未通过
### 变更内容
1. ...
### 变更文件
| 文件 | 改动 |
|------|------|
| `path/to/file` | 描述 |
### 触发原因
- ...
### 备注
- ...