# VideoGen 部署文档

## 项目结构

```
video_item/
├── video-gen-api/          # 后端 (Python FastAPI + SQLAlchemy + Alembic)
├── video-gen-app/          # 前台 (React 19 + Vite 8 + Ant Design 6 + Tailwind)
├── video-gen-admin/        # 后台管理 (React 19 + Vite 8 + Ant Design 6)
└── DEPLOYMENT.md           # 本文档
```

---

## 一、环境要求

| 组件 | 版本要求 | 说明 |
|------|---------|------|
| Python | >= 3.10 | 推荐 3.12 |
| Node.js | >= 18 | 推荐 20+ |
| PostgreSQL | >= 14 | 推荐 16 |
| Redis | >= 6 | 可选，推荐用于限流/验证码/Celery |
| FFmpeg | 任意 | 可选，用于视频封面截帧 |
| alipay-sdk-python | >=3.7.1160 | 可选，用于支付 |
| wechatpayv3 | >=2.0.2  | 可选，用于支付 |
| volcengine-python-sdk | >=1.1.0 | 可选，用于视频生成 |
| ca-certificates | 任意 | **必须**，HTTPS 请求需要（新服务器/容器常缺） |


---

## 二、后端部署 (video-gen-api)

### 1. 安装依赖

```bash
# ⚠️ 新服务器/容器必须先装 CA 证书，否则 HTTPS 请求（支付宝/火山等）全部失败
# CentOS/RHEL
sudo yum install -y ca-certificates
# Ubuntu/Debian
sudo apt-get install -y ca-certificates

cd video-gen-api

# 创建虚拟环境
python -m venv .venv
# Windows
.venv\Scripts\activate
# Linux/Mac
source .venv/bin/activate

# 安装基础依赖 + PostgreSQL 驱动
pip install -e ".[pg]"

# 如需 Redis 支持（限流、验证码、Celery）
pip install -e ".[pg,redis]"

# 如需 Celery 异步任务（ChatAPI 生成流水线）
pip install -e ".[pg,redis,celery]"

#安装阿里支付sdk
pip install -e ".[pg,redis,celery,alipay]"

# 安装微信支付sdk
pip install -e ".[pg,redis,celery,alipay,wechatpayv3]"

#安装火山sdk
pip install -e ".[pg,redis,celery,alipay,wechatpayv3,volc]"


```

### 2. 配置环境变量

复制 `.env.example` 为 `.env`，修改以下关键配置：

```bash
cp .env.example .env
```

```ini
# ── 基础配置 ──
APP_NAME=VideoGen API
DEBUG=false
SECRET_KEY=改成一个随机的长字符串

# ── 数据库 ──
DATABASE_URL=postgresql+asyncpg://用户名:密码@localhost:5432/videogen

# ── Redis（可选，留空则禁用限流和验证码） ──
REDIS_URL=redis://localhost:6379/0

# ── JWT ──
JWT_ALGORITHM=HS256
JWT_EXPIRE_MINUTES=1440          # 普通登录 24h
JWT_EXPIRE_REMEMBER_MINUTES=10080 # 记住登录 7天

# ── 视频生成（火山引擎 Ark） ──
SEEDANCE_API_KEY=你的API Key
SEEDANCE_API_BASE=https://ark.cn-beijing.volces.com/api/v3
SEEDANCE_CALLBACK_URL=https://你的域名/api/generation-records/callback

# ── LLM 提示词优化 ──
LLM_MOCK=false

# ── 前后端通信加密（32字节 base64，留空则禁用） ──
ENCRYPTION_KEY=你的32字节base64密钥

# ── 存储路径 ──
STORAGE_TYPE=local
STORAGE_LOCAL_PATH=./storage/generate/videos
STORAGE_IMAGE_LOCAL_PATH=./storage/generate/images
STORAGE_VIDEO_COVER_LOCAL_PATH=./storage/generate/covers
UPLOAD_LOCAL_PATH=./storage/uploads

# ── 跨域（生产环境务必限制域名） ──
CORS_ORIGINS=["https://你的前台域名.com", "https://你的后台域名.com"]

# ── 回调基础地址 ──
BASE_URL=https://你的域名

# ── 短信（火山引擎 SDK，SMS_MOCK=false 时生效） ──
SMS_MOCK=true
VOLC_SMS_ACCESS_KEY_ID=
VOLC_SMS_SECRET_ACCESS_KEY=
VOLC_SMS_ACCOUNT=消息组ID
VOLC_SMS_TEMPLATE_ID=模板ID
VOLC_SMS_SIGN=短信签名

# ── 支付（PAYMENT_MOCK=false 时生效） ──
PAYMENT_MOCK=true

# ── Celery（可选，留空则禁用 ChatAPI 异步流水线） ──
CELERY_BROKER_URL=redis://localhost:6379/5
CELERY_RESULT_BACKEND=redis://localhost:6379/6

# ── FFmpeg（留空自动从 PATH 查找） ──
FFMPEG_BIN=/usr/bin/ffmpeg
```

### 3. 初始化数据库

