diff --git a/README.md b/README.md index 31fe32d..968a659 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ #### 前端技术栈 - **Web端**: Vue 3.4.21 + TypeScript 5.4.2 + Vite 5.1.6 +- **管理后台**: Vue 3.4.0 + TypeScript 5.3.3 + Element Plus 2.4.4 - **移动端**: SwiftUI (iOS原生) - **UI框架**: Element Plus 2.6.1 + Tailwind CSS 3.4.1 - **状态管理**: Pinia 2.1.7 @@ -108,10 +109,10 @@ cd backend - Node.js 18+ - npm 9+ -#### 安装与启动 +#### 用户前端 (web) ```bash -# 进入新版本Web目录 -cd web-new +# 进入前端目录 +cd web # 安装依赖 npm install @@ -121,6 +122,38 @@ npm run dev # 构建生产版本 npm run build + +# 部署到服务器 +bash deploy.sh +``` + +#### 管理后台 (web-admin) +```bash +# 进入管理后台目录 +cd web-admin + +# 安装依赖 +npm install + +# 启动开发服务器 +npm run dev + +# 构建生产版本 +npm run build + +# 部署到服务器 +bash deploy.sh +``` + +### 一键部署 +```bash +# 部署所有服务(后端 + 前端 + 管理后台) +bash deploy-all.sh + +# 部署指定服务 +bash deploy-all.sh backend # 仅部署后端 +bash deploy-all.sh frontend # 仅部署前端 +bash deploy-all.sh admin # 仅部署管理后台 ``` ## 📊 核心功能模块 @@ -167,11 +200,19 @@ npm run build 4. 集成Tailwind CSS样式框架 5. 使用Pinia进行状态管理 -### API文档 -- 网关地址: http://localhost:8080 -- 用户服务: http://localhost:8081 -- AI服务: http://localhost:8082 -- 各服务健康检查: http://localhost:{port}/actuator/health +### 访问地址 + +#### 生产环境 (101.200.208.45) +- **用户前端**: http://101.200.208.45/emotion-museum/ +- **管理后台**: http://101.200.208.45/emotion-museum-admin/ +- **后端API**: http://101.200.208.45:19089/api +- **WebSocket**: ws://101.200.208.45:19089/ws + +#### 开发环境 (本地) +- **用户前端**: http://localhost:5173 +- **管理后台**: http://localhost:5174 +- **后端API**: http://localhost:19089/api +- **WebSocket**: ws://localhost:19089/ws ## 🧪 测试策略 diff --git a/conf/emotion-museum.conf b/conf/emotion-museum.conf new file mode 100644 index 0000000..1274ecf --- /dev/null +++ b/conf/emotion-museum.conf @@ -0,0 +1,117 @@ +# Emotion Museum 前端应用 Nginx 配置 +# 配置路径: /www/server/panel/vhost/nginx/emotion-museum.conf + +server { + listen 80; + server_name 101.200.208.45 localhost 127.0.0.1; + + # 前端应用路径 + location /emotion-museum/ { + alias /data/www/emotion-museum/; + + # 启用目录索引(可选) + autoindex off; + + # 处理 Vue Router 的 history 模式 + # 所有非文件请求都重定向到 index.html + try_files $uri $uri/ /emotion-museum/index.html; + + # 设置缓存策略 + # HTML 文件不缓存 + location ~ \.html?$ { + add_header Cache-Control "no-cache, no-store, must-revalidate"; + add_header Pragma "no-cache"; + add_header Expires "0"; + } + + # 静态资源缓存 1 年 + location ~ \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + add_header Cache-Control "public, max-age=31536000, immutable"; + expires 1y; + } + } + + # 处理不带末尾斜杠的 /emotion-museum 请求 + location = /emotion-museum { + rewrite ^(.*)$ $1/ permanent; + } + + # 管理后台应用路径 + location /emotion-museum-admin/ { + alias /data/www/emotion-museum-admin/; + + # 启用目录索引(可选) + autoindex off; + + # 处理 Vue Router 的 history 模式 + # 所有非文件请求都重定向到 index.html + try_files $uri $uri/ /emotion-museum-admin/index.html; + + # 设置缓存策略 + # HTML 文件不缓存 + location ~ \.html?$ { + add_header Cache-Control "no-cache, no-store, must-revalidate"; + add_header Pragma "no-cache"; + add_header Expires "0"; + } + + # 静态资源缓存 1 年 + location ~ \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + add_header Cache-Control "public, max-age=31536000, immutable"; + expires 1y; + } + } + + # 处理不带末尾斜杠的 /emotion-museum-admin 请求 + location = /emotion-museum-admin { + rewrite ^(.*)$ $1/ permanent; + } + + # 后端 API 代理 + location /api { + proxy_pass http://127.0.0.1:19089; + 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; + + # 超时设置 + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } + + # WebSocket 代理 + location /ws { + proxy_pass http://127.0.0.1:19089; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + 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; + + # WebSocket 超时设置 + proxy_connect_timeout 7d; + proxy_send_timeout 7d; + proxy_read_timeout 7d; + } + + # 健康检查端点 + location /health { + access_log off; + return 200 "healthy\n"; + add_header Content-Type text/plain; + } + + # 禁止访问敏感文件 + location ~ /\. { + deny all; + access_log off; + log_not_found off; + } + + access_log /www/wwwlogs/access.log; +} + diff --git a/deploy-all.sh b/deploy-all.sh index 40ea2cc..216a509 100755 --- a/deploy-all.sh +++ b/deploy-all.sh @@ -1,8 +1,8 @@ #!/bin/bash # 情绪博物馆 - 一键式部署脚本 -# 同时部署后端和前端到远程服务器 101.200.208.45 -# 使用方法: bash deploy-all.sh [backend|frontend|all] +# 同时部署后端、前端和管理后台到远程服务器 101.200.208.45 +# 使用方法: bash deploy-all.sh [backend|frontend|admin|all] # 默认部署所有服务 set -e @@ -43,9 +43,9 @@ cd "$SCRIPT_DIR" DEPLOY_TYPE="${1:-all}" # 验证部署类型 -if [[ ! "$DEPLOY_TYPE" =~ ^(backend|frontend|all)$ ]]; then +if [[ ! "$DEPLOY_TYPE" =~ ^(backend|frontend|admin|all)$ ]]; then log_error "无效的部署类型: $DEPLOY_TYPE" - echo "使用方法: bash deploy-all.sh [backend|frontend|all]" + echo "使用方法: bash deploy-all.sh [backend|frontend|admin|all]" exit 1 fi @@ -102,6 +102,31 @@ deploy_frontend() { fi } +# ============================================================================ +# 部署管理后台 +# ============================================================================ +deploy_admin() { + log_section "开始部署管理后台" + + if [ ! -f "web-admin/deploy.sh" ]; then + log_error "管理后台部署脚本不存在: web-admin/deploy.sh" + return 1 + fi + + log_info "执行管理后台部署脚本..." + cd web-admin + + if bash deploy.sh; then + log_info "✅ 管理后台部署成功" + cd .. + return 0 + else + log_error "❌ 管理后台部署失败" + cd .. + return 1 + fi +} + # ============================================================================ # 主程序 # ============================================================================ @@ -112,6 +137,7 @@ log_info "部署时间: $(date '+%Y-%m-%d %H:%M:%S')" BACKEND_SUCCESS=true FRONTEND_SUCCESS=true +ADMIN_SUCCESS=true # 执行部署 case "$DEPLOY_TYPE" in @@ -125,6 +151,11 @@ case "$DEPLOY_TYPE" in FRONTEND_SUCCESS=false fi ;; + admin) + if ! deploy_admin; then + ADMIN_SUCCESS=false + fi + ;; all) if ! deploy_backend; then BACKEND_SUCCESS=false @@ -133,6 +164,10 @@ case "$DEPLOY_TYPE" in if ! deploy_frontend; then FRONTEND_SUCCESS=false fi + + if ! deploy_admin; then + ADMIN_SUCCESS=false + fi ;; esac @@ -161,26 +196,53 @@ if [ "$DEPLOY_TYPE" = "frontend" ] || [ "$DEPLOY_TYPE" = "all" ]; then fi fi +if [ "$DEPLOY_TYPE" = "admin" ] || [ "$DEPLOY_TYPE" = "all" ]; then + if [ "$ADMIN_SUCCESS" = true ]; then + log_info "✅ 管理后台部署: 成功" + else + log_error "❌ 管理后台部署: 失败" + fi +fi + log_info "部署耗时: ${DURATION}秒" # ============================================================================ # 访问信息 # ============================================================================ -if [ "$BACKEND_SUCCESS" = true ] && [ "$FRONTEND_SUCCESS" = true ]; then +# 检查部署结果 +ALL_SUCCESS=true +if [ "$DEPLOY_TYPE" = "all" ]; then + if [ "$BACKEND_SUCCESS" = false ] || [ "$FRONTEND_SUCCESS" = false ] || [ "$ADMIN_SUCCESS" = false ]; then + ALL_SUCCESS=false + fi +elif [ "$DEPLOY_TYPE" = "backend" ] && [ "$BACKEND_SUCCESS" = false ]; then + ALL_SUCCESS=false +elif [ "$DEPLOY_TYPE" = "frontend" ] && [ "$FRONTEND_SUCCESS" = false ]; then + ALL_SUCCESS=false +elif [ "$DEPLOY_TYPE" = "admin" ] && [ "$ADMIN_SUCCESS" = false ]; then + ALL_SUCCESS=false +fi + +if [ "$ALL_SUCCESS" = true ]; then echo "" log_section "部署成功!" - log_info "📱 前端访问地址: http://101.200.208.45/emotion-museum/" - log_info "🔌 后端API地址: http://101.200.208.45:19089/api" - log_info "📊 WebSocket地址: ws://101.200.208.45:19089/ws" + + if [ "$DEPLOY_TYPE" = "backend" ] || [ "$DEPLOY_TYPE" = "all" ]; then + log_info "🔌 后端API地址: http://101.200.208.45:19089/api" + log_info "📊 WebSocket地址: ws://101.200.208.45:19089/ws" + fi + + if [ "$DEPLOY_TYPE" = "frontend" ] || [ "$DEPLOY_TYPE" = "all" ]; then + log_info "📱 前端访问地址: http://101.200.208.45/emotion-museum/" + fi + + if [ "$DEPLOY_TYPE" = "admin" ] || [ "$DEPLOY_TYPE" = "all" ]; then + log_info "🔧 管理后台地址: http://101.200.208.45/emotion-museum-admin/" + fi + echo "" exit 0 -elif [ "$BACKEND_SUCCESS" = true ]; then - log_warn "⚠️ 后端部署成功,前端部署失败" - exit 1 -elif [ "$FRONTEND_SUCCESS" = true ]; then - log_warn "⚠️ 前端部署成功,后端部署失败" - exit 1 else log_error "❌ 部署失败" exit 1 diff --git a/web-admin/deploy.sh b/web-admin/deploy.sh new file mode 100755 index 0000000..5cb5d00 --- /dev/null +++ b/web-admin/deploy.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# 部署脚本 - 将构建好的管理后台文件上传到服务器 +# 使用方法: ./deploy.sh + +SERVER_IP="101.200.208.45" +USERNAME="root" +REMOTE_PATH="/data/www/emotion-museum-admin" + +echo "开始部署管理后台应用到服务器..." + +# 检查是否安装了npm +if ! command -v npm &> /dev/null; then + echo "❌ 错误: 未找到npm命令,请先安装Node.js" + exit 1 +fi + +# 执行构建(无论dist目录是否存在,都必须构建) +echo "📦 开始构建管理后台项目..." +if npm run build; then + echo "✅ 管理后台项目构建成功" +else + echo "❌ 管理后台项目构建失败,请检查代码" + exit 1 +fi + +# 验证dist目录是否存在 +if [ ! -d "dist" ]; then + echo "❌ 错误: 构建后dist目录仍不存在,请检查构建配置" + exit 1 +fi + +# 检查是否安装了scp命令 +if ! command -v scp &> /dev/null; then + echo "❌ 错误: 未找到scp命令,请安装OpenSSH客户端" + exit 1 +fi + +echo "正在上传文件到服务器 $SERVER_IP..." + +# 创建远程目录(如果不存在) +echo "📁 创建远程目录..." +ssh "${USERNAME}@${SERVER_IP}" "mkdir -p ${REMOTE_PATH}" + +# 上传所有文件到服务器 +echo "📤 上传文件到服务器..." +if scp dist/index.html "${USERNAME}@${SERVER_IP}:${REMOTE_PATH}/" && \ + scp -r dist/assets "${USERNAME}@${SERVER_IP}:${REMOTE_PATH}/"; then + + # 设置文件权限 + echo "🔐 设置文件权限..." + ssh "${USERNAME}@${SERVER_IP}" "chmod -R 755 ${REMOTE_PATH}" + + echo "✅ 管理后台部署完成!" + echo "📱 访问地址: http://$SERVER_IP/emotion-museum-admin/" + echo "🔧 管理后台功能: AI配置管理、用户管理、数据统计等" + +else + echo "❌ 部署失败,请检查:" + echo "1. 服务器IP地址是否正确" + echo "2. SSH密钥是否配置正确" + echo "3. 服务器目录权限是否正确" + exit 1 +fi \ No newline at end of file diff --git a/web-admin/src/layouts/Layout.vue b/web-admin/src/layouts/Layout.vue index 91642cc..2ac3a53 100644 --- a/web-admin/src/layouts/Layout.vue +++ b/web-admin/src/layouts/Layout.vue @@ -77,13 +77,13 @@