From 5024477b748c68325b2ba4fdef6b2aab85c82d57 Mon Sep 17 00:00:00 2001 From: liuyh Date: Tue, 9 Dec 2025 14:53:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0quickstart.sh=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=E5=B8=AE=E5=8A=A9=E7=94=A8=E6=88=B7=E5=BF=AB=E9=80=9F?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E6=A8=A1=E6=9D=BF=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- quickstart.sh | 429 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 428 insertions(+), 1 deletion(-) mode change 100644 => 100755 quickstart.sh diff --git a/quickstart.sh b/quickstart.sh old mode 100644 new mode 100755 index 7e6e454..6304e78 --- a/quickstart.sh +++ b/quickstart.sh @@ -1,2 +1,429 @@ #!/bin/bash -# 您可以运行这个脚本来快速初始化和使用本模板项目 + +# Hair Keeper 模板项目快速配置脚本 +# 用于帮助用户快速配置环境变量和开发工具 + +set -e + +# 颜色定义 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +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_header() { + echo "" + echo -e "${CYAN}========================================${NC}" + echo -e "${CYAN} $1${NC}" + echo -e "${CYAN}========================================${NC}" + echo "" +} + +# 读取用户输入,支持默认值 +read_input() { + local prompt="$1" + local default="$2" + local allow_empty="$3" + local result + + if [ -n "$default" ]; then + echo -n "$prompt [默认: $default]: " >&2 + read result + result="${result:-$default}" + else + if [ "$allow_empty" = "true" ]; then + echo -n "$prompt (可为空): " >&2 + read result + else + while [ -z "$result" ]; do + echo -n "$prompt: " >&2 + read result + if [ -z "$result" ]; then + print_warning "此项不能为空,请重新输入" + fi + done + fi + fi + echo "$result" +} + +# 读取密码输入(隐藏输入) +read_password() { + local prompt="$1" + local allow_empty="$2" + local result + + if [ "$allow_empty" = "true" ]; then + echo -n "$prompt (可为空): " >&2 + read -s result + echo "" >&2 + else + while [ -z "$result" ]; do + echo -n "$prompt: " >&2 + read -s result + echo "" >&2 + if [ -z "$result" ]; then + print_warning "此项不能为空,请重新输入" + fi + done + fi + echo "$result" +} + +# 生成随机密码 +generate_password() { + local length="$1" + if command -v pwgen &> /dev/null; then + pwgen -s "$length" 1 + else + # 如果没有 pwgen,使用 openssl 或 /dev/urandom + if command -v openssl &> /dev/null; then + openssl rand -base64 "$length" | tr -dc 'a-zA-Z0-9' | head -c "$length" + else + cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c "$length" + fi + fi +} + +# 选择菜单 +select_option() { + local prompt="$1" + shift + local options=("$@") + local choice + + echo "$prompt" >&2 + for i in "${!options[@]}"; do + echo " $((i+1)). ${options[$i]}" >&2 + done + + while true; do + echo -n "请输入选项编号: " >&2 + read choice + if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "${#options[@]}" ]; then + echo "$choice" + return + fi + print_warning "无效选项,请重新输入" + done +} + +# 主函数 +main() { + print_header "Hair Keeper 模板项目快速配置" + + echo "本脚本将帮助您快速配置项目环境变量和开发工具" + echo "" + + # ==================== 环境变量配置 ==================== + print_header "环境变量配置" + + # --- PostgreSQL 配置 --- + print_info "配置 PostgreSQL 数据库..." + echo "" + + POSTGRESQL_USERNAME=$(read_input "PostgreSQL 用户名" "postgres") + POSTGRESQL_PASSWORD=$(read_password "PostgreSQL 密码" "true") + POSTGRESQL_PORT=$(read_input "PostgreSQL 端口" "5432") + + echo "" + db_url_choice=$(select_option "DATABASE_URL 配置方式:" "自动构造 PostgreSQL URL" "手动输入完整 URL") + + if [ "$db_url_choice" = "1" ]; then + POSTGRESQL_HOSTNAME=$(read_input "PostgreSQL 主机名" "") + POSTGRESQL_DBNAME=$(read_input "PostgreSQL 数据库名" "postgres") + POSTGRESQL_SCHEMA=$(read_input "PostgreSQL 模式名" "public") + + if [ -n "$POSTGRESQL_PASSWORD" ]; then + DATABASE_URL="postgresql://${POSTGRESQL_USERNAME}:${POSTGRESQL_PASSWORD}@${POSTGRESQL_HOSTNAME}:${POSTGRESQL_PORT}/${POSTGRESQL_DBNAME}?schema=${POSTGRESQL_SCHEMA}" + else + DATABASE_URL="postgresql://${POSTGRESQL_USERNAME}@${POSTGRESQL_HOSTNAME}:${POSTGRESQL_PORT}/${POSTGRESQL_DBNAME}?schema=${POSTGRESQL_SCHEMA}" + fi + else + DATABASE_URL=$(read_input "DATABASE_URL" "") + fi + + echo "" + print_success "PostgreSQL 配置完成" + echo "" + + # --- Redis 配置 --- + print_info "配置 Redis..." + echo "" + + REDIS_HOST=$(read_input "Redis 主机名" "") + REDIS_PORT=$(read_input "Redis 端口" "6379") + REDIS_PASSWORD=$(read_password "Redis 密码" "true") + + echo "" + print_success "Redis 配置完成" + echo "" + + # --- MinIO 配置 --- + print_info "配置 MinIO 对象存储..." + echo "" + + MINIO_ENDPOINT=$(read_input "MinIO 端点地址" "") + MINIO_API_PORT=$(read_input "MinIO API 端口" "9000") + MINIO_CONSOLE_PORT=$(read_input "MinIO 控制台端口" "9001") + MINIO_USE_SSL=$(read_input "MinIO 是否使用 SSL (true/false)" "false") + MINIO_ROOT_USER=$(read_input "MinIO 用户名" "admin") + MINIO_ROOT_PASSWORD=$(read_password "MinIO 密码" "true") + MINIO_SERVER_URL=$(read_input "MinIO 服务器 URL (用于生成公开访问链接)" "" "true") + MINIO_BUCKET=$(read_input "MinIO 存储桶名称" "app-files") + + echo "" + print_success "MinIO 配置完成" + echo "" + + # --- 应用配置 --- + print_info "配置应用参数..." + echo "" + + SUPER_ADMIN_PASSWORD=$(generate_password 16) + USER_DEFAULT_PASSWORD=$(generate_password 16) + NEXTAUTH_SECRET=$(generate_password 32) + + print_info "已自动生成以下密码:" + echo " SUPER_ADMIN_PASSWORD: $SUPER_ADMIN_PASSWORD" + echo " USER_DEFAULT_PASSWORD: $USER_DEFAULT_PASSWORD" + echo " NEXTAUTH_SECRET: $NEXTAUTH_SECRET" + echo "" + + DB_PARALLEL_LIMIT=$(read_input "数据库批次操作默认并发数" "32") + + echo "" + print_success "应用参数配置完成" + echo "" + + # --- AI API 配置 --- + print_info "配置 AI API..." + echo "" + + PKUAI_API_KEY=$(read_input "PKU AI API Key" "" "true") + PKUAI_API_BASE=$(read_input "PKU AI API Base URL" "https://chat.noc.pku.edu.cn/") + + echo "" + print_success "AI API 配置完成" + echo "" + + # --- 开发环境配置 --- + print_info "配置开发环境参数..." + echo "" + + DEV_PORT=$(read_input "开发服务器端口" "3000") + DEV_TERMINAL_PORT=$(read_input "开发终端默认端口" "7681") + DEV_TERMINAL=$(read_input "开发终端 tmux session 名称" "nextdev") + + echo "" + print_success "开发环境配置完成" + echo "" + + # ==================== 写入配置文件 ==================== + print_header "写入配置文件" + + # 写入 .env 文件 + print_info "写入 .env 文件..." + cat > .env << EOF +# ==================== 容器相关 ==================== +POSTGRESQL_USERNAME=${POSTGRESQL_USERNAME} +POSTGRESQL_PASSWORD=${POSTGRESQL_PASSWORD} +POSTGRESQL_PORT=${POSTGRESQL_PORT} +DATABASE_URL="${DATABASE_URL}" + +REDIS_HOST=${REDIS_HOST} +REDIS_PORT=${REDIS_PORT} +REDIS_PASSWORD=${REDIS_PASSWORD} + +MINIO_ENDPOINT=${MINIO_ENDPOINT} +MINIO_API_PORT=${MINIO_API_PORT} +MINIO_CONSOLE_PORT=${MINIO_CONSOLE_PORT} +MINIO_USE_SSL=${MINIO_USE_SSL} +MINIO_ROOT_USER=${MINIO_ROOT_USER} +MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD} +MINIO_SERVER_URL=${MINIO_SERVER_URL} +MINIO_BUCKET=${MINIO_BUCKET} + +# ==================== 应用相关 ==================== +SUPER_ADMIN_PASSWORD=${SUPER_ADMIN_PASSWORD} +USER_DEFAULT_PASSWORD=${USER_DEFAULT_PASSWORD} +## 数据库批次操作默认并发数 +DB_PARALLEL_LIMIT=${DB_PARALLEL_LIMIT} + +# ==================== NextAuth.js Configuration ==================== +NEXTAUTH_SECRET=${NEXTAUTH_SECRET} + +# ==================== AI API ==================== +PKUAI_API_KEY=${PKUAI_API_KEY} +PKUAI_API_BASE=${PKUAI_API_BASE} +EOF + print_success ".env 文件已创建" + + # 写入 .env.development 文件 + print_info "写入 .env.development 文件..." + cat > .env.development << EOF +# 仅在开发环境加载 +PORT=${DEV_PORT} +NEXT_PUBLIC_DEV_TERMINAL_DEFAULT_PORT=${DEV_TERMINAL_PORT} +DEV_TERMINAL=${DEV_TERMINAL} +EOF + print_success ".env.development 文件已创建" + + # 写入 .env.production 文件 + print_info "写入 .env.production 文件..." + cat > .env.production << EOF +# 仅在生产环境加载 +EOF + print_success ".env.production 文件已创建" + + # ==================== Claude Code 编程代理配置 ==================== + print_header "Claude Code 编程代理配置" + + # 重命名 CLAUDE.md + if [ -f "CLAUDE.md" ]; then + print_info "重命名 CLAUDE.md 为 TEMPLATE_README.md..." + mv CLAUDE.md TEMPLATE_README.md + print_success "CLAUDE.md 已重命名为 TEMPLATE_README.md" + fi + + # 创建新的 CLAUDE.md + print_info "创建新的 CLAUDE.md..." + cat > CLAUDE.md << 'EOF' +# CLAUDE.md + +本文件为 AI 代理(如 Claude)提供在本代码库中工作的指导说明。 + +## 项目说明 + +本项目基于 Hair Keeper 模板构建(详见 @TEMPLATE_README.md),目前尚未实现业务功能 +EOF + print_success "新的 CLAUDE.md 已创建" + + # 创建 Claude Code Router 配置 + print_info "配置 Claude Code Router..." + mkdir -p ~/.claude-code-router + + cat > ~/.claude-code-router/config.json << EOF +{ + "LOG": false, + "LOG_LEVEL": "debug", + "CLAUDE_PATH": "", + "HOST": "127.0.0.1", + "PORT": 3456, + "APIKEY": "", + "API_TIMEOUT_MS": "600000", + "PROXY_URL": "", + "transformers": [], + "Providers": [ + { + "name": "pku-anthropic", + "api_base_url": "${PKUAI_API_BASE}api/anthropic/v1/messages", + "api_key": "${PKUAI_API_KEY}", + "models": [ + "claude-sonnet-4-5-20250929", + "claude-opus-4-5-20251101", + "claude-haiku-4-5-20251001" + ], + "transformer": { + "use": [ + "Anthropic" + ] + } + } + ], + "StatusLine": { + "enabled": false, + "currentStyle": "default", + "default": { + "modules": [] + }, + "powerline": { + "modules": [] + } + }, + "Router": { + "default": "pku-anthropic,claude-opus-4-5-20251101", + "background": "pku-anthropic,claude-haiku-4-5-20251001", + "think": "pku-anthropic,claude-opus-4-5-20251101", + "longContext": "pku-anthropic,claude-opus-4-5-20251101", + "longContextThreshold": 80000, + "webSearch": "", + "image": "pku-anthropic,claude-opus-4-5-20251101" + }, + "CUSTOM_ROUTER_PATH": "" +} +EOF + print_success "Claude Code Router 配置已写入 ~/.claude-code-router/config.json" + + # ==================== Git 版本控制初始化 ==================== + print_header "Git 版本控制初始化" + + # 删除模板项目的 git 仓库 + if [ -d ".git" ]; then + print_info "删除模板项目的 git 仓库..." + rm -rf .git + print_success "已删除 .git 目录" + fi + + # 获取用户的 git 配置信息 + print_info "配置 Git 用户信息..." + echo "" + + GIT_USER_EMAIL=$(read_input "Git 用户邮箱" "") + GIT_USER_NAME=$(read_input "Git 用户名" "") + + echo "" + print_info "设置 Git 全局配置..." + git config --global user.email "$GIT_USER_EMAIL" + git config --global user.name "$GIT_USER_NAME" + print_success "Git 全局配置已设置" + + # 初始化新的 git 仓库 + print_info "初始化 Git 仓库..." + git init + git add . + git commit -m "init" + print_success "Git 仓库已初始化并完成首次提交" + + # ==================== 完成提示 ==================== + print_header "配置完成!" + + echo -e "${GREEN}所有配置已完成!${NC}" + echo "" + echo "Claude Code 编程代理使用说明:" + echo -e " ${CYAN}ccr code${NC} - 打开 Claude Code 编程代理,可通过对话完成编程任务" + echo -e " ${CYAN}ccr ui${NC} - 配置 Claude Code 编程代理对接的大模型" + echo -e " ${CYAN}ccr code --resume${NC} - 查看历史对话" + echo "" + echo "接下来您可以进行以下操作:" + echo -e " ${CYAN}1. pnpm install${NC} - 安装依赖包" + echo -e " ${CYAN}2. pnpm prisma migrate dev${NC} - 迁移数据库并初始化 Prisma 客户端" + echo -e " ${CYAN}3. pnpm run db:seed${NC} - 初始化数据库数据" + echo -e " ${CYAN}4. pnpm run dev${NC} - 运行开发服务器" + echo -e " ${CYAN}5. ccr code${NC} - 打开编程代理后,先输入 ${YELLOW}/init <我的项目的主要功能是...>${NC} 初始化" + echo " 然后再开始使用 AI 完成编程任务" + echo "" + print_success "祝您开发愉快!" +} + +# 运行主函数 +main