```bash
# 创建 PostgreSQL 数据库
psql -U postgres -c "CREATE DATABASE videogen OWNER videogen;"

# 启动后端（首次启动自动建表 + 填充种子数据）
python -m uvicorn app.main:app --host 0.0.0.0 --port 8000
```

首次启动会自动完成：
- 创建所有数据表（23 个 model）
- 创建管理员账号：`admin` / `123456`
- 创建演示用户：`demo` / `123456`（手机号 `13888888888`）
- 填充系统配置、视频引擎（Seedance 2.0 / 2.0 fast）、图片引擎（Seedream 5.0）、模型配置、积分比例、菜单配置、充值套餐（4 档）、行业配置

**首次部署后务必修改默认密码。**

### 4. 数据库迁移 (Alembic)

项目使用 Alembic 管理数据库结构变更，`env.py` 已导入全部 20 个 model。

```bash
cd video-gen-api

# 修改 model 后，自动生成迁移文件
python -m alembic revision --autogenerate -m "描述改动内容"

# 执行迁移
python -m alembic upgrade head

# 查看当前版本
python -m alembic current

# 查看迁移历史
python -m alembic history

# 回滚一步
python -m alembic downgrade -1
```

**部署流程：** 拉取代码后先执行 `alembic upgrade head`，再重启后端服务。

**新增 model 时：** 需要在 `alembic/env.py` 中添加对应的 import。

### 5. 生产运行

```bash
# 方式一：直接运行（推荐 4 workers）
python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4

# 方式二：使用 systemd (Linux)
```

**systemd 服务文件** `/etc/systemd/system/videogen-api.service`：

```ini
[Unit]
Description=VideoGen API
After=network.target postgresql.service

[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/video-gen-api
Environment=PATH=/opt/video-gen-api/.venv/bin
ExecStart=/opt/video-gen-api/.venv/bin/python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
```

```bash
sudo systemctl daemon-reload
sudo systemctl enable videogen-api
sudo systemctl start videogen-api
```

### 6. Celery Worker（可选）

ChatAPI 异步生成流水线需要 Celery Worker。需要 Redis 作为 Broker。

```bash
# 启动 Worker（处理 3 个队列：gen_chatapi_create, gen_provider_poll, gen_result_download）
celery -A app.tasks.celery_app worker -l info -Q gen_chatapi_create,gen_provider_poll,gen_result_download,default
```

**systemd 服务文件** `/etc/systemd/system/videogen-worker.service`：

```ini
[Unit]
Description=VideoGen Celery Worker
After=network.target redis.service

[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/video-gen-api
Environment=PATH=/opt/video-gen-api/.venv/bin
ExecStart=/opt/video-gen-api/.venv/bin/celery -A app.tasks.celery_app worker -l info -Q gen_chatapi_create,gen_provider_poll,gen_result_download,default
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
```

### 7. Docker 部署（可选）

项目提供 `Dockerfile` 和 `docker-compose.yml`，一键启动完整环境：

```bash
cd video-gen-api

# 注意：Dockerfile 默认只装基础依赖，需修改为安装 pg+redis+celery
# 将 Dockerfile 中的 RUN pip install --no-cache-dir . 改为：
# RUN pip install --no-cache-dir ".[pg,redis,celery]"

docker compose up -d
```

启动的服务：
| 服务 | 端口 | 说明 |
|------|------|------|
| api | 8000 | FastAPI 应用（带 `--reload`，开发模式） |
| worker | - | Celery Worker |
| postgres | 5432 | PostgreSQL 16 |
| redis | 6379 | Redis 7 |

### 8. Nginx 反向代理

```nginx
server {
    listen 80;
    server_name api.yourdomain.com;

    # 上传文件大小限制
    client_max_body_size 100M;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 300s;
    }

    # 静态文件 (上传的视频/图片)
    location /uploads/ {
        alias /opt/video-gen-api/storage/uploads/;
        expires 7d;
    }
}
```

---

## 三、前台部署 (video-gen-app)

### 1. 安装依赖 & 构建

```bash
cd video-gen-app

npm install

# 配置 API 地址（创建 .env.production）
echo "VITE_API_BASE=https://api.yourdomain.com" > .env.production

# 如需前后端加密通信
echo "VITE_ENCRYPTION_KEY=与后端ENCRYPTION_KEY相同" >> .env.production

# 构建
npm run build
```

构建产物在 `dist/` 目录。

### 2. Nginx 配置

```nginx
server {
    listen 80;
    server_name yourdomain.com;
    root /opt/video-gen-app/dist;
    index index.html;

    # SPA 路由
    location / {
        try_files $uri $uri/ /index.html;
    }

    # 静态资源缓存
    location /assets/ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}
```

---

## 四、后台管理部署 (video-gen-admin)

### 1. 安装依赖 & 构建

```bash
cd video-gen-admin

npm install

# 配置 API 地址
echo "VITE_API_BASE=https://api.yourdomain.com" > .env.production

# 如需前后端加密通信
echo "VITE_ENCRYPTION_KEY=与后端ENCRYPTION_KEY相同" >> .env.production

# 构建
npm run build
```

