# 后端部署文档

## 一、本地打包

### 1. 环境准备

```bash
cd backend

# 删除 pnpm 的 node_modules（避免软链接问题）
rm -rf node_modules

# 用 npm 安装依赖
npm install

# 构建项目
pnpm build
```

### 2. 打包命令

```bash
# 测试环境
bash scripts/compress.sh --env test --version 1.0.0 -n

# 生产环境
bash scripts/compress.sh --env production --version 1.0.0 -n
```

生成文件：`competition-management-service-{env}-{version}.tgz`

### 3. 打包注意事项

| 问题 | 原因 | 解决方案 |
|------|------|---------|
| 软链接失效 | pnpm 使用软链接管理依赖 | 打包前用 `npm install` 替代 `pnpm install` |
| logs 模块缺失 | 打包脚本排除了 `logs` 目录 | 修改 `compress.sh` 中 `"logs"` 为 `"./logs"` |
| uuid 版本问题 | uuid v9+ 是 ESM 模块 | 安装 `uuid@8.3.2` |

---

## 二、服务器部署

### 1. 上传并解压

```bash
# 本地上传
scp competition-management-service-test-1.0.0.tgz root@服务器IP:/data/web-servers/

# 服务器解压
cd /data/web-servers
tar -xzf competition-management-service-test-1.0.0.tgz
cd competition-management-service
```

### 2. 配置环境变量

```bash
vim .env
```

修改数据库连接：
```env
DATABASE_URL="mysql://用户名:密码@数据库地址:端口/数据库名"
```

示例（腾讯云数据库）：
```env
DATABASE_URL="mysql://root:password@gz-cdb-xxx.sql.tencentcdb.com:20704/db_competition_management"
```

### 3. 生成 Prisma Client

```bash
# 如果遇到 SSL 证书问题
export NODE_TLS_REJECT_UNAUTHORIZED=0

npx prisma generate
```

### 4. 创建数据库表

```bash
npx prisma db push
```

### 5. 启动服务

```bash
# 使用 PM2 启动
pm2 start dist/src/main.js --name competition-api-test

# 保存进程列表
pm2 save

# 设置开机自启
pm2 startup
```

### 6. 验证服务

```bash
# 查看状态
pm2 status

# 查看日志
pm2 logs competition-api-test

# 测试接口
curl -X POST http://localhost:3234/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"123456"}'
```

---

## 三、常见问题

### 1. `prisma generate` 报 SSL 证书错误

```
Error: request to https://binaries.prisma.sh/... failed, reason: unable to get local issuer certificate
```

**解决**：
```bash
export NODE_TLS_REJECT_UNAUTHORIZED=0
npx prisma generate
```

### 2. `pm2: command not found`

**原因**：`/usr/local/bin` 不在 PATH 中

**解决**：
```bash
export PATH=$PATH:/usr/local/bin
echo 'export PATH=$PATH:/usr/local/bin' >> ~/.bashrc
source ~/.bashrc
```

### 3. `MODULE_NOT_FOUND: ./logs/logs.module`

**原因**：打包脚本排除了 `logs` 目录

**解决**：修改 `compress.sh` 第 93 行：
```bash
# 修改前
"logs"
# 修改后
"./logs"
```

### 4. `ERR_REQUIRE_ESM: uuid`

**原因**：uuid v9+ 是 ESM 模块，不支持 CommonJS

**解决**：
```bash
npm install uuid@8.3.2
```

### 5. 数据库认证失败

```
PrismaClientInitializationError: Authentication failed against database server
```

**解决**：检查 `.env` 中 `DATABASE_URL` 的用户名、密码、地址是否正确

### 6. 服务启动后无法访问

**原因**：
- 防火墙未开放端口
- 云服务器安全组未配置

**解决**：
```bash
# 开放防火墙端口
firewall-cmd --permanent --add-port=3234/tcp
firewall-cmd --reload
```

腾讯云控制台 → 安全组 → 添加入站规则（TCP 3234）

---

## 四、PM2 常用命令

```bash
pm2 start dist/src/main.js --name app-name  # 启动
pm2 stop app-name                            # 停止
pm2 restart app-name                         # 重启
pm2 delete app-name                          # 删除
pm2 status                                   # 查看状态
pm2 logs app-name                            # 查看日志
pm2 logs app-name --lines 100                # 查看最近100行日志
pm2 save                                     # 保存进程列表
pm2 startup                                  # 设置开机自启
```

---

## 五、数据初始化

### 方式1：本地初始化后导出导入

**本地操作**：
```bash
cd backend
pnpm init:super-tenant
pnpm init:admin
pnpm init:menus
pnpm init:roles:all

# 导出数据
mysqldump -u root db_competition_management > init_data.sql
```

**导入到云数据库**（使用 DBeaver）：
1. 连接腾讯云数据库
2. 执行 `SET FOREIGN_KEY_CHECKS = 0;`
3. 执行 SQL 文件
4. 执行 `SET FOREIGN_KEY_CHECKS = 1;`

### 方式2：DBeaver 数据传输

1. 连接本地数据库和云数据库
2. 选中本地数据库所有表
3. 右键 → 导出数据 → 数据库表
4. 选择云数据库作为目标
5. 执行传输

---

## 六、目录结构

```
/data/web-servers/competition-management-service/
├── dist/                 # 编译后的代码
│   └── src/
│       └── main.js       # 入口文件
├── node_modules/         # 依赖
├── prisma/               # Prisma schema
├── .env                  # 环境配置
├── .env.test             # 测试环境配置
├── .env.production       # 生产环境配置
├── ecosystem.config.js   # PM2 配置
└── package.json
```
