# FastAPI 应用入口 import os from pathlib import Path from dotenv import load_dotenv load_dotenv() from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles from app.core.database import engine, Base from app.core.logging_config import logger, setup_logging from app.core.error_handler import setup_error_handlers from app.middleware.logging import logging_middleware from app.routers import auth, collections, operations from app.routers import ocr as ocr_router from app.routers import users as users_router from app.routers import information as information_router from app.routers import yichens as yichens_router from app.routers import seek as seek_router from app.routers import deal as deal_router from app.routers import purchase as purchase_router # 版本信息 - 从 config/VERSION 文件读取 def get_version(): """从 config/VERSION 文件读取版本号""" try: version_file = Path(__file__).parent.parent.parent / "config" / "VERSION" if version_file.exists(): with open(version_file, 'r', encoding='utf-8') as f: for line in f: if line.startswith('VERSION='): return line.strip().split('=', 1)[1] except Exception as e: logger.error(f"读取 VERSION 文件失败:{e}") return "0.0.0" # 默认版本号 __version__ = get_version() __app_name__ = "甲辰收藏系统 FastAPI 后端" # 启动时创建数据库表 Base.metadata.create_all(bind=engine) # 初始化日志系统 setup_logging() logger.info(f"{__app_name__} v{__version__} 启动成功") # 创建 FastAPI 应用 app = FastAPI( title=__app_name__, version=__version__, description="生肖纪念钞收藏管理系统后端 API" ) # 设置全局错误处理器 setup_error_handlers(app) # CORS 配置 - 生产环境限制域名 ALLOWED_ORIGINS = os.getenv("ALLOWED_ORIGINS", "http://47.103.29.111,http://120.55.81.21,https://socoolbot.com").split(",") app.add_middleware( CORSMiddleware, allow_origins=ALLOWED_ORIGINS, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # 挂载静态文件目录(图片上传和项目静态资源) uploads_dir = "uploads" os.makedirs(uploads_dir, exist_ok=True) app.mount("/uploads", StaticFiles(directory=uploads_dir), name="uploads") # 挂载项目静态资源目录 static_dir = Path(__file__).parent.parent / "static" if static_dir.exists(): app.mount("/static", StaticFiles(directory=str(static_dir)), name="static") # 添加日志中间件 app.middleware("http")(logging_middleware) # 注册路由 app.include_router(auth.router) app.include_router(collections.router) app.include_router(operations.router) app.include_router(ocr_router.router) # OCR 识别 app.include_router(users_router.router) # 当前用户接口 app.include_router(users_router.admin_router) # 管理员用户管理 app.include_router(information_router.router) app.include_router(yichens_router.router) # 一尘看板 app.include_router(seek_router.router) # 寻配号 app.include_router(deal_router.router) # 成交行情 app.include_router(purchase_router.router) # 认购群 @app.get("/") def root(): """根路径""" return { "name": __app_name__, "version": __version__, "status": "running" } @app.get("/health") def health_check(): """健康检查""" return {"status": "healthy"} if __name__ == "__main__": import uvicorn port = int(os.getenv("PORT", "3000")) uvicorn.run(app, host="0.0.0.0", port=port) from app.routers import seek as seek_router from app.routers import deal as deal_router