### 2. Nginx 配置

```nginx
server {
    listen 80;
    server_name admin.yourdomain.com;
    root /opt/video-gen-admin/dist;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }

    location /assets/ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}
```

---

## 五、完整 Nginx 配置示例 (单机部署)

```nginx
# 后端 API
server {
    listen 80;
    server_name api.yourdomain.com;
    client_max_body_size 100M;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 300s;
    }

    location /uploads/ {
        alias /opt/video-gen-api/storage/uploads/;
        expires 7d;
    }
}

# 前台
server {
    listen 80;
    server_name yourdomain.com;
    root /opt/video-gen-app/dist;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }

    location /assets/ {
        expires 1y;
    }
}

# 后台管理
server {
    listen 80;
    server_name admin.yourdomain.com;
    root /opt/video-gen-admin/dist;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }

    location /assets/ {
        expires 1y;
    }
}
```

---

## 六、SSL 配置 (推荐)

使用 Certbot 获取免费证书：

```bash
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com -d admin.yourdomain.com -d api.yourdomain.com
```

---

## 七、默认账号

| 角色 | 用户名 | 手机号 | 密码 | 积分 |
|------|--------|--------|------|------|
| 管理员 | admin | 13800000000 | 123456 | 10000 |
| 演示用户 | demo | 13888888888 | 123456 | 2680 |

**首次部署后务必修改默认密码。**

---

## 八、架构说明

### 异步任务处理

系统有两套异步任务机制：

| 机制 | 说明 | 依赖 |
|------|------|------|
| 内置 TaskQueue | asyncio 实现，运行在 uvicorn 进程内，轮询视频/图片生成状态 | 无额外依赖 |
| Celery Worker | 处理 ChatAPI 异步生成流水线，3 个队列分优先级 | Redis 作为 Broker |

### 中间件栈（从外到内）

1. `RequestLoggingMiddleware` — 请求/响应日志记录
2. `AntiCrawlerMiddleware` — 反爬虫（拦截空 UA 和常见 bot）
3. `RateLimitMiddleware` — 滑动窗口限流（Redis 支撑）
4. `RequestEncryptMiddleware` — AES-256-GCM 请求/响应加密
5. `CORSMiddleware` — 跨域

### 日志系统

| 日志类型 | 目录 | 控制方式 |
|---------|------|---------|
| 请求/响应日志 | `log/RequestResponse/{日期}.log` | 始终开启 |
| AI 模型日志 | `log/AiModel/{日期}.log` | `AI_LOG_ENABLED` 环境变量 |
| Python 控制台日志 | stderr | `DEBUG=true` 时输出 INFO，否则 WARNING |

文件日志使用 AES-CBC 加密存储，解密工具：`/internal/decrypt-data` 端点。

### 存储路径

| 路径 | 用途 |
|------|------|
| `storage/generate/videos/` | 生成的视频文件 |
| `storage/generate/images/` | 生成的图片文件 |
| `storage/generate/covers/` | 视频封面缩略图 |
| `storage/uploads/` | 用户上传的原始文件 |

### 外部服务依赖

| 服务 | 用途 | 是否必须 |
|------|------|---------|
| 火山引擎 Ark | 视频生成（Seedance 2.0）、图片生成（Seedream 5.0）、LLM | 是 |
| 火山引擎短信 | 短信验证码 | 否（可 mock） |
| 微信支付 / 支付宝 | 充值支付 | 否（可 mock，未完整实现） |
| FFmpeg | 视频封面截帧 | 否（留空自动查找） |

---

## 九、目录结构 (部署后)

```
/opt/
├── video-gen-api/                      # 后端
│   ├── .env                            # 环境变量
│   ├── .venv/                          # Python 虚拟环境
│   ├── app/                            # 应用代码
│   ├── alembic/                        # 数据库迁移文件
│   ├── storage/
│   │   ├── generate/
│   │   │   ├── videos/                 # 生成的视频
│   │   │   ├── images/                 # 生成的图片
│   │   │   └── covers/                 # 视频封面
│   │   └── uploads/                    # 用户上传
│   └── log/
│       ├── AiModel/                    # AI 模型请求日志（加密）
│       └── RequestResponse/            # 请求响应日志（加密）
├── video-gen-app/dist/                 # 前台构建产物
└── video-gen-admin/dist/               # 后台构建产物
```

---

## 十、常用运维命令

```bash
# 查看后端日志
sudo journalctl -u videogen-api -f

# 重启后端
sudo systemctl restart videogen-api

# 重启 Celery Worker
sudo systemctl restart videogen-worker

# 重新构建前端
cd /opt/video-gen-app && npm run build
cd /opt/video-gen-admin && npm run build

# 数据库备份
pg_dump -U videogen videogen > backup_$(date +%Y%m%d).sql

# 数据库恢复
psql -U videogen videogen < backup_20260512.sql

# 执行数据库迁移
cd /opt/video-gen-api && python -m alembic upgrade head

# 生成迁移文件
cd /opt/video-gen-api && python -m alembic revision --autogenerate -m "描述"
```
