403 lines
9.3 KiB
Markdown
403 lines
9.3 KiB
Markdown
|
|
# 前端部署文档
|
|||
|
|
|
|||
|
|
## 一、环境配置
|
|||
|
|
|
|||
|
|
### 1.1 环境文件
|
|||
|
|
|
|||
|
|
项目支持多环境配置:
|
|||
|
|
|
|||
|
|
- `.env.development` - 本地开发环境
|
|||
|
|
- `.env.test` - 测试环境
|
|||
|
|
- `.env.production` - 生产环境
|
|||
|
|
|
|||
|
|
**测试环境配置 (.env.test):**
|
|||
|
|
```env
|
|||
|
|
# 测试环境
|
|||
|
|
VITE_BASE_URL=/web-test/
|
|||
|
|
VITE_API_BASE_URL=/api-test
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**生产环境配置 (.env.production):**
|
|||
|
|
```env
|
|||
|
|
# 生产环境
|
|||
|
|
VITE_BASE_URL=/web/
|
|||
|
|
VITE_API_BASE_URL=/api
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 1.2 Vite 配置
|
|||
|
|
|
|||
|
|
`vite.config.ts` 根据环境设置 base 路径:
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
import { defineConfig } from "vite"
|
|||
|
|
import vue from "@vitejs/plugin-vue"
|
|||
|
|
import { resolve } from "path"
|
|||
|
|
|
|||
|
|
// 根据环境设置 base 路径
|
|||
|
|
const getBase = (mode: string) => {
|
|||
|
|
switch (mode) {
|
|||
|
|
case "test":
|
|||
|
|
return "/web-test/"
|
|||
|
|
case "production":
|
|||
|
|
return "/web/"
|
|||
|
|
default:
|
|||
|
|
return "/"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export default defineConfig(({ mode }) => {
|
|||
|
|
return {
|
|||
|
|
base: getBase(mode),
|
|||
|
|
plugins: [vue()],
|
|||
|
|
resolve: {
|
|||
|
|
alias: {
|
|||
|
|
"@": resolve(__dirname, "src"),
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
server: {
|
|||
|
|
port: 3000,
|
|||
|
|
proxy: {
|
|||
|
|
"/api": {
|
|||
|
|
target: "http://localhost:3234",
|
|||
|
|
changeOrigin: true,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 1.3 路由配置
|
|||
|
|
|
|||
|
|
`src/router/index.ts` 需要配置 base 路径:
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
const router = createRouter({
|
|||
|
|
history: createWebHistory(import.meta.env.BASE_URL),
|
|||
|
|
routes: baseRoutes,
|
|||
|
|
})
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 二、构建打包
|
|||
|
|
|
|||
|
|
### 2.1 构建命令
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 测试环境构建
|
|||
|
|
pnpm build:test
|
|||
|
|
|
|||
|
|
# 生产环境构建
|
|||
|
|
pnpm build:prod
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2.2 压缩打包
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 测试环境压缩
|
|||
|
|
pnpm compress:test
|
|||
|
|
|
|||
|
|
# 生产环境压缩
|
|||
|
|
pnpm compress:prod
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
压缩后文件:
|
|||
|
|
- 测试环境:`competition-web-test-v1.0.0.tgz`
|
|||
|
|
- 生产环境:`competition-web-production-v1.0.0.tgz`
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 三、服务器部署
|
|||
|
|
|
|||
|
|
### 3.1 服务器信息
|
|||
|
|
|
|||
|
|
| 环境 | Nginx 服务器 | 后端服务器 |
|
|||
|
|
|------|-------------|-----------|
|
|||
|
|
| 测试 | 106.52.220.176 | 119.29.229.174:3234 |
|
|||
|
|
| 生产 | 106.52.220.176 | 待定 |
|
|||
|
|
|
|||
|
|
域名:`cmp-3d.linkseaai.com`
|
|||
|
|
|
|||
|
|
### 3.2 部署步骤
|
|||
|
|
|
|||
|
|
**1. 上传压缩包**
|
|||
|
|
```bash
|
|||
|
|
scp competition-web-test-v1.0.0.tgz root@106.52.220.176:/home/
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**2. 登录服务器**
|
|||
|
|
```bash
|
|||
|
|
ssh root@106.52.220.176
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**3. 解压文件**
|
|||
|
|
```bash
|
|||
|
|
# 创建目录(首次部署)
|
|||
|
|
mkdir -p /data/apps/cmp-3d/web-test
|
|||
|
|
mkdir -p /data/apps/cmp-3d/web
|
|||
|
|
|
|||
|
|
# 清空旧文件并解压
|
|||
|
|
rm -rf /data/apps/cmp-3d/web-test/*
|
|||
|
|
cd /home
|
|||
|
|
tar -xzf competition-web-test-v1.0.0.tgz -C /data/apps/cmp-3d/web-test
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**4. 配置 Nginx**
|
|||
|
|
|
|||
|
|
配置文件路径:`/usr/local/nginx/conf/conf.d/cmp-3d.conf`
|
|||
|
|
|
|||
|
|
```nginx
|
|||
|
|
# ========== 比赛管理系统 - cmp-3d.linkseaai.com ==========
|
|||
|
|
|
|||
|
|
server {
|
|||
|
|
listen 443 ssl;
|
|||
|
|
server_name cmp-3d.linkseaai.com;
|
|||
|
|
include /usr/local/nginx/conf/conf.d/linkseaai.ssl.conf;
|
|||
|
|
root /data/apps/cmp-3d/;
|
|||
|
|
include /usr/local/nginx/conf/conf.d/error.conf;
|
|||
|
|
include /usr/local/nginx/conf/conf.d/static.conf;
|
|||
|
|
|
|||
|
|
# ========== 超时配置 ==========
|
|||
|
|
keepalive_timeout 300s;
|
|||
|
|
send_timeout 180s;
|
|||
|
|
proxy_connect_timeout 10s;
|
|||
|
|
proxy_send_timeout 10s;
|
|||
|
|
proxy_read_timeout 300s;
|
|||
|
|
|
|||
|
|
# ========== 测试环境 - 前端 ==========
|
|||
|
|
location /web-test/ {
|
|||
|
|
root /data/apps/cmp-3d/;
|
|||
|
|
index index.html index.htm;
|
|||
|
|
try_files $uri $uri/ /web-test/index.html;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# ========== 测试环境 - API 代理 ==========
|
|||
|
|
location /api-test/ {
|
|||
|
|
proxy_redirect off;
|
|||
|
|
proxy_pass http://119.29.229.174:3234/api/;
|
|||
|
|
proxy_http_version 1.1;
|
|||
|
|
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;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# ========== 生产环境 - 前端 ==========
|
|||
|
|
location /web/ {
|
|||
|
|
root /data/apps/cmp-3d/;
|
|||
|
|
index index.html index.htm;
|
|||
|
|
try_files $uri $uri/ /web/index.html;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# ========== 生产环境 - API 代理 ==========
|
|||
|
|
location /api/ {
|
|||
|
|
proxy_redirect off;
|
|||
|
|
proxy_pass http://119.29.229.174:3234/api/;
|
|||
|
|
proxy_http_version 1.1;
|
|||
|
|
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;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**5. 在 nginx.conf 中添加 include**
|
|||
|
|
|
|||
|
|
编辑 `/usr/local/nginx/conf/nginx.conf`,在 `http {}` 块中添加:
|
|||
|
|
```nginx
|
|||
|
|
include ./conf.d/cmp-3d.conf;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**6. 重载 Nginx**
|
|||
|
|
```bash
|
|||
|
|
/usr/local/nginx/sbin/nginx -t
|
|||
|
|
/usr/local/nginx/sbin/nginx -s reload
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3.3 访问地址
|
|||
|
|
|
|||
|
|
| 环境 | URL |
|
|||
|
|
|------|-----|
|
|||
|
|
| 测试 | https://cmp-3d.linkseaai.com/web-test/super/login |
|
|||
|
|
| 生产 | https://cmp-3d.linkseaai.com/web/super/login |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 四、遇到的问题及解决方案
|
|||
|
|
|
|||
|
|
### 4.1 vite.config.js 覆盖问题
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
项目中同时存在 `vite.config.ts` 和 `vite.config.js`,导致 TypeScript 配置文件被 JavaScript 文件覆盖,`base` 配置不生效。
|
|||
|
|
|
|||
|
|
**表现:**
|
|||
|
|
打包后的 `index.html` 中资源路径是 `/assets/...` 而不是 `/web-test/assets/...`。
|
|||
|
|
|
|||
|
|
**解决方案:**
|
|||
|
|
删除 `vite.config.js` 和 `vite.config.d.ts`,只保留 `vite.config.ts`。
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
rm vite.config.js vite.config.d.ts
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.2 域名重定向到 linkseaaiglobal.com
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
访问 `https://cmp-3d.linkseaai.com/web-test/` 被重定向到 `https://linkseaaiglobal.com/`。
|
|||
|
|
|
|||
|
|
**原因:**
|
|||
|
|
`nginx.conf` 中没有 include `cmp-3d.conf` 配置文件。
|
|||
|
|
|
|||
|
|
**解决方案:**
|
|||
|
|
在 `/usr/local/nginx/conf/nginx.conf` 的 `http {}` 块中添加:
|
|||
|
|
```nginx
|
|||
|
|
include ./conf.d/cmp-3d.conf;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.3 租户编码获取错误
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
登录时提示"租户不存在",租户编码被识别为 `web-test` 而不是 `super`。
|
|||
|
|
|
|||
|
|
**原因:**
|
|||
|
|
`src/utils/auth.ts` 中的 `getTenantCodeFromUrl()` 函数直接从 URL 第一部分提取租户编码,没有考虑 base 路径。
|
|||
|
|
|
|||
|
|
URL `/web-test/super/login` 被解析为租户编码 `web-test`。
|
|||
|
|
|
|||
|
|
**解决方案:**
|
|||
|
|
修改 `getTenantCodeFromUrl()` 函数,去掉 base 路径后再提取租户编码:
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
function getTenantCodeFromUrl(): string | null {
|
|||
|
|
let path = window.location.pathname;
|
|||
|
|
|
|||
|
|
// 去掉 base 路径前缀(如 /web-test/ 或 /web/)
|
|||
|
|
const base = import.meta.env.BASE_URL || "/";
|
|||
|
|
if (base !== "/" && path.startsWith(base)) {
|
|||
|
|
path = path.slice(base.length - 1); // 保留开头的 /
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const match = path.match(/^\/([^/]+)/);
|
|||
|
|
return match ? match[1] : null;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
同时修改 `setToken()` 和 `removeToken()` 函数,Cookie 路径也需要包含 base 路径。
|
|||
|
|
|
|||
|
|
### 4.4 Vue Router base 路径问题
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
在 URL 中添加租户编码后,回车会自动去掉租户编码部分。
|
|||
|
|
|
|||
|
|
**原因:**
|
|||
|
|
`createWebHistory()` 没有传入 base 路径。
|
|||
|
|
|
|||
|
|
**解决方案:**
|
|||
|
|
修改 `src/router/index.ts`:
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
const router = createRouter({
|
|||
|
|
history: createWebHistory(import.meta.env.BASE_URL),
|
|||
|
|
routes: baseRoutes,
|
|||
|
|
})
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.5 API 路径 404 错误
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
登录接口返回 `Cannot POST /auth/login`。
|
|||
|
|
|
|||
|
|
**原因:**
|
|||
|
|
Nginx 代理配置中,`/api-test/` 被代理到 `http://119.29.229.174:3234/`,但后端路由前缀是 `/api`。
|
|||
|
|
|
|||
|
|
请求 `/api-test/auth/login` 被代理到 `http://119.29.229.174:3234/auth/login`,而正确应该是 `/api/auth/login`。
|
|||
|
|
|
|||
|
|
**解决方案:**
|
|||
|
|
修改 Nginx 配置,将 `/api-test/` 代理到 `/api/`:
|
|||
|
|
|
|||
|
|
```nginx
|
|||
|
|
location /api-test/ {
|
|||
|
|
proxy_pass http://119.29.229.174:3234/api/;
|
|||
|
|
# ...
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.6 3D 建模实验室链接 404
|
|||
|
|
|
|||
|
|
**问题描述:**
|
|||
|
|
点击 3D 建模实验室菜单,打开的 URL 是 `https://cmp-3d.linkseaai.com/school1/workbench/3d-lab`,缺少 `/web-test/` 前缀。
|
|||
|
|
|
|||
|
|
**原因:**
|
|||
|
|
`src/layouts/BasicLayout.vue` 中生成 URL 时使用 `window.location.origin` 直接拼接路径,没有包含 base 路径。
|
|||
|
|
|
|||
|
|
**解决方案:**
|
|||
|
|
修改 BasicLayout.vue 中的 URL 生成逻辑:
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
const base = import.meta.env.BASE_URL || "/"
|
|||
|
|
const basePath = base.endsWith("/") ? base.slice(0, -1) : base
|
|||
|
|
const fullUrl = `${window.location.origin}${basePath}/${tenantCode}/workbench/3d-lab`
|
|||
|
|
window.open(fullUrl, "_blank")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 五、常用命令
|
|||
|
|
|
|||
|
|
### Nginx 命令
|
|||
|
|
```bash
|
|||
|
|
# Nginx 路径(编译安装)
|
|||
|
|
/usr/local/nginx/sbin/nginx
|
|||
|
|
|
|||
|
|
# 测试配置
|
|||
|
|
/usr/local/nginx/sbin/nginx -t
|
|||
|
|
|
|||
|
|
# 重载配置
|
|||
|
|
/usr/local/nginx/sbin/nginx -s reload
|
|||
|
|
|
|||
|
|
# 查看完整配置
|
|||
|
|
/usr/local/nginx/sbin/nginx -T
|
|||
|
|
|
|||
|
|
# 查看配置文件
|
|||
|
|
cat /usr/local/nginx/conf/nginx.conf
|
|||
|
|
cat /usr/local/nginx/conf/conf.d/cmp-3d.conf
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 部署快捷命令
|
|||
|
|
```bash
|
|||
|
|
# 一键部署测试环境
|
|||
|
|
rm -rf /data/apps/cmp-3d/web-test/* && \
|
|||
|
|
cd /home && \
|
|||
|
|
tar -xzf competition-web-test-v1.0.0.tgz -C /data/apps/cmp-3d/web-test
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 六、目录结构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
/data/apps/cmp-3d/
|
|||
|
|
├── web-test/ # 测试环境前端
|
|||
|
|
│ ├── index.html
|
|||
|
|
│ └── assets/
|
|||
|
|
└── web/ # 生产环境前端
|
|||
|
|
├── index.html
|
|||
|
|
└── assets/
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 七、注意事项
|
|||
|
|
|
|||
|
|
1. **base 路径一致性**:前端 `vite.config.ts`、`.env` 文件、Nginx 配置中的路径必须一致。
|
|||
|
|
|
|||
|
|
2. **API 代理路径**:Nginx 代理到后端时,注意后端的路由前缀是 `/api`。
|
|||
|
|
|
|||
|
|
3. **Cookie 路径**:登录后的 Token 存储在 Cookie 中,路径需要包含 base 路径。
|
|||
|
|
|
|||
|
|
4. **清除缓存**:部署后如果有问题,先清除浏览器缓存或使用无痕模式测试。
|
|||
|
|
|
|||
|
|
5. **Nginx include**:新增配置文件后,需要在 `nginx.conf` 中添加 include 语句。
|