- 完整实现Apple HIG 2025设计系统 - 添加Modal弹窗组件(毛玻璃效果、流畅动画) - 添加FileUpload文件上传组件(拖拽、批量上传、进度显示) - 实现产品上传功能(支持DWG/GLB/GLTF文件) - 优化产品列表展示(可折叠的产品+SKU结构) - 实现Tab切换功能(3D模型管理、五金件、BOM、文档) - 修复主题系统hydration错误 - 优化按钮和间距,符合Apple设计规范 - 添加分享页面的Apple风格重设计 - 创建测试数据脚本
333 lines
8.7 KiB
Bash
333 lines
8.7 KiB
Bash
#!/bin/bash
|
||
|
||
# 3D 家具安装展示系统 - 远程部署脚本
|
||
# 适用于: 从管理机远程部署到目标设备
|
||
#
|
||
# 使用方法:
|
||
# chmod +x scripts/remote-deploy.sh
|
||
# ./scripts/remote-deploy.sh <target-host> <username>
|
||
|
||
set -e
|
||
|
||
# 颜色输出
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# 打印带颜色的消息
|
||
print_info() {
|
||
echo -e "${BLUE}[INFO]${NC} $1"
|
||
}
|
||
|
||
print_success() {
|
||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||
}
|
||
|
||
print_warning() {
|
||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||
}
|
||
|
||
print_error() {
|
||
echo -e "${RED}[ERROR]${NC} $1"
|
||
}
|
||
|
||
# 打印欢迎信息
|
||
print_welcome() {
|
||
echo ""
|
||
echo "=========================================="
|
||
echo " 3D 家具安装展示系统"
|
||
echo " 远程部署脚本 v1.0"
|
||
echo "=========================================="
|
||
echo ""
|
||
}
|
||
|
||
# 打印使用说明
|
||
print_usage() {
|
||
echo "使用方法:"
|
||
echo " $0 <target-host> <username> [options]"
|
||
echo ""
|
||
echo "参数:"
|
||
echo " target-host 目标设备的 IP 地址或主机名"
|
||
echo " username SSH 登录用户名"
|
||
echo ""
|
||
echo "选项:"
|
||
echo " -p, --port SSH 端口 (默认: 22)"
|
||
echo " -k, --key SSH 私钥文件路径"
|
||
echo " -m, --mode 部署模式 (standard/lightweight/auto)"
|
||
echo " --silent 静默模式,使用默认配置"
|
||
echo ""
|
||
echo "示例:"
|
||
echo " $0 192.168.1.100 admin"
|
||
echo " $0 192.168.1.100 admin -p 2222 -k ~/.ssh/id_rsa"
|
||
echo " $0 192.168.1.100 admin --mode lightweight"
|
||
}
|
||
|
||
# 解析命令行参数
|
||
parse_arguments() {
|
||
if [ $# -lt 2 ]; then
|
||
print_error "参数不足"
|
||
print_usage
|
||
exit 1
|
||
fi
|
||
|
||
TARGET_HOST=$1
|
||
USERNAME=$2
|
||
shift 2
|
||
|
||
# 默认值
|
||
SSH_PORT=22
|
||
SSH_KEY=""
|
||
DEPLOYMENT_MODE="auto"
|
||
SILENT_MODE=false
|
||
|
||
# 解析选项
|
||
while [[ $# -gt 0 ]]; do
|
||
case $1 in
|
||
-p|--port)
|
||
SSH_PORT="$2"
|
||
shift 2
|
||
;;
|
||
-k|--key)
|
||
SSH_KEY="$2"
|
||
shift 2
|
||
;;
|
||
-m|--mode)
|
||
DEPLOYMENT_MODE="$2"
|
||
shift 2
|
||
;;
|
||
--silent)
|
||
SILENT_MODE=true
|
||
shift
|
||
;;
|
||
-h|--help)
|
||
print_usage
|
||
exit 0
|
||
;;
|
||
*)
|
||
print_error "未知选项: $1"
|
||
print_usage
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
}
|
||
|
||
# 构建 SSH 命令
|
||
build_ssh_command() {
|
||
SSH_CMD="ssh -p $SSH_PORT"
|
||
if [ -n "$SSH_KEY" ]; then
|
||
SSH_CMD="$SSH_CMD -i $SSH_KEY"
|
||
fi
|
||
SSH_CMD="$SSH_CMD $USERNAME@$TARGET_HOST"
|
||
}
|
||
|
||
# 测试 SSH 连接
|
||
test_ssh_connection() {
|
||
print_info "测试 SSH 连接到 $TARGET_HOST..."
|
||
|
||
if $SSH_CMD "echo 'Connection test'" &> /dev/null; then
|
||
print_success "SSH 连接成功"
|
||
return 0
|
||
else
|
||
print_error "SSH 连接失败,请检查:"
|
||
echo " - 目标主机是否可达"
|
||
echo " - SSH 服务是否运行"
|
||
echo " - 用户名和密码/密钥是否正确"
|
||
echo " - 防火墙设置"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# 检测远程系统
|
||
detect_remote_system() {
|
||
print_info "检测远程系统..."
|
||
|
||
# 检测操作系统
|
||
OS_TYPE=$($SSH_CMD "uname -s")
|
||
print_info "操作系统: $OS_TYPE"
|
||
|
||
# 检测 Docker
|
||
if $SSH_CMD "command -v docker" &> /dev/null; then
|
||
DOCKER_VERSION=$($SSH_CMD "docker --version")
|
||
print_success "Docker 已安装: $DOCKER_VERSION"
|
||
else
|
||
print_error "目标设备未安装 Docker"
|
||
exit 1
|
||
fi
|
||
|
||
# 检测 Docker Compose
|
||
if $SSH_CMD "command -v docker-compose" &> /dev/null; then
|
||
COMPOSE_VERSION=$($SSH_CMD "docker-compose --version")
|
||
print_success "Docker Compose 已安装: $COMPOSE_VERSION"
|
||
else
|
||
print_error "目标设备未安装 Docker Compose"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# 检测远程硬件
|
||
detect_remote_hardware() {
|
||
print_info "检测远程硬件配置..."
|
||
|
||
# 检测内存 (GB)
|
||
TOTAL_MEM=$($SSH_CMD "free -g | awk '/^Mem:/{print \$2}'")
|
||
print_info "总内存: ${TOTAL_MEM}GB"
|
||
|
||
# 检测 CPU 核心数
|
||
CPU_CORES=$($SSH_CMD "nproc")
|
||
print_info "CPU 核心数: ${CPU_CORES}"
|
||
|
||
# 检测磁盘空间 (GB)
|
||
DISK_AVAIL=$($SSH_CMD "df -BG / | awk 'NR==2 {print \$4}' | sed 's/G//'")
|
||
print_info "可用磁盘空间: ${DISK_AVAIL}GB"
|
||
|
||
# 推荐部署模式
|
||
if [ "$DEPLOYMENT_MODE" = "auto" ]; then
|
||
if [ "$TOTAL_MEM" -lt 4 ]; then
|
||
print_error "内存不足 4GB,无法部署系统"
|
||
exit 1
|
||
elif [ "$TOTAL_MEM" -lt 8 ]; then
|
||
DEPLOYMENT_MODE="lightweight"
|
||
print_warning "内存为 ${TOTAL_MEM}GB,将使用轻量级模式"
|
||
else
|
||
DEPLOYMENT_MODE="standard"
|
||
print_success "内存充足,将使用标准模式"
|
||
fi
|
||
fi
|
||
|
||
if [ "$DISK_AVAIL" -lt 50 ]; then
|
||
print_warning "磁盘可用空间不足 50GB,建议清理磁盘"
|
||
fi
|
||
}
|
||
|
||
# 生成配置文件
|
||
generate_remote_config() {
|
||
print_info "生成配置文件..."
|
||
|
||
# 创建临时目录
|
||
TEMP_DIR=$(mktemp -d)
|
||
|
||
# 复制模板
|
||
cp .env.example "$TEMP_DIR/.env"
|
||
|
||
# 生成随机密码
|
||
ADMIN_PASSWORD=$(openssl rand -base64 16 | tr -d "=+/" | cut -c1-16)
|
||
DB_PASSWORD=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-32)
|
||
MINIO_PASSWORD=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-32)
|
||
|
||
# 更新配置
|
||
sed -i "s/DEPLOYMENT_MODE=.*/DEPLOYMENT_MODE=${DEPLOYMENT_MODE}/" "$TEMP_DIR/.env"
|
||
sed -i "s/ADMIN_PASSWORD=.*/ADMIN_PASSWORD=${ADMIN_PASSWORD}/" "$TEMP_DIR/.env"
|
||
sed -i "s/DB_PASSWORD=.*/DB_PASSWORD=${DB_PASSWORD}/" "$TEMP_DIR/.env"
|
||
sed -i "s/MINIO_PASSWORD=.*/MINIO_PASSWORD=${MINIO_PASSWORD}/" "$TEMP_DIR/.env"
|
||
|
||
print_success "配置文件已生成"
|
||
|
||
# 保存密码供后续使用
|
||
echo "$ADMIN_PASSWORD" > "$TEMP_DIR/admin_password.txt"
|
||
}
|
||
|
||
# 上传文件到远程设备
|
||
upload_files() {
|
||
print_info "上传配置文件到远程设备..."
|
||
|
||
# 创建远程目录
|
||
$SSH_CMD "mkdir -p ~/furniture-3d-system"
|
||
|
||
# 构建 SCP 命令
|
||
SCP_CMD="scp -P $SSH_PORT"
|
||
if [ -n "$SSH_KEY" ]; then
|
||
SCP_CMD="$SCP_CMD -i $SSH_KEY"
|
||
fi
|
||
|
||
# 上传 .env 文件
|
||
$SCP_CMD "$TEMP_DIR/.env" "$USERNAME@$TARGET_HOST:~/furniture-3d-system/"
|
||
|
||
# 上传 docker-compose 文件
|
||
COMPOSE_FILE="docker-compose.${DEPLOYMENT_MODE}.yml"
|
||
$SCP_CMD "$COMPOSE_FILE" "$USERNAME@$TARGET_HOST:~/furniture-3d-system/"
|
||
|
||
print_success "文件上传完成"
|
||
}
|
||
|
||
# 远程启动服务
|
||
start_remote_services() {
|
||
print_info "在远程设备上启动服务..."
|
||
|
||
COMPOSE_FILE="docker-compose.${DEPLOYMENT_MODE}.yml"
|
||
|
||
# 拉取镜像
|
||
print_info "拉取 Docker 镜像..."
|
||
$SSH_CMD "cd ~/furniture-3d-system && docker-compose -f $COMPOSE_FILE pull"
|
||
|
||
# 启动服务
|
||
print_info "启动服务..."
|
||
$SSH_CMD "cd ~/furniture-3d-system && docker-compose -f $COMPOSE_FILE up -d"
|
||
|
||
print_success "服务已启动"
|
||
}
|
||
|
||
# 等待服务就绪
|
||
wait_for_remote_services() {
|
||
print_info "等待服务就绪..."
|
||
|
||
MAX_WAIT=120
|
||
ELAPSED=0
|
||
|
||
while [ $ELAPSED -lt $MAX_WAIT ]; do
|
||
if $SSH_CMD "cd ~/furniture-3d-system && docker-compose ps | grep -q 'healthy'"; then
|
||
print_success "服务已就绪"
|
||
return 0
|
||
fi
|
||
sleep 5
|
||
ELAPSED=$((ELAPSED + 5))
|
||
echo -n "."
|
||
done
|
||
|
||
echo ""
|
||
print_warning "服务启动超时,请检查日志"
|
||
}
|
||
|
||
# 显示访问信息
|
||
show_access_info() {
|
||
ADMIN_PASSWORD=$(cat "$TEMP_DIR/admin_password.txt")
|
||
|
||
echo ""
|
||
echo "=========================================="
|
||
echo " 远程部署完成!"
|
||
echo "=========================================="
|
||
echo ""
|
||
print_success "访问地址: http://${TARGET_HOST}:3000"
|
||
print_success "管理员账号: admin"
|
||
print_success "管理员密码: $ADMIN_PASSWORD"
|
||
echo ""
|
||
print_warning "请妥善保存以上密码!"
|
||
echo ""
|
||
print_info "查看日志: ssh $USERNAME@$TARGET_HOST 'cd ~/furniture-3d-system && docker-compose logs -f'"
|
||
print_info "停止服务: ssh $USERNAME@$TARGET_HOST 'cd ~/furniture-3d-system && docker-compose down'"
|
||
echo ""
|
||
|
||
# 清理临时文件
|
||
rm -rf "$TEMP_DIR"
|
||
}
|
||
|
||
# 主函数
|
||
main() {
|
||
print_welcome
|
||
parse_arguments "$@"
|
||
build_ssh_command
|
||
test_ssh_connection
|
||
detect_remote_system
|
||
detect_remote_hardware
|
||
generate_remote_config
|
||
upload_files
|
||
start_remote_services
|
||
wait_for_remote_services
|
||
show_access_info
|
||
}
|
||
|
||
# 运行主函数
|
||
main "$@"
|