#!/usr/bin/env bash set -euo pipefail REMOTE_IP="192.168.11.79" REMOTE_USER="dieya" REMOTE_DIR="/home/dieya/.openclaw/workspace/dy-dashboard" LOCAL_DIR="/home/gxd/.openclaw/workspace/dy-dashboard" VAULT_DIR="/home/gxd/蝶雅供应链" DB_USER="dy_app" DB_PASS="dy_data_2026" DB_NAME="dy_data" RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m' info() { echo -e "${CYAN}[INFO]${NC} $*"; } ok() { echo -e "${GREEN}[OK]${NC} $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } err() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; } echo "" echo -e "${GREEN}==============================================${NC}" echo -e "${GREEN} 蝶雅智能体平台 → 生产环境完全升级${NC}" echo -e "${GREEN}==============================================${NC}" echo "" # 1. SSH 连接测试 info "[1/7] 测试 SSH 连接..." if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=accept-new \ "${REMOTE_USER}@${REMOTE_IP}" "echo SSH_OK" 2>/dev/null | grep -q "SSH_OK"; then ok "SSH 连接成功" else err "SSH 连接失败: ssh ${REMOTE_USER}@${REMOTE_IP}" fi # 2. 导出合同模板 DB 数据 info "[2/7] 导出合同模板数据库数据..." DUMP_FILE="/tmp/contract_templates_data.sql" mysqldump -u${DB_USER} -p${DB_PASS} ${DB_NAME} contract_templates \ --no-create-info --complete-insert > "${DUMP_FILE}" ok "合同模板数据已导出 ($(wc -l < "${DUMP_FILE}") 行)" # 3. 同步项目代码 info "[3/7] 同步项目代码..." rsync -avz --delete \ --exclude='venv/' \ --exclude='.git/' \ --exclude='__pycache__/' \ --exclude='*.pyc' \ --exclude='logs/' \ --exclude='backups/' \ --exclude='static/uploads/feedback/' \ --exclude='static/uploads/new_products/' \ --exclude='*.tar.gz' \ --exclude='*.sql' \ "${LOCAL_DIR}/" "${REMOTE_USER}@${REMOTE_IP}:${REMOTE_DIR}/" # 新品图片独立备份:升级前保留生产图片目录,升级过程不删除已有图片。 TS=$(date +%Y%m%d_%H%M%S) ssh "${REMOTE_USER}@${REMOTE_IP}" " set -e mkdir -p ${REMOTE_DIR}_backups if [ -d ${REMOTE_DIR}/static/uploads/new_products ]; then tar -czf ${REMOTE_DIR}_backups/new_products_pre_upgrade_${TS}.tar.gz -C ${REMOTE_DIR}/static/uploads new_products fi " # 新品图片按增量合并:上传测试环境新增图片,但不删除生产环境已有图片。 ssh "${REMOTE_USER}@${REMOTE_IP}" "mkdir -p ${REMOTE_DIR}/static/uploads/new_products" rsync -avz \ "${LOCAL_DIR}/static/uploads/new_products/" \ "${REMOTE_USER}@${REMOTE_IP}:${REMOTE_DIR}/static/uploads/new_products/" ok "项目代码与新品图片同步完成" # 4. 同步知识库文件 info "[4/7] 同步知识库文件..." ssh "${REMOTE_USER}@${REMOTE_IP}" "mkdir -p ${REMOTE_DIR}/vault/知识库" rsync -avz --delete \ --exclude='.obsidian/' \ "${VAULT_DIR}/知识库/" "${REMOTE_USER}@${REMOTE_IP}:${REMOTE_DIR}/vault/知识库/" ok "知识库文件同步完成" # 5. 上传并导入合同模板数据 info "[5/7] 上传并导入合同模板数据..." scp "${DUMP_FILE}" "${REMOTE_USER}@${REMOTE_IP}:/tmp/" if ssh "${REMOTE_USER}@${REMOTE_IP}" \ "mysql -u${DB_USER} -p${DB_PASS} ${DB_NAME} < /tmp/contract_templates_data.sql" 2>/dev/null; then ok "合同模板数据导入成功" else warn "合同模板数据导入失败(可能是重复数据,不影响后续步骤)" fi # 6. 更新生产环境 VAULT_PATH 配置 info "[6/7] 更新生产环境配置..." ssh "${REMOTE_USER}@${REMOTE_IP}" " cd ${REMOTE_DIR} sed -i 's|^VAULT_PATH.*|VAULT_PATH = \"${REMOTE_DIR}/vault\"|' config.py if grep -q '${REMOTE_DIR}/vault' config.py; then echo CFG_OK; else echo CFG_FAIL; fi " | grep -q "CFG_OK" ok "配置已更新 (VAULT_PATH → ${REMOTE_DIR}/vault)" # 7. 数据库迁移 + 清理 + 重启 info "[7/7] 数据库迁移 + 重启服务..." ssh "${REMOTE_USER}@${REMOTE_IP}" " cd ${REMOTE_DIR} venv/bin/python3 migrate_db.py 2>&1 rm -f /tmp/contract_templates_data.sql find . -type d -name '__pycache__' -exec rm -rf {} + 2>/dev/null find . -name '*.pyc' -delete 2>/dev/null PID=\$(lsof -t -i:18888 2>/dev/null || true) [ -n \"\$PID\" ] && kill -9 \$PID 2>/dev/null || true sleep 1 mkdir -p logs nohup venv/bin/gunicorn -w 4 -b 0.0.0.0:18888 --timeout 120 \ --access-logfile logs/access.log \ --error-logfile logs/error.log \ app:app > /dev/null 2>&1 & sleep 3 curl -s http://127.0.0.1:18888/ > /dev/null 2>&1 && echo SRV_OK || echo SRV_FAIL " | grep -q "SRV_OK" && ok "服务重启成功" || warn "服务可能未启动,请检查日志" rm -f "${DUMP_FILE}" echo "" echo -e "${GREEN}==============================================${NC}" echo -e "${GREEN} 升级完成!${NC}" echo -e "${GREEN}==============================================${NC}" echo "" echo -e " 访问地址:${CYAN}http://${REMOTE_IP}:18888${NC}" echo -e " 知识库路径:${REMOTE_DIR}/vault/知识库/" echo ""