Compare commits

...

7 Commits

Author SHA1 Message Date
xiaoxia 9c0535da19 fix(generate): Step6 本地上传封面走 OSS + 标题样式恢复 Modal 弹窗模式 (#2061)
CI/CD Pipeline / Check if frontend-only change (push) Has been skipped
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 (push) Successful in 2s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 3s
CI/CD Pipeline / PR Build Web Image (push) Has been skipped
CI/CD Pipeline / PR Build Worker Image (push) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 3s
CI/CD Pipeline / PR Build API Image (push) Has been skipped
CI/CD Pipeline / Frontend Lint (push) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Check push changed paths (push) Successful in 11s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Style (pull_request) Has been skipped
CI/CD Pipeline / Validate - Security (pull_request) Has been skipped
CI/CD Pipeline / Validate - Python (mypy + alembic) (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 / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 55s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 57s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 1m12s
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 / 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 3s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (push) Successful in 1m11s
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 / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (push) Successful in 1m0s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m0s
CI/CD Pipeline / Validate - Python (mypy + alembic) (push) Successful in 2m23s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 1m8s
CI/CD Pipeline / Retag skipped Staging API Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (push) Has been skipped
CI/CD Pipeline / Integration Tests (push) Successful in 2m34s
CI/CD Pipeline / Validate - Style (push) Successful in 3m8s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 43s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m18s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (push) Failing after 3m51s
CI/CD Pipeline / Staging E2E Tests (push) Failing after 1m38s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 1m47s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 3m0s
AI Code Review / AI Code Review (pull_request) Successful in 6m41s
CI/CD Pipeline / Validate - Security (push) Successful in 7m17s
CI/CD Pipeline / Unit Tests (push) Successful in 14m14s
CI/CD Pipeline / Build Production API Image (push) Has been skipped
CI/CD Pipeline / Build Production Web Image (push) Has been skipped
CI/CD Pipeline / CI Gate (push) Has been skipped
CI/CD Pipeline / Build Production Worker Image (push) Has been skipped
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Canary Release to Production (push) Has been skipped
Co-authored-by: xiaoxia <dev@xiaoxiajianji.com>
Co-committed-by: xiaoxia <dev@xiaoxiajianji.com>
2026-09-27 11:19:04 +08:00
xiaoxia c7288cd46b fix(generate): Step6封面完成按钮在awaiting_cover阶段可用 (#2060)
CI/CD Pipeline / Check if frontend-only change (push) Has been skipped
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (push) Has been skipped
CI/CD Pipeline / PR Build Web Image (push) Has been skipped
CI/CD Pipeline / PR Build Worker Image (push) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 4s
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (push) Successful in 1s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 3s
CI/CD Pipeline / Frontend Lint (push) 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 / Check push changed paths (push) Successful in 11s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Style (pull_request) Has been skipped
CI/CD Pipeline / Validate - Security (pull_request) Has been skipped
CI/CD Pipeline / Validate - Python (mypy + alembic) (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 / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 1m22s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m9s
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 / Build Staging API Image (push) Successful in 1m52s
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
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 / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (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 / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (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 / Validate - Python (mypy + alembic) (push) Successful in 3m6s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m19s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 3m14s
CI/CD Pipeline / Validate - Style (push) Successful in 3m30s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 1m59s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 3m31s
CI/CD Pipeline / CI Gate (pull_request) Successful in 2s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 3m18s
CI/CD Pipeline / Retag skipped Staging API Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (push) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 45s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 4m51s
CI/CD Pipeline / Validate - Security (push) Successful in 5m51s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 1m52s
CI/CD Pipeline / Integration Tests (push) Successful in 6m36s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 3m4s
CI/CD Pipeline / Staging E2E Tests (push) Failing after 3m43s
AI Code Review / AI Code Review (pull_request) Successful in 9m55s
CI/CD Pipeline / Unit Tests (push) Successful in 10m15s
CI/CD Pipeline / Build Production API Image (push) Has been skipped
CI/CD Pipeline / Build Production Web Image (push) Has been skipped
CI/CD Pipeline / Build Production Worker Image (push) Has been skipped
CI/CD Pipeline / CI Gate (push) Has been skipped
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Canary Release to Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
Co-authored-by: xiaoxia <dev@xiaoxiajianji.com>
Co-committed-by: xiaoxia <dev@xiaoxiajianji.com>
2026-09-27 10:34:38 +08:00
xiaoxia 447aad166b fix(title): 爆款预设缩略图色块/缺字回归bug (#2059)
CI/CD Pipeline / Check if frontend-only change (push) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (push) Successful in 2s
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 2s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
CI/CD Pipeline / PR Build Worker Image (push) Has been skipped
CI/CD Pipeline / PR Build Web Image (push) Has been skipped
CI/CD Pipeline / PR Build API Image (push) Has been skipped
CI/CD Pipeline / Frontend Lint (push) Has been skipped
CI/CD Pipeline / Validate - Style (pull_request) Has been skipped
CI/CD Pipeline / Validate - Security (pull_request) Has been skipped
CI/CD Pipeline / Validate - Python (mypy + alembic) (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 / Check push changed paths (push) Successful in 10s
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 49s
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 / PR Build API Image (pull_request) Successful in 59s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m13s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 1m12s
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 Staging API Image (push) Successful in 1m19s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (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 / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Validate - Style (push) Successful in 3m25s
CI/CD Pipeline / Validate - Python (mypy + alembic) (push) Successful in 4m6s
CI/CD Pipeline / Integration Tests (push) Successful in 4m23s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 4m42s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 2m53s
CI/CD Pipeline / Retag skipped Staging API Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (push) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 3s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 5m50s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 37s
CI/CD Pipeline / Validate - Security (push) Successful in 5m58s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 6m27s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been skipped
AI Code Review / AI Code Review (pull_request) Successful in 7m7s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 1m41s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 3m50s
CI/CD Pipeline / Staging E2E Tests (push) Failing after 4m5s
CI/CD Pipeline / Unit Tests (push) Successful in 12m24s
CI/CD Pipeline / Build Production API Image (push) Has been skipped
CI/CD Pipeline / Build Production Worker Image (push) Has been skipped
CI/CD Pipeline / CI Gate (push) Has been skipped
CI/CD Pipeline / Build Production Web Image (push) Has been skipped
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Canary Release to Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
Co-authored-by: xiaoxia <dev@xiaoxiajianji.com>
Co-committed-by: xiaoxia <dev@xiaoxiajianji.com>
2026-09-27 10:19:58 +08:00
xiaoxia 1463cf0834 fix(version): /health 返回真实 commit SHA,不再是 unknown (#2058)
CI/CD Pipeline / Check if frontend-only change (push) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (push) Successful in 1s
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 3s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 3s
CI/CD Pipeline / Frontend Lint (push) Has been skipped
CI/CD Pipeline / PR Build Web Image (push) Has been skipped
CI/CD Pipeline / PR Build Worker Image (push) 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 / PR Build API Image (push) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Style (pull_request) Has been skipped
CI/CD Pipeline / Validate - Security (pull_request) Has been skipped
CI/CD Pipeline / Validate - Python (mypy + alembic) (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 / Check push changed paths (push) Successful in 14s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit 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 / PR Build Worker Image (pull_request) Successful in 1m5s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 1m6s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 1m11s
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 / 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 / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 3s
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (push) Successful in 1m5s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 32s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 34s
CI/CD Pipeline / Retag skipped Staging API Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (push) Has been skipped
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m52s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 48s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m21s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been skipped
CI/CD Pipeline / Validate - Python (mypy + alembic) (push) Successful in 3m36s
CI/CD Pipeline / Validate - Style (push) Successful in 4m12s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 4m30s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 2m15s
CI/CD Pipeline / Integration Tests (push) Successful in 6m3s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 3m33s
AI Code Review / AI Code Review (pull_request) Successful in 6m50s
CI/CD Pipeline / Staging E2E Tests (push) Failing after 5m33s
CI/CD Pipeline / Validate - Security (push) Successful in 9m15s
CI/CD Pipeline / Unit Tests (push) Successful in 10m1s
CI/CD Pipeline / Build Production API Image (push) Has been skipped
CI/CD Pipeline / Build Production Web Image (push) Has been skipped
CI/CD Pipeline / CI Gate (push) Has been skipped
CI/CD Pipeline / Build Production Worker Image (push) Has been skipped
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Canary Release to Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
Co-authored-by: xiaoxia <dev@xiaoxiajianji.com>
Co-committed-by: xiaoxia <dev@xiaoxiajianji.com>
2026-09-27 01:13:33 +08:00
xiaoxia 3a8d5e50d0 fix(ci): staging SSH 默认目标改为业务机 47.98.113.167:22222 (#2057)
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (push) Successful in 2s
CI/CD Pipeline / Check if frontend-only change (push) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 2s
CI/CD Pipeline / Check push changed paths (push) Successful in 8s
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m0s
CI/CD Pipeline / Frontend Lint (push) Has been skipped
CI/CD Pipeline / PR Build API Image (push) Has been skipped
CI/CD Pipeline / PR Build Web Image (push) Has been skipped
CI/CD Pipeline / PR Build Worker Image (push) Has been skipped
CI/CD Pipeline / Validate - Style (pull_request) Has been skipped
CI/CD Pipeline / Validate - Security (pull_request) Has been skipped
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Has been skipped
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m56s
CI/CD Pipeline / Validate - Python (mypy + alembic) (push) Successful in 4m3s
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (push) Successful in 17s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (push) Successful in 30s
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 / PR Build API Image (pull_request) Successful in 23s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 26s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 30s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been skipped
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 / 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 / Retag skipped Staging API Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (push) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (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 Worker Image (pull_request) Successful in 44s
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 2s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 1m14s
AI Code Review / AI Code Review (pull_request) Successful in 6m53s
CI/CD Pipeline / Validate - Style (push) Successful in 7m57s
CI/CD Pipeline / Integration Tests (push) Successful in 5m15s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 4m36s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 3m12s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 4m17s
CI/CD Pipeline / Validate - Security (push) Successful in 10m26s
CI/CD Pipeline / Build Production API Image (push) Has been cancelled
CI/CD Pipeline / Build Production Web Image (push) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (push) Has been cancelled
CI/CD Pipeline / Deploy Production (push) Has been cancelled
CI/CD Pipeline / Production Browser E2E (push) Has been cancelled
CI/CD Pipeline / Canary Release to Production (push) Has been cancelled
CI/CD Pipeline / CI Gate (push) Has been cancelled
CI/CD Pipeline / Unit Tests (push) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (push) Has been cancelled
Co-authored-by: xiaoxia <dev@xiaoxiajianji.com>
Co-committed-by: xiaoxia <dev@xiaoxiajianji.com>
2026-09-27 00:59:28 +08:00
xiaoxia 6778f4be32 test(title): 补标题工具函数单测,前端覆盖率从49.99%提升到50.15% (#2056)
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 (push) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (push) Successful in 0s
CI/CD Pipeline / Validate - Style (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
CI/CD Pipeline / Validate - Security (pull_request) Has been skipped
CI/CD Pipeline / Validate - Python (mypy + alembic) (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 / Frontend Lint (push) Has been skipped
CI/CD Pipeline / PR Build API Image (push) Has been skipped
CI/CD Pipeline / PR Build Web Image (push) Has been skipped
CI/CD Pipeline / PR Build Worker Image (push) 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 / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Check push changed paths (push) Successful in 9s
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 / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker 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 / PR Build Web Image (pull_request) Successful in 56s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 1m7s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (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 / Canary Release to Production (pull_request) Has been skipped
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m47s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 1m18s
CI/CD Pipeline / Build Staging API Image (push) Successful in 1m23s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 2m33s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 1m47s
CI/CD Pipeline / CI Gate (pull_request) Successful in 3s
CI/CD Pipeline / Retag skipped Staging API Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (push) Has been skipped
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m10s
CI/CD Pipeline / Integration Tests (push) Successful in 3m16s
CI/CD Pipeline / Validate - Style (push) Successful in 3m27s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 1m17s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 6m7s
AI Code Review / AI Code Review (pull_request) Successful in 6m40s
CI/CD Pipeline / Validate - Python (mypy + alembic) (push) Successful in 7m1s
CI/CD Pipeline / Validate - Security (push) Successful in 7m39s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 1m51s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 3m43s
CI/CD Pipeline / Staging E2E Tests (push) Failing after 3m58s
CI/CD Pipeline / Unit Tests (push) Successful in 13m42s
CI/CD Pipeline / Build Production API Image (push) Has been skipped
CI/CD Pipeline / Build Production Web Image (push) Has been skipped
CI/CD Pipeline / Build Production Worker Image (push) Has been skipped
CI/CD Pipeline / CI Gate (push) Has been skipped
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Canary Release to Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
Co-authored-by: xiaoxia <dev@xiaoxiajianji.com>
Co-committed-by: xiaoxia <dev@xiaoxiajianji.com>
2026-09-27 00:45:23 +08:00
xiaoxia 778b17a723 Merge pull request 'feat(gpu): 接入 P4000 NVENC 硬件编码加速' (#2055) from feature/gpu-nvenc-encode into develop
CI/CD Pipeline / Check if frontend-only change (push) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (push) Successful in 1s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 1s
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 2s
CI/CD Pipeline / Frontend Lint (push) Has been skipped
CI/CD Pipeline / PR Build API Image (push) Has been skipped
CI/CD Pipeline / PR Build Web Image (push) Has been skipped
CI/CD Pipeline / PR Build Worker Image (push) Has been skipped
CI/CD Pipeline / Validate - Style (pull_request) Has been skipped
CI/CD Pipeline / Check push changed paths (push) Successful in 7s
CI/CD Pipeline / Validate - Security (pull_request) Has been skipped
CI/CD Pipeline / Validate - Python (mypy + alembic) (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 / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (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
PR Automation / Auto Approve on CI Green (pull_request) Successful in 1m12s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 1m14s
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 / 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
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (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 / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (push) Successful in 1m26s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 2m34s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 1m36s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 2m17s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 3m33s
CI/CD Pipeline / Retag skipped Staging API Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (push) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 1m7s
CI/CD Pipeline / Frontend Unit Tests (push) Failing after 4m52s
CI/CD Pipeline / Integration Tests (push) Successful in 5m33s
CI/CD Pipeline / Validate - Style (push) Successful in 6m15s
AI Code Review / AI Code Review (pull_request) Successful in 7m6s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 2m31s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 4m8s
CI/CD Pipeline / PR Build Web Image (pull_request) Failing after 10m6s
CI/CD Pipeline / Staging E2E Tests (push) Failing after 5m31s
CI/CD Pipeline / CI Gate (pull_request) Failing after 2s
CI/CD Pipeline / Unit Tests (push) Successful in 12m24s
CI/CD Pipeline / Validate - Security (push) Successful in 13m8s
CI/CD Pipeline / Validate - Python (mypy + alembic) (push) Successful in 24m42s
CI/CD Pipeline / Build Production API Image (push) Has been skipped
CI/CD Pipeline / Build Production Web Image (push) Has been skipped
CI/CD Pipeline / Build Production Worker Image (push) Has been skipped
CI/CD Pipeline / CI Gate (push) Has been skipped
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Canary Release to Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
2026-09-26 21:46:42 +08:00
11 changed files with 628 additions and 83 deletions
+8 -7
View File
@@ -813,7 +813,7 @@ jobs:
IMAGE_TAG="${REGISTRY}/${{ matrix.image_name }}:pr-${GITHUB_SHA}" IMAGE_TAG="${REGISTRY}/${{ matrix.image_name }}:pr-${GITHUB_SHA}"
CACHE_REF="${REGISTRY}/${{ matrix.cache_name }}:develop" CACHE_REF="${REGISTRY}/${{ matrix.cache_name }}:develop"
EXTRA_BUILD_ARGS="APP_VERSION=\"${GITHUB_SHA}\"" EXTRA_BUILD_ARGS="APP_VERSION=${GITHUB_SHA}"
# Worker 与 API/Web 统一走持久 builder(ci-builder-persist),共享宿主机层缓存 # Worker 与 API/Web 统一走持久 builder(ci-builder-persist),共享宿主机层缓存
NO_CACHE_FLAG="" NO_CACHE_FLAG=""
@@ -1014,7 +1014,7 @@ jobs:
PUSHED_TAGS_SUMMARY="${BRANCH_TAG}" PUSHED_TAGS_SUMMARY="${BRANCH_TAG}"
fi fi
EXTRA_BUILD_ARGS="APP_VERSION=\"${GITHUB_SHA}\"" EXTRA_BUILD_ARGS="APP_VERSION=${GITHUB_SHA}"
NO_CACHE_FLAG="" NO_CACHE_FLAG=""
for i in 1 2 3; do for i in 1 2 3; do
@@ -1238,11 +1238,12 @@ jobs:
ACR_PASSWORD: "${{ secrets.ACR_PASSWORD }}" ACR_PASSWORD: "${{ secrets.ACR_PASSWORD }}"
run: | run: |
set -eux set -eux
# CI runner (act_runner) 部署在 116 staging 本机(116.62.226.203 公网 22 未开放), # Staging 业务机 = 47.98.113.167(公网 sshd 端口 22222;内网 VPC 10.0.0.2:22)。
# 默认走 127.0.0.1:22 本机 SSH,避免跨机网络依赖;可通过 secrets 覆盖。 # CI runner 已迁移到独立 CI 机器、job 在隔离容器网络内执行,127.0.0.1 会指向 job 容器自身而失败,
staging_host="${STAGING_SSH_HOST:-127.0.0.1}" # 故默认目标必须是 staging 业务机;仍可通过 secrets 覆盖。
staging_host="${STAGING_SSH_HOST:-47.98.113.167}"
staging_user="${STAGING_SSH_USER:-root}" staging_user="${STAGING_SSH_USER:-root}"
staging_port="${STAGING_SSH_PORT:-22}" staging_port="${STAGING_SSH_PORT:-22222}"
echo "Host: $staging_host" echo "Host: $staging_host"
echo "Port: $staging_port" echo "Port: $staging_port"
@@ -1552,7 +1553,7 @@ jobs:
IMAGE_TAG="${REGISTRY}/${{ matrix.image_name }}:${TAG_NAME}" IMAGE_TAG="${REGISTRY}/${{ matrix.image_name }}:${TAG_NAME}"
CACHE_REF="${REGISTRY}/${{ matrix.cache_name }}:main" CACHE_REF="${REGISTRY}/${{ matrix.cache_name }}:main"
EXTRA_BUILD_ARGS="APP_VERSION=\"${TAG_NAME}\"" EXTRA_BUILD_ARGS="APP_VERSION=${TAG_NAME}"
# Docker build 带重试:失败自动重试2次,第2次重试加--no-cache # Docker build 带重试:失败自动重试2次,第2次重试加--no-cache
NO_CACHE_FLAG="" NO_CACHE_FLAG=""
+5 -5
View File
@@ -20,15 +20,15 @@ export const FONT_OPTIONS: FontOption[] = [
{ {
value: "优设标题黑", value: "优设标题黑",
label: "优设标题黑", label: "优设标题黑",
// 原版"优设标题黑"为商用字体,非开源;这里优先使用本地已安装字体,兜底用 ZCOOL QingKe HuangYou(站酷庆科黄油体,同为厚重黑体/海报风格,可从 Google Fonts 加载) // 原版"优设标题黑"为商用字体非开源;优先本地已安装字体,兜底用 Noto Sans SC(Google Fonts 已加载 wght@900,保证 bold 字重可用),再用 ZCOOL 庆科黄油体作风格兜底
family: family:
'"YouSheBiaoTiHei","YouShe Title Black","ZCOOL QingKe HuangYou","Noto Sans SC","PingFang SC","Microsoft YaHei",sans-serif', '"YouSheBiaoTiHei","YouShe Title Black","Noto Sans SC","ZCOOL QingKe HuangYou","PingFang SC","Microsoft YaHei",sans-serif',
tag: "hot", tag: "hot",
}, },
{ {
value: "阿里普惠体Bold", value: "阿里普惠体Bold",
label: "阿里普惠体Bold", label: "阿里普惠体Bold",
// 阿里普惠体需要从阿里官网下载;兜底用 Noto Sans SC 900(同等字重) // 阿里普惠体需从阿里官网下载;兜底用 Noto Sans SC 900(同等字重,已在 Google Fonts wght@400;500;700;900 加载)
family: family:
'"Alibaba PuHuiTi","Alibaba PuHuiTi Bold","Alibaba Sans","Noto Sans SC",system-ui,"PingFang SC","Microsoft YaHei",sans-serif', '"Alibaba PuHuiTi","Alibaba PuHuiTi Bold","Alibaba Sans","Noto Sans SC",system-ui,"PingFang SC","Microsoft YaHei",sans-serif',
tag: "hot", tag: "hot",
@@ -36,9 +36,9 @@ export const FONT_OPTIONS: FontOption[] = [
{ {
value: "抖音美好体", value: "抖音美好体",
label: "抖音美好体", label: "抖音美好体",
// 抖音美好体版权字体兜底 ZCOOL KuaiLe(站酷快乐体,圆润卡通风格近似) // 抖音美好体为版权字体;兜底用 Noto Sans SC(确保 bold 字重可用),再用 ZCOOL KuaiLe(站酷快乐体,圆润卡通风格近似)
family: family:
'"Douyin Sans","DouyinSans","ZCOOL KuaiLe","Noto Sans SC","PingFang SC","Microsoft YaHei",sans-serif', '"Douyin Sans","DouyinSans","Noto Sans SC","ZCOOL KuaiLe","PingFang SC","Microsoft YaHei",sans-serif',
tag: "hot", tag: "hot",
}, },
{ {
+13 -5
View File
@@ -421,7 +421,10 @@ const GeneratePage: React.FC = () => {
return return
} }
} else { } else {
if (!finalVideo) { // 单视频:finalVideo 可能因 /results 接口在 awaiting_cover 阶段暂未返回
// GeneratedVideo 记录而为 undefined;此时 currentTaskId 已在创建任务时保存,
// 下面 singleTaskId 兜底逻辑会用 currentTaskId 调 finalize,不应拦截
if (!finalVideo && !currentTaskId) {
message.warning("请等待视频生成完成") message.warning("请等待视频生成完成")
return return
} }
@@ -438,19 +441,24 @@ const GeneratePage: React.FC = () => {
await Promise.all( await Promise.all(
batchTasks.map(async (task) => { batchTasks.map(async (task) => {
const vi = task.variantIndex const vi = task.variantIndex
const coverUrl = previewCovers[vi] || "" const rawCoverUrl = previewCovers[vi] || ""
const coverUrl = rawCoverUrl.startsWith("blob:") ? "" : rawCoverUrl
const title = previewTitles[vi] || titleSettings.title || "" const title = previewTitles[vi] || titleSettings.title || ""
return finalizeGeneration(task.taskId, { return finalizeGeneration(task.taskId, {
cover_url: coverUrl || undefined, cover_url: coverUrl || undefined,
custom_title: title, custom_title: title || undefined,
}) })
}), }),
) )
} else if (singleTaskId) { } else if (singleTaskId) {
const coverUrl = coverSettings.thumbnail_url || coverSettings.upload_url || "" // 单视频:cover_url 仅在非 blob: 本地预览地址时才传;blob: URL 浏览器本地临时地址,
// 后端无法下载,此时不传让后端回退自动截帧封面(避免 400 保存失败)。
// 正常流程本地上传完成后 uploadLocalCover 会把 URL 替换为 OSS 真实 URL,这里仅兜底异常场景。
const rawCoverUrl = coverSettings.thumbnail_url || coverSettings.upload_url || ""
const coverUrl = rawCoverUrl.startsWith("blob:") ? "" : rawCoverUrl
await finalizeGeneration(singleTaskId, { await finalizeGeneration(singleTaskId, {
cover_url: coverUrl || undefined, cover_url: coverUrl || undefined,
custom_title: titleSettings.title || "", custom_title: titleSettings.title || undefined,
}) })
} else { } else {
console.warn("[handleFinish] 未找到任务 ID,跳过 finalize 直接跳转") console.warn("[handleFinish] 未找到任务 ID,跳过 finalize 直接跳转")
@@ -6,13 +6,12 @@
* - 批量:N 个独立标题输入框(AutoComplete 支持标题库选择) * - 批量:N 个独立标题输入框(AutoComplete 支持标题库选择)
* - 标题样式(字体/颜色/位置/大小/粗斜描边/预设):全局统一 * - 标题样式(字体/颜色/位置/大小/粗斜描边/预设):全局统一
*/ */
import React, { useMemo } from "react" import React, { useMemo, useState } from "react"
import type { TitleSettings } from "../types" import type { TitleSettings } from "../types"
import { POSITION_OPTIONS } from "../constants"
import { FONT_OPTIONS } from "@/components/title/constants"
import { useStep4Title } from "../hooks/useStep4Title" import { useStep4Title } from "../hooks/useStep4Title"
import TitleLibraryAutoComplete from "./title/TitleLibraryAutoComplete" import TitleLibraryAutoComplete from "./title/TitleLibraryAutoComplete"
import TitleStylePanel from "./title/TitleStylePanel" import TitleStyleModal from "./title/TitleStyleModal"
import Button from "@/components/ui/Button"
import type { TitleTemplate } from "@/components/title/template-types" import type { TitleTemplate } from "@/components/title/template-types"
interface Step4TitleSettingsProps { interface Step4TitleSettingsProps {
@@ -58,13 +57,6 @@ interface Step4TitleSettingsProps {
const Step4TitleSettings: React.FC<Step4TitleSettingsProps> = (props) => { const Step4TitleSettings: React.FC<Step4TitleSettingsProps> = (props) => {
const t = useStep4Title(props) const t = useStep4Title(props)
const { const {
onUpdatePosition,
onUpdateFont,
onUpdateSize,
onToggleBold,
onToggleItalic,
onToggleStroke,
onToggleShadow,
onApplyPreset, onApplyPreset,
onUpdateStyle, onUpdateStyle,
activePreset, activePreset,
@@ -72,14 +64,12 @@ const Step4TitleSettings: React.FC<Step4TitleSettingsProps> = (props) => {
previewCount = 1, previewCount = 1,
previewTitles, previewTitles,
onPreviewTitlesChange, onPreviewTitlesChange,
enableTemplates,
selectedTemplateId,
onApplyTemplate,
onConfirmGenerate, onConfirmGenerate,
generating, generating,
selectedCount = 1, selectedCount = 1,
} = props } = props
const [showTitleStyleModal, setShowTitleStyleModal] = useState(false)
const isBatch = previewCount > 1 const isBatch = previewCount > 1
/** 更新单个变体标题;变体0同步写回 titleSettings.title(全局样式面板/草稿/TTS 链路依赖) */ /** 更新单个变体标题;变体0同步写回 titleSettings.title(全局样式面板/草稿/TTS 链路依赖) */
@@ -184,27 +174,30 @@ const Step4TitleSettings: React.FC<Step4TitleSettingsProps> = (props) => {
</div> </div>
)} )}
{/* 标题样式面板(全局共用) */} {/* 标题样式:点击打开弹窗(参考字幕模板/封面模板 Modal 模式) */}
<TitleStylePanel <TitleStyleModal
open={showTitleStyleModal}
onClose={() => setShowTitleStyleModal(false)}
titleText={previewTitles?.[0] ?? t.titleSettings.title}
settings={t.titleSettings} settings={t.titleSettings}
onUpdatePosition={onUpdatePosition}
onUpdateFont={onUpdateFont}
onUpdateSize={onUpdateSize}
onToggleBold={onToggleBold}
onToggleItalic={onToggleItalic}
onToggleStroke={onToggleStroke}
onToggleShadow={onToggleShadow}
onApplyPreset={onApplyPreset}
onUpdateStyle={onUpdateStyle}
showCoverToggle
activePreset={activePreset} activePreset={activePreset}
titlePresets={titlePresets} onSave={(nextSettings, nextPreset) => {
POSITION_OPTIONS={POSITION_OPTIONS} onUpdateStyle?.(nextSettings)
FONT_OPTIONS={FONT_OPTIONS} if (nextPreset) onApplyPreset(nextPreset)
enableTemplates={enableTemplates} }}
selectedTemplateId={selectedTemplateId}
onApplyTemplate={onApplyTemplate}
/> />
<div className="xx-form-field">
<label>标题样式</label>
<Button
buttonType="ghost"
onClick={() => setShowTitleStyleModal(true)}
style={{ justifyContent: "flex-start", textAlign: "left" }}
>
{activePreset
? titlePresets.find((p) => p.key === activePreset)?.label || "自定义样式"
: "点击选择标题样式(预设 / 字体 / 颜色 / 描边 / 阴影)"}
</Button>
</div>
</div> </div>
) )
} }
@@ -5,8 +5,8 @@
* *
* 模板 CRUD + 编辑器弹窗 + 自动生成 + 上传 复用 components/cover/useSharedCover * 模板 CRUD + 编辑器弹窗 + 自动生成 + 上传 复用 components/cover/useSharedCover
*/ */
import React, { useEffect, useMemo } from "react" import React, { useCallback, useEffect, useMemo, useState } from "react"
import { Modal, Spin } from "antd" import { Modal, Spin, message } from "antd"
import { LoadingOutlined } from "@ant-design/icons" import { LoadingOutlined } from "@ant-design/icons"
import type { CoverConfig } from "../types/cover" import type { CoverConfig } from "../types/cover"
import type { GeneratedVideo } from "@/api/template-editor" import type { GeneratedVideo } from "@/api/template-editor"
@@ -17,6 +17,7 @@ import CoverSettingsModal from "./cover-settings/CoverSettingsModal"
import CoverEditorModal from "./cover-settings/CoverEditorModal" import CoverEditorModal from "./cover-settings/CoverEditorModal"
import { useSharedCover } from "@/components/cover/useSharedCover" import { useSharedCover } from "@/components/cover/useSharedCover"
import { generateCover as apiGenerateCover } from "@/api/generation" import { generateCover as apiGenerateCover } from "@/api/generation"
import { uploadAssetDirect, getAssetLibraries } from "@/api/assets"
interface Step6CoverSettingsProps { interface Step6CoverSettingsProps {
coverSettings: CoverConfig coverSettings: CoverConfig
@@ -159,9 +160,65 @@ const Step6CoverSettings: React.FC<Step6CoverSettingsProps> = (props) => {
} }
}, [isBatch, shared.selectedTemplateId, parentSelectedTemplate, onTemplateChange]) }, [isBatch, shared.selectedTemplateId, parentSelectedTemplate, onTemplateChange])
/** 单视频本地上传封面:选完文件后上传到素材库 OSS,拿到真实 URL 再 set */
const [uploadingLocalCover, setUploadingLocalCover] = useState(false)
const { coverSettings: curCoverSettings, onCoverSettingsChange } = props
const uploadLocalCover = useCallback(
async (file: File): Promise<string | null> => {
const hide = message.loading("正在上传封面...", 0)
setUploadingLocalCover(true)
try {
// 立即创建 blob URL 用于即时预览,同时异步上传 OSS
const previewUrl = URL.createObjectURL(file)
onCoverSettingsChange({
...curCoverSettings,
upload_url: previewUrl,
thumbnail_url: previewUrl,
mode: "upload",
})
// 查找图片素材库(复用批量封面的逻辑)
const libs = await getAssetLibraries()
const imageLib = libs.find((l) => l.kind === "image") || libs[0]
if (!imageLib) {
hide()
message.error("未找到素材库,请先创建图片素材库")
return previewUrl
}
const result = await uploadAssetDirect({ file, library_id: imageLib.id })
const realUrl = result?.url || ""
if (!realUrl) {
hide()
message.warning("上传完成但未获取到URL,将使用本地预览")
return previewUrl
}
hide()
// 替换 blob URL 为真实 OSS URL(blob 用于预览过渡,finalize 时必须用真实 URL)
onCoverSettingsChange({
...curCoverSettings,
upload_url: realUrl,
thumbnail_url: realUrl,
mode: "upload",
})
message.success("封面上传成功")
return realUrl
} catch (err) {
hide()
console.error("[Step6] 封面上传失败:", err)
message.error("封面上传失败,请重试")
return null
} finally {
setUploadingLocalCover(false)
}
},
[curCoverSettings, onCoverSettingsChange],
)
useEffect(() => { useEffect(() => {
shared.setOnUploadFile(() => null) // 单视频:注册实际上传函数;批量场景已由 batchCovers.uploadOne 接管,
}, [shared]) // 这里不要覆盖(批量时 input ref 绑定到 batchUploadRef,不走 shared.handleFileInputChange)
if (!isBatch) {
shared.setOnUploadFile((file) => uploadLocalCover(file))
}
}, [shared, isBatch, uploadLocalCover])
const batchUploadRef = React.useRef<HTMLInputElement>(null) const batchUploadRef = React.useRef<HTMLInputElement>(null)
const [batchUploadCard, setBatchUploadCard] = React.useState<number | null>(null) const [batchUploadCard, setBatchUploadCard] = React.useState<number | null>(null)
@@ -399,7 +456,12 @@ const Step6CoverSettings: React.FC<Step6CoverSettingsProps> = (props) => {
<Button buttonType="ghost" onClick={() => shared.setShowCoverSettings(true)}> <Button buttonType="ghost" onClick={() => shared.setShowCoverSettings(true)}>
⚙️ 封面模板 ⚙️ 封面模板
</Button> </Button>
<Button buttonType="ghost" onClick={shared.handleUploadClick}> <Button
buttonType="ghost"
onClick={shared.handleUploadClick}
disabled={uploadingLocalCover}
loading={uploadingLocalCover}
>
📷 本地上传 📷 本地上传
</Button> </Button>
<input <input
@@ -407,18 +469,7 @@ const Step6CoverSettings: React.FC<Step6CoverSettingsProps> = (props) => {
type="file" type="file"
accept="image/*" accept="image/*"
style={{ display: "none" }} style={{ display: "none" }}
onChange={(e) => { onChange={shared.handleFileInputChange}
const file = e.target.files?.[0]
e.target.value = ""
if (!file) return
const url = URL.createObjectURL(file)
props.onCoverSettingsChange({
...props.coverSettings,
upload_url: url,
thumbnail_url: url,
mode: "upload",
})
}}
/> />
<input <input
ref={batchUploadRef} ref={batchUploadRef}
@@ -89,9 +89,8 @@ const TitleMiniPreview: React.FC<Props> = ({
ctx.fillRect(0, 0, width, h) ctx.fillRect(0, 0, width, h)
} }
// 分辨率缩放:以 360 宽为基准(对应 720p 的一半) // 分辨率缩放:以 360 宽为基准(对应 720p 的一半),与外层 previewScale/previewR 保持一致
const scale = width / 360 const r = previewR
const r = (v: number) => Math.round(v * scale)
// 字体 // 字体
const size = r(settings.size) const size = r(settings.size)
@@ -158,6 +157,9 @@ const TitleMiniPreview: React.FC<Props> = ({
ctx.fillStyle = settings.bgColor ?? "rgba(0,0,0,0.5)" ctx.fillStyle = settings.bgColor ?? "rgba(0,0,0,0.5)"
roundRect(ctx, bx, by, bw, bh, rad) roundRect(ctx, bx, by, bw, bh, rad)
ctx.fill() ctx.fill()
// 关键修复:画完背景块后必须把 fillStyle 重置为文字颜色,
// 否则后续 fillText 会用 bgColor 填充文字,导致「文字看不见只剩色块」
ctx.fillStyle = settings.color
// 恢复阴影 // 恢复阴影
if (shadowEnabled) { if (shadowEnabled) {
ctx.shadowColor = settings.shadowColor ?? "rgba(0,0,0,0.8)" ctx.shadowColor = settings.shadowColor ?? "rgba(0,0,0,0.8)"
@@ -194,15 +196,38 @@ const TitleMiniPreview: React.FC<Props> = ({
ctx.shadowOffsetX = prevShadow.ox ctx.shadowOffsetX = prevShadow.ox
ctx.shadowOffsetY = prevShadow.oy ctx.shadowOffsetY = prevShadow.oy
} }
// Web fonts (Google Fonts 等) 加载需要时间,等 fonts.ready 后再画, // 计算当前字号(draw() 内部同样逻辑,抽出来供 fontString 复用)
// 避免第一次渲染用 sans-serif 画完再切字体造成「字体选择没反应」的错觉 const previewScale = width / 360
if (typeof document !== "undefined" && document.fonts && document.fonts.ready) { const previewR = (v: number) => Math.round(v * previewScale)
document.fonts.ready.then(() => { const buildFontString = () => {
if (cancelled) return const size = previewR(settings.size)
draw() const ff = getFontFamily(settings.font)
}) const parts: string[] = []
if (settings.italic) parts.push("italic")
if (settings.bold) parts.push("bold")
parts.push(`${size}px`, ff)
return parts.join(" ")
} }
draw()
// Web Font 加载保障:
// 1) 等 document.fonts.ready(CSS @font-face 首次可用)
// 2) 显式 FontFaceSet.load(fontString, text) 触发浏览器真正下载并加载
// 当前字体到 Canvas 可用,避免首次绘制用 fallback 字体画出错字/色块
const doDrawWhenReady = async () => {
try {
if (typeof document !== "undefined" && document.fonts) {
await document.fonts.ready
try {
await document.fonts.load(buildFontString(), text)
} catch {
/* ignore */
}
}
} finally {
if (!cancelled) draw()
}
}
doDrawWhenReady()
return () => { return () => {
cancelled = true cancelled = true
} }
@@ -0,0 +1,90 @@
.tsm-body {
padding: 0;
}
.tsm-preview {
width: 100%;
background: #111;
border-radius: 8px;
padding: 12px;
margin-bottom: 16px;
display: flex;
justify-content: center;
overflow: hidden;
}
.tsm-presets-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
gap: 12px;
max-height: 440px;
overflow-y: auto;
padding: 4px 2px 8px;
}
.tsm-preset-card {
display: flex;
flex-direction: column;
align-items: center;
background: #fff;
border: 2px solid #e5e7eb;
border-radius: 10px;
padding: 8px 6px 6px;
cursor: pointer;
transition: all 0.15s ease;
overflow: hidden;
}
.tsm-preset-card:hover {
border-color: #c4b5fd;
transform: translateY(-1px);
box-shadow: 0 4px 10px rgba(124, 58, 237, 0.12);
}
.tsm-preset-card.active {
border-color: #7c3aed;
box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.18);
}
.tsm-preset-preview {
width: 100%;
aspect-ratio: 9 / 16;
background: #1a1a1a;
border-radius: 6px;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
.tsm-preset-meta {
display: flex;
align-items: center;
gap: 4px;
margin-top: 6px;
font-size: 12px;
color: #374151;
}
.tsm-preset-emoji {
font-size: 14px;
}
.tsm-preset-label {
font-weight: 500;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100px;
}
.tsm-custom-panel {
max-height: 440px;
overflow-y: auto;
padding: 4px 2px 8px;
}
.tsm-footer {
display: flex;
justify-content: flex-end;
gap: 8px;
padding-top: 16px;
margin-top: 16px;
border-top: 1px solid #f3f4f6;
}
@@ -0,0 +1,189 @@
/**
* 标题样式弹窗(Step3/智能剪辑用)
*
* 交互:
* - 点击"标题样式"按钮/卡片打开
* - 默认 Tab「预设」:10 个爆款预设卡片网格(Canvas 实时预览),点击选中
* - Tab「自定义」:详细参数(位置/字体/字号/粗斜/描边/阴影/颜色/背景)
* - 底部「取消」「保存」按钮:保存才会把临时编辑的 settings 应用到父组件
*
* 设计参考:CoverSettingsModal / 字幕模板选择弹窗
*/
import React, { useEffect, useState } from "react"
import { Tabs } from "antd"
import Modal from "@/components/ui/Modal"
import Button from "@/components/ui/Button"
import type { TitleSettings } from "../../types"
import { POSITION_OPTIONS } from "../../constants"
import { FONT_OPTIONS } from "@/components/title/constants"
import TitleStylePanel from "./TitleStylePanel"
import TitleMiniPreview from "./TitleMiniPreview"
import { titleStyleConfigToCamel } from "@/components/title/utils"
import { TITLE_PRESETS as TITLE_PRESETS_DATA } from "@/components/title/constants"
import "./TitleStyleModal.css"
interface TitleStyleModalProps {
open: boolean
onClose: () => void
/** 当前标题文字(用于预览) */
titleText?: string
/** 当前生效的标题样式 */
settings: TitleSettings
/** 保存回调:把编辑后的 settings 回传父组件 */
onSave: (settings: TitleSettings, presetKey: string | null) => void
/** 当前选中的爆款预设 key(用于高亮) */
activePreset?: string | null
}
/** 把预设应用到 base settings(参考 useTitleStyleUpdaters.applyPreset 逻辑) */
function applyPresetToSettings(base: TitleSettings, presetKey: string): TitleSettings {
const preset = TITLE_PRESETS_DATA.find((p) => p.key === presetKey)
if (!preset) return base
return {
...base,
...(titleStyleConfigToCamel(preset.style) as Partial<TitleSettings>),
lineOverrides: [],
}
}
const TitleStyleModal: React.FC<TitleStyleModalProps> = ({
open,
onClose,
titleText = "标题",
settings,
onSave,
activePreset: externalActivePreset = null,
}) => {
// 弹窗内维护一份草稿 settings,点保存才提交到父组件;取消/关闭丢弃
const [draft, setDraft] = useState<TitleSettings>(settings)
const [activePreset, setActivePreset] = useState<string | null>(externalActivePreset)
// 每次打开弹窗,用父组件最新 settings 重置草稿
useEffect(() => {
if (open) {
setDraft(settings)
setActivePreset(externalActivePreset)
}
}, [open, settings, externalActivePreset])
const handleApplyPreset = (presetKey: string) => {
setActivePreset(presetKey)
const next = applyPresetToSettings(draft, presetKey)
setDraft(next)
}
const handleUpdateStyle = (patch: Partial<TitleSettings>) => {
setDraft((prev) => ({ ...prev, ...patch }))
// 手动调了参数,清除预设高亮(因为不再严格匹配某个预设)
setActivePreset(null)
}
const handleUpdatePosition = (position: string) =>
handleUpdateStyle({ position: position as TitleSettings["position"] })
const handleUpdateFont = (font: string) => handleUpdateStyle({ font })
const handleUpdateSize = (size: number) => handleUpdateStyle({ size })
const handleToggleBold = () => handleUpdateStyle({ bold: !draft.bold })
const handleToggleItalic = () => handleUpdateStyle({ italic: !draft.italic })
const handleToggleStroke = () => handleUpdateStyle({ stroke: !draft.stroke })
const handleToggleShadow = () => handleUpdateStyle({ shadow: !draft.shadow })
const handleSave = () => {
onSave(draft, activePreset)
onClose()
}
return (
<Modal open={open} onCancel={onClose} title="标题样式" width={720} footer={null} destroyOnClose>
<div className="tsm-body">
{/* 顶部预览 */}
<div className="tsm-preview">
<TitleMiniPreview
settings={draft}
width={640}
sampleText={titleText || "标题"}
transparent={false}
portrait
/>
</div>
<Tabs
defaultActiveKey="presets"
size="small"
items={[
{
key: "presets",
label: "爆款预设",
children: (
<div className="tsm-presets-grid">
{TITLE_PRESETS_DATA.map((p) => {
const previewSettings = applyPresetToSettings(draft, p.key)
const isActive = activePreset === p.key
return (
<button
key={p.key}
type="button"
className={`tsm-preset-card${isActive ? " active" : ""}`}
onClick={() => handleApplyPreset(p.key)}
title={p.label}
>
<div className="tsm-preset-preview">
<TitleMiniPreview
settings={previewSettings}
width={140}
sampleText="标题"
/>
</div>
<div className="tsm-preset-meta">
<span className="tsm-preset-emoji">{p.emoji}</span>
<span className="tsm-preset-label">{p.label}</span>
</div>
</button>
)
})}
</div>
),
},
{
key: "custom",
label: "自定义",
children: (
<div className="tsm-custom-panel">
<TitleStylePanel
settings={draft}
onUpdatePosition={handleUpdatePosition}
onUpdateFont={handleUpdateFont}
onUpdateSize={handleUpdateSize}
onToggleBold={handleToggleBold}
onToggleItalic={handleToggleItalic}
onToggleStroke={handleToggleStroke}
onToggleShadow={handleToggleShadow}
onApplyPreset={handleApplyPreset}
onUpdateStyle={handleUpdateStyle}
activePreset={activePreset}
titlePresets={[]}
POSITION_OPTIONS={POSITION_OPTIONS}
FONT_OPTIONS={FONT_OPTIONS}
paramsOnly
hideEditor
/>
</div>
),
},
]}
/>
</div>
{/* 底部按钮栏 */}
<div className="tsm-footer">
<Button buttonType="ghost" onClick={onClose}>
取消
</Button>
<Button buttonType="primary" onClick={handleSave}>
保存
</Button>
</div>
</Modal>
)
}
export default TitleStyleModal
@@ -0,0 +1,190 @@
/**
* 标题工具函数单测 — 提升覆盖率到 50% 阈值以上
*/
import { describe, it, expect } from "vitest"
import {
titleStyleConfigToCamel,
camelToTitleStyleConfig,
buildPresetPreviewSettings,
templateToPreviewSettings,
} from "@/components/title/utils"
import {
getFontFamily,
getTitlePreset,
TITLE_PRESETS,
FONT_OPTIONS,
} from "@/components/title/constants"
import { DEFAULT_TITLE_SETTINGS_FULL } from "@/pages/generate/types"
import type { TitleStyleConfig } from "@/components/title/types"
import type { TitleTemplate } from "@/components/title/template-types"
describe("getFontFamily", () => {
it("已知字体名返回对应 family 栈", () => {
const f = getFontFamily("思源黑体")
expect(f).toContain("Noto Sans SC")
})
it("未知字体名回退到思源黑体", () => {
const f = getFontFamily("not-exist-font")
expect(f).toBe(FONT_OPTIONS[4].family)
})
it("新增书法字体能查到", () => {
expect(getFontFamily("马善政毛笔")).toContain("Ma Shan Zheng")
expect(getFontFamily("站酷小薇体")).toContain("ZCOOL XiaoWei")
})
})
describe("getTitlePreset", () => {
it("合法 key 返回对应 preset", () => {
const p = getTitlePreset(TITLE_PRESETS[0].key)
expect(p).toBeDefined()
expect(p?.key).toBe(TITLE_PRESETS[0].key)
})
it("不存在的 key 返回 undefined", () => {
expect(getTitlePreset("__not_exist__")).toBeUndefined()
})
})
describe("titleStyleConfigToCamel", () => {
it("snake_case 字段映射到 camelCase", () => {
const cfg: Partial<TitleStyleConfig> = {
font: "思源黑体",
size: 48,
pos_x: 10,
pos_y: 20,
line_height: 1.4,
margin_top: 30,
max_chars_per_line: 8,
stroke_width: 4,
stroke_color: "#000",
shadow_offset_x: 2,
bg_enabled: true,
bg_padding: 12,
bg_radius: 6,
}
const out = titleStyleConfigToCamel(cfg)
expect(out.font).toBe("思源黑体")
expect(out.size).toBe(48)
expect(out.posX).toBe(10)
expect(out.posY).toBe(20)
expect(out.lineHeight).toBe(1.4)
expect(out.marginTop).toBe(30)
expect(out.maxCharsPerLine).toBe(8)
expect(out.strokeWidth).toBe(4)
expect(out.strokeColor).toBe("#000")
expect(out.shadowOffsetX).toBe(2)
expect(out.bgEnabled).toBe(true)
expect(out.bgPadding).toBe(12)
expect(out.bgRadius).toBe(6)
})
it("空对象返回空对象", () => {
expect(titleStyleConfigToCamel({})).toEqual({})
})
})
describe("camelToTitleStyleConfig", () => {
it("camelCase 字段映射到 snake_case", () => {
const out = camelToTitleStyleConfig({
font: "思源宋体",
size: 36,
posX: 5,
posY: 15,
strokeWidth: 2,
shadowBlur: 8,
bgEnabled: false,
})
expect(out.font).toBe("思源宋体")
expect(out.pos_x).toBe(5)
expect(out.pos_y).toBe(15)
expect(out.stroke_width).toBe(2)
expect(out.shadow_blur).toBe(8)
expect(out.bg_enabled).toBe(false)
})
it("两种转换在已知字段上往返一致", () => {
const camel = {
font: "优设标题黑",
size: 56,
color: "#ffffff",
stroke: true,
strokeWidth: 6,
bold: true,
shadow: true,
shadowOffsetX: 3,
shadowOffsetY: 3,
shadowBlur: 10,
bgEnabled: true,
bgColor: "#000000",
bgPadding: 16,
bgRadius: 8,
} as const
const snake = camelToTitleStyleConfig({ ...camel })
const back = titleStyleConfigToCamel(snake)
for (const k of Object.keys(camel) as (keyof typeof camel)[]) {
expect(back[k]).toBe(camel[k])
}
})
})
describe("buildPresetPreviewSettings", () => {
it("未知 preset key 返回 base", () => {
const base = { ...DEFAULT_TITLE_SETTINGS_FULL, size: 32 }
const out = buildPresetPreviewSettings(base, "__no_such_preset__")
expect(out).toBe(base)
})
it("合法 preset 返回固定字号并缩放描边/阴影/padding", () => {
const key = TITLE_PRESETS[0].key
const out = buildPresetPreviewSettings(DEFAULT_TITLE_SETTINGS_FULL, key, 56)
expect(out.size).toBe(56)
expect(Array.isArray(out.lineOverrides)).toBe(true)
})
})
describe("templateToPreviewSettings", () => {
it("按模板 style 合并默认值,固定字号并缩放装饰尺寸", () => {
const tpl: TitleTemplate = {
id: "tpl-test",
name: "测试模板",
category: "test",
thumbnail_url: "",
is_system: true,
style: {
font: "思源黑体",
size: 72,
color: "#ffd700",
stroke: true,
stroke_width: 8,
shadow: true,
shadow_offset_x: 4,
shadow_offset_y: 4,
shadow_blur: 12,
bg_enabled: false,
bg_padding: 24,
bg_radius: 0,
},
}
const out = templateToPreviewSettings(tpl, 48)
expect(out.size).toBe(48)
expect(out.color).toBe("#ffd700")
expect(out.strokeWidth).toBe(Math.max(1, Math.round((48 / 72) * 8)))
expect(out.shadowBlur).toBe(Math.round((48 / 72) * 12))
expect(Array.isArray(out.lineOverrides)).toBe(true)
})
it("模板未指定 size 时使用默认 size(不触发缩放)", () => {
const tpl: TitleTemplate = {
id: "tpl-no-size",
name: "无字号模板",
category: "test",
thumbnail_url: "",
is_system: false,
style: { font: "思源黑体" },
}
const out = templateToPreviewSettings(tpl, 48)
expect(out.size).toBeDefined()
})
})
-2
View File
@@ -56,7 +56,6 @@ services:
environment: environment:
APP_ENV: ${APP_ENV:-staging} APP_ENV: ${APP_ENV:-staging}
APP_VERSION: ${APP_VERSION:-unknown}
GENERATED_FILES_DIR: /app/generated GENERATED_FILES_DIR: /app/generated
GENERATED_FILES_URL_PREFIX: /generated-files GENERATED_FILES_URL_PREFIX: /generated-files
PUBLIC_API_BASE_URL: ${PUBLIC_API_BASE_URL:-https://api.xiaoxiajianji.com} PUBLIC_API_BASE_URL: ${PUBLIC_API_BASE_URL:-https://api.xiaoxiajianji.com}
@@ -113,7 +112,6 @@ services:
environment: environment:
APP_ENV: ${APP_ENV:-staging} APP_ENV: ${APP_ENV:-staging}
APP_VERSION: ${APP_VERSION:-unknown}
WORKER_CONCURRENCY: ${WORKER_CONCURRENCY:-4} WORKER_CONCURRENCY: ${WORKER_CONCURRENCY:-4}
WORKER_MAX_TASKS_PER_CHILD: ${WORKER_MAX_TASKS_PER_CHILD:-100} WORKER_MAX_TASKS_PER_CHILD: ${WORKER_MAX_TASKS_PER_CHILD:-100}
# #1714 队列隔离:generation 队列独占 worker(默认并发 2),其余并发给转码 # #1714 队列隔离:generation 队列独占 worker(默认并发 2),其余并发给转码
+4 -4
View File
@@ -17,9 +17,9 @@
# SKIP_NOTIFY - 跳过通知 (true/false, 默认 false) # SKIP_NOTIFY - 跳过通知 (true/false, 默认 false)
# CI_NOTIFY_WEBHOOK - 通知 Webhook URL # CI_NOTIFY_WEBHOOK - 通知 Webhook URL
# #
# STAGING_SSH_HOST - Staging 服务器 SSH 地址 (默认 127.0.0.1,CI runner 在 staging 本机) # STAGING_SSH_HOST - Staging 服务器 SSH 地址 (默认 47.98.113.167,CI runner 在独立 CI 机器)
# STAGING_SSH_USER - SSH 用户名 (默认 root) # STAGING_SSH_USER - SSH 用户名 (默认 root)
# STAGING_SSH_PORT - SSH 端口 (默认 22) # STAGING_SSH_PORT - SSH 端口 (默认 22222,公网;内网 VNC 用 10.0.0.2:22)
# STAGING_SSH_KEY - SSH 私钥内容 # STAGING_SSH_KEY - SSH 私钥内容
# REGISTRY_TOKEN - Registry Token(回滚时拉取旧镜像需要) # REGISTRY_TOKEN - Registry Token(回滚时拉取旧镜像需要)
# #
@@ -40,9 +40,9 @@ HEALTH_CHECK_TIMEOUT="${HEALTH_CHECK_TIMEOUT:-120}"
SKIP_ROLLBACK="${SKIP_ROLLBACK:-false}" SKIP_ROLLBACK="${SKIP_ROLLBACK:-false}"
SKIP_NOTIFY="${SKIP_NOTIFY:-false}" SKIP_NOTIFY="${SKIP_NOTIFY:-false}"
STAGING_SSH_HOST="${STAGING_SSH_HOST:-127.0.0.1}" STAGING_SSH_HOST="${STAGING_SSH_HOST:-47.98.113.167}"
STAGING_SSH_USER="${STAGING_SSH_USER:-root}" STAGING_SSH_USER="${STAGING_SSH_USER:-root}"
STAGING_SSH_PORT="${STAGING_SSH_PORT:-22}" STAGING_SSH_PORT="${STAGING_SSH_PORT:-22222}"
REGISTRY="${REGISTRY:-git.xiaoxiajianji.com/xiaoxia/xiaoxia-saas}" REGISTRY="${REGISTRY:-git.xiaoxiajianji.com/xiaoxia/xiaoxia-saas}"
REGISTRY_USER="${REGISTRY_USER:-xiaoxia}" REGISTRY_USER="${REGISTRY_USER:-xiaoxia}"