|
|
@@ -0,0 +1,166 @@
|
|
|
+#!/bin/bash
|
|
|
+
|
|
|
+# ============================================================
|
|
|
+# 一键部署脚本
|
|
|
+# 用法: ./deploy.sh [admin|miniapp|all] [--skip-frontend]
|
|
|
+# 调试: bash -x ./deploy.sh
|
|
|
+# ============================================================
|
|
|
+
|
|
|
+APP_DIR="/data/app"
|
|
|
+CODE_DIR="/data/code/car-wash-java"
|
|
|
+BACKUP_DIR="/data/backup"
|
|
|
+LOG_DIR="/data/logs"
|
|
|
+HISTORY_FILE="/data/history"
|
|
|
+
|
|
|
+RED='\033[0;31m'
|
|
|
+GREEN='\033[0;32m'
|
|
|
+YELLOW='\033[1;33m'
|
|
|
+NC='\033[0m'
|
|
|
+
|
|
|
+log() { echo -e "[$(date '+%H:%M:%S')] $1"; }
|
|
|
+info() { log "${GREEN}INFO${NC} $1"; }
|
|
|
+warn() { log "${YELLOW}WARN${NC} $1"; }
|
|
|
+error() { log "${RED}ERROR${NC} $1"; }
|
|
|
+
|
|
|
+mkdir -p "$LOG_DIR" "$BACKUP_DIR"
|
|
|
+
|
|
|
+info "开始部署..."
|
|
|
+
|
|
|
+# ---- 参数解析 ----
|
|
|
+TARGET="${1:-all}"
|
|
|
+SKIP_FRONTEND=false
|
|
|
+[ "$2" = "--skip-frontend" ] || [ "$1" = "--skip-frontend" ] && SKIP_FRONTEND=true
|
|
|
+
|
|
|
+# ---- 拉取最新代码 ----
|
|
|
+info "拉取最新代码..."
|
|
|
+cd "$CODE_DIR" || { error "无法进入 $CODE_DIR"; exit 1; }
|
|
|
+git pull origin master || { error "git pull 失败"; exit 1; }
|
|
|
+
|
|
|
+# ---- 前端构建 ----
|
|
|
+if [ "$SKIP_FRONTEND" = false ] && [ "$TARGET" != "miniapp" ]; then
|
|
|
+ info "构建管理后台前端 (admin-web)..."
|
|
|
+ (cd "$CODE_DIR/admin-web" && npm run build) || { error "admin-web 构建失败"; exit 1; }
|
|
|
+
|
|
|
+ info "构建 H5 前端 (admin-h5)..."
|
|
|
+ (cd "$CODE_DIR/admin-h5" && npm run build) || { error "admin-h5 构建失败"; exit 1; }
|
|
|
+
|
|
|
+ info "前端构建完成"
|
|
|
+fi
|
|
|
+
|
|
|
+# ---- Maven 打包 ----
|
|
|
+if [ "$TARGET" = "miniapp" ]; then
|
|
|
+ info "Maven 打包 (仅 miniapp)..."
|
|
|
+ (cd "$CODE_DIR" && mvn clean package -DskipTests -pl car-wash-miniapp -am) || { error "Maven 打包失败"; exit 1; }
|
|
|
+else
|
|
|
+ info "Maven 打包..."
|
|
|
+ (cd "$CODE_DIR" && mvn clean package -DskipTests) || { error "Maven 打包失败"; exit 1; }
|
|
|
+fi
|
|
|
+
|
|
|
+# ---- 备份并复制 jar ----
|
|
|
+backup_and_copy() {
|
|
|
+ local module=$1
|
|
|
+ local jar_src="$CODE_DIR/$module/target/${module}-0.0.1-SNAPSHOT.jar"
|
|
|
+ local jar_dst="$APP_DIR/${module}-0.0.1-SNAPSHOT.jar"
|
|
|
+
|
|
|
+ if [ ! -f "$jar_src" ]; then
|
|
|
+ error "未找到 jar 文件: $jar_src"
|
|
|
+ exit 1
|
|
|
+ fi
|
|
|
+
|
|
|
+ if [ -f "$jar_dst" ]; then
|
|
|
+ cp "$jar_dst" "$BACKUP_DIR/${module}-0.0.1-SNAPSHOT.jar.$(date +%Y%m%d_%H%M%S)"
|
|
|
+ info "已备份 $module (保留最近 5 个)"
|
|
|
+ ls -t "$BACKUP_DIR/${module}"-*.jar 2>/dev/null | tail -n +6 | xargs -r rm -f
|
|
|
+ fi
|
|
|
+ cp "$jar_src" "$jar_dst"
|
|
|
+ info "$module jar 已复制到 $APP_DIR"
|
|
|
+}
|
|
|
+
|
|
|
+# ---- 重启服务 (使用原版 wash-restart.sh 的 PID 检测逻辑) ----
|
|
|
+restart_service() {
|
|
|
+ local module=$1
|
|
|
+ local jar_file="${module}-0.0.1-SNAPSHOT.jar"
|
|
|
+ local start_log="$LOG_DIR/${module}.log"
|
|
|
+
|
|
|
+ info "正在停止 $module ..."
|
|
|
+
|
|
|
+ # 用原版脚本的 grep 方式: grep java | grep 模块名
|
|
|
+ local pid=$(ps -ef | grep java | grep "$module" | grep -v grep | awk '{print $2}')
|
|
|
+
|
|
|
+ if [ -n "$pid" ]; then
|
|
|
+ # 多 pid 情况:逐个处理
|
|
|
+ for p in $pid; do
|
|
|
+ info "终止进程 $module (pid=$p)..."
|
|
|
+ kill "$p" 2>/dev/null
|
|
|
+
|
|
|
+ # 等待 10 秒
|
|
|
+ for i in $(seq 1 10); do
|
|
|
+ if ! kill -0 "$p" 2>/dev/null; then
|
|
|
+ info "进程 $p 已退出"
|
|
|
+ break
|
|
|
+ fi
|
|
|
+ sleep 1
|
|
|
+ done
|
|
|
+
|
|
|
+ # 没退出就强制 kill
|
|
|
+ if kill -0 "$p" 2>/dev/null; then
|
|
|
+ warn "强制终止 $p"
|
|
|
+ kill -9 "$p" 2>/dev/null
|
|
|
+ sleep 1
|
|
|
+ fi
|
|
|
+ done
|
|
|
+ else
|
|
|
+ info "$module 未在运行"
|
|
|
+ fi
|
|
|
+
|
|
|
+ # 确认端口释放
|
|
|
+ info "启动 $module ..."
|
|
|
+
|
|
|
+ local cert_arg=""
|
|
|
+ if [ "$module" = "car-wash-admin" ]; then
|
|
|
+ cert_arg="-Dwechat.payment.certPath=/data/wash-pem/apiclient_cert.pem -Dwechat.payment.keyPath=/data/wash-pem/apiclient_key.pem"
|
|
|
+ fi
|
|
|
+
|
|
|
+ cd "$APP_DIR"
|
|
|
+ nohup java -jar -Dspring.profiles.active=prod $cert_arg "$jar_file" > "$start_log" 2>&1 &
|
|
|
+
|
|
|
+ sleep 5
|
|
|
+ local new_pid=$(ps -ef | grep java | grep "$module" | grep -v grep | awk '{print $2}')
|
|
|
+
|
|
|
+ if [ -n "$new_pid" ]; then
|
|
|
+ info "$module 启动成功 (pid=$new_pid)"
|
|
|
+ echo "$(date) $module restarted" >> "$HISTORY_FILE"
|
|
|
+ else
|
|
|
+ error "$module 可能启动失败,查看日志:"
|
|
|
+ echo "--- $start_log ---"
|
|
|
+ tail -30 "$start_log"
|
|
|
+ echo "--- end ---"
|
|
|
+ exit 1
|
|
|
+ fi
|
|
|
+}
|
|
|
+
|
|
|
+# ---- 执行部署 ----
|
|
|
+case "$TARGET" in
|
|
|
+ admin)
|
|
|
+ backup_and_copy "car-wash-admin"
|
|
|
+ restart_service "car-wash-admin"
|
|
|
+ ;;
|
|
|
+ miniapp)
|
|
|
+ backup_and_copy "car-wash-miniapp"
|
|
|
+ restart_service "car-wash-miniapp"
|
|
|
+ ;;
|
|
|
+ all)
|
|
|
+ backup_and_copy "car-wash-admin"
|
|
|
+ backup_and_copy "car-wash-miniapp"
|
|
|
+ restart_service "car-wash-admin"
|
|
|
+ restart_service "car-wash-miniapp"
|
|
|
+ ;;
|
|
|
+ *)
|
|
|
+ error "未知模块: $TARGET (可选: admin | miniapp | all)"
|
|
|
+ exit 1
|
|
|
+ ;;
|
|
|
+esac
|
|
|
+
|
|
|
+echo "========================================"
|
|
|
+info "部署完成"
|
|
|
+echo "========================================"
|