2025-11-11 21:39:12 +08:00
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
"""
|
|
|
|
|
|
KaMiXiTong 启动脚本
|
|
|
|
|
|
快速启动开发服务器
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
import os
|
|
|
|
|
|
import sys
|
|
|
|
|
|
import subprocess
|
2025-11-15 23:57:05 +08:00
|
|
|
|
import threading
|
|
|
|
|
|
import time
|
2025-11-11 21:39:12 +08:00
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
|
|
|
|
def check_python_version():
|
|
|
|
|
|
"""检查Python版本"""
|
|
|
|
|
|
if sys.version_info < (3, 6):
|
|
|
|
|
|
print("❌ 错误: 需要Python 3.6或更高版本")
|
|
|
|
|
|
print(f"当前版本: {sys.version}")
|
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
print(f"✅ Python版本检查通过: {sys.version}")
|
|
|
|
|
|
|
|
|
|
|
|
def install_dependencies():
|
|
|
|
|
|
"""安装依赖"""
|
|
|
|
|
|
print("📦 正在安装依赖包...")
|
|
|
|
|
|
try:
|
|
|
|
|
|
subprocess.check_call([sys.executable, '-m', 'pip', 'install', '-r', 'requirements.txt'])
|
2025-11-15 23:57:05 +08:00
|
|
|
|
# 检查并安装FastAPI依赖
|
|
|
|
|
|
if os.path.exists('requirements-fastapi.txt'):
|
|
|
|
|
|
try:
|
|
|
|
|
|
subprocess.check_call([sys.executable, '-m', 'pip', 'install', '-r', 'requirements-fastapi.txt'])
|
|
|
|
|
|
print("✅ FastAPI依赖安装完成")
|
|
|
|
|
|
except subprocess.CalledProcessError:
|
|
|
|
|
|
print("⚠️ FastAPI依赖安装失败,将跳过FastAPI服务")
|
2025-11-11 21:39:12 +08:00
|
|
|
|
print("✅ 依赖安装完成")
|
|
|
|
|
|
except subprocess.CalledProcessError:
|
|
|
|
|
|
print("❌ 依赖安装失败")
|
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
|
|
def check_env_file():
|
|
|
|
|
|
"""检查环境配置文件"""
|
|
|
|
|
|
env_file = Path('.env')
|
|
|
|
|
|
if not env_file.exists():
|
|
|
|
|
|
print("⚠️ 未找到 .env 文件,正在创建默认配置...")
|
|
|
|
|
|
try:
|
|
|
|
|
|
with open('.env.example', 'r', encoding='utf-8') as src:
|
|
|
|
|
|
with open('.env', 'w', encoding='utf-8') as dst:
|
|
|
|
|
|
dst.write(src.read())
|
|
|
|
|
|
print("✅ 已创建默认 .env 文件")
|
|
|
|
|
|
except FileNotFoundError:
|
|
|
|
|
|
print("❌ 未找到 .env.example 文件")
|
|
|
|
|
|
else:
|
|
|
|
|
|
print("✅ 环境配置文件已存在")
|
|
|
|
|
|
|
|
|
|
|
|
def init_database():
|
|
|
|
|
|
"""初始化数据库"""
|
|
|
|
|
|
print("🗄️ 正在初始化数据库...")
|
|
|
|
|
|
try:
|
|
|
|
|
|
from app import create_app, db
|
|
|
|
|
|
from app.models.admin import Admin
|
|
|
|
|
|
|
|
|
|
|
|
app = create_app('development')
|
|
|
|
|
|
with app.app_context():
|
|
|
|
|
|
# 创建数据表
|
|
|
|
|
|
db.create_all()
|
|
|
|
|
|
|
|
|
|
|
|
# 创建默认管理员
|
|
|
|
|
|
admin = Admin.query.filter_by(username='admin').first()
|
|
|
|
|
|
if not admin:
|
|
|
|
|
|
admin = Admin(
|
|
|
|
|
|
username='admin',
|
|
|
|
|
|
email='admin@example.com',
|
|
|
|
|
|
role=1 # 超级管理员
|
|
|
|
|
|
)
|
|
|
|
|
|
admin.set_password('admin123')
|
|
|
|
|
|
db.session.add(admin)
|
|
|
|
|
|
db.session.commit()
|
|
|
|
|
|
print("✅ 默认管理员账号创建成功: admin/admin123")
|
|
|
|
|
|
else:
|
|
|
|
|
|
print("✅ 数据库已初始化")
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(f"❌ 数据库初始化失败: {e}")
|
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
|
|
def create_directories():
|
|
|
|
|
|
"""创建必要的目录"""
|
|
|
|
|
|
directories = [
|
|
|
|
|
|
'logs',
|
|
|
|
|
|
'static/uploads',
|
|
|
|
|
|
'static/css',
|
|
|
|
|
|
'static/js'
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
for directory in directories:
|
|
|
|
|
|
Path(directory).mkdir(parents=True, exist_ok=True)
|
|
|
|
|
|
print("✅ 目录结构创建完成")
|
|
|
|
|
|
|
2025-11-15 23:57:05 +08:00
|
|
|
|
def start_flask_app():
|
|
|
|
|
|
"""启动Flask应用"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
from run import app
|
|
|
|
|
|
print("🚀 正在启动Flask应用...")
|
|
|
|
|
|
app.run(
|
2025-11-22 16:48:45 +08:00
|
|
|
|
host=os.environ.get('HOST', '0.0.0.0'),
|
|
|
|
|
|
port=int(os.environ.get('PORT', 5088)),
|
2025-11-15 23:57:05 +08:00
|
|
|
|
debug=True,
|
|
|
|
|
|
use_reloader=False # 禁用重载器以避免子进程问题
|
|
|
|
|
|
)
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(f"❌ Flask应用启动失败: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
def start_fastapi_app():
|
|
|
|
|
|
"""启动FastAPI应用"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 检查FastAPI应用文件是否存在
|
|
|
|
|
|
if not os.path.exists('fastapi_app.py'):
|
|
|
|
|
|
print("⚠️ FastAPI应用文件不存在,跳过FastAPI服务启动")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
print("🚀 正在启动FastAPI应用...")
|
|
|
|
|
|
# 使用uvicorn启动FastAPI应用
|
2025-11-16 19:06:49 +08:00
|
|
|
|
fastapi_host = os.environ.get('FASTAPI_HOST', '127.0.0.1')
|
2025-11-22 16:48:45 +08:00
|
|
|
|
fastapi_port = os.environ.get('FASTAPI_PORT', '9002')
|
2025-11-16 19:06:49 +08:00
|
|
|
|
|
2025-11-15 23:57:05 +08:00
|
|
|
|
subprocess.run([
|
|
|
|
|
|
sys.executable, '-m', 'uvicorn',
|
|
|
|
|
|
'fastapi_app:app',
|
2025-11-16 19:06:49 +08:00
|
|
|
|
'--host', fastapi_host,
|
|
|
|
|
|
'--port', fastapi_port
|
2025-11-15 23:57:05 +08:00
|
|
|
|
])
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(f"❌ FastAPI应用启动失败: {e}")
|
|
|
|
|
|
|
2025-11-11 21:39:12 +08:00
|
|
|
|
def main():
|
|
|
|
|
|
"""主函数"""
|
|
|
|
|
|
print("=" * 50)
|
|
|
|
|
|
print(" KaMiXiTong 软件授权管理系统")
|
|
|
|
|
|
print(" 启动脚本 v1.0")
|
|
|
|
|
|
print("=" * 50)
|
|
|
|
|
|
|
|
|
|
|
|
# 检查Python版本
|
|
|
|
|
|
check_python_version()
|
|
|
|
|
|
|
|
|
|
|
|
# 创建目录
|
|
|
|
|
|
create_directories()
|
|
|
|
|
|
|
|
|
|
|
|
# 检查环境配置
|
|
|
|
|
|
check_env_file()
|
|
|
|
|
|
|
|
|
|
|
|
# 安装依赖
|
|
|
|
|
|
if not os.environ.get('SKIP_INSTALL'):
|
|
|
|
|
|
install_dependencies()
|
|
|
|
|
|
else:
|
|
|
|
|
|
print("⏭️ 跳过依赖安装")
|
|
|
|
|
|
|
|
|
|
|
|
# 初始化数据库
|
|
|
|
|
|
init_database()
|
|
|
|
|
|
|
|
|
|
|
|
print("\n" + "=" * 50)
|
|
|
|
|
|
print("🚀 启动开发服务器...")
|
|
|
|
|
|
print("=" * 50)
|
2025-11-16 19:06:49 +08:00
|
|
|
|
host = os.environ.get('HOST', '127.0.0.1')
|
2025-11-22 16:48:45 +08:00
|
|
|
|
port = os.environ.get('PORT', '5088')
|
|
|
|
|
|
fastapi_port = os.environ.get('FASTAPI_PORT', '9002')
|
2025-11-16 19:06:49 +08:00
|
|
|
|
|
|
|
|
|
|
print(f"📍 Flask访问地址: http://{host}:{port}")
|
|
|
|
|
|
print(f"📍 FastAPI访问地址: http://{host}:{fastapi_port}")
|
|
|
|
|
|
print(f"📍 FastAPI文档: http://{host}:{fastapi_port}/docs")
|
2025-11-11 21:39:12 +08:00
|
|
|
|
print("👤 管理员账号: admin")
|
|
|
|
|
|
print("🔑 管理员密码: admin123")
|
|
|
|
|
|
print("⏹️ 按 Ctrl+C 停止服务器")
|
|
|
|
|
|
print("=" * 50 + "\n")
|
|
|
|
|
|
|
2025-11-15 23:57:05 +08:00
|
|
|
|
# 启动Flask和FastAPI应用
|
2025-11-11 21:39:12 +08:00
|
|
|
|
try:
|
2025-11-15 23:57:05 +08:00
|
|
|
|
# 在单独的线程中启动Flask应用
|
|
|
|
|
|
flask_thread = threading.Thread(target=start_flask_app)
|
|
|
|
|
|
flask_thread.daemon = True
|
|
|
|
|
|
flask_thread.start()
|
|
|
|
|
|
|
|
|
|
|
|
# 等待Flask启动
|
|
|
|
|
|
time.sleep(2)
|
|
|
|
|
|
|
|
|
|
|
|
# 在主线程中启动FastAPI应用
|
|
|
|
|
|
start_fastapi_app()
|
|
|
|
|
|
|
2025-11-11 21:39:12 +08:00
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
|
|
print("\n👋 服务器已停止")
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(f"❌ 启动失败: {e}")
|
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
|
main()
|