# main.py import sys import os from pathlib import Path # 添加项目根目录到Python路径 project_root = Path(__file__).parent.parent src_root = Path(__file__).parent sys.path.insert(0, str(project_root)) sys.path.insert(0, str(src_root)) # 确保当前工作目录是项目根目录 os.chdir(project_root) # 打印调试信息 print(f"项目根目录: {project_root}") print(f"Python路径: {sys.path}") print(f"当前工作目录: {os.getcwd()}") # 测试导入配置模块 try: from config.settings import settings print("[OK] 配置模块导入成功") except ImportError as e: print(f"[FAIL] 配置模块导入失败: {e}") # 列出当前目录内容 print("当前目录内容:") for item in os.listdir('.'): print(f" - {item}") # 列出config目录内容 if os.path.exists('config'): print("config目录内容:") for item in os.listdir('config'): print(f" - {item}") raise from fastapi import FastAPI, Request from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse import asyncio import time from api.auth_routes import router as auth_router from api.inventory import inventory_router from api.aluminum_price_routes import router as aluminum_price_router from utils.logger import setup_logging, get_logger from database.init_db import init_database setup_logging() logger = get_logger(__name__) app = FastAPI( title="Gemold - 模具制造管理系统", description="模具制造行业综合管理平台,包含模具分析、进销存管理等功能", version="4.0.0" ) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.middleware("http") async def log_requests(request: Request, call_next): start_time = time.time() response = await call_next(request) duration = time.time() - start_time status = response.status_code if status >= 400: auth_header = request.headers.get("authorization", "") token_preview = "" if auth_header.startswith("Bearer "): token_raw = auth_header[7:] token_preview = token_raw[:20] + "..." if len(token_raw) > 20 else token_raw logger.warning( f"[HTTP] {request.method} {request.url.path} -> {status} " f"({duration:.2f}s) " f"token={token_preview or 'none'}" ) return response # 启动时初始化数据库和RustFS @app.on_event("startup") async def startup_event(): """应用启动时初始化数据库和RustFS""" # 初始化数据库 success = await init_database(keep_connected=True) if success: print("[OK] 数据库初始化成功") else: print("[FAIL] 数据库初始化失败,服务将继续运行但数据库功能不可用") # 初始化RustFS连接 try: from storage.rustfs_storage import rustfs_manager from config.settings import settings await rustfs_manager.connect( endpoint=settings.RUSTFS_ENDPOINT, access_key=settings.RUSTFS_ACCESS_KEY, secret_key=settings.RUSTFS_SECRET_KEY, timeout=settings.RUSTFS_TIMEOUT ) print("[OK] RustFS连接成功") except Exception as e: print(f"[FAIL] RustFS连接失败: {e}") print("[WARN] 文件上传功能将不可用,但其他功能正常") # 初始化Redis连接 try: from services.redis_task_manager import redis_task_manager await redis_task_manager.connect() if redis_task_manager.is_connected: print("[OK] Redis连接成功") else: print("[WARN] Redis连接失败,任务状态将使用内存回退") except Exception as e: print(f"[WARN] Redis初始化异常: {e},任务状态将使用内存回退") @app.on_event("shutdown") async def shutdown_event(): """应用关闭时清理资源""" try: from services.redis_task_manager import redis_task_manager await redis_task_manager.disconnect() print("[OK] Redis连接已断开") except Exception as e: print(f"[WARN] Redis断开异常: {e}") # 创建必要目录 UPLOAD_DIR = Path("uploads") UPLOAD_DIR.mkdir(exist_ok=True) TEMPLATES_DIR = Path("templates") TEMPLATES_DIR.mkdir(exist_ok=True) STATIC_DIR = Path("static") STATIC_DIR.mkdir(exist_ok=True) HTML_OUTPUT_DIR = Path("html_output") HTML_OUTPUT_DIR.mkdir(exist_ok=True) # 挂载静态文件 import os # 使用当前工作目录下的static文件夹 static_dir = os.path.join(os.getcwd(), "static") app.mount("/static", StaticFiles(directory=static_dir), name="static") # 挂载HTML输出目录 html_output_dir = os.path.join(os.getcwd(), "html_output") app.mount("/html", StaticFiles(directory=html_output_dir), name="html") app.include_router(auth_router) app.include_router(inventory_router) app.include_router(aluminum_price_router, prefix="/api") try: from api.v1 import router as moldinsight_router except Exception as e: moldinsight_router = None print(f"[WARN] MoldInsight v1路由未加载: {e}") if moldinsight_router is None: try: from api.routes import router as moldinsight_router print("[WARN] 已回退到旧版 MoldInsight 路由") except Exception as fallback_error: moldinsight_router = None print(f"[WARN] MoldInsight旧版路由也未加载: {fallback_error}") if moldinsight_router is not None: app.include_router(moldinsight_router, prefix="/api") @app.get("/health") @app.post("/health") async def health(): from database.database import db_manager from sqlalchemy import text db_ok = False db_error = None try: if not db_manager.is_connected: await db_manager.connect() async with db_manager.engine.begin() as conn: await conn.execute(text("SELECT 1")) db_ok = True except Exception as e: db_ok = False db_error = str(e) return { "status": "healthy", "service": "gemold", "version": "4.0.0", "database_connected": db_ok, "database_error": db_error } @app.get("/") async def root(): from fastapi.responses import FileResponse return FileResponse(os.path.join(os.getcwd(), "static", "index.html")) @app.get("/moldinsight") async def moldinsight(): from fastapi.responses import FileResponse return FileResponse(os.path.join(os.getcwd(), "static", "index.html")) @app.get("/inventory") async def inventory(): from fastapi.responses import FileResponse return FileResponse(os.path.join(os.getcwd(), "static", "index.html")) @app.get("/login") async def login(): from fastapi.responses import FileResponse return FileResponse(os.path.join(os.getcwd(), "static", "index.html")) @app.get("/users") async def users(): from fastapi.responses import FileResponse return FileResponse(os.path.join(os.getcwd(), "static", "index.html")) if __name__ == "__main__": import uvicorn from config.settings import settings reload_enabled = os.getenv("UVICORN_RELOAD", "0").lower() in {"1", "true", "yes", "on"} print("启动 Gemold 模具制造管理系统 v4.0...") print(f"访问 http://localhost:{settings.PORT}") print(f"Python可执行文件: {sys.executable}") print(f"进程ID: {os.getpid()}") print(f"热重载: {reload_enabled}") print("功能模块:") print(" - 首页仪表盘") print(" - 用户管理") print(" - MoldInsight 模具分析") print(" - 进销存管理") uvicorn.run( "main:app", host=settings.HOST, port=settings.PORT, reload=reload_enabled )