1126 lines
19 KiB
Markdown
1126 lines
19 KiB
Markdown
# Tencent IP Port Dev Deploy Implementation Plan
|
||
|
||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||
|
||
**Goal:** 将当前 ForgeFlow ERP 前后端部署到腾讯云 1Panel Ubuntu 服务器,临时开启动态加载,通过 `公网 IP + 端口` 访问,数据库继续连接阿里云 MySQL。
|
||
|
||
**Architecture:** 临时测试阶段不走域名、HTTPS、Nginx/OpenResty 反代。浏览器访问 Vite dev server `http://腾讯云公网IP:5173`,前端请求 FastAPI `http://腾讯云公网IP:8000/api`,后端连接阿里云 MySQL `121.40.97.156:3306`。稳定后再切到正式生产架构:前端静态构建、OpenResty 反代 `/api`、HTTPS、后端仅监听本机。
|
||
|
||
**Tech Stack:** Ubuntu 22.04/1Panel, Python 3, FastAPI/Uvicorn, Vue 3/Vite, Node.js 20, MySQL on Aliyun.
|
||
|
||
---
|
||
|
||
## Phase 0: 部署边界确认
|
||
|
||
本计划只做临时测试部署,不代表最终生产配置。
|
||
|
||
临时测试访问方式:
|
||
|
||
```text
|
||
浏览器
|
||
-> http://<腾讯云公网IP>:5173
|
||
Vite dev server,支持前端热更新
|
||
|
||
前端 API 请求
|
||
-> http://<腾讯云公网IP>:8000/api
|
||
FastAPI/Uvicorn,使用 --reload 支持后端动态加载
|
||
|
||
后端数据库连接
|
||
-> 121.40.97.156:3306
|
||
阿里云 MySQL
|
||
```
|
||
|
||
需要提前准备的信息:
|
||
|
||
```bash
|
||
export TENCENT_IP="<腾讯云服务器公网IP>"
|
||
export ALIYUN_MYSQL_HOST="121.40.97.156"
|
||
export ALIYUN_MYSQL_PORT="3306"
|
||
export ERP_DB_NAME="jiaheng_erp"
|
||
export ERP_DB_USER="<数据库用户名>"
|
||
export ERP_DB_PASSWORD="<数据库密码>"
|
||
```
|
||
|
||
本阶段必须接受的临时风险:
|
||
|
||
- `5173` 和 `8000` 会临时暴露在公网,只适合测试期。
|
||
- Vite dev server 和 `uvicorn --reload` 不是最终生产运行方式。
|
||
- 如果直接连现有阿里云数据库,腾讯云上的操作会真实写入同一个库。
|
||
- 数据库账号不要长期使用 `root`,至少正式前要换成 ERP 专用账号。
|
||
|
||
---
|
||
|
||
## Phase 1: 腾讯云服务器基础准备
|
||
|
||
### Task 1: 登录服务器并确认系统
|
||
|
||
- [ ] **Step 1: SSH 登录腾讯云服务器**
|
||
|
||
```bash
|
||
ssh root@<腾讯云公网IP>
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
成功进入 Ubuntu shell
|
||
```
|
||
|
||
- [ ] **Step 2: 确认系统版本和架构**
|
||
|
||
```bash
|
||
uname -a
|
||
lsb_release -a || cat /etc/os-release
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
Linux VM-0-14-ubuntu ...
|
||
Ubuntu ...
|
||
x86_64
|
||
```
|
||
|
||
### Task 2: 安装基础依赖
|
||
|
||
- [ ] **Step 1: 更新 apt 包索引**
|
||
|
||
```bash
|
||
sudo apt update
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
Reading package lists... Done
|
||
```
|
||
|
||
- [ ] **Step 2: 安装 Python、构建工具、Git、MySQL 客户端**
|
||
|
||
```bash
|
||
sudo apt install -y git curl build-essential python3 python3-venv python3-pip mysql-client tmux
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
git, curl, python3, python3-venv, mysql-client, tmux 安装完成
|
||
```
|
||
|
||
- [ ] **Step 3: 安装 Node.js 20**
|
||
|
||
如果当前没有 Node,或者 `node -v` 低于 20,执行:
|
||
|
||
```bash
|
||
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
||
sudo apt install -y nodejs
|
||
```
|
||
|
||
验证:
|
||
|
||
```bash
|
||
node -v
|
||
npm -v
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
v20.x.x
|
||
10.x.x 或更高
|
||
```
|
||
|
||
---
|
||
|
||
## Phase 2: 网络和防火墙放行
|
||
|
||
### Task 3: 腾讯云安全组放行临时端口
|
||
|
||
- [ ] **Step 1: 在腾讯云控制台安全组放行 TCP 端口**
|
||
|
||
放行入站规则:
|
||
|
||
```text
|
||
TCP 5173 来源:你的办公公网 IP/32
|
||
TCP 8000 来源:你的办公公网 IP/32
|
||
TCP 22 来源:你的办公公网 IP/32
|
||
```
|
||
|
||
如果测试人员公网 IP 不固定,临时可用:
|
||
|
||
```text
|
||
TCP 5173 来源:0.0.0.0/0
|
||
TCP 8000 来源:0.0.0.0/0
|
||
```
|
||
|
||
但这只能用于短期测试,稳定后必须收口。
|
||
|
||
Expected:
|
||
|
||
```text
|
||
外网可以访问 5173 和 8000,不再被腾讯云安全组拦截
|
||
```
|
||
|
||
### Task 4: 1Panel 或 Ubuntu 防火墙放行端口
|
||
|
||
- [ ] **Step 1: 如果使用 1Panel 防火墙,在 1Panel 面板中放行**
|
||
|
||
```text
|
||
端口:5173/tcp
|
||
端口:8000/tcp
|
||
```
|
||
|
||
- [ ] **Step 2: 如果服务器启用了 ufw,执行放行**
|
||
|
||
```bash
|
||
sudo ufw allow 5173/tcp
|
||
sudo ufw allow 8000/tcp
|
||
sudo ufw status
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
5173/tcp ALLOW
|
||
8000/tcp ALLOW
|
||
```
|
||
|
||
### Task 5: 阿里云 MySQL 放行腾讯云公网 IP
|
||
|
||
- [ ] **Step 1: 在阿里云服务器或 RDS 安全组中放行腾讯云公网 IP**
|
||
|
||
放行规则:
|
||
|
||
```text
|
||
入站 TCP 3306 来源:<腾讯云公网IP>/32
|
||
```
|
||
|
||
- [ ] **Step 2: 在腾讯云服务器测试 MySQL 连通性**
|
||
|
||
```bash
|
||
mysql -h 121.40.97.156 -P 3306 -u <数据库用户名> -p -e "SELECT NOW() AS db_time;"
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
+---------------------+
|
||
| db_time |
|
||
+---------------------+
|
||
| 2026-... |
|
||
+---------------------+
|
||
```
|
||
|
||
如果报错:
|
||
|
||
```text
|
||
ERROR 2003 Can't connect to MySQL server
|
||
```
|
||
|
||
处理方向:
|
||
|
||
```text
|
||
优先检查阿里云安全组、MySQL bind-address、防火墙、账号 Host 权限。
|
||
```
|
||
|
||
---
|
||
|
||
## Phase 3: 部署项目代码
|
||
|
||
### Task 6: 准备项目目录
|
||
|
||
- [ ] **Step 1: 创建部署目录**
|
||
|
||
```bash
|
||
sudo mkdir -p /opt/ForgeFlow-ERP
|
||
sudo chown -R $USER:$USER /opt/ForgeFlow-ERP
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
/opt/ForgeFlow-ERP 可由当前用户读写
|
||
```
|
||
|
||
### Task 7: 上传或拉取代码
|
||
|
||
推荐方式 A:服务器可以访问 Git 仓库时使用 `git clone`。
|
||
|
||
- [ ] **Step 1A: 克隆项目**
|
||
|
||
```bash
|
||
cd /opt
|
||
git clone <ForgeFlow-ERP仓库地址> ForgeFlow-ERP
|
||
cd /opt/ForgeFlow-ERP
|
||
git status
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
On branch ...
|
||
working tree clean
|
||
```
|
||
|
||
推荐方式 B:如果仓库暂时不方便从服务器拉取,就从 Mac 同步代码。
|
||
|
||
- [ ] **Step 1B: 在 Mac 上执行 rsync 上传**
|
||
|
||
```bash
|
||
rsync -av --delete \
|
||
--exclude 'frontend/node_modules' \
|
||
--exclude 'backend/.venv' \
|
||
--exclude '.git' \
|
||
/Users/souplearn/Gitlab/py/ForgeFlow-ERP/ \
|
||
root@<腾讯云公网IP>:/opt/ForgeFlow-ERP/
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
代码同步到 /opt/ForgeFlow-ERP
|
||
```
|
||
|
||
- [ ] **Step 2: 在服务器确认目录结构**
|
||
|
||
```bash
|
||
cd /opt/ForgeFlow-ERP
|
||
ls -la
|
||
ls -la backend frontend
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
backend/
|
||
frontend/
|
||
README.md
|
||
```
|
||
|
||
---
|
||
|
||
## Phase 4: 后端动态加载部署
|
||
|
||
### Task 8: 配置后端 `.env`
|
||
|
||
- [ ] **Step 1: 创建后端环境变量文件**
|
||
|
||
```bash
|
||
cd /opt/ForgeFlow-ERP/backend
|
||
cp .env.example .env
|
||
```
|
||
|
||
- [ ] **Step 2: 编辑 `.env`**
|
||
|
||
```bash
|
||
nano /opt/ForgeFlow-ERP/backend/.env
|
||
```
|
||
|
||
推荐内容:
|
||
|
||
```env
|
||
APP_NAME=Baihua Hardware ERP API
|
||
APP_ENV=staging-dev
|
||
APP_HOST=0.0.0.0
|
||
APP_PORT=8000
|
||
|
||
MYSQL_HOST=121.40.97.156
|
||
MYSQL_PORT=3306
|
||
MYSQL_DATABASE=jiaheng_erp
|
||
MYSQL_USER=<数据库用户名>
|
||
MYSQL_PASSWORD=<数据库密码>
|
||
|
||
ALLOWED_ORIGINS=http://<腾讯云公网IP>:5173
|
||
|
||
AUTH_SECRET_KEY=<生成一串至少32位的随机字符串>
|
||
AUTH_TOKEN_EXPIRE_MINUTES=480
|
||
```
|
||
|
||
生成随机密钥:
|
||
|
||
```bash
|
||
python3 - <<'PY'
|
||
import secrets
|
||
print(secrets.token_urlsafe(48))
|
||
PY
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
输出一串随机字符串,将它填入 AUTH_SECRET_KEY
|
||
```
|
||
|
||
注意:
|
||
|
||
```text
|
||
不要把正式数据库密码、AUTH_SECRET_KEY 发到聊天或提交到 Git。
|
||
```
|
||
|
||
### Task 9: 安装后端依赖
|
||
|
||
- [ ] **Step 1: 创建虚拟环境**
|
||
|
||
```bash
|
||
cd /opt/ForgeFlow-ERP/backend
|
||
python3 -m venv .venv
|
||
```
|
||
|
||
- [ ] **Step 2: 安装依赖**
|
||
|
||
```bash
|
||
cd /opt/ForgeFlow-ERP/backend
|
||
. .venv/bin/activate
|
||
pip install -U pip
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
Successfully installed fastapi uvicorn sqlalchemy pymysql ...
|
||
```
|
||
|
||
### Task 10: 临时启动后端动态加载
|
||
|
||
- [ ] **Step 1: 用 tmux 启动后端**
|
||
|
||
```bash
|
||
tmux new -s forgeflow-backend
|
||
```
|
||
|
||
在 tmux 窗口内执行:
|
||
|
||
```bash
|
||
cd /opt/ForgeFlow-ERP/backend
|
||
. .venv/bin/activate
|
||
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
Uvicorn running on http://0.0.0.0:8000
|
||
Started reloader process
|
||
```
|
||
|
||
退出 tmux 但保留进程:
|
||
|
||
```text
|
||
按 Ctrl+B,然后按 D
|
||
```
|
||
|
||
- [ ] **Step 2: 服务器本机验证后端**
|
||
|
||
```bash
|
||
curl -s http://127.0.0.1:8000/ | python3 -m json.tool
|
||
curl -s http://127.0.0.1:8000/api/system/health | python3 -m json.tool
|
||
```
|
||
|
||
Expected:
|
||
|
||
```json
|
||
{
|
||
"app": "ok",
|
||
"database": {
|
||
"connected": true
|
||
}
|
||
}
|
||
```
|
||
|
||
- [ ] **Step 3: Mac 或浏览器外网验证后端**
|
||
|
||
```bash
|
||
curl -s http://<腾讯云公网IP>:8000/api/system/health
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
能返回 app ok,database connected true
|
||
```
|
||
|
||
---
|
||
|
||
## Phase 5: 前端动态加载部署
|
||
|
||
### Task 11: 配置前端 `.env`
|
||
|
||
- [ ] **Step 1: 创建前端环境变量文件**
|
||
|
||
```bash
|
||
cd /opt/ForgeFlow-ERP/frontend
|
||
cp .env.example .env
|
||
```
|
||
|
||
- [ ] **Step 2: 修改 API 地址**
|
||
|
||
```bash
|
||
nano /opt/ForgeFlow-ERP/frontend/.env
|
||
```
|
||
|
||
内容:
|
||
|
||
```env
|
||
VITE_API_BASE_URL=http://<腾讯云公网IP>:8000/api
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
前端所有 API 请求都会打到腾讯云后端 8000 端口
|
||
```
|
||
|
||
### Task 12: 安装前端依赖
|
||
|
||
- [ ] **Step 1: 安装 npm 依赖**
|
||
|
||
```bash
|
||
cd /opt/ForgeFlow-ERP/frontend
|
||
npm install
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
added ... packages
|
||
```
|
||
|
||
### Task 13: 临时启动前端动态加载
|
||
|
||
- [ ] **Step 1: 用 tmux 启动前端**
|
||
|
||
```bash
|
||
tmux new -s forgeflow-frontend
|
||
```
|
||
|
||
在 tmux 窗口内执行:
|
||
|
||
```bash
|
||
cd /opt/ForgeFlow-ERP/frontend
|
||
npm run dev -- --host 0.0.0.0 --port 5173
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
VITE v5.x.x ready
|
||
Local: http://localhost:5173/
|
||
Network: http://<内网IP>:5173/
|
||
```
|
||
|
||
退出 tmux 但保留进程:
|
||
|
||
```text
|
||
按 Ctrl+B,然后按 D
|
||
```
|
||
|
||
- [ ] **Step 2: 服务器本机验证前端**
|
||
|
||
```bash
|
||
curl -I http://127.0.0.1:5173
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
HTTP/1.1 200 OK
|
||
```
|
||
|
||
- [ ] **Step 3: 浏览器访问**
|
||
|
||
```text
|
||
http://<腾讯云公网IP>:5173/login?redirect=/
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
出现 ERP 登录页
|
||
```
|
||
|
||
---
|
||
|
||
## Phase 6: 测试期进程守护
|
||
|
||
tmux 适合第一天快速验证。如果需要测试环境持续跑几天,建议改成 systemd 管理,但仍然保留动态加载。
|
||
|
||
### Task 14: 创建后端 dev systemd 服务
|
||
|
||
- [ ] **Step 1: 创建服务文件**
|
||
|
||
```bash
|
||
sudo nano /etc/systemd/system/forgeflow-backend-dev.service
|
||
```
|
||
|
||
内容:
|
||
|
||
```ini
|
||
[Unit]
|
||
Description=ForgeFlow ERP Backend Dev Reload
|
||
After=network.target
|
||
|
||
[Service]
|
||
Type=simple
|
||
WorkingDirectory=/opt/ForgeFlow-ERP/backend
|
||
ExecStart=/opt/ForgeFlow-ERP/backend/.venv/bin/uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
|
||
Restart=always
|
||
RestartSec=3
|
||
Environment=PYTHONUNBUFFERED=1
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
```
|
||
|
||
- [ ] **Step 2: 启动服务**
|
||
|
||
```bash
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl enable forgeflow-backend-dev
|
||
sudo systemctl start forgeflow-backend-dev
|
||
sudo systemctl status forgeflow-backend-dev --no-pager
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
Active: active (running)
|
||
```
|
||
|
||
- [ ] **Step 3: 查看日志**
|
||
|
||
```bash
|
||
journalctl -u forgeflow-backend-dev -f
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
Uvicorn running on http://0.0.0.0:8000
|
||
```
|
||
|
||
### Task 15: 创建前端 dev systemd 服务
|
||
|
||
- [ ] **Step 1: 查出 npm 路径**
|
||
|
||
```bash
|
||
which npm
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
/usr/bin/npm
|
||
```
|
||
|
||
- [ ] **Step 2: 创建服务文件**
|
||
|
||
```bash
|
||
sudo nano /etc/systemd/system/forgeflow-frontend-dev.service
|
||
```
|
||
|
||
如果 `which npm` 输出 `/usr/bin/npm`,内容如下:
|
||
|
||
```ini
|
||
[Unit]
|
||
Description=ForgeFlow ERP Frontend Vite Dev Server
|
||
After=network.target
|
||
|
||
[Service]
|
||
Type=simple
|
||
WorkingDirectory=/opt/ForgeFlow-ERP/frontend
|
||
ExecStart=/usr/bin/npm run dev -- --host 0.0.0.0 --port 5173
|
||
Restart=always
|
||
RestartSec=3
|
||
Environment=NODE_ENV=development
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
```
|
||
|
||
- [ ] **Step 3: 启动服务**
|
||
|
||
```bash
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl enable forgeflow-frontend-dev
|
||
sudo systemctl start forgeflow-frontend-dev
|
||
sudo systemctl status forgeflow-frontend-dev --no-pager
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
Active: active (running)
|
||
```
|
||
|
||
- [ ] **Step 4: 查看日志**
|
||
|
||
```bash
|
||
journalctl -u forgeflow-frontend-dev -f
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
VITE v5.x.x ready
|
||
```
|
||
|
||
---
|
||
|
||
## Phase 7: 动态加载更新流程
|
||
|
||
### Task 16: 代码更新后验证热加载
|
||
|
||
- [ ] **Step 1: 更新代码**
|
||
|
||
如果使用 Git:
|
||
|
||
```bash
|
||
cd /opt/ForgeFlow-ERP
|
||
git pull
|
||
```
|
||
|
||
如果使用 rsync,在 Mac 重新执行同步命令:
|
||
|
||
```bash
|
||
rsync -av --delete \
|
||
--exclude 'frontend/node_modules' \
|
||
--exclude 'backend/.venv' \
|
||
--exclude '.git' \
|
||
/Users/souplearn/Gitlab/py/ForgeFlow-ERP/ \
|
||
root@<腾讯云公网IP>:/opt/ForgeFlow-ERP/
|
||
```
|
||
|
||
- [ ] **Step 2: 如果只改后端 Python 代码**
|
||
|
||
Expected:
|
||
|
||
```text
|
||
uvicorn --reload 自动重载,无需手动重启
|
||
```
|
||
|
||
验证:
|
||
|
||
```bash
|
||
journalctl -u forgeflow-backend-dev -n 80 --no-pager
|
||
```
|
||
|
||
- [ ] **Step 3: 如果改前端 Vue/CSS/JS**
|
||
|
||
Expected:
|
||
|
||
```text
|
||
Vite dev server 自动热更新浏览器页面
|
||
```
|
||
|
||
验证:
|
||
|
||
```bash
|
||
journalctl -u forgeflow-frontend-dev -n 80 --no-pager
|
||
```
|
||
|
||
- [ ] **Step 4: 如果改了依赖**
|
||
|
||
后端依赖变更:
|
||
|
||
```bash
|
||
cd /opt/ForgeFlow-ERP/backend
|
||
. .venv/bin/activate
|
||
pip install -r requirements.txt
|
||
sudo systemctl restart forgeflow-backend-dev
|
||
```
|
||
|
||
前端依赖变更:
|
||
|
||
```bash
|
||
cd /opt/ForgeFlow-ERP/frontend
|
||
npm install
|
||
sudo systemctl restart forgeflow-frontend-dev
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
依赖安装成功,服务重启成功
|
||
```
|
||
|
||
---
|
||
|
||
## Phase 8: 功能验收清单
|
||
|
||
### Task 17: 登录和基础页面验收
|
||
|
||
- [ ] **Step 1: 打开登录页**
|
||
|
||
```text
|
||
http://<腾讯云公网IP>:5173/login?redirect=/
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
登录页正常渲染,浏览器控制台无 CORS 报错
|
||
```
|
||
|
||
- [ ] **Step 2: 登录 ERP**
|
||
|
||
Expected:
|
||
|
||
```text
|
||
登录成功,进入首页
|
||
```
|
||
|
||
- [ ] **Step 3: 打开浏览器开发者工具 Network**
|
||
|
||
Expected:
|
||
|
||
```text
|
||
API 请求地址是 http://<腾讯云公网IP>:8000/api/...
|
||
状态码不是 CORS error
|
||
```
|
||
|
||
### Task 18: 核心业务验收
|
||
|
||
- [ ] **Step 1: 基础资料页面**
|
||
|
||
验证:
|
||
|
||
```text
|
||
供应商名录、客户名录、原材料名录、产品需规清单能打开
|
||
```
|
||
|
||
- [ ] **Step 2: 订单与采购页面**
|
||
|
||
验证:
|
||
|
||
```text
|
||
销售订单列表、采购订单、到货入库、质量校验能打开
|
||
```
|
||
|
||
- [ ] **Step 3: 仓库页面**
|
||
|
||
验证:
|
||
|
||
```text
|
||
百华仓库六大库能打开,出入库弹窗能打开
|
||
```
|
||
|
||
- [ ] **Step 4: 生产执行页面**
|
||
|
||
验证:
|
||
|
||
```text
|
||
工单台账、工序报工能打开
|
||
```
|
||
|
||
- [ ] **Step 5: 发货概览页面**
|
||
|
||
验证:
|
||
|
||
```text
|
||
发货台账能打开
|
||
```
|
||
|
||
### Task 19: Excel 导入导出验收
|
||
|
||
- [ ] **Step 1: 测试导出**
|
||
|
||
验证:
|
||
|
||
```text
|
||
供应商名录、原材料名录、客户名录、仓库期初模板、盘库清单导出正常
|
||
```
|
||
|
||
- [ ] **Step 2: 测试导入**
|
||
|
||
验证:
|
||
|
||
```text
|
||
上传 Excel 时无 413、CORS、权限、临时目录报错
|
||
```
|
||
|
||
- [ ] **Step 3: 检查响应头**
|
||
|
||
Expected:
|
||
|
||
```text
|
||
浏览器能识别 Content-Disposition,下载文件名正常
|
||
```
|
||
|
||
说明:
|
||
|
||
```text
|
||
后端 CORS 已 expose Content-Disposition,只要 ALLOWED_ORIGINS 配对即可。
|
||
```
|
||
|
||
---
|
||
|
||
## Phase 9: 常见故障处理
|
||
|
||
### Task 20: 前端页面打不开
|
||
|
||
- [ ] **Step 1: 检查 Vite 服务**
|
||
|
||
```bash
|
||
sudo systemctl status forgeflow-frontend-dev --no-pager
|
||
journalctl -u forgeflow-frontend-dev -n 120 --no-pager
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
Active: active (running)
|
||
VITE ready
|
||
```
|
||
|
||
- [ ] **Step 2: 检查端口监听**
|
||
|
||
```bash
|
||
ss -lntp | grep 5173
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
0.0.0.0:5173
|
||
```
|
||
|
||
如果只看到 `127.0.0.1:5173`,说明没有绑定公网网卡,需要加:
|
||
|
||
```bash
|
||
npm run dev -- --host 0.0.0.0 --port 5173
|
||
```
|
||
|
||
### Task 21: 后端接口打不开
|
||
|
||
- [ ] **Step 1: 检查后端服务**
|
||
|
||
```bash
|
||
sudo systemctl status forgeflow-backend-dev --no-pager
|
||
journalctl -u forgeflow-backend-dev -n 120 --no-pager
|
||
```
|
||
|
||
- [ ] **Step 2: 检查端口监听**
|
||
|
||
```bash
|
||
ss -lntp | grep 8000
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
0.0.0.0:8000
|
||
```
|
||
|
||
- [ ] **Step 3: 本机 curl**
|
||
|
||
```bash
|
||
curl -s http://127.0.0.1:8000/api/system/health
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
本机通则进程正常;外网不通则优先查腾讯云安全组和 1Panel 防火墙。
|
||
```
|
||
|
||
### Task 22: 登录时报 CORS
|
||
|
||
- [ ] **Step 1: 确认前端访问地址**
|
||
|
||
```text
|
||
http://<腾讯云公网IP>:5173
|
||
```
|
||
|
||
- [ ] **Step 2: 确认后端 `.env`**
|
||
|
||
```bash
|
||
grep ALLOWED_ORIGINS /opt/ForgeFlow-ERP/backend/.env
|
||
```
|
||
|
||
Expected:
|
||
|
||
```env
|
||
ALLOWED_ORIGINS=http://<腾讯云公网IP>:5173
|
||
```
|
||
|
||
- [ ] **Step 3: 修改后重启后端**
|
||
|
||
```bash
|
||
sudo systemctl restart forgeflow-backend-dev
|
||
```
|
||
|
||
### Task 23: 数据库连接失败
|
||
|
||
- [ ] **Step 1: 用 mysql 客户端直连**
|
||
|
||
```bash
|
||
mysql -h 121.40.97.156 -P 3306 -u <数据库用户名> -p -e "SELECT 1;"
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
返回 1
|
||
```
|
||
|
||
- [ ] **Step 2: 如果 MySQL 客户端通,但后端 health 不通**
|
||
|
||
检查:
|
||
|
||
```bash
|
||
grep MYSQL /opt/ForgeFlow-ERP/backend/.env
|
||
journalctl -u forgeflow-backend-dev -n 120 --no-pager
|
||
```
|
||
|
||
处理方向:
|
||
|
||
```text
|
||
数据库名、账号、密码、账号 Host 权限、SQLAlchemy 连接字符串。
|
||
```
|
||
|
||
---
|
||
|
||
## Phase 10: 临时阶段转正式生产阶段
|
||
|
||
临时测试稳定后,再做以下切换。
|
||
|
||
### Task 24: 正式化前端
|
||
|
||
- [ ] **Step 1: 生产构建**
|
||
|
||
```bash
|
||
cd /opt/ForgeFlow-ERP/frontend
|
||
npm run build
|
||
```
|
||
|
||
Expected:
|
||
|
||
```text
|
||
dist/ 构建成功
|
||
```
|
||
|
||
- [ ] **Step 2: 用 1Panel OpenResty/Nginx 托管 dist**
|
||
|
||
站点根目录:
|
||
|
||
```text
|
||
/opt/ForgeFlow-ERP/frontend/dist
|
||
```
|
||
|
||
### Task 25: 正式化后端
|
||
|
||
- [ ] **Step 1: 后端改为只监听本机**
|
||
|
||
正式阶段后端不再暴露公网端口:
|
||
|
||
```text
|
||
127.0.0.1:8000
|
||
```
|
||
|
||
- [ ] **Step 2: systemd 去掉 `--reload`**
|
||
|
||
正式命令:
|
||
|
||
```bash
|
||
/opt/ForgeFlow-ERP/backend/.venv/bin/uvicorn app.main:app --host 127.0.0.1 --port 8000
|
||
```
|
||
|
||
### Task 26: 正式化反向代理
|
||
|
||
- [ ] **Step 1: 配置 OpenResty/Nginx**
|
||
|
||
核心规则:
|
||
|
||
```nginx
|
||
location /api/ {
|
||
proxy_pass http://127.0.0.1:8000/api/;
|
||
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 / {
|
||
try_files $uri $uri/ /index.html;
|
||
}
|
||
```
|
||
|
||
- [ ] **Step 2: 前端正式环境 API 改为相对路径**
|
||
|
||
```env
|
||
VITE_API_BASE_URL=/api
|
||
```
|
||
|
||
### Task 27: 正式化安全策略
|
||
|
||
- [ ] **Step 1: 关闭临时公网端口**
|
||
|
||
腾讯云安全组和服务器防火墙关闭:
|
||
|
||
```text
|
||
5173/tcp
|
||
8000/tcp
|
||
```
|
||
|
||
只保留:
|
||
|
||
```text
|
||
80/tcp
|
||
443/tcp
|
||
22/tcp
|
||
```
|
||
|
||
- [ ] **Step 2: 配置域名和 HTTPS**
|
||
|
||
```text
|
||
ERP 正式访问地址:https://<正式域名>
|
||
```
|
||
|
||
- [ ] **Step 3: 数据库账号最小权限**
|
||
|
||
正式账号只给 ERP 所需库权限:
|
||
|
||
```sql
|
||
CREATE USER 'forgeflow_erp'@'<腾讯云公网IP>' IDENTIFIED BY '<强密码>';
|
||
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, REFERENCES
|
||
ON jiaheng_erp.* TO 'forgeflow_erp'@'<腾讯云公网IP>';
|
||
FLUSH PRIVILEGES;
|
||
```
|
||
|
||
---
|
||
|
||
## Final Verification
|
||
|
||
- [ ] 腾讯云服务器能访问阿里云 MySQL。
|
||
- [ ] `http://<腾讯云公网IP>:8000/api/system/health` 返回后端和数据库正常。
|
||
- [ ] `http://<腾讯云公网IP>:5173/login?redirect=/` 能打开登录页。
|
||
- [ ] 登录后页面 API 请求没有 CORS 报错。
|
||
- [ ] Excel 导入导出正常。
|
||
- [ ] 基础资料、订单、采购、仓库、生产、发货页面都能打开。
|
||
- [ ] 修改前端代码后 Vite 能热更新。
|
||
- [ ] 修改后端代码后 Uvicorn 能自动 reload。
|
||
- [ ] 测试期结束后有明确计划关闭公网 `5173` 和 `8000`。
|
||
|
||
---
|
||
|
||
## Recommended Execution Mode
|
||
|
||
先用 `tmux` 跑通当天部署,再切 `systemd` 守护。
|
||
|
||
原因:
|
||
|
||
```text
|
||
tmux 启动最快,排错最直观;确认前后端、数据库、跨域都通后,再用 systemd 固化。
|
||
```
|
||
|
||
如果需要我来执行,建议按这个顺序:
|
||
|
||
```text
|
||
1. 先要腾讯云公网 IP、SSH 登录方式、数据库测试账号。
|
||
2. 执行 Phase 1 到 Phase 5,让系统先能访问。
|
||
3. 执行 Phase 8 做业务验收。
|
||
4. 验收没问题后执行 Phase 6,把进程挂 systemd。
|
||
5. 等测试稳定后,再执行 Phase 10 转正式生产配置。
|
||
```
|