- 新增 deploy/docker/:Docker 本机模拟部署,含 Dockerfile、docker-compose、deploy.sh 一键脚本 - 新增 deploy/remote/:远程服务器部署,含 SSH 自动上传、重启、回滚脚本 - 新增 deploy/README.md:完整使用手册,含现状分析、落地调整工作清单、命令速查 - 新增 build.sh/start.sh:本地构建和启动脚本(含飞书通知) - 新增前端 .env.docker 环境配置,API 指向测试服务器 - 前端 package.json 新增 build-docker 命令 - 更新 .gitignore:排除 IDE 配置、SQL 数据、Docker 敏感文件 - 前端 UI 样式优化(多个页面组件) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
238 lines
6.8 KiB
Bash
Executable File
238 lines
6.8 KiB
Bash
Executable File
#!/bin/bash
|
||
#
|
||
# SmartClean 构建打包脚本(带飞书通知)
|
||
# 用法:
|
||
# ./build.sh # 构建所有模块(public + web + task + frontend)
|
||
# ./build.sh web # 仅构建后端 web (含 public)
|
||
# ./build.sh task # 仅构建后端 task (含 public)
|
||
# ./build.sh backend # 构建后端 web + task
|
||
# ./build.sh front # 仅构建前端
|
||
# ./build.sh front-test # 构建前端测试环境包
|
||
|
||
# ===== 飞书 Webhook 配置 =====
|
||
FEISHU_WEBHOOK="https://open.feishu.cn/open-apis/bot/v2/hook/5703e8cc-6998-46a6-af9d-8c5102cc8c1e"
|
||
|
||
# ===== 初始化 =====
|
||
export SDKMAN_DIR="$HOME/.sdkman"
|
||
source "$SDKMAN_DIR/bin/sdkman-init.sh"
|
||
sdk use java 8.0.432-zulu > /dev/null 2>&1
|
||
|
||
ROOT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||
PUBLIC_DIR="$ROOT_DIR/backend/xiaoqu-intellectual-public"
|
||
WEB_DIR="$ROOT_DIR/backend/xiaoqu-intellectual-web"
|
||
TASK_DIR="$ROOT_DIR/backend/xiaoqu-intellectual-task"
|
||
FRONT_DIR="$ROOT_DIR/frontend/witcleansystem"
|
||
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
NC='\033[0m'
|
||
|
||
BUILD_START_TIME=$(date +%s)
|
||
BUILD_RESULTS=()
|
||
HAS_ERROR=0
|
||
|
||
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||
|
||
# ===== 飞书通知函数 =====
|
||
send_feishu_notify() {
|
||
local title="$1"
|
||
local content="$2"
|
||
local color="$3" # green / red / yellow
|
||
|
||
# 构建富文本消息
|
||
local json_content
|
||
json_content=$(cat <<EOJSON
|
||
{
|
||
"msg_type": "interactive",
|
||
"card": {
|
||
"header": {
|
||
"title": {
|
||
"tag": "plain_text",
|
||
"content": "$title"
|
||
},
|
||
"template": "$color"
|
||
},
|
||
"elements": [
|
||
{
|
||
"tag": "markdown",
|
||
"content": "$content"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
EOJSON
|
||
)
|
||
|
||
curl -s -X POST "$FEISHU_WEBHOOK" \
|
||
-H "Content-Type: application/json" \
|
||
-d "$json_content" > /dev/null 2>&1
|
||
}
|
||
|
||
# ===== 构建函数 =====
|
||
build_public() {
|
||
log_info "编译 public 模块..."
|
||
local start=$(date +%s)
|
||
cd "$PUBLIC_DIR"
|
||
local output
|
||
output=$(mvn clean install -q -DskipTests 2>&1)
|
||
local rc=$?
|
||
local elapsed=$(( $(date +%s) - start ))
|
||
|
||
if [ $rc -eq 0 ]; then
|
||
log_info "public 模块编译成功 (${elapsed}s)"
|
||
BUILD_RESULTS+=("✅ **public 模块** — 编译成功 (${elapsed}s)")
|
||
else
|
||
log_error "public 模块编译失败"
|
||
HAS_ERROR=1
|
||
BUILD_RESULTS+=("❌ **public 模块** — 编译失败 (${elapsed}s)")
|
||
BUILD_RESULTS+=("错误信息: $(echo "$output" | tail -5 | sed 's/"/\\"/g')")
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
build_web() {
|
||
log_info "打包 Web 服务 (ROOT.war)..."
|
||
local start=$(date +%s)
|
||
cd "$WEB_DIR"
|
||
local output
|
||
output=$(mvn clean package -q -DskipTests 2>&1)
|
||
local rc=$?
|
||
local elapsed=$(( $(date +%s) - start ))
|
||
|
||
if [ $rc -eq 0 ]; then
|
||
local war_file="$WEB_DIR/target/ROOT.war"
|
||
local war_size=""
|
||
if [ -f "$war_file" ]; then
|
||
war_size=" | 文件大小: $(du -h "$war_file" | cut -f1)"
|
||
fi
|
||
log_info "Web 服务打包成功 (${elapsed}s)$war_size"
|
||
BUILD_RESULTS+=("✅ **Web 服务 (ROOT.war)** — 打包成功 (${elapsed}s)$war_size")
|
||
else
|
||
log_error "Web 服务打包失败"
|
||
HAS_ERROR=1
|
||
BUILD_RESULTS+=("❌ **Web 服务** — 打包失败 (${elapsed}s)")
|
||
BUILD_RESULTS+=("错误信息: $(echo "$output" | tail -5 | sed 's/"/\\"/g')")
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
build_task() {
|
||
log_info "打包 Task 服务..."
|
||
local start=$(date +%s)
|
||
cd "$TASK_DIR"
|
||
local output
|
||
output=$(mvn clean package -q -DskipTests 2>&1)
|
||
local rc=$?
|
||
local elapsed=$(( $(date +%s) - start ))
|
||
|
||
if [ $rc -eq 0 ]; then
|
||
log_info "Task 服务打包成功 (${elapsed}s)"
|
||
BUILD_RESULTS+=("✅ **Task 服务** — 打包成功 (${elapsed}s)")
|
||
else
|
||
log_error "Task 服务打包失败"
|
||
HAS_ERROR=1
|
||
BUILD_RESULTS+=("❌ **Task 服务** — 打包失败 (${elapsed}s)")
|
||
BUILD_RESULTS+=("错误信息: $(echo "$output" | tail -5 | sed 's/"/\\"/g')")
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
build_front() {
|
||
local mode="${1:-build}" # build 或 build-test
|
||
local mode_label="生产"
|
||
[ "$mode" = "build-test" ] && mode_label="测试"
|
||
|
||
log_info "构建前端 (${mode_label}环境)..."
|
||
local start=$(date +%s)
|
||
cd "$FRONT_DIR"
|
||
|
||
if [ ! -d "node_modules" ]; then
|
||
log_warn "未检测到 node_modules, 正在安装依赖..."
|
||
npm install
|
||
fi
|
||
|
||
local output
|
||
output=$(npm run "$mode" 2>&1)
|
||
local rc=$?
|
||
local elapsed=$(( $(date +%s) - start ))
|
||
|
||
if [ $rc -eq 0 ]; then
|
||
log_info "前端构建成功 (${mode_label}, ${elapsed}s)"
|
||
BUILD_RESULTS+=("✅ **前端 (${mode_label})** — 构建成功 (${elapsed}s)")
|
||
else
|
||
log_error "前端构建失败"
|
||
HAS_ERROR=1
|
||
BUILD_RESULTS+=("❌ **前端 (${mode_label})** — 构建失败 (${elapsed}s)")
|
||
BUILD_RESULTS+=("错误信息: $(echo "$output" | tail -5 | sed 's/"/\\"/g')")
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# ===== 发送构建汇总通知 =====
|
||
send_build_summary() {
|
||
local total_elapsed=$(( $(date +%s) - BUILD_START_TIME ))
|
||
local branch=$(cd "$ROOT_DIR" && git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
|
||
local commit=$(cd "$ROOT_DIR" && git log -1 --format='%h %s' 2>/dev/null || echo "unknown")
|
||
local build_target="${1:-all}"
|
||
local hostname=$(hostname)
|
||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||
|
||
local status_emoji="✅"
|
||
local title_status="成功"
|
||
local color="green"
|
||
if [ $HAS_ERROR -ne 0 ]; then
|
||
status_emoji="❌"
|
||
title_status="失败"
|
||
color="red"
|
||
fi
|
||
|
||
# 拼接结果列表
|
||
local detail=""
|
||
for item in "${BUILD_RESULTS[@]}"; do
|
||
detail="${detail}\n${item}"
|
||
done
|
||
|
||
local content="**构建目标:** ${build_target}\\n**分支:** ${branch}\\n**最新提交:** ${commit}\\n**构建机器:** ${hostname}\\n**时间:** ${timestamp}\\n**总耗时:** ${total_elapsed}s\\n\\n---\\n${detail}"
|
||
|
||
send_feishu_notify "${status_emoji} SmartClean 构建${title_status}" "$content" "$color"
|
||
log_info "飞书通知已发送"
|
||
}
|
||
|
||
# ===== 主流程 =====
|
||
TARGET="${1:-all}"
|
||
|
||
case "$TARGET" in
|
||
web)
|
||
build_public && build_web
|
||
;;
|
||
task)
|
||
build_public && build_task
|
||
;;
|
||
backend)
|
||
build_public && build_web && build_task
|
||
;;
|
||
front)
|
||
build_front "build"
|
||
;;
|
||
front-test)
|
||
build_front "build-test"
|
||
;;
|
||
all)
|
||
build_public && build_web && build_task
|
||
build_front "build"
|
||
;;
|
||
*)
|
||
echo "用法: $0 {all|web|task|backend|front|front-test}"
|
||
exit 1
|
||
;;
|
||
esac
|
||
|
||
send_build_summary "$TARGET"
|
||
|
||
if [ $HAS_ERROR -ne 0 ]; then
|
||
exit 1
|
||
fi
|