Files
smartClean/build.sh
xqzp2026 8373460096 feat: 添加自动化部署方案(Docker + 远程服务器两套方案)
- 新增 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>
2026-04-15 18:41:15 +09:30

238 lines
6.8 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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