library-picturebook-activity/docs/deployment/frontend-deployment.md
aid 418aa57ea8 Day4: 超管端设计优化 + UGC绘本创作社区P0实现
一、超管端设计优化
- 文档管理SOP体系建立,docs目录重组
- 统一用户管理:跨租户全局视角,合并用户管理+公众用户
- 活动监管全模块重构:全部活动(统计卡片+阶段筛选+SuperDetail详情页)、报名数据/作品数据/评审进度(两层合一扁平列表)、成果发布(去Tab+统计+隐藏写操作)
- 菜单精简:移除评委管理/评审规则/通知管理
- Bug修复:租户编辑丢失隐藏菜单、pageSize限制、主色统一

二、UGC绘本创作社区P0
- 数据库:10张新表(user_works/user_work_pages/work_tags等)
- 子女账号独立化:Child升级为独立User,家长切换+独立登录
- 用户作品库:CRUD+发布审核,8个API
- AI创作流程:提交→生成→保存到作品库,4个API
- 作品广场:首页改造为推荐流,标签+搜索+排序
- 内容审核(超管端):作品审核+作品管理+标签管理
- 活动联动:WorkSelector作品选择器
- 布局改造:底部5Tab(发现/创作/活动/作品库/我的)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 22:20:25 +08:00

403 lines
9.7 KiB
Markdown
Raw Permalink 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.

# 前端部署文档
## 一、环境配置
### 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 语句。