first commit
This commit is contained in:
79
.gitignore
vendored
Normal file
79
.gitignore
vendored
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
# 依赖目录
|
||||||
|
node_modules/
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
|
pnpm-lock.yaml
|
||||||
|
|
||||||
|
# 构建输出
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.test
|
||||||
|
|
||||||
|
# Go 编译输出
|
||||||
|
*.exe
|
||||||
|
*.test
|
||||||
|
*.out
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Python
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
*.so
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
venv/
|
||||||
|
env/
|
||||||
|
|
||||||
|
# Java
|
||||||
|
*.class
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
||||||
|
target/
|
||||||
|
.mvn/
|
||||||
|
|
||||||
|
# 数据文件
|
||||||
|
data/data.json
|
||||||
|
|
||||||
|
# 日志
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# 操作系统文件
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
desktop.ini
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# 测试覆盖率
|
||||||
|
coverage/
|
||||||
|
.nyc_output/
|
||||||
|
|
||||||
|
# 环境变量
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
174
README.md
Normal file
174
README.md
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
# QuickStack - 前后端分离项目初始化工具
|
||||||
|
|
||||||
|
[](https://www.python.org/downloads/)
|
||||||
|
[](https://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
> 🚀 **QuickStack** - 一款强大的全栈项目初始化工具,让你在几秒钟内搭建好前后端分离的开发环境。
|
||||||
|
|
||||||
|
## ✨ 功能特性
|
||||||
|
|
||||||
|
- **多种前端框架支持**: React, Vue
|
||||||
|
- **丰富的后端选择**: Go(标准库/Gin), Python(Flask/FastAPI/Django), Java(Spring Boot), JavaScript(Express.js/NestJS)
|
||||||
|
- **集成 Tailwind CSS**: 一键配置现代化的 CSS 框架
|
||||||
|
- **自动生成启动脚本**: Windows BAT 脚本,双击即可启动项目
|
||||||
|
- **跨域配置**: 所有后端模板均已配置 CORS,前后端联调无障碍
|
||||||
|
- **交互式 CLI**: 友好的命令行交互界面
|
||||||
|
|
||||||
|
## 📦 支持的技术栈
|
||||||
|
|
||||||
|
### 前端框架
|
||||||
|
- ⚛️ React (Vite + React)
|
||||||
|
- 💚 Vue (Vite + Vue)
|
||||||
|
|
||||||
|
### 后端框架
|
||||||
|
- 🐹 Go (标准库 http)
|
||||||
|
- 🚀 Go (Gin 框架)
|
||||||
|
- 🐍 Python (Flask)
|
||||||
|
- ⚡ Python (FastAPI)
|
||||||
|
- 🎯 Python (Django)
|
||||||
|
- ☕ Java (Spring Boot)
|
||||||
|
- 🟨 JavaScript (Express.js)
|
||||||
|
- 🐈⬛ JavaScript (NestJS)
|
||||||
|
|
||||||
|
## 🔧 环境要求
|
||||||
|
|
||||||
|
- Python 3.8+
|
||||||
|
- Node.js 16+ (前端项目和 JS 后端需要)
|
||||||
|
- Go 1.18+ (Go 后端需要)
|
||||||
|
- Java 17+ 和 Maven 3.6+ (Spring Boot 后端需要)
|
||||||
|
|
||||||
|
## 🚀 使用方法
|
||||||
|
|
||||||
|
### 1. 克隆项目
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone <your-repo-url>
|
||||||
|
cd QuickStack
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 运行初始化脚本
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 按照提示操作
|
||||||
|
|
||||||
|
- 输入项目名称(英文)
|
||||||
|
- 选择前端框架(React/Vue)
|
||||||
|
- 选择是否使用 Tailwind CSS
|
||||||
|
- 选择后端框架
|
||||||
|
|
||||||
|
### 4. 启动项目
|
||||||
|
|
||||||
|
进入生成的项目目录,双击运行:
|
||||||
|
|
||||||
|
- `开启前端.bat` - 启动前端开发服务器
|
||||||
|
- `开启后端.bat` - 启动后端服务
|
||||||
|
- `构建前端.bat` - 构建前端生产版本
|
||||||
|
|
||||||
|
## 📁 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
QuickStack/
|
||||||
|
├── main.py # 主程序入口
|
||||||
|
├── utils.py # 工具函数
|
||||||
|
├── directory.py # 目录管理
|
||||||
|
├── scripts.py # 启动脚本生成
|
||||||
|
├── frontend/ # 前端模块
|
||||||
|
│ ├── react.py # React 初始化
|
||||||
|
│ ├── vue.py # Vue 初始化
|
||||||
|
│ └── tailwind.py # Tailwind CSS 配置
|
||||||
|
├── backend/ # 后端模块
|
||||||
|
│ ├── golang.py # Go 初始化
|
||||||
|
│ ├── python_flask.py # Flask 初始化
|
||||||
|
│ ├── python_fastapi.py# FastAPI 初始化
|
||||||
|
│ ├── python_django.py # Django 初始化
|
||||||
|
│ ├── java_spring.py # Spring Boot 初始化
|
||||||
|
│ ├── js_express.py # Express.js 初始化
|
||||||
|
│ └── js_nestjs.py # NestJS 初始化
|
||||||
|
└── README.md # 项目说明
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎯 生成的项目示例
|
||||||
|
|
||||||
|
```
|
||||||
|
myproject/
|
||||||
|
├── myproject-frontend/ # 前端项目
|
||||||
|
│ ├── src/
|
||||||
|
│ ├── package.json
|
||||||
|
│ └── ...
|
||||||
|
├── myproject-backend/ # 后端项目
|
||||||
|
│ ├── src/ 或 main.go 等
|
||||||
|
│ └── ...
|
||||||
|
├── 开启前端.bat # 启动前端
|
||||||
|
├── 开启后端.bat # 启动后端
|
||||||
|
└── 构建前端.bat # 构建前端
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔌 API 端点
|
||||||
|
|
||||||
|
所有后端模板都包含健康检查端点:
|
||||||
|
|
||||||
|
```
|
||||||
|
GET http://localhost:8080/api/health
|
||||||
|
```
|
||||||
|
|
||||||
|
响应示例:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "ok",
|
||||||
|
"message": "Welcome to myproject API"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## ⚙️ 自定义配置
|
||||||
|
|
||||||
|
### Tailwind CSS
|
||||||
|
|
||||||
|
如果选择使用 Tailwind CSS,会自动:
|
||||||
|
- 安装 tailwindcss、postcss、autoprefixer
|
||||||
|
- 初始化配置文件
|
||||||
|
- 更新 CSS 文件
|
||||||
|
- 创建示例组件
|
||||||
|
|
||||||
|
### CORS 跨域
|
||||||
|
|
||||||
|
所有后端模板均已配置 CORS,允许:
|
||||||
|
- 来源: `*` (所有域名)
|
||||||
|
- 方法: GET, POST, PUT, DELETE, OPTIONS
|
||||||
|
- 请求头: Content-Type, Authorization 等
|
||||||
|
|
||||||
|
## 📝 注意事项
|
||||||
|
|
||||||
|
1. **Windows 专用**: 本项目生成的启动脚本是 `.bat` 格式,专用于 Windows 系统
|
||||||
|
2. **Python 虚拟环境**: Python 后端会自动创建虚拟环境并安装依赖
|
||||||
|
3. **npm 依赖**: 前端项目会自动安装 npm 依赖
|
||||||
|
4. **端口**: 后端服务默认运行在 8080 端口
|
||||||
|
|
||||||
|
## 🐛 常见问题
|
||||||
|
|
||||||
|
### Q: 前端项目创建失败?
|
||||||
|
A: 请确保已安装 Node.js (16+) 和 npm,并检查网络连接。
|
||||||
|
|
||||||
|
### Q: Python 后端依赖安装失败?
|
||||||
|
A: 请确保 Python 环境正常,并检查 pip 是否可用。可以手动进入目录运行 `pip install -r requirements.txt`。
|
||||||
|
|
||||||
|
### Q: 如何修改默认端口?
|
||||||
|
A: 修改后端项目的配置文件或代码中的端口设置即可。
|
||||||
|
|
||||||
|
## 🤝 贡献
|
||||||
|
|
||||||
|
欢迎提交 Issue 和 Pull Request!
|
||||||
|
|
||||||
|
## 📄 许可证
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
## 💖 致谢
|
||||||
|
|
||||||
|
感谢使用 QuickStack!祝开发愉快!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**QuickStack** - 让全栈开发更简单 🚀
|
||||||
23
backend/__init__.py
Normal file
23
backend/__init__.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
后端模块包
|
||||||
|
"""
|
||||||
|
|
||||||
|
from backend.golang import init_golang_project, init_gin_project
|
||||||
|
from backend.python_flask import init_flask_project
|
||||||
|
from backend.python_fastapi import init_fastapi_project
|
||||||
|
from backend.python_django import init_django_project
|
||||||
|
from backend.java_spring import init_spring_project
|
||||||
|
from backend.js_express import init_express_project
|
||||||
|
from backend.js_nestjs import init_nestjs_project
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
'init_golang_project',
|
||||||
|
'init_gin_project',
|
||||||
|
'init_flask_project',
|
||||||
|
'init_fastapi_project',
|
||||||
|
'init_django_project',
|
||||||
|
'init_spring_project',
|
||||||
|
'init_express_project',
|
||||||
|
'init_nestjs_project'
|
||||||
|
]
|
||||||
202
backend/golang.py
Normal file
202
backend/golang.py
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Go 后端项目初始化模块
|
||||||
|
"""
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def run_command_with_progress(cmd, cwd, description):
|
||||||
|
"""运行命令并显示实时输出"""
|
||||||
|
try:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"执行: {description}")
|
||||||
|
print(f"{'=' * 60}")
|
||||||
|
|
||||||
|
process = subprocess.Popen(
|
||||||
|
cmd,
|
||||||
|
cwd=cwd,
|
||||||
|
shell=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
bufsize=0
|
||||||
|
)
|
||||||
|
|
||||||
|
for line in process.stdout:
|
||||||
|
try:
|
||||||
|
decoded_line = line.decode('utf-8', errors='replace')
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
decoded_line = line.decode('gbk', errors='replace')
|
||||||
|
except:
|
||||||
|
decoded_line = line.decode('latin-1', errors='replace')
|
||||||
|
print(decoded_line, end='')
|
||||||
|
|
||||||
|
process.wait()
|
||||||
|
|
||||||
|
if process.returncode == 0:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"✅ {description} - 完成")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"❌ {description} - 失败 (错误码: {process.returncode})")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n❌ 执行失败: {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def init_golang_project(backend_dir, project_name):
|
||||||
|
"""初始化 Go 后端项目"""
|
||||||
|
print("\n🚀 初始化 Go 后端项目...")
|
||||||
|
|
||||||
|
# 初始化 Go 模块
|
||||||
|
success = run_command_with_progress(
|
||||||
|
f"go mod init {project_name}-backend",
|
||||||
|
backend_dir,
|
||||||
|
"初始化 Go 模块"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not success:
|
||||||
|
print("\n💡 提示: 请确保已安装 Go")
|
||||||
|
print(" 下载地址: https://golang.org/dl/")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# 创建 main.go - 使用标准库
|
||||||
|
main_go = backend_dir / "main.go"
|
||||||
|
main_go.write_text(f'''package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {{
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
|
||||||
|
// 健康检查接口
|
||||||
|
mux.HandleFunc("GET /api/health", healthHandler)
|
||||||
|
|
||||||
|
// 添加 CORS 中间件
|
||||||
|
handler := corsMiddleware(mux)
|
||||||
|
|
||||||
|
log.Println("🚀 服务器启动: http://localhost:8080")
|
||||||
|
log.Println("📍 健康检查: http://localhost:8080/api/health")
|
||||||
|
log.Fatal(http.ListenAndServe(":8080", handler))
|
||||||
|
}}
|
||||||
|
|
||||||
|
func healthHandler(w http.ResponseWriter, r *http.Request) {{
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(map[string]string{{
|
||||||
|
"status": "ok",
|
||||||
|
"message": "Welcome to {project_name} API",
|
||||||
|
}})
|
||||||
|
}}
|
||||||
|
|
||||||
|
func corsMiddleware(next http.Handler) http.Handler {{
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {{
|
||||||
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
|
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
|
||||||
|
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
|
||||||
|
|
||||||
|
if r.Method == "OPTIONS" {{
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
return
|
||||||
|
}}
|
||||||
|
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
}})
|
||||||
|
}}
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
# 整理依赖
|
||||||
|
run_command_with_progress("go mod tidy", backend_dir, "整理 Go 依赖")
|
||||||
|
|
||||||
|
print("\n✅ Go 后端项目初始化成功")
|
||||||
|
print("💡 启动命令: go run main.go")
|
||||||
|
print("📝 注意: 使用 Go 标准库,无需第三方依赖")
|
||||||
|
|
||||||
|
|
||||||
|
def init_gin_project(backend_dir, project_name):
|
||||||
|
"""初始化 Go Gin 后端项目"""
|
||||||
|
print("\n🚀 初始化 Go Gin 后端项目...")
|
||||||
|
|
||||||
|
# 初始化 Go 模块
|
||||||
|
success = run_command_with_progress(
|
||||||
|
f"go mod init {project_name}-backend",
|
||||||
|
backend_dir,
|
||||||
|
"初始化 Go 模块"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not success:
|
||||||
|
print("\n💡 提示: 请确保已安装 Go")
|
||||||
|
print(" 下载地址: https://golang.org/dl/")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# 拉取 Gin 依赖
|
||||||
|
deps_ok = run_command_with_progress(
|
||||||
|
"go get github.com/gin-gonic/gin github.com/gin-contrib/cors",
|
||||||
|
backend_dir,
|
||||||
|
"安装 Gin 依赖"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not deps_ok:
|
||||||
|
print("\n❌ 无法安装 Gin 依赖,请检查 Go 环境和网络")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# 创建 main.go - Gin 框架
|
||||||
|
main_go = backend_dir / "main.go"
|
||||||
|
main_go.write_text(f'''package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-contrib/cors"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {{
|
||||||
|
r := gin.New()
|
||||||
|
r.Use(gin.Logger())
|
||||||
|
r.Use(gin.Recovery())
|
||||||
|
|
||||||
|
// CORS 配置
|
||||||
|
r.Use(cors.New(cors.Config{{
|
||||||
|
AllowOrigins: []string{{"*"}},
|
||||||
|
AllowMethods: []string{{"GET", "POST", "PUT", "DELETE", "OPTIONS"}},
|
||||||
|
AllowHeaders: []string{{"Origin", "Content-Type", "Authorization"}},
|
||||||
|
ExposeHeaders: []string{{"Content-Length"}},
|
||||||
|
AllowCredentials: false,
|
||||||
|
MaxAge: 12 * time.Hour,
|
||||||
|
}}))
|
||||||
|
|
||||||
|
// 健康检查
|
||||||
|
r.GET("/api/health", func(c *gin.Context) {{
|
||||||
|
c.JSON(200, gin.H{{
|
||||||
|
"status": "ok",
|
||||||
|
"message": "Welcome to {project_name} API",
|
||||||
|
}})
|
||||||
|
}})
|
||||||
|
|
||||||
|
addr := ":8080"
|
||||||
|
log.Printf("🚀 Gin 服务启动: http://localhost%s", addr)
|
||||||
|
log.Printf("📍 健康检查: http://localhost%s/api/health", addr)
|
||||||
|
|
||||||
|
if err := r.Run(addr); err != nil {{
|
||||||
|
log.Fatalf("启动失败: %v", err)
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
# 整理依赖
|
||||||
|
run_command_with_progress("go mod tidy", backend_dir, "整理 Go 依赖")
|
||||||
|
|
||||||
|
print("\n✅ Go Gin 后端项目初始化成功")
|
||||||
|
print("💡 启动命令: go run main.go")
|
||||||
104
backend/java_spring.py
Normal file
104
backend/java_spring.py
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Java Spring Boot 后端项目初始化模块
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def init_spring_project(backend_dir, project_name):
|
||||||
|
"""初始化 Spring Boot 项目"""
|
||||||
|
print("\n🚀 初始化 Spring Boot 项目...")
|
||||||
|
|
||||||
|
# 创建基本的 Spring Boot 项目结构
|
||||||
|
src_main = backend_dir / "src" / "main"
|
||||||
|
src_main_java = src_main / "java" / "com" / project_name.replace("-", "")
|
||||||
|
src_main_resources = src_main / "resources"
|
||||||
|
|
||||||
|
src_main_java.mkdir(parents=True, exist_ok=True)
|
||||||
|
src_main_resources.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
# 创建主应用类
|
||||||
|
package_name = project_name.replace("-", "")
|
||||||
|
app_java = src_main_java / "Application.java"
|
||||||
|
app_java.write_text(f'''package com.{package_name};
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@RestController
|
||||||
|
@CrossOrigin(origins = "*")
|
||||||
|
public class Application {{
|
||||||
|
|
||||||
|
public static void main(String[] args) {{
|
||||||
|
System.out.println("🚀 服务器启动: http://localhost:8080");
|
||||||
|
System.out.println("📍 健康检查: http://localhost:8080/api/health");
|
||||||
|
SpringApplication.run(Application.class, args);
|
||||||
|
}}
|
||||||
|
|
||||||
|
@GetMapping("/api/health")
|
||||||
|
public Map<String, String> health() {{
|
||||||
|
Map<String, String> response = new HashMap<>();
|
||||||
|
response.put("status", "ok");
|
||||||
|
response.put("message", "Welcome to {project_name} API");
|
||||||
|
return response;
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
# 创建 application.properties
|
||||||
|
app_properties = src_main_resources / "application.properties"
|
||||||
|
app_properties.write_text(f'''server.port=8080
|
||||||
|
spring.application.name={project_name}
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
# 创建 pom.xml
|
||||||
|
pom_xml = backend_dir / "pom.xml"
|
||||||
|
pom_xml.write_text(f'''<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||||
|
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
<relativePath/>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>com.{package_name}</groupId>
|
||||||
|
<artifactId>{project_name}-backend</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>{project_name}</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>17</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
print("\n✅ Spring Boot 项目初始化成功")
|
||||||
|
print("💡 启动命令: mvn spring-boot:run")
|
||||||
|
print("⚠️ 注意: 需要安装 Maven 和 JDK 17+ 才能运行此项目")
|
||||||
128
backend/js_express.py
Normal file
128
backend/js_express.py
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
JavaScript Express.js 后端项目初始化模块
|
||||||
|
"""
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def run_command_with_progress(cmd, cwd, description):
|
||||||
|
"""运行命令并显示实时输出"""
|
||||||
|
try:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"执行: {description}")
|
||||||
|
print(f"{'=' * 60}")
|
||||||
|
|
||||||
|
process = subprocess.Popen(
|
||||||
|
cmd,
|
||||||
|
cwd=cwd,
|
||||||
|
shell=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
bufsize=0
|
||||||
|
)
|
||||||
|
|
||||||
|
for line in process.stdout:
|
||||||
|
try:
|
||||||
|
decoded_line = line.decode('utf-8', errors='replace')
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
decoded_line = line.decode('gbk', errors='replace')
|
||||||
|
except:
|
||||||
|
decoded_line = line.decode('latin-1', errors='replace')
|
||||||
|
print(decoded_line, end='')
|
||||||
|
|
||||||
|
process.wait()
|
||||||
|
|
||||||
|
if process.returncode == 0:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"✅ {description} - 完成")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"❌ {description} - 失败 (错误码: {process.returncode})")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n❌ 执行失败: {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def init_express_project(backend_dir, project_name):
|
||||||
|
"""初始化 Express.js 项目"""
|
||||||
|
print("\n🚀 初始化 Express.js 项目...")
|
||||||
|
|
||||||
|
# 初始化 npm 项目
|
||||||
|
success = run_command_with_progress(
|
||||||
|
"npm init -y",
|
||||||
|
backend_dir,
|
||||||
|
"初始化 npm 项目"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not success:
|
||||||
|
print("\n💡 提示: 请确保已安装 Node.js 和 npm")
|
||||||
|
print(" 下载地址: https://nodejs.org/")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# 安装依赖
|
||||||
|
run_command_with_progress(
|
||||||
|
"npm install express cors",
|
||||||
|
backend_dir,
|
||||||
|
"安装 Express.js 依赖"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 安装开发依赖
|
||||||
|
run_command_with_progress(
|
||||||
|
"npm install -D nodemon",
|
||||||
|
backend_dir,
|
||||||
|
"安装开发依赖 (nodemon)"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 创建 app.js
|
||||||
|
app_js = backend_dir / "app.js"
|
||||||
|
app_js.write_text(f'''const express = require('express');
|
||||||
|
const cors = require('cors');
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
const PORT = 8080;
|
||||||
|
|
||||||
|
// 中间件
|
||||||
|
app.use(cors());
|
||||||
|
app.use(express.json());
|
||||||
|
|
||||||
|
// 健康检查接口
|
||||||
|
app.get('/api/health', (req, res) => {{
|
||||||
|
res.json({{
|
||||||
|
status: 'ok',
|
||||||
|
message: 'Welcome to {project_name} API'
|
||||||
|
}});
|
||||||
|
}});
|
||||||
|
|
||||||
|
// 示例接口
|
||||||
|
app.get('/api/hello', (req, res) => {{
|
||||||
|
res.json({{ message: 'Hello from Express.js!' }});
|
||||||
|
}});
|
||||||
|
|
||||||
|
// 启动服务器
|
||||||
|
app.listen(PORT, () => {{
|
||||||
|
console.log('🚀 服务器启动: http://localhost:' + PORT);
|
||||||
|
console.log('📍 健康检查: http://localhost:' + PORT + '/api/health');
|
||||||
|
}});
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
# 更新 package.json 添加脚本
|
||||||
|
package_json = backend_dir / "package.json"
|
||||||
|
import json
|
||||||
|
pkg = json.loads(package_json.read_text(encoding='utf-8'))
|
||||||
|
pkg['scripts'] = {
|
||||||
|
'start': 'node app.js',
|
||||||
|
'dev': 'nodemon app.js'
|
||||||
|
}
|
||||||
|
pkg['name'] = f'{project_name}-backend'
|
||||||
|
package_json.write_text(json.dumps(pkg, indent=2, ensure_ascii=False), encoding='utf-8')
|
||||||
|
|
||||||
|
print("\n✅ Express.js 项目初始化成功")
|
||||||
|
print("💡 启动命令: npm run dev (开发模式) 或 npm start (生产模式)")
|
||||||
158
backend/js_nestjs.py
Normal file
158
backend/js_nestjs.py
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
JavaScript NestJS 后端项目初始化模块
|
||||||
|
"""
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
|
||||||
|
def run_command_interactive(cmd, cwd, description):
|
||||||
|
"""运行命令并支持用户交互"""
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"执行: {description}")
|
||||||
|
print(f"{'=' * 60}")
|
||||||
|
print(f"💡 提示: 此步骤可能需要您进行交互操作")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = subprocess.run(cmd, cwd=cwd, shell=True)
|
||||||
|
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
if result.returncode == 0:
|
||||||
|
print(f"✅ {description} - 完成")
|
||||||
|
else:
|
||||||
|
print(f"❌ {description} - 失败 (错误码: {result.returncode})")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
|
||||||
|
return result.returncode == 0
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n❌ 执行失败: {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def run_command_with_progress(cmd, cwd, description):
|
||||||
|
"""运行命令并显示实时输出"""
|
||||||
|
try:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"执行: {description}")
|
||||||
|
print(f"{'=' * 60}")
|
||||||
|
|
||||||
|
process = subprocess.Popen(
|
||||||
|
cmd,
|
||||||
|
cwd=cwd,
|
||||||
|
shell=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
bufsize=0
|
||||||
|
)
|
||||||
|
|
||||||
|
for line in process.stdout:
|
||||||
|
try:
|
||||||
|
decoded_line = line.decode('utf-8', errors='replace')
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
decoded_line = line.decode('gbk', errors='replace')
|
||||||
|
except:
|
||||||
|
decoded_line = line.decode('latin-1', errors='replace')
|
||||||
|
print(decoded_line, end='')
|
||||||
|
|
||||||
|
process.wait()
|
||||||
|
|
||||||
|
if process.returncode == 0:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"✅ {description} - 完成")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"❌ {description} - 失败 (错误码: {process.returncode})")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n❌ 执行失败: {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def init_nestjs_project(backend_dir, project_name):
|
||||||
|
"""初始化 NestJS 项目"""
|
||||||
|
print("\n🚀 初始化 NestJS 项目...")
|
||||||
|
print("\n⚠️ 重要提示:")
|
||||||
|
print(" 1. NestJS CLI 会询问使用哪个包管理器,建议选择 npm")
|
||||||
|
print(" 2. 创建过程可能需要几分钟,请耐心等待\n")
|
||||||
|
|
||||||
|
# 删除空目录,因为 NestJS CLI 需要创建目录
|
||||||
|
backend_dir.rmdir()
|
||||||
|
|
||||||
|
# 使用 NestJS CLI 创建项目
|
||||||
|
success = run_command_interactive(
|
||||||
|
f"npx @nestjs/cli new {backend_dir.name} --skip-git",
|
||||||
|
backend_dir.parent,
|
||||||
|
"创建 NestJS 项目"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not success:
|
||||||
|
# 如果失败,重新创建目录
|
||||||
|
backend_dir.mkdir(exist_ok=True)
|
||||||
|
print("\n💡 提示: 请确保已安装 Node.js 和 npm")
|
||||||
|
print(" 下载地址: https://nodejs.org/")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# 检查目录是否创建成功
|
||||||
|
if not backend_dir.exists():
|
||||||
|
print("❌ 项目目录创建失败")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# 修改默认端口为 8080 并添加 CORS
|
||||||
|
main_ts = backend_dir / "src" / "main.ts"
|
||||||
|
if main_ts.exists():
|
||||||
|
main_ts.write_text(f'''import {{ NestFactory }} from '@nestjs/core';
|
||||||
|
import {{ AppModule }} from './app.module';
|
||||||
|
|
||||||
|
async function bootstrap() {{
|
||||||
|
const app = await NestFactory.create(AppModule);
|
||||||
|
|
||||||
|
// 启用 CORS
|
||||||
|
app.enableCors();
|
||||||
|
|
||||||
|
// 设置全局前缀
|
||||||
|
app.setGlobalPrefix('api');
|
||||||
|
|
||||||
|
await app.listen(8080);
|
||||||
|
console.log('🚀 服务器启动: http://localhost:8080');
|
||||||
|
console.log('📍 健康检查: http://localhost:8080/api/health');
|
||||||
|
}}
|
||||||
|
bootstrap();
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
# 修改 AppController 添加健康检查
|
||||||
|
app_controller = backend_dir / "src" / "app.controller.ts"
|
||||||
|
if app_controller.exists():
|
||||||
|
app_controller.write_text(f'''import {{ Controller, Get }} from '@nestjs/common';
|
||||||
|
import {{ AppService }} from './app.service';
|
||||||
|
|
||||||
|
@Controller()
|
||||||
|
export class AppController {{
|
||||||
|
constructor(private readonly appService: AppService) {{}}
|
||||||
|
|
||||||
|
@Get('health')
|
||||||
|
health() {{
|
||||||
|
return {{
|
||||||
|
status: 'ok',
|
||||||
|
message: 'Welcome to {project_name} API',
|
||||||
|
}};
|
||||||
|
}}
|
||||||
|
|
||||||
|
@Get('hello')
|
||||||
|
getHello(): string {{
|
||||||
|
return this.appService.getHello();
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
print("\n✅ NestJS 项目初始化成功")
|
||||||
|
print("💡 启动命令: npm run start:dev (开发模式) 或 npm run start (生产模式)")
|
||||||
|
print("📚 NestJS 文档: https://docs.nestjs.com/")
|
||||||
206
backend/python_django.py
Normal file
206
backend/python_django.py
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Python Django 后端项目初始化模块
|
||||||
|
"""
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def run_command_with_progress(cmd, cwd, description):
|
||||||
|
"""运行命令并显示实时输出"""
|
||||||
|
try:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"执行: {description}")
|
||||||
|
print(f"{'=' * 60}")
|
||||||
|
|
||||||
|
process = subprocess.Popen(
|
||||||
|
cmd,
|
||||||
|
cwd=cwd,
|
||||||
|
shell=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
bufsize=0
|
||||||
|
)
|
||||||
|
|
||||||
|
for line in process.stdout:
|
||||||
|
try:
|
||||||
|
decoded_line = line.decode('utf-8', errors='replace')
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
decoded_line = line.decode('gbk', errors='replace')
|
||||||
|
except:
|
||||||
|
decoded_line = line.decode('latin-1', errors='replace')
|
||||||
|
print(decoded_line, end='')
|
||||||
|
|
||||||
|
process.wait()
|
||||||
|
|
||||||
|
if process.returncode == 0:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"✅ {description} - 完成")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"❌ {description} - 失败 (错误码: {process.returncode})")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n❌ 执行失败: {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def init_django_project(backend_dir, project_name):
|
||||||
|
"""初始化 Django 项目"""
|
||||||
|
print("\n🚀 初始化 Django 项目...")
|
||||||
|
|
||||||
|
# 创建虚拟环境
|
||||||
|
success = run_command_with_progress(
|
||||||
|
f'"{sys.executable}" -m venv venv',
|
||||||
|
backend_dir,
|
||||||
|
"创建 Python 虚拟环境"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not success:
|
||||||
|
print("\n⚠️ 虚拟环境创建失败,请检查 Python 安装")
|
||||||
|
return
|
||||||
|
|
||||||
|
venv_python = backend_dir / "venv" / "Scripts" / "python.exe"
|
||||||
|
venv_pip = backend_dir / "venv" / "Scripts" / "pip.exe"
|
||||||
|
|
||||||
|
if not venv_python.exists():
|
||||||
|
print("\n⚠️ 虚拟环境创建失败")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 安装 Django 和 CORS 支持
|
||||||
|
run_command_with_progress(
|
||||||
|
f'"{venv_pip}" install django django-cors-headers',
|
||||||
|
backend_dir,
|
||||||
|
"安装 Django 依赖"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 使用 django-admin 创建项目
|
||||||
|
django_admin = backend_dir / "venv" / "Scripts" / "django-admin.exe"
|
||||||
|
run_command_with_progress(
|
||||||
|
f'"{django_admin}" startproject config .',
|
||||||
|
backend_dir,
|
||||||
|
"创建 Django 项目"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 创建 api 应用
|
||||||
|
run_command_with_progress(
|
||||||
|
f'"{venv_python}" manage.py startapp api',
|
||||||
|
backend_dir,
|
||||||
|
"创建 api 应用"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 创建 requirements.txt
|
||||||
|
requirements = backend_dir / "requirements.txt"
|
||||||
|
requirements.write_text('''Django==5.0.0
|
||||||
|
django-cors-headers==4.3.0
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
# 修改 settings.py 添加 CORS 和 api 应用
|
||||||
|
settings_file = backend_dir / "config" / "settings.py"
|
||||||
|
if settings_file.exists():
|
||||||
|
settings_content = settings_file.read_text(encoding='utf-8')
|
||||||
|
|
||||||
|
# 添加 INSTALLED_APPS
|
||||||
|
settings_content = settings_content.replace(
|
||||||
|
"INSTALLED_APPS = [",
|
||||||
|
"""INSTALLED_APPS = [
|
||||||
|
'corsheaders',
|
||||||
|
'api',"""
|
||||||
|
)
|
||||||
|
|
||||||
|
# 添加 MIDDLEWARE
|
||||||
|
settings_content = settings_content.replace(
|
||||||
|
"MIDDLEWARE = [",
|
||||||
|
"""MIDDLEWARE = [
|
||||||
|
'corsheaders.middleware.CorsMiddleware',"""
|
||||||
|
)
|
||||||
|
|
||||||
|
# 添加 CORS 配置
|
||||||
|
settings_content += """
|
||||||
|
|
||||||
|
# CORS 配置
|
||||||
|
CORS_ALLOW_ALL_ORIGINS = True
|
||||||
|
|
||||||
|
# 允许的请求头
|
||||||
|
CORS_ALLOW_HEADERS = [
|
||||||
|
'accept',
|
||||||
|
'accept-encoding',
|
||||||
|
'authorization',
|
||||||
|
'content-type',
|
||||||
|
'dnt',
|
||||||
|
'origin',
|
||||||
|
'user-agent',
|
||||||
|
'x-csrftoken',
|
||||||
|
'x-requested-with',
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
settings_file.write_text(settings_content, encoding='utf-8')
|
||||||
|
|
||||||
|
# 创建 api/views.py
|
||||||
|
api_views = backend_dir / "api" / "views.py"
|
||||||
|
api_views.write_text(f'''from django.http import JsonResponse
|
||||||
|
|
||||||
|
|
||||||
|
def health(request):
|
||||||
|
"""健康检查接口"""
|
||||||
|
return JsonResponse({{
|
||||||
|
'status': 'ok',
|
||||||
|
'message': 'Welcome to {project_name} API'
|
||||||
|
}})
|
||||||
|
|
||||||
|
|
||||||
|
def hello(request):
|
||||||
|
"""示例接口"""
|
||||||
|
return JsonResponse({{
|
||||||
|
'message': 'Hello from Django!'
|
||||||
|
}})
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
# 创建 api/urls.py
|
||||||
|
api_urls = backend_dir / "api" / "urls.py"
|
||||||
|
api_urls.write_text('''from django.urls import path
|
||||||
|
from . import views
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('health', views.health, name='health'),
|
||||||
|
path('hello', views.hello, name='hello'),
|
||||||
|
]
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
# 修改主 urls.py
|
||||||
|
main_urls = backend_dir / "config" / "urls.py"
|
||||||
|
main_urls.write_text('''from django.contrib import admin
|
||||||
|
from django.urls import path, include
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('admin/', admin.site.urls),
|
||||||
|
path('api/', include('api.urls')),
|
||||||
|
]
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
# 创建启动脚本 run.py
|
||||||
|
run_py = backend_dir / "run.py"
|
||||||
|
run_py.write_text('''#!/usr/bin/env python
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
|
||||||
|
print("🚀 服务器启动: http://localhost:8080")
|
||||||
|
print("📍 健康检查: http://localhost:8080/api/health")
|
||||||
|
print("🔧 管理后台: http://localhost:8080/admin/")
|
||||||
|
|
||||||
|
from django.core.management import execute_from_command_line
|
||||||
|
execute_from_command_line(["manage.py", "runserver", "0.0.0.0:8080"])
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
print("\n✅ Django 项目初始化成功")
|
||||||
|
print("💡 启动命令: venv\\Scripts\\python run.py")
|
||||||
|
print("🔧 管理后台: http://localhost:8080/admin/")
|
||||||
|
print("📝 提示: 首次运行前执行 venv\\Scripts\\python manage.py migrate")
|
||||||
119
backend/python_fastapi.py
Normal file
119
backend/python_fastapi.py
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Python FastAPI 后端项目初始化模块
|
||||||
|
"""
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def run_command_with_progress(cmd, cwd, description):
|
||||||
|
"""运行命令并显示实时输出"""
|
||||||
|
try:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"执行: {description}")
|
||||||
|
print(f"{'=' * 60}")
|
||||||
|
|
||||||
|
process = subprocess.Popen(
|
||||||
|
cmd,
|
||||||
|
cwd=cwd,
|
||||||
|
shell=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
bufsize=0
|
||||||
|
)
|
||||||
|
|
||||||
|
for line in process.stdout:
|
||||||
|
try:
|
||||||
|
decoded_line = line.decode('utf-8', errors='replace')
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
decoded_line = line.decode('gbk', errors='replace')
|
||||||
|
except:
|
||||||
|
decoded_line = line.decode('latin-1', errors='replace')
|
||||||
|
print(decoded_line, end='')
|
||||||
|
|
||||||
|
process.wait()
|
||||||
|
|
||||||
|
if process.returncode == 0:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"✅ {description} - 完成")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"❌ {description} - 失败 (错误码: {process.returncode})")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n❌ 执行失败: {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def init_fastapi_project(backend_dir, project_name):
|
||||||
|
"""初始化 FastAPI 项目"""
|
||||||
|
print("\n🚀 初始化 FastAPI 项目...")
|
||||||
|
|
||||||
|
# 创建 main.py
|
||||||
|
main_py = backend_dir / "main.py"
|
||||||
|
main_py.write_text(f'''from fastapi import FastAPI
|
||||||
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
import uvicorn
|
||||||
|
|
||||||
|
app = FastAPI(title="{project_name} API")
|
||||||
|
|
||||||
|
# 允许跨域
|
||||||
|
app.add_middleware(
|
||||||
|
CORSMiddleware,
|
||||||
|
allow_origins=["*"],
|
||||||
|
allow_credentials=True,
|
||||||
|
allow_methods=["*"],
|
||||||
|
allow_headers=["*"],
|
||||||
|
)
|
||||||
|
|
||||||
|
@app.get("/api/health")
|
||||||
|
async def health():
|
||||||
|
return {{
|
||||||
|
"status": "ok",
|
||||||
|
"message": "Welcome to {project_name} API"
|
||||||
|
}}
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("🚀 服务器启动: http://localhost:8080")
|
||||||
|
print("📍 健康检查: http://localhost:8080/api/health")
|
||||||
|
print("📚 API文档: http://localhost:8080/docs")
|
||||||
|
uvicorn.run(app, host="0.0.0.0", port=8080)
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
# 创建 requirements.txt
|
||||||
|
requirements = backend_dir / "requirements.txt"
|
||||||
|
requirements.write_text('''fastapi==0.109.0
|
||||||
|
uvicorn[standard]==0.27.0
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
# 创建虚拟环境并安装依赖
|
||||||
|
success = run_command_with_progress(
|
||||||
|
f'"{sys.executable}" -m venv venv',
|
||||||
|
backend_dir,
|
||||||
|
"创建 Python 虚拟环境"
|
||||||
|
)
|
||||||
|
|
||||||
|
if success:
|
||||||
|
venv_python = backend_dir / "venv" / "Scripts" / "python.exe"
|
||||||
|
if venv_python.exists():
|
||||||
|
success = run_command_with_progress(
|
||||||
|
f'"{venv_python}" -m pip install -r requirements.txt',
|
||||||
|
backend_dir,
|
||||||
|
"安装 FastAPI 依赖"
|
||||||
|
)
|
||||||
|
|
||||||
|
if success:
|
||||||
|
print("\n✅ FastAPI 项目初始化成功")
|
||||||
|
print("💡 启动命令: venv\\Scripts\\python main.py")
|
||||||
|
print("📚 API文档: http://localhost:8080/docs")
|
||||||
|
else:
|
||||||
|
print("\n⚠️ FastAPI 项目创建成功,但依赖安装失败")
|
||||||
|
print(f" 请手动运行: cd {project_name}-backend && venv\\Scripts\\pip install -r requirements.txt")
|
||||||
|
else:
|
||||||
|
print("\n⚠️ 虚拟环境创建失败,请检查 Python 安装")
|
||||||
108
backend/python_flask.py
Normal file
108
backend/python_flask.py
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Python Flask 后端项目初始化模块
|
||||||
|
"""
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def run_command_with_progress(cmd, cwd, description):
|
||||||
|
"""运行命令并显示实时输出"""
|
||||||
|
try:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"执行: {description}")
|
||||||
|
print(f"{'=' * 60}")
|
||||||
|
|
||||||
|
process = subprocess.Popen(
|
||||||
|
cmd,
|
||||||
|
cwd=cwd,
|
||||||
|
shell=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
bufsize=0
|
||||||
|
)
|
||||||
|
|
||||||
|
for line in process.stdout:
|
||||||
|
try:
|
||||||
|
decoded_line = line.decode('utf-8', errors='replace')
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
decoded_line = line.decode('gbk', errors='replace')
|
||||||
|
except:
|
||||||
|
decoded_line = line.decode('latin-1', errors='replace')
|
||||||
|
print(decoded_line, end='')
|
||||||
|
|
||||||
|
process.wait()
|
||||||
|
|
||||||
|
if process.returncode == 0:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"✅ {description} - 完成")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"❌ {description} - 失败 (错误码: {process.returncode})")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n❌ 执行失败: {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def init_flask_project(backend_dir, project_name):
|
||||||
|
"""初始化 Flask 项目"""
|
||||||
|
print("\n🚀 初始化 Flask 项目...")
|
||||||
|
|
||||||
|
# 创建 app.py
|
||||||
|
app_py = backend_dir / "app.py"
|
||||||
|
app_py.write_text(f'''from flask import Flask, jsonify
|
||||||
|
from flask_cors import CORS
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
CORS(app) # 允许跨域
|
||||||
|
|
||||||
|
@app.route('/api/health', methods=['GET'])
|
||||||
|
def health():
|
||||||
|
return jsonify({{
|
||||||
|
'status': 'ok',
|
||||||
|
'message': 'Welcome to {project_name} API'
|
||||||
|
}})
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
print("🚀 服务器启动: http://localhost:8080")
|
||||||
|
print("📍 健康检查: http://localhost:8080/api/health")
|
||||||
|
app.run(debug=True, host='0.0.0.0', port=8080)
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
# 创建 requirements.txt
|
||||||
|
requirements = backend_dir / "requirements.txt"
|
||||||
|
requirements.write_text('''Flask==3.0.0
|
||||||
|
flask-cors==4.0.0
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
# 创建虚拟环境并安装依赖
|
||||||
|
success = run_command_with_progress(
|
||||||
|
f'"{sys.executable}" -m venv venv',
|
||||||
|
backend_dir,
|
||||||
|
"创建 Python 虚拟环境"
|
||||||
|
)
|
||||||
|
|
||||||
|
if success:
|
||||||
|
venv_python = backend_dir / "venv" / "Scripts" / "python.exe"
|
||||||
|
if venv_python.exists():
|
||||||
|
success = run_command_with_progress(
|
||||||
|
f'"{venv_python}" -m pip install -r requirements.txt',
|
||||||
|
backend_dir,
|
||||||
|
"安装 Flask 依赖"
|
||||||
|
)
|
||||||
|
|
||||||
|
if success:
|
||||||
|
print("\n✅ Flask 项目初始化成功")
|
||||||
|
print("💡 启动命令: venv\\Scripts\\python app.py")
|
||||||
|
else:
|
||||||
|
print("\n⚠️ Flask 项目创建成功,但依赖安装失败")
|
||||||
|
print(f" 请手动运行: cd {project_name}-backend && venv\\Scripts\\pip install -r requirements.txt")
|
||||||
|
else:
|
||||||
|
print("\n⚠️ 虚拟环境创建失败,请检查 Python 安装")
|
||||||
39
directory.py
Normal file
39
directory.py
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
目录管理模块
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import shutil
|
||||||
|
from pathlib import Path
|
||||||
|
from utils import get_script_dir
|
||||||
|
|
||||||
|
|
||||||
|
def create_directory_structure(project_name):
|
||||||
|
"""创建项目目录结构"""
|
||||||
|
print(f"\n📁 创建项目目录: {project_name}")
|
||||||
|
|
||||||
|
# 获取脚本所在目录
|
||||||
|
script_dir = get_script_dir()
|
||||||
|
project_root = script_dir / project_name
|
||||||
|
|
||||||
|
if project_root.exists():
|
||||||
|
overwrite = input(f"⚠️ 项目目录 {project_name} 已存在,是否覆盖? (y/n): ").strip().lower()
|
||||||
|
if overwrite != 'y':
|
||||||
|
print("❌ 操作已取消")
|
||||||
|
sys.exit(0)
|
||||||
|
shutil.rmtree(project_root)
|
||||||
|
|
||||||
|
# 创建主目录
|
||||||
|
project_root.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
# 创建前后端目录
|
||||||
|
frontend_dir = project_root / f"{project_name}-frontend"
|
||||||
|
backend_dir = project_root / f"{project_name}-backend"
|
||||||
|
|
||||||
|
frontend_dir.mkdir(exist_ok=True)
|
||||||
|
backend_dir.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
print(f"✅ 目录创建成功: {project_root}")
|
||||||
|
|
||||||
|
return project_root, frontend_dir, backend_dir
|
||||||
10
frontend/__init__.py
Normal file
10
frontend/__init__.py
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
前端模块包
|
||||||
|
"""
|
||||||
|
|
||||||
|
from frontend.react import init_react_project
|
||||||
|
from frontend.vue import init_vue_project
|
||||||
|
from frontend.tailwind import setup_tailwind
|
||||||
|
|
||||||
|
__all__ = ['init_react_project', 'init_vue_project', 'setup_tailwind']
|
||||||
113
frontend/react.py
Normal file
113
frontend/react.py
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
React 项目初始化模块
|
||||||
|
"""
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def run_command_interactive(cmd, cwd, description):
|
||||||
|
"""运行命令并支持用户交互"""
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"执行: {description}")
|
||||||
|
print(f"{'=' * 60}")
|
||||||
|
print(f"💡 提示: 此步骤需要您进行交互操作")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = subprocess.run(cmd, cwd=cwd, shell=True)
|
||||||
|
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
if result.returncode == 0:
|
||||||
|
print(f"✅ {description} - 完成")
|
||||||
|
else:
|
||||||
|
print(f"❌ {description} - 失败 (错误码: {result.returncode})")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
|
||||||
|
return result.returncode == 0
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n❌ 执行失败: {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def run_command_with_progress(cmd, cwd, description):
|
||||||
|
"""运行命令并显示实时输出"""
|
||||||
|
try:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"执行: {description}")
|
||||||
|
print(f"{'=' * 60}")
|
||||||
|
|
||||||
|
process = subprocess.Popen(
|
||||||
|
cmd,
|
||||||
|
cwd=cwd,
|
||||||
|
shell=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
bufsize=0
|
||||||
|
)
|
||||||
|
|
||||||
|
for line in process.stdout:
|
||||||
|
try:
|
||||||
|
decoded_line = line.decode('utf-8', errors='replace')
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
decoded_line = line.decode('gbk', errors='replace')
|
||||||
|
except:
|
||||||
|
decoded_line = line.decode('latin-1', errors='replace')
|
||||||
|
print(decoded_line, end='')
|
||||||
|
|
||||||
|
process.wait()
|
||||||
|
|
||||||
|
if process.returncode == 0:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"✅ {description} - 完成")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"❌ {description} - 失败 (错误码: {process.returncode})")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n❌ 执行失败: {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def init_react_project(frontend_dir, project_name):
|
||||||
|
"""初始化 React 项目"""
|
||||||
|
print("\n🚀 初始化 React 项目...")
|
||||||
|
print("\n⚠️ 重要提示:")
|
||||||
|
print(" 1. 当询问 'Use rolldown-vite?' 时,建议选择 No")
|
||||||
|
print(" 2. 当询问 'Install and start now?' 时,请选择 No(否则会启动服务器)")
|
||||||
|
print(" 3. 我们会在之后单独安装依赖\n")
|
||||||
|
|
||||||
|
# 删除空目录,因为 create-vite 需要在不存在的目录中创建
|
||||||
|
frontend_dir.rmdir()
|
||||||
|
|
||||||
|
# 使用 Vite 创建 React 项目
|
||||||
|
cmd = f'npm create vite@latest {frontend_dir.name} -- --template react'
|
||||||
|
success = run_command_interactive(cmd, frontend_dir.parent, "创建 React 项目结构")
|
||||||
|
|
||||||
|
if not success:
|
||||||
|
print("\n💡 提示: 请确保已安装 Node.js 和 npm")
|
||||||
|
print(" 下载地址: https://nodejs.org/")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# 检查目录是否创建成功
|
||||||
|
if not frontend_dir.exists():
|
||||||
|
print("❌ 项目目录创建失败")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# 检查是否已安装依赖
|
||||||
|
node_modules = frontend_dir / "node_modules"
|
||||||
|
if not node_modules.exists():
|
||||||
|
print("\n⏳ 开始安装依赖...")
|
||||||
|
success = run_command_with_progress("npm install", frontend_dir, "安装 React 项目依赖")
|
||||||
|
|
||||||
|
if not success:
|
||||||
|
print("⚠️ 依赖安装失败,请稍后手动运行: cd {}-frontend && npm install".format(project_name))
|
||||||
|
|
||||||
|
print("\n✅ React 项目初始化成功")
|
||||||
181
frontend/tailwind.py
Normal file
181
frontend/tailwind.py
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Tailwind CSS 配置模块
|
||||||
|
"""
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
|
def run_command_with_progress(cmd, cwd, description):
|
||||||
|
"""运行命令并显示实时输出"""
|
||||||
|
try:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"执行: {description}")
|
||||||
|
print(f"{'=' * 60}")
|
||||||
|
|
||||||
|
process = subprocess.Popen(
|
||||||
|
cmd,
|
||||||
|
cwd=cwd,
|
||||||
|
shell=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
bufsize=0
|
||||||
|
)
|
||||||
|
|
||||||
|
for line in process.stdout:
|
||||||
|
try:
|
||||||
|
decoded_line = line.decode('utf-8', errors='replace')
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
decoded_line = line.decode('gbk', errors='replace')
|
||||||
|
except:
|
||||||
|
decoded_line = line.decode('latin-1', errors='replace')
|
||||||
|
print(decoded_line, end='')
|
||||||
|
|
||||||
|
process.wait()
|
||||||
|
|
||||||
|
if process.returncode == 0:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"✅ {description} - 完成")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"❌ {description} - 失败 (错误码: {process.returncode})")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n❌ 执行失败: {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def setup_tailwind(frontend_dir, framework):
|
||||||
|
"""配置 Tailwind CSS"""
|
||||||
|
print("\n🎨 配置 Tailwind CSS...")
|
||||||
|
|
||||||
|
# 安装 Tailwind 依赖
|
||||||
|
success = run_command_with_progress(
|
||||||
|
"npm install -D tailwindcss postcss autoprefixer",
|
||||||
|
frontend_dir,
|
||||||
|
"安装 Tailwind CSS 依赖"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not success:
|
||||||
|
print("⚠️ Tailwind 安装失败,请稍后手动安装")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 初始化 Tailwind 配置
|
||||||
|
run_command_with_progress(
|
||||||
|
"npx tailwindcss init -p",
|
||||||
|
frontend_dir,
|
||||||
|
"初始化 Tailwind 配置"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 根据框架配置 tailwind.config.js
|
||||||
|
if framework == "react":
|
||||||
|
content_config = '"./index.html", "./src/**/*.{js,ts,jsx,tsx}"'
|
||||||
|
else: # vue
|
||||||
|
content_config = '"./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"'
|
||||||
|
|
||||||
|
tailwind_config = frontend_dir / "tailwind.config.js"
|
||||||
|
tailwind_config.write_text(f'''/** @type {{import('tailwindcss').Config}} */
|
||||||
|
export default {{
|
||||||
|
content: [{content_config}],
|
||||||
|
theme: {{
|
||||||
|
extend: {{}},
|
||||||
|
}},
|
||||||
|
plugins: [],
|
||||||
|
}}
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
# 创建或修改 CSS 文件
|
||||||
|
if framework == "react":
|
||||||
|
css_file = frontend_dir / "src" / "index.css"
|
||||||
|
else: # vue
|
||||||
|
css_file = frontend_dir / "src" / "style.css"
|
||||||
|
|
||||||
|
# 在 CSS 文件开头添加 Tailwind 指令
|
||||||
|
tailwind_directives = '''@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
if css_file.exists():
|
||||||
|
original_css = css_file.read_text(encoding='utf-8')
|
||||||
|
css_file.write_text(tailwind_directives + original_css, encoding='utf-8')
|
||||||
|
else:
|
||||||
|
css_file.write_text(tailwind_directives, encoding='utf-8')
|
||||||
|
|
||||||
|
# 创建示例组件展示 Tailwind
|
||||||
|
if framework == "react":
|
||||||
|
create_react_tailwind_example(frontend_dir)
|
||||||
|
else:
|
||||||
|
create_vue_tailwind_example(frontend_dir)
|
||||||
|
|
||||||
|
print("\n✅ Tailwind CSS 配置成功")
|
||||||
|
print("💡 提示: 可以在组件中使用 Tailwind 类名了")
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def create_react_tailwind_example(frontend_dir):
|
||||||
|
"""创建 React Tailwind 示例"""
|
||||||
|
app_jsx = frontend_dir / "src" / "App.jsx"
|
||||||
|
app_jsx.write_text('''function App() {
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center">
|
||||||
|
<div className="bg-white rounded-2xl shadow-2xl p-8 max-w-md w-full mx-4">
|
||||||
|
<h1 className="text-3xl font-bold text-gray-800 text-center mb-4">
|
||||||
|
🚀 React + Tailwind
|
||||||
|
</h1>
|
||||||
|
<p className="text-gray-600 text-center mb-6">
|
||||||
|
项目已成功初始化!Tailwind CSS 已配置完成。
|
||||||
|
</p>
|
||||||
|
<div className="flex gap-4 justify-center">
|
||||||
|
<button className="px-6 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors">
|
||||||
|
开始开发
|
||||||
|
</button>
|
||||||
|
<button className="px-6 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors">
|
||||||
|
查看文档
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
|
||||||
|
def create_vue_tailwind_example(frontend_dir):
|
||||||
|
"""创建 Vue Tailwind 示例"""
|
||||||
|
app_vue = frontend_dir / "src" / "App.vue"
|
||||||
|
app_vue.write_text('''<script setup>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="min-h-screen bg-gradient-to-br from-green-500 to-teal-600 flex items-center justify-center">
|
||||||
|
<div class="bg-white rounded-2xl shadow-2xl p-8 max-w-md w-full mx-4">
|
||||||
|
<h1 class="text-3xl font-bold text-gray-800 text-center mb-4">
|
||||||
|
🚀 Vue + Tailwind
|
||||||
|
</h1>
|
||||||
|
<p class="text-gray-600 text-center mb-6">
|
||||||
|
项目已成功初始化!Tailwind CSS 已配置完成。
|
||||||
|
</p>
|
||||||
|
<div class="flex gap-4 justify-center">
|
||||||
|
<button class="px-6 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition-colors">
|
||||||
|
开始开发
|
||||||
|
</button>
|
||||||
|
<button class="px-6 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors">
|
||||||
|
查看文档
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
||||||
|
''', encoding='utf-8')
|
||||||
113
frontend/vue.py
Normal file
113
frontend/vue.py
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Vue 项目初始化模块
|
||||||
|
"""
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def run_command_interactive(cmd, cwd, description):
|
||||||
|
"""运行命令并支持用户交互"""
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"执行: {description}")
|
||||||
|
print(f"{'=' * 60}")
|
||||||
|
print(f"💡 提示: 此步骤需要您进行交互操作")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = subprocess.run(cmd, cwd=cwd, shell=True)
|
||||||
|
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
if result.returncode == 0:
|
||||||
|
print(f"✅ {description} - 完成")
|
||||||
|
else:
|
||||||
|
print(f"❌ {description} - 失败 (错误码: {result.returncode})")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
|
||||||
|
return result.returncode == 0
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n❌ 执行失败: {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def run_command_with_progress(cmd, cwd, description):
|
||||||
|
"""运行命令并显示实时输出"""
|
||||||
|
try:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"执行: {description}")
|
||||||
|
print(f"{'=' * 60}")
|
||||||
|
|
||||||
|
process = subprocess.Popen(
|
||||||
|
cmd,
|
||||||
|
cwd=cwd,
|
||||||
|
shell=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
bufsize=0
|
||||||
|
)
|
||||||
|
|
||||||
|
for line in process.stdout:
|
||||||
|
try:
|
||||||
|
decoded_line = line.decode('utf-8', errors='replace')
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
decoded_line = line.decode('gbk', errors='replace')
|
||||||
|
except:
|
||||||
|
decoded_line = line.decode('latin-1', errors='replace')
|
||||||
|
print(decoded_line, end='')
|
||||||
|
|
||||||
|
process.wait()
|
||||||
|
|
||||||
|
if process.returncode == 0:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"✅ {description} - 完成")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"\n{'=' * 60}")
|
||||||
|
print(f"❌ {description} - 失败 (错误码: {process.returncode})")
|
||||||
|
print(f"{'=' * 60}\n")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n❌ 执行失败: {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def init_vue_project(frontend_dir, project_name):
|
||||||
|
"""初始化 Vue 项目"""
|
||||||
|
print("\n🚀 初始化 Vue 项目...")
|
||||||
|
print("\n⚠️ 重要提示:")
|
||||||
|
print(" 1. 当询问 'Use rolldown-vite?' 时,建议选择 No")
|
||||||
|
print(" 2. 当询问 'Install and start now?' 时,请选择 No(否则会启动服务器)")
|
||||||
|
print(" 3. 我们会在之后单独安装依赖\n")
|
||||||
|
|
||||||
|
# 删除空目录
|
||||||
|
frontend_dir.rmdir()
|
||||||
|
|
||||||
|
# 使用 Vite 创建 Vue 项目
|
||||||
|
cmd = f'npm create vite@latest {frontend_dir.name} -- --template vue'
|
||||||
|
success = run_command_interactive(cmd, frontend_dir.parent, "创建 Vue 项目结构")
|
||||||
|
|
||||||
|
if not success:
|
||||||
|
print("\n💡 提示: 请确保已安装 Node.js 和 npm")
|
||||||
|
print(" 下载地址: https://nodejs.org/")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# 检查目录是否创建成功
|
||||||
|
if not frontend_dir.exists():
|
||||||
|
print("❌ 项目目录创建失败")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# 检查是否已安装依赖
|
||||||
|
node_modules = frontend_dir / "node_modules"
|
||||||
|
if not node_modules.exists():
|
||||||
|
print("\n⏳ 开始安装依赖...")
|
||||||
|
success = run_command_with_progress("npm install", frontend_dir, "安装 Vue 项目依赖")
|
||||||
|
|
||||||
|
if not success:
|
||||||
|
print("⚠️ 依赖安装失败,请稍后手动运行: cd {}-frontend && npm install".format(project_name))
|
||||||
|
|
||||||
|
print("\n✅ Vue 项目初始化成功")
|
||||||
95
main.py
Normal file
95
main.py
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
前后端分离项目初始化脚本 - 主程序
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from utils import print_banner, get_project_name, select_frontend, select_backend, select_use_tailwind
|
||||||
|
from directory import create_directory_structure
|
||||||
|
from frontend import init_react_project, init_vue_project, setup_tailwind
|
||||||
|
from backend import (
|
||||||
|
init_golang_project,
|
||||||
|
init_gin_project,
|
||||||
|
init_flask_project,
|
||||||
|
init_fastapi_project,
|
||||||
|
init_django_project,
|
||||||
|
init_spring_project,
|
||||||
|
init_express_project,
|
||||||
|
init_nestjs_project
|
||||||
|
)
|
||||||
|
from scripts import create_bat_scripts
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""主函数"""
|
||||||
|
print_banner()
|
||||||
|
|
||||||
|
# 获取项目信息
|
||||||
|
project_name = get_project_name()
|
||||||
|
frontend_type = select_frontend()
|
||||||
|
use_tailwind = select_use_tailwind()
|
||||||
|
backend_type = select_backend()
|
||||||
|
|
||||||
|
# 创建目录结构
|
||||||
|
project_root, frontend_dir, backend_dir = create_directory_structure(project_name)
|
||||||
|
|
||||||
|
# 初始化前端项目
|
||||||
|
if frontend_type == "react":
|
||||||
|
init_react_project(frontend_dir, project_name)
|
||||||
|
elif frontend_type == "vue":
|
||||||
|
init_vue_project(frontend_dir, project_name)
|
||||||
|
|
||||||
|
# 配置 Tailwind CSS
|
||||||
|
if use_tailwind:
|
||||||
|
setup_tailwind(frontend_dir, frontend_type)
|
||||||
|
|
||||||
|
# 初始化后端项目
|
||||||
|
if backend_type == "golang":
|
||||||
|
init_golang_project(backend_dir, project_name)
|
||||||
|
elif backend_type == "gin":
|
||||||
|
init_gin_project(backend_dir, project_name)
|
||||||
|
elif backend_type == "flask":
|
||||||
|
init_flask_project(backend_dir, project_name)
|
||||||
|
elif backend_type == "fastapi":
|
||||||
|
init_fastapi_project(backend_dir, project_name)
|
||||||
|
elif backend_type == "django":
|
||||||
|
init_django_project(backend_dir, project_name)
|
||||||
|
elif backend_type == "spring":
|
||||||
|
init_spring_project(backend_dir, project_name)
|
||||||
|
elif backend_type == "express":
|
||||||
|
init_express_project(backend_dir, project_name)
|
||||||
|
elif backend_type == "nestjs":
|
||||||
|
init_nestjs_project(backend_dir, project_name)
|
||||||
|
|
||||||
|
# 创建 BAT 脚本
|
||||||
|
create_bat_scripts(project_root, project_name, frontend_type, backend_type)
|
||||||
|
|
||||||
|
# 完成
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("🎉 项目初始化完成!")
|
||||||
|
print("=" * 60)
|
||||||
|
print(f"\n📁 项目位置: {project_root}")
|
||||||
|
print(f" ├── {project_name}-frontend ({frontend_type.upper()})")
|
||||||
|
print(f" ├── {project_name}-backend ({backend_type.upper()})")
|
||||||
|
print(f" ├── 开启前端.bat")
|
||||||
|
print(f" ├── 开启后端.bat")
|
||||||
|
print(f" └── 构建前端.bat")
|
||||||
|
print("\n💡 使用说明:")
|
||||||
|
print(f" 1. 双击 '开启前端.bat' 启动前端开发服务器")
|
||||||
|
print(f" 2. 双击 '开启后端.bat' 启动后端服务")
|
||||||
|
print(f" 3. 双击 '构建前端.bat' 构建前端生产版本")
|
||||||
|
print("\n✨ 祝开发愉快!")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n\n❌ 操作已取消")
|
||||||
|
sys.exit(0)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n❌ 发生错误: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
sys.exit(1)
|
||||||
65
scripts.py
Normal file
65
scripts.py
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
启动脚本生成模块
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def create_bat_scripts(project_root, project_name, frontend_type, backend_type):
|
||||||
|
"""创建启动脚本"""
|
||||||
|
print("\n📝 创建启动脚本...")
|
||||||
|
|
||||||
|
# 前端启动命令
|
||||||
|
frontend_start_cmd = "npm run dev"
|
||||||
|
|
||||||
|
# 后端启动命令
|
||||||
|
backend_start_commands = {
|
||||||
|
"golang": "go run main.go",
|
||||||
|
"gin": "go run main.go",
|
||||||
|
"flask": "venv\\Scripts\\python app.py",
|
||||||
|
"fastapi": "venv\\Scripts\\python main.py",
|
||||||
|
"django": "venv\\Scripts\\python run.py",
|
||||||
|
"spring": "mvn spring-boot:run",
|
||||||
|
"express": "npm run dev",
|
||||||
|
"nestjs": "npm run start:dev"
|
||||||
|
}
|
||||||
|
backend_start_cmd = backend_start_commands.get(backend_type, "echo 未知后端类型")
|
||||||
|
|
||||||
|
# 1. 开启前端.bat
|
||||||
|
start_frontend = project_root / "开启前端.bat"
|
||||||
|
start_frontend.write_text(f'''@echo off
|
||||||
|
chcp 65001 >nul
|
||||||
|
echo ====================================
|
||||||
|
echo 启动前端项目 ({frontend_type.upper()})
|
||||||
|
echo ====================================
|
||||||
|
cd {project_name}-frontend
|
||||||
|
{frontend_start_cmd}
|
||||||
|
pause
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
# 2. 开启后端.bat
|
||||||
|
start_backend = project_root / "开启后端.bat"
|
||||||
|
start_backend.write_text(f'''@echo off
|
||||||
|
chcp 65001 >nul
|
||||||
|
echo ====================================
|
||||||
|
echo 启动后端项目 ({backend_type.upper()})
|
||||||
|
echo ====================================
|
||||||
|
cd {project_name}-backend
|
||||||
|
{backend_start_cmd}
|
||||||
|
pause
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
# 3. 构建前端.bat
|
||||||
|
build_frontend = project_root / "构建前端.bat"
|
||||||
|
build_frontend.write_text(f'''@echo off
|
||||||
|
chcp 65001 >nul
|
||||||
|
echo ====================================
|
||||||
|
echo 构建前端项目 ({frontend_type.upper()})
|
||||||
|
echo ====================================
|
||||||
|
cd {project_name}-frontend
|
||||||
|
npm run build
|
||||||
|
echo.
|
||||||
|
echo ✅ 构建完成!输出目录: dist
|
||||||
|
pause
|
||||||
|
''', encoding='utf-8')
|
||||||
|
|
||||||
|
print("✅ 启动脚本创建成功")
|
||||||
97
utils.py
Normal file
97
utils.py
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
工具函数模块
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def print_banner():
|
||||||
|
"""打印欢迎信息"""
|
||||||
|
print("=" * 60)
|
||||||
|
print(" 前后端分离项目初始化工具")
|
||||||
|
print("=" * 60)
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
def get_project_name():
|
||||||
|
"""获取项目名称"""
|
||||||
|
while True:
|
||||||
|
project_name = input("请输入项目英文名(如 mengyaping): ").strip()
|
||||||
|
if project_name and project_name.replace("_", "").replace("-", "").isalnum():
|
||||||
|
return project_name
|
||||||
|
print("❌ 项目名称无效,请使用英文字母、数字、下划线或短横线")
|
||||||
|
|
||||||
|
|
||||||
|
def select_frontend():
|
||||||
|
"""选择前端技术栈"""
|
||||||
|
print("\n📦 请选择前端技术栈:")
|
||||||
|
print("1. React")
|
||||||
|
print("2. Vue")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
choice = input("请输入选项 (1-2): ").strip()
|
||||||
|
if choice == "1":
|
||||||
|
return "react"
|
||||||
|
elif choice == "2":
|
||||||
|
return "vue"
|
||||||
|
print("❌ 无效选项,请重新输入")
|
||||||
|
|
||||||
|
|
||||||
|
def select_use_tailwind():
|
||||||
|
"""选择是否使用 Tailwind CSS"""
|
||||||
|
print("\n🎨 是否使用 Tailwind CSS?")
|
||||||
|
print("1. 是 (推荐)")
|
||||||
|
print("2. 否")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
choice = input("请输入选项 (1-2): ").strip()
|
||||||
|
if choice == "1":
|
||||||
|
return True
|
||||||
|
elif choice == "2":
|
||||||
|
return False
|
||||||
|
print("❌ 无效选项,请重新输入")
|
||||||
|
|
||||||
|
|
||||||
|
def select_backend():
|
||||||
|
"""选择后端技术栈"""
|
||||||
|
print("\n🔧 请选择后端技术栈:")
|
||||||
|
print("1. Go (标准库)")
|
||||||
|
print("2. Go (Gin)")
|
||||||
|
print("3. Python (Flask)")
|
||||||
|
print("4. Python (FastAPI)")
|
||||||
|
print("5. Python (Django)")
|
||||||
|
print("6. Java (Spring Boot)")
|
||||||
|
print("7. JavaScript (Express.js)")
|
||||||
|
print("8. JavaScript (NestJS)")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
choice = input("请输入选项 (1-8): ").strip()
|
||||||
|
if choice == "1":
|
||||||
|
return "golang"
|
||||||
|
elif choice == "2":
|
||||||
|
return "gin"
|
||||||
|
elif choice == "3":
|
||||||
|
return "flask"
|
||||||
|
elif choice == "4":
|
||||||
|
return "fastapi"
|
||||||
|
elif choice == "5":
|
||||||
|
return "django"
|
||||||
|
elif choice == "6":
|
||||||
|
return "spring"
|
||||||
|
elif choice == "7":
|
||||||
|
return "express"
|
||||||
|
elif choice == "8":
|
||||||
|
return "nestjs"
|
||||||
|
print("❌ 无效选项,请重新输入")
|
||||||
|
|
||||||
|
|
||||||
|
def get_script_dir():
|
||||||
|
"""获取脚本所在目录"""
|
||||||
|
if getattr(sys, 'frozen', False):
|
||||||
|
# 打包后的exe
|
||||||
|
return Path(sys.executable).parent
|
||||||
|
else:
|
||||||
|
# 直接运行的py文件
|
||||||
|
return Path(__file__).parent
|
||||||
Reference in New Issue
Block a user