From 2df57fb5d5d3e4a593712f6dce680ae2933fe803 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 27 Feb 2026 18:39:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E9=83=A8=E7=BD=B2?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=92=8C=E5=8F=91=E5=B8=83=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复前端 TypeScript 编译错误 - 更新部署文档(前端本地构建,后端 Git 部署) - 新增服务器端部署脚本 - 优化部署流程 Co-Authored-By: Claude Opus 4.6 --- deploy/deploy-1panel.sh | 48 +- deploy/server-deploy.sh | 89 ++++ docs/DEPLOY_ONLINE_GUIDE.md | 410 ++++++------------ .../modules/approval/hooks/useApprovalList.ts | 2 +- frontend/src/modules/approval/index.ts | 2 +- .../src/modules/approval/services/approval.ts | 2 +- 6 files changed, 253 insertions(+), 300 deletions(-) create mode 100644 deploy/server-deploy.sh diff --git a/deploy/deploy-1panel.sh b/deploy/deploy-1panel.sh index 3bc40c5..e9c8216 100755 --- a/deploy/deploy-1panel.sh +++ b/deploy/deploy-1panel.sh @@ -1,6 +1,6 @@ #!/bin/bash # uniservice-mobile.hnxinyouhe.com 部署脚本 -# 使用方法: ./deploy-1panel.sh [server] +# 使用方法: ./deploy/deploy-1panel.sh [server] set -e @@ -54,7 +54,7 @@ check_env() { fi if [ ! -d "$FRONTEND_BUILD_DIR" ]; then - log_error "❌ 前端构建目录不存在: $FRONTEND_BUILD_DIR" + log_error "前端构建目录不存在: $FRONTEND_BUILD_DIR" echo "" log_info "请先在本地构建前端:" echo " cd frontend" @@ -64,7 +64,7 @@ check_env() { exit 1 fi - log_info "✓ 环境检查通过" + log_info "环境检查通过" } # ============================================ @@ -74,15 +74,15 @@ verify_frontend() { log_step "验证前端构建..." if [ ! -f "$FRONTEND_BUILD_DIR/index.html" ]; then - log_error "❌ 前端构建不完整,缺少 index.html" + log_error "前端构建不完整,缺少 index.html" exit 1 fi if [ ! -d "$FRONTEND_BUILD_DIR/assets" ]; then - log_warn "⚠️ 未找到 assets 目录,可能是构建失败" + log_warn "未找到 assets 目录,可能是构建失败" fi - log_info "✓ 前端构建验证通过" + log_info "前端构建验证通过" echo " - index.html: 存在" echo " - 构建时间: $(ls -lt $FRONTEND_BUILD_DIR/index.html | head -1 | awk '{print $6, $7, $8}')" } @@ -102,7 +102,7 @@ deploy_frontend() { ${FRONTEND_BUILD_DIR}/ \ ${DEPLOY_USER}@${SERVER}:${REMOTE_ROOT}/ - log_info "✓ 前端部署完成" + log_info "前端部署完成" } # ============================================ @@ -127,7 +127,7 @@ deploy_backend() { ${BACKEND_SOURCE_DIR}/ \ ${DEPLOY_USER}@${SERVER}:${REMOTE_BACKEND_DIR}/ - log_info "✓ 后端部署完成" + log_info "后端代码部署完成" } # ============================================ @@ -137,33 +137,34 @@ restart_backend() { log_step "重启后端容器..." ssh ${DEPLOY_USER}@${SERVER} << 'EOF' - echo "正在检查后端目录..." + set -e + echo "正在检查部署目录..." cd /opt/x-server-mobile - if [ ! -f "deploy/docker-compose.prod.yml" ]; then - echo "❌ docker-compose.prod.yml 不存在" - echo " 请先上传部署配置文件" + if [ ! -f "docker-compose.prod.yml" ]; then + echo "docker-compose.prod.yml 不存在" + echo "请先上传部署配置文件" exit 1 fi echo "停止旧容器..." - docker-compose -f deploy/docker-compose.prod.yml down 2>/dev/null || true + docker-compose -f docker-compose.prod.yml down 2>/dev/null || true echo "启动新容器..." - docker-compose -f deploy/docker-compose.prod.yml up -d + docker-compose -f docker-compose.prod.yml up -d echo "" echo "容器状态:" - docker ps | grep x-server + docker ps | grep x-server || echo "未找到运行中的容器" echo "" - echo "✓ 后端容器重启完成" + echo "后端容器重启完成" EOF if [ $? -eq 0 ]; then - log_info "✓ 后端容器重启成功" + log_info "后端容器重启成功" else - log_error "✗ 后端容器重启失败" + log_error "后端容器重启失败" exit 1 fi } @@ -175,12 +176,11 @@ show_deployment_info() { echo "" log_step "部署信息" echo "" - echo "🌐 访问地址: https://uniservice-mobile.hnxinyouhe.com" + echo "访问地址: https://uniservice-mobile.hnxinyouhe.com" echo "" - echo "📁 前端目录: ${REMOTE_ROOT}" - echo "📁 后端目录: ${REMOTE_BACKEND_DIR}" - echo "" - echo "📊 后端容器: x-server-backend-prod (端口 8787)" + echo "前端目录: ${REMOTE_ROOT}" + echo "后端目录: ${REMOTE_BACKEND_DIR}" + echo "后端容器: x-server-backend-prod (端口 8787)" echo "" } @@ -192,7 +192,7 @@ main() { echo " uniservice-mobile 部署脚本" echo "==========================================" echo "" - echo "📍 目标服务器: ${SERVER}" + echo "目标服务器: ${SERVER}" echo "" # 检查环境 diff --git a/deploy/server-deploy.sh b/deploy/server-deploy.sh new file mode 100644 index 0000000..65a65d7 --- /dev/null +++ b/deploy/server-deploy.sh @@ -0,0 +1,89 @@ +#!/bin/bash +# X-Server Mobile 后端部署脚本(服务器端) +# 使用方法: cd /opt/x-server-mobile && ./deploy.sh + +set -e + +# 颜色输出 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +log_step() { + echo -e "${BLUE}==>${NC} $1" +} + +# 项目目录 +PROJECT_DIR="/opt/x-server-mobile" +cd "$PROJECT_DIR" + +echo "==========================================" +echo " X-Server Mobile 后端部署" +echo "==========================================" +echo "" +echo "项目目录: $PROJECT_DIR" +echo "" + +# ============================================ +# 1. 拉取最新代码 +# ============================================ +log_step "拉取最新代码..." + +# 获取当前分支名 +CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) + +# 拉取最新代码 +git fetch origin +git reset --hard "origin/${CURRENT_BRANCH}" + +log_info "代码已更新" + +# ============================================ +# 2. 重启后端容器 +# ============================================ +log_step "重启后端容器..." + +if [ ! -f "docker-compose.prod.yml" ]; then + log_error "docker-compose.prod.yml 不存在" + exit 1 +fi + +# 重启容器 +docker-compose -f docker-compose.prod.yml down 2>/dev/null || true +docker-compose -f docker-compose.prod.yml up -d + +log_info "后端容器已重启" + +# ============================================ +# 3. 显示容器状态 +# ============================================ +echo "" +log_step "容器状态" +echo "" +docker ps | grep x-server || log_warn "未找到运行中的容器" +echo "" + +# ============================================ +# 4. 完成 +# ============================================ +log_info "后端部署完成!" +echo "" +echo "访问地址: https://uniservice-mobile.hnxinyouhe.com" +echo "" +echo "查看后端日志:" +echo " docker logs -f x-server-backend-prod" +echo "" diff --git a/docs/DEPLOY_ONLINE_GUIDE.md b/docs/DEPLOY_ONLINE_GUIDE.md index 0f6a79d..893d031 100644 --- a/docs/DEPLOY_ONLINE_GUIDE.md +++ b/docs/DEPLOY_ONLINE_GUIDE.md @@ -5,140 +5,170 @@ | 项目 | 值 | |------|-----| | **域名** | uniservice-mobile.hnxinyouhe.com | -| **网站根目录** | /www/sites/uniservice-mobile.hnxinyouhe.com/index | -| **后端端口** | 8787 | +| **前端目录** | /www/sites/uniservice-mobile.hnxinyouhe.com/index | +| **后端目录** | /opt/x-server-mobile | +| **后端容器** | x-server-backend-prod (端口 8787) | | **MySQL 容器** | 1Panel-mysql-XyxS | | **Redis 容器** | 1Panel-redis-pxdb | | **Docker 网络** | 1panel-network | --- -## 部署架构说明 +## 部署架构 -**重要:前后端分离部署** - -| 组件 | 部署位置 | 部署方式 | -|------|---------|---------| -| **前端** | 1Panel 静态站点 | 本地打包 → 上传静态文件 | -| **后端** | Docker 容器 | 上传代码 → 容器运行 | - -### 为什么前端要本地打包? - -1. **服务器不需要 Node.js** - 只需 Nginx 托管静态文件 -2. **打包速度快** - 本地开发机性能通常更好 -3. **节省服务器资源** - 不占用服务器 CPU/内存编译 -4. **避免环境问题** - 本地打包更稳定可靠 +| 组件 | 部署方式 | +|------|---------| +| **前端** | 本地构建 → 上传静态文件 | +| **后端** | Git 拉取 → Docker 重启 | --- -## 部署目录结构 +## 快速部署 -``` -线上服务器: +### 方式一:自动部署脚本(推荐) -/www/sites/uniservice-mobile.hnxinyouhe.com/ -├── index/ ← 前端静态文件(本地打包后上传) -│ ├── index.html -│ ├── assets/ -│ └── ... -├── log/ ← 访问日志 -│ ├── access.log -│ └── error.log -└── ssl/ ← SSL 证书(1Panel 管理) - ├── fullchain.pem - └── privkey.pem - -/opt/x-server-mobile/ ← 后端部署目录 -├── backend/ ← 后端代码 -│ ├── app/ -│ ├── vendor/ -│ └── ... -├── deploy/ ← 部署配置文件 -│ ├── docker-compose.prod.yml -│ ├── .env.production -│ ├── nginx-1panel.conf -│ └── deploy-1panel.sh -└── logs/ ← 后端日志 - └── backend/ -``` - ---- - -## 快速部署步骤 - -### 第一步:本地打包前端(开发机执行) +**本地执行**(前端+后端一起部署): ```bash -# 在开发机本地执行 +# 1. 本地构建前端 cd /www/x-server-mobile/frontend - -# 安装依赖(首次或依赖变化时) -npm install - -# 构建生产版本 npm run build -# 构建完成后,静态文件在 frontend/dist/ 目录 -ls frontend/dist/ -# 输出: index.html, assets/, ... +# 2. 执行部署脚本 +cd .. +./deploy/deploy-1panel.sh your-server-ip ``` -### 第二步:上传到服务器 +脚本会自动: +- 上传前端静态文件到 1Panel 静态站点 +- 上传后端代码到服务器 +- 重启后端 Docker 容器 + +### 方式二:手动部署 + +#### 前端部署(本地) ```bash -# 上传前端静态文件到服务器 -rsync -avz --delete frontend/dist/* root@your-server:/www/sites/uniservice-mobile.hnxinyouhe.com/index/ +# 本地构建 +cd /www/x-server-mobile/frontend +npm run build -# 或使用 scp -scp -r frontend/dist/* root@your-server:/www/sites/uniservice-mobile.hnxinyouhe.com/index/ +# 上传静态文件 +rsync -avz --delete \ + frontend/dist/ \ + root@your-server:/www/sites/uniservice-mobile.hnxinyouhe.com/index/ ``` -### 第三步:上传后端代码 +#### 后端部署(服务器) ```bash -# 上传后端代码到服务器 -rsync -avz --exclude='vendor' --exclude='runtime' backend/ root@your-server:/opt/x-server-mobile/backend/ -``` - -### 第四步:配置 1Panel Nginx - -在 1Panel 面板中配置反向代理(详见下方 Nginx 配置章节) - -### 第五步:启动后端容器 - -```bash -# 在服务器上执行 +# 登录服务器 ssh root@your-server cd /opt/x-server-mobile -# 确保配置文件已上传 -ls deploy/docker-compose.prod.yml -ls deploy/.env.production +# 拉取代码 +git pull -# 启动后端容器 -docker-compose -f deploy/docker-compose.prod.yml up -d +# 重启容器 +docker-compose -f docker-compose.prod.yml down +docker-compose -f docker-compose.prod.yml up -d +``` -# 查看容器状态 +--- + +## 服务器端部署脚本 + +在服务器上创建 `/opt/x-server-mobile/deploy.sh`: + +```bash +#!/bin/bash +cd /opt/x-server-mobile +git pull +docker-compose -f docker-compose.prod.yml down +docker-compose -f docker-compose.prod.yml up -d docker ps | grep x-server -docker logs -f x-server-backend-prod +``` + +使用: + +```bash +ssh root@your-server +cd /opt/x-server-mobile +chmod +x deploy.sh +./deploy.sh +``` + +--- + +## 首次部署 + +### 1. 服务器准备 + +```bash +ssh root@your-server + +# 创建项目目录 +mkdir -p /opt/x-server-mobile +cd /opt/x-server-mobile + +# 克隆代码 +git clone . + +# 上传部署配置 +# (在本地执行) +scp deploy/docker-compose.prod.yml root@your-server:/opt/x-server-mobile/ +scp deploy/.env.production root@your-server:/opt/x-server-mobile/ +``` + +### 2. 配置环境变量 + +```bash +ssh root@your-server +vi /opt/x-server-mobile/.env.production +``` + +填写飞书配置: + +```env +FEISHU_APP_ID=cli_axxxxxxxxxxxx +FEISHU_APP_SECRET=xxxxxxxxxxxxxxxxxxxx +FEISHU_ENCRYPT_KEY=xxxxxxxxxxxxxxxxxxxx +FEISHU_VERIFICATION_TOKEN=xxxxxxxxxxxxxxxxxxxx +``` + +### 3. 启动后端容器 + +```bash +ssh root@your-server +cd /opt/x-server-mobile +docker-compose -f docker-compose.prod.yml up -d +docker ps | grep x-server +``` + +### 4. 配置 1Panel 静态站点 + +1. 在 1Panel 面板创建静态网站 +2. 根目录: `/www/sites/uniservice-mobile.hnxinyouhe.com/index` +3. 添加 Nginx 反向代理(见下方配置) + +### 5. 上传前端 + +```bash +cd /www/x-server-mobile/frontend +npm run build +rsync -avz --delete \ + frontend/dist/ \ + root@your-server:/www/sites/uniservice-mobile.hnxinyouhe.com/index/ ``` --- ## 1Panel Nginx 配置 -### 配置位置 -1Panel 面板 → 网站 → 找到 `uniservice-mobile.hnxinyouhe.com` → 配置文件 - -### 需要添加的反向代理规则 - -将以下内容添加到现有的 `server {}` 配置块中(在 `root` 指令之前): +在 1Panel 面板(网站设置 → 配置文件)添加反向代理: ```nginx -# ============================================ -# 后端 API 反向代理 -# ============================================ - +# 后端 API location /api/ { proxy_pass http://127.0.0.1:8787; proxy_http_version 1.1; @@ -146,16 +176,9 @@ location /api/ { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $host; - - proxy_connect_timeout 60s; - proxy_send_timeout 60s; - proxy_read_timeout 60s; } -# ============================================ -# 飞书登录回调(必须在 API 之前匹配) -# ============================================ - +# 飞书登录回调 location /login { proxy_pass http://127.0.0.1:8787; proxy_http_version 1.1; @@ -192,200 +215,41 @@ location /feishu/card/callback { proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $host; } - -# ============================================ -# 静态资源缓存(可选,提升性能) -# ============================================ - -location ~* \.(js|css|png|jpg|jpeg|gif|webp|svg|ico|woff|woff2|ttf|eot)$ { - root /www/sites/uniservice-mobile.hnxinyouhe.com/index; - expires 7d; - add_header Cache-Control "public, immutable"; - access_log off; -} ``` -### 配置说明 - -| 路径 | 说明 | -|------|------| -| `/api/*` | 后端 API 接口,代理到 8787 端口 | -| `/login/*` | 飞书登录回调,代理到后端 | -| `/feishu/card/callback` | 飞书卡片回调,代理到后端 | -| 静态资源 | js/css/images 等,缓存 7 天(可选) | -| 根路径 `/` | SPA 路由,返回 index.html | - -**重要**: -- 反向代理规则要放在 `root` 指令**之前** -- 静态资源缓存规则要放在反向代理之前(优先匹配) - ---- - -## 环境变量配置 - -### 飞书配置(必须配置) - -编辑 `deploy/.env.production`,填写飞书应用配置: - -```env -# 飞书配置(必须配置) -FEISHU_APP_ID=cli_axxxxxxxxxxxx -FEISHU_APP_SECRET=xxxxxxxxxxxxxxxxxxxx -FEISHU_ENCRYPT_KEY=xxxxxxxxxxxxxxxxxxxx -FEISHU_VERIFICATION_TOKEN=xxxxxxxxxxxxxxxxxxxx -``` - -### 数据库和 Redis 配置 - -已预先配置好线上环境,无需修改: - -```env -# 数据库(已配置) -DB_HOST=1Panel-mysql-XyxS -DB_PORT=3306 -DB_DATABASE=xserver -DB_USERNAME=xserver -DB_PASSWORD=NsNBSQm4b2b7SzhR - -# Redis(已配置) -REDIS_HOST=1Panel-redis-pxdb -REDIS_PORT=6379 -REDIS_PASSWORD=redis_FTzdM6 -``` - ---- - -## 使用部署脚本(可选) - -如需自动化部署,可以使用部署脚本: - -```bash -./deploy/deploy-1panel.sh your-server-ip -``` - -脚本功能: -- 自动上传前端静态文件 -- 自动上传后端代码 -- 自动重启后端容器 - -**注意**:使用脚本前需要先在本地执行 `npm run build` 打包前端。 - --- ## 部署验证 -### 1. 检查前端 - ```bash -# 检查首页是否可访问 +# 检查前端 curl -I https://uniservice-mobile.hnxinyouhe.com -# 应该返回 200 OK -``` - -### 2. 检查 API - -```bash -# 检查 API 是否正常(需要有效的 token) -curl https://uniservice-mobile.hnxinyouhe.com/api/v1/user/info \ - -H "Authorization: Bearer YOUR_TOKEN" -``` - -### 3. 检查后端容器 - -```bash +# 检查后端容器 ssh root@your-server docker ps | grep x-server -# 应该看到 x-server-backend-prod 容器 - docker logs -f x-server-backend-prod -# 查看后端日志 -``` - -### 4. 检查 Nginx 日志 - -```bash -# 在 1Panel 面板中查看 -# 或者直接查看日志文件 -tail -f /www/sites/uniservice-mobile.hnxinyouhe.com/log/access.log ``` --- ## 常见问题 -### Q1: 前端显示但 API 调用 404? -**A**: 检查 1Panel Nginx 配置中是否添加了 `/api/` 的反向代理规则。 - -### Q2: 后端容器启动失败? -**A**: 检查: -- 数据库和 Redis 容器是否运行 -- Docker 网络 `1panel-network` 是否存在 -- 容器日志:`docker logs x-server-backend-prod` - -### Q3: 飞书登录失败? -**A**: 检查 `/login/*` 的反向代理规则是否已添加。 - -### Q4: 静态资源加载 404? -**A**: 确认前端上传到了正确的目录:`/www/sites/uniservice-mobile.hnxinyouhe.com/index/` - -### Q5: 前端页面空白? -**A**: 检查: -- 确认前端打包成功:`ls frontend/dist/` 是否有 `index.html` -- 检查浏览器控制台是否有错误 - ---- - -## 开发环境 vs 生产环境 - -| 项目 | 开发环境 | 生产环境 | -|------|---------|---------| -| **前端** | `npm run dev` (Vite 开发服务器) | `npm run build` + 上传静态文件 | -| **后端** | `docker-compose.yml` | `deploy/docker-compose.prod.yml` | -| **API 地址** | `http://localhost:8787/api/v1` | `/api/v1` (相对路径) | -| **数据** | 本地数据库或开发数据库 | 线上数据库 | - ---- - -## 回滚操作 - -### 前端回滚 - -```bash -# 从之前的备份恢复 -ssh root@your-server -cp -r /www/sites/uniservice-mobile.hnxinyouhe.com/backup/YYYYMMDD_HHMMSS/* \ - /www/sites/uniservice-mobile.hnxinyouhe.com/index/ -``` - -### 后端回滚 - -```bash -ssh root@your-server -cd /opt/x-server-mobile - -# 切换到之前的提交 -git log --oneline -git checkout - -# 重新构建并启动 -docker-compose -f deploy/docker-compose.prod.yml up -d --build -``` +| 问题 | 解决方案 | +|------|---------| +| API 404 | 检查 Nginx 反向代理配置 | +| 容器启动失败 | 检查数据库/Redis 容器状态,查看日志 | +| 飙书登录失败 | 检查 `/login/*` 反向代理配置 | +| 静态资源 404 | 确认前端上传到正确目录 | --- ## 文件清单 -部署相关的所有文件: - | 文件 | 用途 | |------|------| -| `deploy/docker-compose.prod.yml` | 线上后端容器配置 | -| `deploy/.env.production` | 线上环境变量 | +| `deploy/docker-compose.prod.yml` | 生产环境 Docker Compose | +| `deploy/.env.production` | 生产环境变量 | | `deploy/nginx-1panel.conf` | Nginx 配置参考 | -| `deploy/deploy-1panel.sh` | 自动部署脚本 | -| `docs/DEPLOY_ONLINE_GUIDE.md` | 本文档 | - -**注意**: -- 开发环境配置(`docker-compose.yml`)与线上环境完全分离 -- 部署文件都在 `deploy/` 目录,不会影响开发环境配置 +| `deploy/deploy-1panel.sh` | 本端部署脚本 | +| `deploy/server-deploy.sh` | 服务器端部署脚本 | diff --git a/frontend/src/modules/approval/hooks/useApprovalList.ts b/frontend/src/modules/approval/hooks/useApprovalList.ts index c1521ce..e9ab7bf 100644 --- a/frontend/src/modules/approval/hooks/useApprovalList.ts +++ b/frontend/src/modules/approval/hooks/useApprovalList.ts @@ -1,5 +1,5 @@ import { useQuery } from '@tanstack/react-query' -import { getApprovalList } from '../services' +import { getApprovalList } from '../services/approval' import type { ApprovalListParams } from '../types' export function useApprovalList(params: ApprovalListParams = {}) { diff --git a/frontend/src/modules/approval/index.ts b/frontend/src/modules/approval/index.ts index 145e534..269ab57 100644 --- a/frontend/src/modules/approval/index.ts +++ b/frontend/src/modules/approval/index.ts @@ -4,7 +4,7 @@ export type { ApprovalNode, Approver, - ApprovalFlow, + ApprovalFlow as ApprovalFlowType, ApprovalOrder, Attachment, ApprovalTimeline, diff --git a/frontend/src/modules/approval/services/approval.ts b/frontend/src/modules/approval/services/approval.ts index 75b4b1b..c9e6608 100644 --- a/frontend/src/modules/approval/services/approval.ts +++ b/frontend/src/modules/approval/services/approval.ts @@ -1,4 +1,4 @@ -import { api } from '@/services/api' +import api from '@/services/api' import type { ApprovalOrder, ApprovalFlow,