# AI 英语学习辅助平台 — 线上部署操作流程 ## 项目概述 - **项目名称**:AI 英语学习辅助平台 - **技术栈**: - 前端:Vue 3 + Vite + Vue Router(History 模式) - 后端:Express.js + FFmpeg(视频合成服务) - **项目结构**: - 前端:纯静态文件(HTML / CSS / JS),可部署到任意静态托管服务 - 后端:Node.js 服务,需要 FFmpeg 环境,提供视频合成 API --- ## 一、部署前准备 ### 1.1 环境要求 | 工具 | 版本要求 | 用途 | |------|----------|------| | Node.js | >= 18.x(推荐 20.x LTS) | 前端构建 & 后端服务运行 | | npm | >= 9.x | 包管理器 | | FFmpeg | 最新稳定版 | 后端视频合成(仅后端服务需要) | ```bash # 检查 Node.js 和 npm 版本 node -v npm -v # 检查 FFmpeg 是否已安装(后端服务需要) ffmpeg -version ``` ### 1.2 安装 FFmpeg(后端服务必需) #### Windows 1. 下载 FFmpeg: https://www.gyan.dev/ffmpeg/builds/ 2. 解压到 `C:\ffmpeg` 3. 添加 `C:\ffmpeg\bin` 到系统环境变量 PATH 4. 验证安装: ```bash ffmpeg -version ``` #### macOS ```bash # 使用 Homebrew 安装 brew install ffmpeg # 验证安装 ffmpeg -version ``` #### Linux (Ubuntu/Debian) ```bash # 安装 FFmpeg sudo apt update && sudo apt install ffmpeg # 验证安装 ffmpeg -version ``` ### 1.3 安装依赖 ```bash # 安装前端依赖 cd AI_Demo npm install # 安装后端依赖 cd server npm install ``` --- ## 二、关键配置说明 ### 2.1 API 配置(必须在部署前确认) 项目所有 API 密钥集中在 `src/config/index.js`,部署前请确认以下配置项均已填写正确: | 配置项 | 说明 | |--------|------| | `GRS_API_KEY` | GRS AI 接口密钥(作文批改) | | `DOUBAO_KEY` | 豆包 API 密钥 | | `DOUBAO_APP_ID` | 豆包语音 App ID | | `DOUBAO_ACCESS_TOKEN` | 豆包语音访问令牌 | | `DOUBAO_RESOURCE_ID` | 豆包 TTS 资源 ID | | `DOUBAO_ASR_RESOURCE_ID` | 豆包 ASR 资源 ID | | `ARK_API_KEY` | 火山引擎 Ark 大模型密钥(口语对话) | | `ARK_MODEL` | Ark 模型名称(如 doubao-pro-4k) | ### 2.2 跨域响应头要求(重要) 项目使用了 `@ffmpeg/ffmpeg`(WebAssembly),需要服务器返回以下响应头,否则视频讲解功能将无法运行: ``` Cross-Origin-Opener-Policy: same-origin Cross-Origin-Embedder-Policy: require-corp ``` > 各部署平台的配置方式见下方对应章节。 ### 2.3 API 代理配置(重要) 项目在开发环境通过 Vite 代理转发以下 API 请求,**生产环境必须在服务器/网关层配置对应的反向代理**: | 前端请求路径前缀 | 代理目标 | 用途 | 备注 | |-----------------|----------|------|------| | `/api/video` | 后端服务(默认 http://localhost:3001) | 视频合成 | **无需跨域代理**,直接访问后端服务 | | `/tts-api` | `https://openspeech.bytedance.com` | 豆包 TTS 语音合成 | 需要反向代理 | | `/ark-api` | `https://ark.cn-beijing.volces.com` | 火山引擎 Ark 大模型 | 需要反向代理 | | `/dashscope-api` | `https://dashscope.aliyuncs.com` | 阿里云百炼 | 需要反向代理 | | `/asr-ws` | `wss://openspeech.bytedance.com` | 豆包 ASR WebSocket | 需要反向代理+注入鉴权 Header | > **后端服务说明**:`/api/video` 接口由本项目的后端服务(`server/`)提供,不需要跨域代理,但需要确保后端服务正常运行。 > **ASR WebSocket 特殊说明**:`/asr-ws` 代理需要在代理层注入以下鉴权 Header(浏览器原生 WebSocket 不支持自定义 Header): > - `X-Api-App-Key` > - `X-Api-Access-Key` > - `X-Api-Resource-Id` > - `X-Api-Connect-Id`(每次连接随机 UUID) --- ## 三、构建生产包 ### 3.1 前端构建 ```bash npm run build ``` 构建完成后,产物位于 `dist/` 目录,包含: ``` dist/ ├── index.html ├── favicon.svg └── assets/ ├── *.js └── *.css ``` 可在本地预览构建结果: ```bash npm run preview ``` ### 3.2 后端服务准备 后端服务无需构建,直接使用源码运行即可。确保: 1. 已安装 FFmpeg(见 1.2 节) 2. 已安装依赖: ```bash cd server npm install ``` 3. 测试服务是否正常: ```bash npm start ``` 访问 http://localhost:3001/health 应返回 `{"status":"ok"}` --- ## 四、部署方案 ### 方案 A:Nginx 部署(推荐,自有服务器) #### 4.A.1 上传文件 将 `dist/` 目录内容上传到服务器,例如 `/var/www/ai-demo/`: ```bash scp -r dist/* user@your-server:/var/www/ai-demo/ ``` #### 4.A.2 Nginx 配置 创建或修改 Nginx 站点配置文件(如 `/etc/nginx/sites-available/ai-demo.conf`): ```nginx server { listen 80; server_name your-domain.com; # 替换为你的域名或 IP root /var/www/ai-demo; index index.html; # 跨域响应头(FFmpeg WASM 必需) add_header Cross-Origin-Opener-Policy "same-origin" always; add_header Cross-Origin-Embedder-Policy "require-corp" always; # Vue Router History 模式:所有路由回退到 index.html location / { try_files $uri $uri/ /index.html; } # 后端视频合成服务代理 location /api/video/ { proxy_pass http://localhost:3001/api/video/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; 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; # 增大请求体大小限制(视频合成可能需要) client_max_body_size 100m; # 增加超时时间(视频合成耗时较长) proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 300; } # 代理:豆包 TTS location /tts-api/ { proxy_pass https://openspeech.bytedance.com/; proxy_ssl_server_name on; proxy_set_header Host openspeech.bytedance.com; } # 代理:火山引擎 Ark location /ark-api/ { proxy_pass https://ark.cn-beijing.volces.com/; proxy_ssl_server_name on; proxy_set_header Host ark.cn-beijing.volces.com; } # 代理:阿里云百炼 location /dashscope-api/ { proxy_pass https://dashscope.aliyuncs.com/; proxy_ssl_server_name on; proxy_set_header Host dashscope.aliyuncs.com; } # 代理:豆包 ASR WebSocket(需注入鉴权 Header) location /asr-ws/ { proxy_pass https://openspeech.bytedance.com/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host openspeech.bytedance.com; proxy_ssl_server_name on; # 注入豆包 ASR 鉴权 Header(替换为实际值) proxy_set_header X-Api-App-Key "YOUR_DOUBAO_APP_ID"; proxy_set_header X-Api-Access-Key "YOUR_DOUBAO_ACCESS_TOKEN"; proxy_set_header X-Api-Resource-Id "volc.bigasr.sauc.duration"; } # 静态资源缓存 location /assets/ { expires 1y; add_header Cache-Control "public, immutable"; add_header Cross-Origin-Opener-Policy "same-origin" always; add_header Cross-Origin-Embedder-Policy "require-corp" always; } } ``` ``` #### 4.A.3 启用配置并重启 Nginx ```bash # 启用站点(Ubuntu/Debian) ln -s /etc/nginx/sites-available/ai-demo.conf /etc/nginx/sites-enabled/ # 检查配置语法 nginx -t # 重载 Nginx systemctl reload nginx ``` #### 4.A.4 启动后端服务 后端服务需要使用进程管理器(如 PM2)保持持续运行: ```bash # 安装 PM2(如果未安装) npm install -g pm2 # 进入后端目录 cd /path/to/AI_Demo/server # 启动后端服务 pm2 start index.js --name ai-demo-server # 查看服务状态 pm2 status # 查看日志 pm2 logs ai-demo-server # 设置开机自启 pm2 startup pm2 save ``` 后端服务将在 `http://localhost:3001` 启动,Nginx 会将 `/api/video` 请求代理到该端口。 #### 4.A.5 配置 HTTPS(推荐) ```bash # 使用 Certbot 申请免费 SSL 证书 apt install certbot python3-certbot-nginx certbot --nginx -d your-domain.com ``` --- ### 方案 B:Node.js + Express 部署(前后端分离) 适用于需要在 Node.js 环境中自定义响应头的场景,前后端独立部署。 #### 4.B.1 后端服务部署 后端服务已在 `server/` 目录中,需要独立运行: ```bash # 进入后端目录 cd server # 安装依赖 npm install # 使用 PM2 启动服务 pm2 start index.js --name ai-demo-backend # 设置开机自启 pm2 startup pm2 save ``` 后端服务将在 `http://localhost:3001` 启动。 #### 4.B.2 前端静态服务器 创建前端静态服务器文件 `frontend-server.js`(项目根目录): ```js import express from 'express' import { createProxyMiddleware } from 'http-proxy-middleware' import { fileURLToPath } from 'url' import path from 'path' import crypto from 'crypto' const __dirname = path.dirname(fileURLToPath(import.meta.url)) const app = express() const PORT = process.env.PORT || 3000 // 全局注入 COOP/COEP 响应头(FFmpeg WASM 必需) app.use((req, res, next) => { res.setHeader('Cross-Origin-Opener-Policy', 'same-origin') res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp') next() }) // 后端视频合成服务代理 app.use('/api/video', createProxyMiddleware({ target: 'http://localhost:3001', changeOrigin: true, timeout: 300000, // 5分钟超时 })) // 第三方 API 代理 app.use('/tts-api', createProxyMiddleware({ target: 'https://openspeech.bytedance.com', changeOrigin: true, pathRewrite: { '^/tts-api': '' } })) app.use('/ark-api', createProxyMiddleware({ target: 'https://ark.cn-beijing.volces.com', changeOrigin: true, pathRewrite: { '^/ark-api': '' } })) app.use('/dashscope-api', createProxyMiddleware({ target: 'https://dashscope.aliyuncs.com', changeOrigin: true, pathRewrite: { '^/dashscope-api': '' } })) app.use('/asr-ws', createProxyMiddleware({ target: 'wss://openspeech.bytedance.com', changeOrigin: true, ws: true, pathRewrite: { '^/asr-ws': '' }, on: { proxyReqWs: (proxyReq) => { proxyReq.setHeader('X-Api-App-Key', process.env.DOUBAO_APP_ID) proxyReq.setHeader('X-Api-Access-Key', process.env.DOUBAO_ACCESS_TOKEN) proxyReq.setHeader('X-Api-Resource-Id', 'volc.bigasr.sauc.duration') proxyReq.setHeader('X-Api-Connect-Id', crypto.randomUUID()) } } })) // 静态文件服务 app.use(express.static(path.join(__dirname, 'dist'))) // Vue Router History 模式回退 app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'dist', 'index.html')) }) app.listen(PORT, () => { console.log(`Frontend server running at http://localhost:${PORT}`) console.log(`Backend API: http://localhost:3001`) }) ``` #### 4.B.3 安装前端服务器依赖 ```bash # 在项目根目录安装 npm install express http-proxy-middleware ``` #### 4.B.4 启动前端服务器 ```bash # 在项目根目录启动 DOUBAO_APP_ID=xxx DOUBAO_ACCESS_TOKEN=xxx pm2 start frontend-server.js --name ai-demo-frontend # 查看两个服务的状态 pm2 status # 设置开机自启 pm2 save ``` 现在有两个服务运行: - **前端服务**:`http://localhost:3000`(提供静态文件和代理) - **后端服务**:`http://localhost:3001`(视频合成 API) --- ### 方案 C:EdgeOne Pages / Vercel / Netlify(纯静态托管) > **注意**:此类平台**不支持服务端代理**,`/tts-api`、`/ark-api`、`/dashscope-api`、`/asr-ws` 等接口将因跨域或缺少鉴权 Header 而失败。 > 建议仅用于演示或配合独立后端服务使用。 #### 部署步骤(以 Vercel 为例) 1. 将项目推送到 GitHub 2. 在 Vercel 控制台导入仓库 3. 构建命令:`npm run build`,输出目录:`dist` 4. 创建 `vercel.json` 配置 History 模式路由回退和响应头: ```json { "rewrites": [{ "source": "/(.*)", "destination": "/index.html" }], "headers": [ { "source": "/(.*)", "headers": [ { "key": "Cross-Origin-Opener-Policy", "value": "same-origin" }, { "key": "Cross-Origin-Embedder-Policy", "value": "require-corp" } ] } ] } ``` --- ## 五、部署后验证清单 ### 5.1 后端服务验证 | 验证项 | 检查方法 | 预期结果 | |--------|----------|----------| | 后端服务运行 | `pm2 status` 或 `ps aux \| grep node` | 显示 ai-demo-server 进程 | | 健康检查接口 | `curl http://localhost:3001/health` | 返回 `{"status":"ok"}` | | FFmpeg 可用 | `curl http://localhost:3001/api/video/health` | 返回 `{"status":"ok","message":"视频合成服务正常运行"}` | | 后端日志无错误 | `pm2 logs ai-demo-server` | 无报错信息 | ### 5.2 前端服务验证 | 验证项 | 检查方法 | |--------|----------| | 页面正常加载 | 访问首页,确认功能卡片显示正常 | | 路由刷新不 404 | 直接访问 `/pronunciation`、`/speaking` 等子路由 | | COOP/COEP 响应头 | 浏览器 DevTools → Network → 查看 index.html 响应头 | | TTS 语音合成 | 进入发音练习页,测试语音播放 | | ASR 语音识别 | 进入口语对话页,测试麦克风录音识别 | | 作文批改 | 进入作文批改页,提交一段英文作文 | | 试题分析 | 进入试题分析页,上传图片或输入题目 | | 单词拼写练习 | 进入单词拼写页,测试拼写检测功能 | ### 5.3 视频合成功能验证 | 验证项 | 检查方法 | |--------|----------| | 前端可访问后端 | 浏览器 Network 标签查看 `/api/video/health` 请求 | | 视频合成接口 | 在试题分析页生成视频讲解,检查是否能正常下载 | --- ## 六、常见问题排查 ### Q1:视频讲解页面报错 `SharedArrayBuffer is not defined` **原因**:服务器未返回 `Cross-Origin-Opener-Policy: same-origin` 和 `Cross-Origin-Embedder-Policy: require-corp` 响应头。 **解决**:参考第二节 2.2,在 Nginx 或 Node.js 服务器中添加对应响应头。 ### Q2:刷新页面出现 404 **原因**:Vue Router 使用 History 模式,服务器未配置路由回退。 **解决**:Nginx 添加 `try_files $uri $uri/ /index.html;`,Node.js 添加通配路由返回 `index.html`。 ### Q3:API 请求跨域报错(CORS) **原因**:生产环境未配置反向代理,浏览器直接请求第三方 API 被跨域拦截。 **解决**:参考第二节 2.3,在 Nginx 或 Node.js 中配置对应代理规则。 ### Q4:ASR 语音识别 WebSocket 连接失败 **原因**:代理未注入豆包 ASR 鉴权 Header,或 WebSocket 升级配置缺失。 **解决**:确认 Nginx 配置中包含 `proxy_set_header Upgrade $http_upgrade;` 及三个 `X-Api-*` Header。 ### Q5:视频合成失败或接口 504 超时 **原因**:视频合成耗时较长,默认代理超时时间不足,或后端服务未启动。 **解决**: 1. 检查后端服务是否运行:`pm2 status` 或 `curl http://localhost:3001/health` 2. 检查 FFmpeg 是否安装:`ffmpeg -version` 3. 增加 Nginx 超时时间(已在配置中设置为 300 秒) 4. 查看后端日志:`pm2 logs ai-demo-server` ### Q6:后端服务启动失败:`FFmpeg not found` **原因**:系统未安装 FFmpeg 或未添加到环境变量。 **解决**:参考第一节 1.2,安装 FFmpeg 并配置环境变量。 ### Q7:视频合成返回 `Internal server error` **原因**:可能是 FFmpeg 处理错误、临时目录权限问题或资源下载失败。 **解决**: 1. 查看后端详细日志:`pm2 logs ai-demo-server` 2. 检查 `server/temp/` 目录权限:`ls -la server/temp` 3. 测试后端健康检查:`curl http://localhost:3001/api/video/health` ### Q8:构建时内存不足 **原因**:项目包含 FFmpeg WASM,构建产物较大。 **解决**: ```bash # 增大 Node.js 内存限制 NODE_OPTIONS=--max-old-space-size=4096 npm run build ``` --- ## 七、页面路由清单 | 路由路径 | 页面名称 | 功能说明 | |----------|----------|----------| | `/` | 首页 | 功能导航卡片 | | `/pronunciation` | 发音练习 | TTS 语音合成,音标学习 | | `/speaking` | 口语对话 | ASR 语音识别,AI 对话 | | `/essay-correction` | 作文批改 | 图片/文本作文批改 | | `/exam-analysis` | 试题分析 | 图片题目分析解答 | | `/spell-practice` | 单词拼写 | 单词拼写练习检测 | | `/problem-solving` | 解题指导 | AI 解题步骤指导 | | `/question-generator` | 题目生成 | 自动生成练习题 | | `/question-variant` | 题目变体 | 生成相似题目变体 | | `/audio-to-text` | 语音转文字 | 音频转文本功能 | | `/question-explanation` | 视频讲解 | 视频合成讲解(使用后端服务)| --- ## 八、依赖版本参考 ### 前端依赖(package.json) | 依赖包 | 版本 | |--------|------| | vue | ^3.5.30 | | vue-router | ^5.0.3 | | vite | ^8.0.0 | | @ffmpeg/ffmpeg | ^0.12.15 | | @ffmpeg/util | ^0.12.2 | | axios | ^1.13.6 | | marked | ^17.0.5 | | pako | ^2.1.0 | ### 后端依赖(server/package.json) | 依赖包 | 版本 | 用途 | |--------|------|------| | express | ^4.21.0 | Web 服务器框架 | | cors | ^2.8.5 | 跨域中间件 | | fluent-ffmpeg | ^2.1.3 | FFmpeg Node.js 封装 | | axios | ^1.7.0 | HTTP 客户端 | | uuid | ^10.0.0 | UUID 生成 | --- ## 九、目录结构参考 ``` AI_Demo/ ├── dist/ # 前端构建产物(部署此目录) ├── server/ # 后端服务 │ ├── routes/ # 路由模块 │ │ └── video.js # 视频合成 API │ ├── temp/ # 临时文件目录(自动创建) │ ├── index.js # 后端服务入口 │ ├── package.json # 后端依赖配置 │ └── README.md # 后端服务文档 ├── src/ # 前端源码 │ ├── config/index.js # API 密钥配置(部署前确认) │ ├── router/index.js # 路由定义 │ ├── views/ # 页面组件 │ │ ├── HomePage.vue # 首页 │ │ ├── Pronunciation.vue # 发音练习 │ │ ├── Speaking.vue # 口语对话 │ │ ├── EssayCorrection.vue # 作文批改 │ │ ├── ExamAnalysis.vue # 试题分析 │ │ ├── SpellPractice.vue # 单词拼写 │ │ ├── ProblemSolving.vue # 解题指导 │ │ ├── QuestionGenerator.vue # 题目生成 │ │ ├── QuestionVariant.vue # 题目变体 │ │ ├── AudioToText.vue # 语音转文字 │ │ └── QuestionExplanation.vue # 视频讲解 │ ├── components/ # 公共组件 │ ├── assets/ # 静态资源 │ └── MainLayout.vue # 布局组件 ├── vite.config.js # 开发代理配置(生产环境需在服务器复现) ├── package.json # 前端依赖配置 └── DEPLOY.md # 本文档 ``` --- ## 十、后端服务详细说明 ### 10.1 服务架构 后端服务基于 Express.js 构建,主要提供视频合成功能: - **技术栈**:Express.js + Fluent-FFmpeg - **默认端口**:3001 - **主要功能**:接收图片和音频 URL,合成 MP4 视频文件 ### 10.2 API 接口 #### POST `/api/video/compose` 合成视频接口,将多组图片和音频合成为视频。 **请求体示例**: ```json { "slides": [ { "imageUrl": "https://example.com/image1.png", "audioUrl": "https://example.com/audio1.mp3" }, { "imageUrl": "https://example.com/image2.png", "audioUrl": "https://example.com/audio2.mp3" } ], "width": 1920, "height": 1080 } ``` **参数说明**: - `slides`(必需):幻灯片数组,每个元素包含: - `imageUrl`:图片 URL(支持 HTTP/HTTPS URL 或 base64 data URI) - `audioUrl`:音频 URL(MP3 格式) - `width`(可选):视频宽度,默认 1920 - `height`(可选):视频高度,默认 1080 **响应**: - Content-Type: `video/mp4` - 返回合成后的 MP4 视频文件 #### GET `/api/video/health` 健康检查接口,检查 FFmpeg 服务状态。 **响应示例**: ```json { "status": "ok", "message": "视频合成服务正常运行", "formats": 300 } ``` #### GET `/health` 服务健康检查接口。 **响应示例**: ```json { "status": "ok", "timestamp": "2024-01-01T12:00:00.000Z" } ``` ### 10.3 环境变量配置 后端服务支持以下环境变量: | 环境变量 | 默认值 | 说明 | |---------|--------|------| | `PORT` | 3001 | 服务监听端口 | 使用示例: ```bash PORT=3002 pm2 start index.js --name ai-demo-server ``` ### 10.4 临时文件管理 - 后端服务在 `server/temp/` 目录下存储临时文件 - 每个视频合成任务会创建独立的子目录(使用 UUID 命名) - 任务完成后,临时文件会自动清理 - 如遇异常中断,可手动清理 `temp/` 目录 ### 10.5 性能与资源要求 **建议配置**: - **CPU**:2 核以上(视频合成需要较多 CPU 资源) - **内存**:2GB 以上 - **磁盘**:10GB 以上可用空间(临时文件存储) **并发处理**: - 单个视频合成任务处理时间:约 10-60 秒(取决于片段数量和时长) - 建议使用队列机制处理高并发请求(当前版本为同步处理) ### 10.6 日志查看 使用 PM2 查看后端服务日志: ```bash # 查看实时日志 pm2 logs ai-demo-server # 查看最近 100 行日志 pm2 logs ai-demo-server --lines 100 # 清空日志 pm2 flush ai-demo-server ``` 日志包含: - 服务启动信息 - FFmpeg 命令执行日志 - 视频合成进度 - 错误信息 ### 10.7 监控与告警 建议监控以下指标: - 服务进程状态(PM2 监控) - 端口 3001 响应状态(健康检查) - 磁盘空间(`temp/` 目录) - CPU 和内存使用率 --- ## 十一、Docker 部署(可选) ### 11.1 后端服务 Dockerfile 已提供 Dockerfile 位于 `Dockerfiles/backend.Dockerfile`(如需创建): ```dockerfile FROM node:20-alpine # 安装 FFmpeg RUN apk add --no-cache ffmpeg WORKDIR /app # 复制依赖文件 COPY server/package*.json ./ RUN npm ci --only=production # 复制源码 COPY server/ ./ # 创建临时目录 RUN mkdir -p temp EXPOSE 3001 CMD ["node", "index.js"] ``` ### 11.2 Docker Compose 部署 创建 `docker-compose.yml`: ```yaml version: '3.8' services: backend: build: context: . dockerfile: Dockerfiles/backend.Dockerfile ports: - "3001:3001" volumes: - ./server/temp:/app/temp restart: unless-stopped environment: - PORT=3001 frontend: image: nginx:alpine ports: - "80:80" volumes: - ./dist:/usr/share/nginx/html - ./nginx.conf:/etc/nginx/conf.d/default.conf depends_on: - backend restart: unless-stopped ``` 启动: ```bash docker-compose up -d ``` --- ## 十二、安全建议 1. **HTTPS 强制**:生产环境务必启用 HTTPS 2. **API 密钥保护**:不要将 API 密钥提交到代码仓库 3. **文件上传限制**:限制视频合成的图片和音频大小 4. **频率限制**:对 `/api/video/compose` 接口添加速率限制 5. **临时文件清理**:定期检查并清理异常终止的临时文件 6. **日志审计**:记录所有视频合成请求的来源和处理结果 --- ## 十三、更新与维护 ### 更新前端 ```bash git pull npm install npm run build # 重新部署 dist/ 目录 ``` ### 更新后端 ```bash cd server git pull npm install pm2 restart ai-demo-server ``` ### 查看服务状态 ```bash pm2 status pm2 logs ``` --- **文档版本**:v2.0 **更新日期**:2024-01-01 **更新内容**:新增后端视频合成服务部署说明