Files
python-template/create-from-template.sh
2025-11-27 21:17:46 +08:00

514 lines
12 KiB
Bash
Executable File
Raw Permalink 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
# 项目模板创建脚本
# 用法: ./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 ""