AI.Demo/DEPLOY.md

420 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# AI 英语学习辅助平台 — 线上部署操作流程
## 项目概述
- **项目名称**AI 英语学习辅助平台
- **技术栈**Vue 3 + Vite + Vue RouterHistory 模式)
- **构建产物**纯静态文件HTML / CSS / JS可部署到任意静态托管服务
---
## 一、部署前准备
### 1.1 环境要求
| 工具 | 版本要求 |
|------|----------|
| Node.js | >= 18.x推荐 20.x LTS |
| npm | >= 9.x |
```bash
node -v
npm -v
```
### 1.2 安装依赖
```bash
cd AI_Demo
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 请求,**生产环境必须在服务器/网关层配置对应的反向代理**
| 前端请求路径前缀 | 代理目标 | 用途 |
|-----------------|----------|------|
| `/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 |
> **ASR WebSocket 特殊说明**`/asr-ws` 代理需要在代理层注入以下鉴权 Header浏览器原生 WebSocket 不支持自定义 Header
> - `X-Api-App-Key`
> - `X-Api-Access-Key`
> - `X-Api-Resource-Id`
> - `X-Api-Connect-Id`(每次连接随机 UUID
---
## 三、构建生产包
```bash
npm run build
```
构建完成后,产物位于 `dist/` 目录,包含:
```
dist/
├── index.html
├── favicon.svg
└── assets/
├── *.js
└── *.css
```
可在本地预览构建结果:
```bash
npm run preview
```
---
## 四、部署方案
### 方案 ANginx 部署(推荐,自有服务器)
#### 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;
}
# 代理:豆包 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 配置 HTTPS推荐
```bash
# 使用 Certbot 申请免费 SSL 证书
apt install certbot python3-certbot-nginx
certbot --nginx -d your-domain.com
```
---
### 方案 BNode.js + Express 静态服务器
适用于需要在 Node.js 环境中自定义响应头的场景。
#### 4.B.1 安装依赖
```bash
npm install express http-proxy-middleware
```
#### 4.B.2 创建服务器文件 `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()
})
// 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(`Server running at http://localhost:${PORT}`)
})
```
#### 4.B.3 启动服务
```bash
DOUBAO_APP_ID=xxx DOUBAO_ACCESS_TOKEN=xxx node server.js
```
---
### 方案 CEdgeOne 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" }
]
}
]
}
```
---
## 五、部署后验证清单
| 验证项 | 检查方法 |
|--------|----------|
| 页面正常加载 | 访问首页,确认 6 个功能卡片显示正常 |
| 路由刷新不 404 | 直接访问 `/pronunciation`、`/speaking` 等子路由 |
| COOP/COEP 响应头 | 浏览器 DevTools → Network → 查看 index.html 响应头 |
| TTS 语音合成 | 进入发音练习页,测试语音播放 |
| ASR 语音识别 | 进入口语对话页,测试麦克风录音识别 |
| 作文批改 | 进入作文批改页,提交一段英文作文 |
| 试题分析 | 进入试题分析页,上传图片或输入题目 |
| 单词拼写练习 | 进入单词拼写页,测试拼写检测功能 |
---
## 六、常见问题排查
### 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`
### Q3API 请求跨域报错CORS
**原因**:生产环境未配置反向代理,浏览器直接请求第三方 API 被跨域拦截。
**解决**:参考第二节 2.3,在 Nginx 或 Node.js 中配置对应代理规则。
### Q4ASR 语音识别 WebSocket 连接失败
**原因**:代理未注入豆包 ASR 鉴权 Header或 WebSocket 升级配置缺失。
**解决**:确认 Nginx 配置中包含 `proxy_set_header Upgrade $http_upgrade;` 及三个 `X-Api-*` Header。
### Q5构建时内存不足
**原因**:项目包含 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` | 单词拼写 | 单词拼写练习检测 |
---
## 八、依赖版本参考
| 依赖包 | 版本 |
|--------|------|
| 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 |
---
## 九、目录结构参考
```
AI_Demo/
├── dist/ # 构建产物(部署此目录)
├── src/
│ ├── config/index.js # API 密钥配置(部署前确认)
│ ├── router/index.js # 路由定义
│ ├── views/ # 页面组件
│ │ ├── HomePage.vue # 首页
│ │ ├── Pronunciation.vue # 发音练习
│ │ ├── Speaking.vue # 口语对话
│ │ ├── EssayCorrection.vue # 作文批改
│ │ ├── ExamAnalysis.vue # 试题分析
│ │ └── SpellPractice.vue # 单词拼写
│ ├── components/ # 公共组件
│ ├── assets/ # 静态资源
│ └── MainLayout.vue # 布局组件
├── vite.config.js # 开发代理配置(生产环境需在服务器复现)
├── package.json
└── DEPLOY.md # 本文档
```