#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 管理后台部署脚本 - 将构建好的管理后台文件上传到服务器 使用方法: python deploy.py """ import os import sys import shutil import subprocess from pathlib import Path # 配置变量 SERVER_IP = "101.200.208.45" USERNAME = "root" REMOTE_PATH = "/data/www/emotion-museum-admin" # 本地路径 SCRIPT_DIR = Path(__file__).parent.absolute() DIST_DIR = SCRIPT_DIR / "dist" class Colors: """终端颜色""" GREEN = '\033[32m' RED = '\033[31m' YELLOW = '\033[33m' RESET = '\033[0m' def log_info(msg): """打印信息日志""" print(f"{Colors.GREEN}✅{Colors.RESET} {msg}") def log_error(msg): """打印错误日志""" print(f"{Colors.RED}❌{Colors.RESET} {msg}") def log_step(msg): """打印步骤日志""" print(f"📦 {msg}") def run_command(cmd, cwd=None, shell=True, capture=True): """执行本地命令""" try: if capture: result = subprocess.run(cmd, cwd=cwd, shell=shell, capture_output=True, text=True) return result.returncode == 0, result.stdout, result.stderr else: result = subprocess.run(cmd, cwd=cwd, shell=shell) return result.returncode == 0, "", "" except Exception as e: return False, "", str(e) def check_npm(): """检查npm是否安装""" success, _, _ = run_command("npm --version") if not success: log_error("错误: 未找到npm命令,请先安装Node.js") sys.exit(1) def check_scp(): """检查scp是否可用""" success, _, _ = run_command("scp -V 2>&1 || echo ok") # scp通常没有--version,但命令存在即可 return True def clean_dist(): """清理旧的构建文件""" log_step("🧹 清理旧的构建文件...") if DIST_DIR.exists(): shutil.rmtree(DIST_DIR) def build_project(): """构建项目""" log_step("开始构建管理后台项目(生产环境)...") os.chdir(SCRIPT_DIR) # 设置环境变量并执行构建 env = os.environ.copy() env["NODE_ENV"] = "production" try: result = subprocess.run( "npm run build", shell=True, cwd=SCRIPT_DIR, env=env ) if result.returncode != 0: log_error("管理后台项目构建失败,请检查代码") sys.exit(1) except Exception as e: log_error(f"构建失败: {e}") sys.exit(1) log_info("管理后台项目构建成功") def verify_dist(): """验证dist目录是否存在""" if not DIST_DIR.exists(): log_error("错误: 构建后dist目录仍不存在,请检查构建配置") sys.exit(1) # 检查关键文件 index_file = DIST_DIR / "index.html" assets_dir = DIST_DIR / "assets" if not index_file.exists(): log_error("错误: dist/index.html 不存在") sys.exit(1) if not assets_dir.exists(): log_error("错误: dist/assets 目录不存在") sys.exit(1) def create_remote_dir(): """创建远程目录""" log_step("📁 创建远程目录...") cmd = f'ssh {USERNAME}@{SERVER_IP} "mkdir -p {REMOTE_PATH}"' success, _, stderr = run_command(cmd) if not success: log_error(f"创建远程目录失败: {stderr}") sys.exit(1) def upload_files(): """上传文件到服务器""" log_step("📤 上传文件到服务器...") print(f"正在上传文件到服务器 {SERVER_IP}...") # 上传 index.html index_file = DIST_DIR / "index.html" cmd1 = f'scp "{index_file}" {USERNAME}@{SERVER_IP}:{REMOTE_PATH}/' success1, _, stderr1 = run_command(cmd1) if not success1: log_error(f"上传 index.html 失败: {stderr1}") return False # 上传 assets 目录 assets_dir = DIST_DIR / "assets" cmd2 = f'scp -r "{assets_dir}" {USERNAME}@{SERVER_IP}:{REMOTE_PATH}/' success2, _, stderr2 = run_command(cmd2) if not success2: log_error(f"上传 assets 目录失败: {stderr2}") return False return True def set_permissions(): """设置文件权限""" log_step("🔐 设置文件权限...") cmd = f'ssh {USERNAME}@{SERVER_IP} "chmod -R 755 {REMOTE_PATH}"' success, _, stderr = run_command(cmd) if not success: log_error(f"设置权限失败: {stderr}") def deploy(): """执行部署""" print("开始部署管理后台应用到服务器...") # 检查npm check_npm() # 清理旧构建 clean_dist() # 构建项目 build_project() # 验证构建结果 verify_dist() # 创建远程目录 create_remote_dir() # 上传文件 if upload_files(): # 设置权限 set_permissions() log_info("管理后台部署完成!") print(f"📱 访问地址: http://{SERVER_IP}/emotion-museum-admin/") print("🔧 管理后台功能: AI配置管理、用户管理、数据统计等") else: log_error("部署失败,请检查:") print("1. 服务器IP地址是否正确") print("2. SSH密钥是否配置正确") print("3. 服务器目录权限是否正确") sys.exit(1) def main(): """主函数""" deploy() if __name__ == "__main__": main()