514 lines
12 KiB
Bash
Executable File
514 lines
12 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# 项目模板创建脚本
|
||
# 用法: ./create-from-template.sh [目标目录]
|
||
|
||
set -e # 遇到错误立即退出
|
||
|
||
# 颜色定义
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# 打印带颜色的消息
|
||
print_success() {
|
||
echo -e "${GREEN}✓ $1${NC}"
|
||
}
|
||
|
||
print_info() {
|
||
echo -e "${BLUE}ℹ $1${NC}"
|
||
}
|
||
|
||
print_warning() {
|
||
echo -e "${YELLOW}⚠ $1${NC}"
|
||
}
|
||
|
||
print_error() {
|
||
echo -e "${RED}✗ $1${NC}"
|
||
}
|
||
|
||
print_header() {
|
||
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
echo -e "${BLUE} $1${NC}"
|
||
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
}
|
||
|
||
# 获取当前模板目录
|
||
TEMPLATE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
|
||
# 欢迎信息
|
||
clear
|
||
print_header "FastAPI + Vue 3 项目模板生成器"
|
||
echo ""
|
||
print_info "此脚本将基于当前模板创建一个新项目"
|
||
echo ""
|
||
|
||
# 获取目标目录
|
||
if [ -n "$1" ]; then
|
||
TARGET_DIR="$1"
|
||
else
|
||
read -p "$(echo -e ${BLUE}请输入新项目目录 [默认: ../my-new-project]: ${NC})" TARGET_DIR
|
||
TARGET_DIR=${TARGET_DIR:-../my-new-project}
|
||
fi
|
||
|
||
# 转换为绝对路径
|
||
TARGET_DIR=$(cd "$(dirname "$TARGET_DIR")" 2>/dev/null && pwd)/$(basename "$TARGET_DIR") || TARGET_DIR="$TARGET_DIR"
|
||
|
||
# 检查目标目录是否已存在
|
||
if [ -d "$TARGET_DIR" ]; then
|
||
print_warning "目录 $TARGET_DIR 已存在"
|
||
read -p "$(echo -e ${YELLOW}是否覆盖? [y/N]: ${NC})" OVERWRITE
|
||
if [[ ! $OVERWRITE =~ ^[Yy]$ ]]; then
|
||
print_info "已取消"
|
||
exit 0
|
||
fi
|
||
rm -rf "$TARGET_DIR"
|
||
fi
|
||
|
||
echo ""
|
||
print_header "项目配置"
|
||
echo ""
|
||
|
||
# 收集项目信息
|
||
read -p "$(echo -e ${BLUE}项目名称 (小写,用连字符) [my-app]: ${NC})" PROJECT_NAME
|
||
PROJECT_NAME=${PROJECT_NAME:-my-app}
|
||
|
||
read -p "$(echo -e ${BLUE}项目显示名称 [My Application]: ${NC})" PROJECT_DISPLAY_NAME
|
||
PROJECT_DISPLAY_NAME=${PROJECT_DISPLAY_NAME:-My Application}
|
||
|
||
read -p "$(echo -e ${BLUE}数据库名称 [${PROJECT_NAME//-/_}_db]: ${NC})" DATABASE_NAME
|
||
DATABASE_NAME=${DATABASE_NAME:-${PROJECT_NAME//-/_}_db}
|
||
|
||
read -p "$(echo -e ${BLUE}后端 API 端口 [8888]: ${NC})" API_PORT
|
||
API_PORT=${API_PORT:-8888}
|
||
|
||
read -p "$(echo -e ${BLUE}前端开发端口 [3000]: ${NC})" FRONTEND_PORT
|
||
FRONTEND_PORT=${FRONTEND_PORT:-3000}
|
||
|
||
read -p "$(echo -e ${BLUE}域名 (可选,按回车跳过): ${NC})" DOMAIN_NAME
|
||
|
||
# 数据库类型
|
||
echo ""
|
||
echo -e "${BLUE}选择数据库类型:${NC}"
|
||
echo " 1) SQLite (默认,适合开发)"
|
||
echo " 2) PostgreSQL (推荐生产环境)"
|
||
read -p "$(echo -e ${BLUE}请选择 [1]: ${NC})" DB_TYPE
|
||
DB_TYPE=${DB_TYPE:-1}
|
||
|
||
if [ "$DB_TYPE" = "2" ]; then
|
||
read -p "$(echo -e ${BLUE}PostgreSQL 主机 [localhost]: ${NC})" PG_HOST
|
||
PG_HOST=${PG_HOST:-localhost}
|
||
|
||
read -p "$(echo -e ${BLUE}PostgreSQL 端口 [5432]: ${NC})" PG_PORT
|
||
PG_PORT=${PG_PORT:-5432}
|
||
|
||
read -p "$(echo -e ${BLUE}PostgreSQL 用户名 [postgres]: ${NC})" PG_USER
|
||
PG_USER=${PG_USER:-postgres}
|
||
|
||
read -s -p "$(echo -e ${BLUE}PostgreSQL 密码: ${NC})" PG_PASSWORD
|
||
echo ""
|
||
|
||
DATABASE_URL="postgresql://${PG_USER}:${PG_PASSWORD}@${PG_HOST}:${PG_PORT}/${DATABASE_NAME}"
|
||
else
|
||
DATABASE_URL="sqlite:///./${DATABASE_NAME}.db"
|
||
fi
|
||
|
||
# 生成随机 SECRET_KEY
|
||
SECRET_KEY=$(openssl rand -base64 32 2>/dev/null || python3 -c "import secrets; print(secrets.token_urlsafe(32))")
|
||
|
||
# 确认信息
|
||
echo ""
|
||
print_header "配置确认"
|
||
echo ""
|
||
echo -e "${BLUE}项目名称:${NC} $PROJECT_NAME"
|
||
echo -e "${BLUE}显示名称:${NC} $PROJECT_DISPLAY_NAME"
|
||
echo -e "${BLUE}数据库名称:${NC} $DATABASE_NAME"
|
||
echo -e "${BLUE}数据库 URL:${NC} $DATABASE_URL"
|
||
echo -e "${BLUE}API 端口:${NC} $API_PORT"
|
||
echo -e "${BLUE}前端端口:${NC} $FRONTEND_PORT"
|
||
echo -e "${BLUE}域名:${NC} ${DOMAIN_NAME:-未设置}"
|
||
echo -e "${BLUE}目标目录:${NC} $TARGET_DIR"
|
||
echo ""
|
||
|
||
read -p "$(echo -e ${BLUE}确认创建项目? [Y/n]: ${NC})" CONFIRM
|
||
if [[ $CONFIRM =~ ^[Nn]$ ]]; then
|
||
print_info "已取消"
|
||
exit 0
|
||
fi
|
||
|
||
# 开始创建项目
|
||
echo ""
|
||
print_header "创建项目"
|
||
echo ""
|
||
|
||
# 1. 创建目标目录
|
||
print_info "创建目录: $TARGET_DIR"
|
||
mkdir -p "$TARGET_DIR"
|
||
|
||
# 2. 复制文件
|
||
print_info "复制项目文件..."
|
||
rsync -a --progress "$TEMPLATE_DIR/" "$TARGET_DIR/" \
|
||
--exclude='.git' \
|
||
--exclude='node_modules' \
|
||
--exclude='__pycache__' \
|
||
--exclude='*.pyc' \
|
||
--exclude='dist' \
|
||
--exclude='backend/wordmaster.db' \
|
||
--exclude='backend/uploads/*' \
|
||
--exclude='frontend/.env.local' \
|
||
--exclude='.DS_Store'
|
||
|
||
print_success "文件复制完成"
|
||
|
||
# 3. 替换配置
|
||
print_info "更新配置文件..."
|
||
|
||
cd "$TARGET_DIR"
|
||
|
||
# 替换后端配置
|
||
if [ -f "backend/main.py" ]; then
|
||
# macOS 和 Linux 兼容的 sed
|
||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||
sed -i '' "s/wordmaster/$DATABASE_NAME/g" backend/main.py
|
||
sed -i '' "s/学习助手 Pro/$PROJECT_DISPLAY_NAME/g" backend/main.py
|
||
else
|
||
sed -i "s/wordmaster/$DATABASE_NAME/g" backend/main.py
|
||
sed -i "s/学习助手 Pro/$PROJECT_DISPLAY_NAME/g" backend/main.py
|
||
fi
|
||
fi
|
||
|
||
# 创建 .env 文件
|
||
cat > backend/.env << EOF
|
||
# Database Configuration
|
||
DATABASE_URL=$DATABASE_URL
|
||
|
||
# JWT Configuration
|
||
SECRET_KEY=$SECRET_KEY
|
||
ALGORITHM=HS256
|
||
ACCESS_TOKEN_EXPIRE_MINUTES=30
|
||
|
||
# OpenRouter AI Configuration (for Claude Sonnet 4.5 access)
|
||
# Get your API key from: https://openrouter.ai/keys
|
||
OPENROUTER_API_KEY=your-openrouter-api-key-here
|
||
|
||
# AI Model Selection
|
||
# Available models:
|
||
# - anthropic/claude-sonnet-4.5 (默认,通用能力强)
|
||
# - google/gemini-3-pro-preview (数学能力强,推荐数学试卷使用)
|
||
# - openai/gpt-4o
|
||
# - openai/gpt-4-turbo
|
||
AI_MODEL=anthropic/claude-sonnet-4.5
|
||
|
||
# Parser Configuration
|
||
USE_CLAUDE_PARSER=true
|
||
EOF
|
||
|
||
print_success "后端配置已更新"
|
||
|
||
# 替换前端配置
|
||
if [ -f "frontend/package.json" ]; then
|
||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||
sed -i '' "s/\"name\": \"wordmaster-frontend\"/\"name\": \"$PROJECT_NAME-frontend\"/g" frontend/package.json
|
||
else
|
||
sed -i "s/\"name\": \"wordmaster-frontend\"/\"name\": \"$PROJECT_NAME-frontend\"/g" frontend/package.json
|
||
fi
|
||
fi
|
||
|
||
if [ -f "frontend/index.html" ]; then
|
||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||
sed -i '' "s/<title>.*<\/title>/<title>$PROJECT_DISPLAY_NAME<\/title>/g" frontend/index.html
|
||
else
|
||
sed -i "s/<title>.*<\/title>/<title>$PROJECT_DISPLAY_NAME<\/title>/g" frontend/index.html
|
||
fi
|
||
fi
|
||
|
||
# 更新前端配置文件
|
||
if [ -f "frontend/src/config/index.js" ]; then
|
||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||
sed -i '' "s/:8888/:$API_PORT/g" frontend/src/config/index.js
|
||
else
|
||
sed -i "s/:8888/:$API_PORT/g" frontend/src/config/index.js
|
||
fi
|
||
fi
|
||
|
||
print_success "前端配置已更新"
|
||
|
||
# 4. 创建 README
|
||
print_info "生成项目 README..."
|
||
|
||
cat > README.md << EOF
|
||
# $PROJECT_DISPLAY_NAME
|
||
|
||
基于 FastAPI + Vue 3 全栈模板创建的项目。
|
||
|
||
## 快速启动
|
||
|
||
### 后端
|
||
|
||
\`\`\`bash
|
||
cd backend
|
||
|
||
# 安装依赖
|
||
pip install -r requirements.txt
|
||
|
||
# 启动服务
|
||
python main.py
|
||
# 访问 http://localhost:$API_PORT
|
||
# API 文档: http://localhost:$API_PORT/docs
|
||
\`\`\`
|
||
|
||
### 前端
|
||
|
||
\`\`\`bash
|
||
cd frontend
|
||
|
||
# 安装依赖
|
||
npm install
|
||
|
||
# 启动开发服务器
|
||
npm run dev
|
||
# 访问 http://localhost:$FRONTEND_PORT
|
||
\`\`\`
|
||
|
||
### 使用启动脚本
|
||
|
||
\`\`\`bash
|
||
# 同时启动前后端
|
||
./start.sh
|
||
|
||
# 查看状态
|
||
./status.sh
|
||
|
||
# 停止所有服务
|
||
./stop.sh
|
||
\`\`\`
|
||
|
||
## 配置
|
||
|
||
### 环境变量
|
||
|
||
后端配置文件: \`backend/.env\`
|
||
|
||
主要配置项:
|
||
- \`DATABASE_URL\`: 数据库连接
|
||
- \`SECRET_KEY\`: JWT 密钥 (已自动生成)
|
||
- \`OPENROUTER_API_KEY\`: AI API 密钥 (可选)
|
||
|
||
### 端口配置
|
||
|
||
- 后端 API: $API_PORT
|
||
- 前端开发: $FRONTEND_PORT
|
||
|
||
## 数据库
|
||
|
||
- 类型: $([ "$DB_TYPE" = "2" ] && echo "PostgreSQL" || echo "SQLite")
|
||
- 数据库名: $DATABASE_NAME
|
||
$([ "$DB_TYPE" = "2" ] && echo "- 连接: $PG_HOST:$PG_PORT" || echo "- 文件: $DATABASE_NAME.db")
|
||
|
||
首次运行时会自动创建数据库表。
|
||
|
||
## 技术栈
|
||
|
||
**后端:**
|
||
- FastAPI - 高性能 Web 框架
|
||
- SQLAlchemy - ORM
|
||
- JWT - 身份认证
|
||
- Pydantic - 数据验证
|
||
|
||
**前端:**
|
||
- Vue 3 - 渐进式框架
|
||
- Element Plus - UI 组件库
|
||
- Pinia - 状态管理
|
||
- Vite - 构建工具
|
||
|
||
## 文档
|
||
|
||
- 查看 \`TEMPLATE_GUIDE.md\` 了解详细开发指南
|
||
- 查看 \`CLAUDE.md\` 了解项目架构
|
||
|
||
## 部署
|
||
|
||
请参考 \`TEMPLATE_GUIDE.md\` 中的部署章节。
|
||
|
||
---
|
||
|
||
创建时间: $(date +%Y-%m-%d)
|
||
EOF
|
||
|
||
print_success "README 已生成"
|
||
|
||
# 5. 初始化 git
|
||
print_info "初始化 Git 仓库..."
|
||
git init
|
||
git add .
|
||
git commit -m "Initial commit: Created from template
|
||
|
||
Project: $PROJECT_DISPLAY_NAME
|
||
Database: $DATABASE_NAME
|
||
API Port: $API_PORT
|
||
Frontend Port: $FRONTEND_PORT
|
||
"
|
||
|
||
print_success "Git 仓库已初始化"
|
||
|
||
# 6. 创建启动帮助文档
|
||
cat > GETTING_STARTED.md << EOF
|
||
# 快速开始指南
|
||
|
||
## 第一次运行
|
||
|
||
### 1. 配置环境
|
||
|
||
#### 后端配置
|
||
已自动生成 \`backend/.env\` 文件,主要配置:
|
||
- ✅ 数据库已配置: $DATABASE_NAME
|
||
- ✅ JWT 密钥已生成
|
||
- ⚠️ 如需 AI 功能,请在 \`backend/.env\` 中设置 \`OPENROUTER_API_KEY\`
|
||
|
||
#### 前端配置
|
||
默认配置已就绪,无需修改。
|
||
|
||
### 2. 安装依赖
|
||
|
||
#### 后端依赖
|
||
\`\`\`bash
|
||
cd backend
|
||
pip install -r requirements.txt
|
||
\`\`\`
|
||
|
||
推荐使用虚拟环境:
|
||
\`\`\`bash
|
||
python -m venv venv
|
||
source venv/bin/activate # Linux/Mac
|
||
# 或
|
||
venv\\Scripts\\activate # Windows
|
||
pip install -r requirements.txt
|
||
\`\`\`
|
||
|
||
#### 前端依赖
|
||
\`\`\`bash
|
||
cd frontend
|
||
npm install
|
||
# 或使用 yarn
|
||
yarn install
|
||
\`\`\`
|
||
|
||
### 3. 启动开发服务器
|
||
|
||
#### 方式一: 使用启动脚本 (推荐)
|
||
\`\`\`bash
|
||
./start.sh
|
||
\`\`\`
|
||
|
||
#### 方式二: 手动启动
|
||
|
||
**后端:**
|
||
\`\`\`bash
|
||
cd backend
|
||
python main.py
|
||
\`\`\`
|
||
|
||
**前端:**
|
||
\`\`\`bash
|
||
cd frontend
|
||
npm run dev
|
||
\`\`\`
|
||
|
||
### 4. 访问应用
|
||
|
||
- 前端界面: http://localhost:$FRONTEND_PORT
|
||
- 后端 API: http://localhost:$API_PORT
|
||
- API 文档: http://localhost:$API_PORT/docs
|
||
|
||
### 5. 默认账户
|
||
|
||
首次访问需要注册账户。系统会自动创建数据库表。
|
||
|
||
## 开发流程
|
||
|
||
### 添加新功能
|
||
|
||
1. **后端 API**
|
||
- 编辑 \`backend/main.py\`
|
||
- 添加新的端点和数据模型
|
||
- 自动重载会生效
|
||
|
||
2. **前端页面**
|
||
- 在 \`frontend/src/views/\` 创建新组件
|
||
- 在 \`frontend/src/router/index.js\` 注册路由
|
||
- Vite 会自动热更新
|
||
|
||
3. **状态管理**
|
||
- 在 \`frontend/src/stores/\` 创建新 store
|
||
- 使用 Pinia 管理全局状态
|
||
|
||
### 调试技巧
|
||
|
||
**后端调试:**
|
||
- 查看终端日志
|
||
- 访问 http://localhost:$API_PORT/docs 测试 API
|
||
- 使用 Python 调试器
|
||
|
||
**前端调试:**
|
||
- 使用浏览器开发者工具
|
||
- Vue DevTools 扩展
|
||
- 检查网络请求
|
||
|
||
## 常见问题
|
||
|
||
### 端口被占用
|
||
修改配置文件中的端口号:
|
||
- 后端: \`backend/.env\` 或 \`backend/main.py\`
|
||
- 前端: \`frontend/vite.config.js\`
|
||
|
||
### 数据库连接失败
|
||
- SQLite: 检查文件权限
|
||
- PostgreSQL: 检查连接字符串和服务状态
|
||
|
||
### 前端 API 请求失败
|
||
检查 \`frontend/src/config/index.js\` 中的 API_BASE_URL 配置
|
||
|
||
## 下一步
|
||
|
||
- 📖 阅读 \`TEMPLATE_GUIDE.md\` 了解完整功能
|
||
- 🔧 根据需求定制功能模块
|
||
- 🚀 参考部署指南发布应用
|
||
|
||
祝开发顺利! 🎉
|
||
EOF
|
||
|
||
print_success "快速开始指南已生成"
|
||
|
||
# 完成
|
||
echo ""
|
||
print_header "项目创建完成!"
|
||
echo ""
|
||
echo -e "${GREEN}✨ 项目已成功创建在: $TARGET_DIR${NC}"
|
||
echo ""
|
||
echo -e "${BLUE}下一步:${NC}"
|
||
echo ""
|
||
echo -e " 1. 进入项目目录:"
|
||
echo -e " ${YELLOW}cd $TARGET_DIR${NC}"
|
||
echo ""
|
||
echo -e " 2. 安装后端依赖:"
|
||
echo -e " ${YELLOW}cd backend && pip install -r requirements.txt${NC}"
|
||
echo ""
|
||
echo -e " 3. 安装前端依赖:"
|
||
echo -e " ${YELLOW}cd frontend && npm install${NC}"
|
||
echo ""
|
||
echo -e " 4. 启动项目:"
|
||
echo -e " ${YELLOW}./start.sh${NC}"
|
||
echo ""
|
||
echo -e " 5. 访问应用:"
|
||
echo -e " ${YELLOW}http://localhost:$FRONTEND_PORT${NC}"
|
||
echo ""
|
||
echo -e "${BLUE}📚 详细文档:${NC}"
|
||
echo -e " - GETTING_STARTED.md - 快速开始"
|
||
echo -e " - TEMPLATE_GUIDE.md - 完整指南"
|
||
echo -e " - README.md - 项目说明"
|
||
echo ""
|
||
print_success "祝您开发顺利! 🚀"
|
||
echo ""
|