Files
zcglxt/app/main.py
Claude e71181f0a3 fix: 修复多个关键问题
- 修复前端路由守卫:未登录时不显示提示,直接跳转登录页
- 修复API拦截器:401错误不显示提示,直接跳转
- 增强验证码显示:图片尺寸从120x40增加到200x80
- 增大验证码字体:从28号增加到48号
- 优化验证码字符:排除易混淆的0和1
- 减少干扰线:从5条减少到3条,添加背景色优化
- 增强登录API日志:添加详细的调试日志
- 增强验证码生成和验证日志
- 优化异常处理和错误追踪

影响文件:
- src/router/index.ts
- src/api/request.ts
- app/services/auth_service.py
- app/api/v1/auth.py
- app/schemas/user.py

测试状态:
- 前端构建通过
- 后端语法检查通过
- 验证码显示效果优化完成

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-25 00:26:21 +08:00

178 lines
5.1 KiB
Python
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.
"""
FastAPI应用主入口
"""
from contextlib import asynccontextmanager
from fastapi import FastAPI, Request, status
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from starlette.exceptions import HTTPException as StarletteHTTPException
from loguru import logger
import sys
from app.core.config import settings
from app.core.exceptions import BusinessException
from app.core.response import error_response
from app.api.v1 import api_router
from app.db.session import init_db, close_db
# 配置日志
logger.remove()
logger.add(
sys.stderr,
level=settings.LOG_LEVEL,
format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>",
colorize=True
)
logger.add(
settings.LOG_FILE,
rotation=settings.LOG_ROTATION,
retention=settings.LOG_RETENTION,
level=settings.LOG_LEVEL,
format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name}:{function}:{line} - {message}",
encoding="utf-8"
)
@asynccontextmanager
async def lifespan(app: FastAPI):
"""应用生命周期管理"""
# 启动时执行
logger.info("🚀 应用启动中...")
logger.info(f"📦 环境: {settings.APP_ENVIRONMENT}")
logger.info(f"🔗 数据库: {settings.DATABASE_URL}")
# 初始化数据库生产环境使用Alembic迁移
if settings.is_development:
await init_db()
logger.info("✅ 数据库初始化完成")
yield
# 关闭时执行
logger.info("🛑 应用关闭中...")
await close_db()
logger.info("✅ 数据库连接已关闭")
# 创建FastAPI应用
app = FastAPI(
title=settings.APP_NAME,
version=settings.APP_VERSION,
description="企业级资产管理系统后端API",
docs_url="/docs" if settings.DEBUG else None,
redoc_url="/redoc" if settings.DEBUG else None,
openapi_url="/openapi.json" if settings.DEBUG else None,
lifespan=lifespan
)
# 配置CORS
app.add_middleware(
CORSMiddleware,
allow_origins=settings.CORS_ORIGINS,
allow_credentials=settings.CORS_ALLOW_CREDENTIALS,
allow_methods=settings.CORS_ALLOW_METHODS,
allow_headers=settings.CORS_ALLOW_HEADERS,
)
# 自定义异常处理器
@app.exception_handler(BusinessException)
async def business_exception_handler(request: Request, exc: BusinessException):
"""业务异常处理"""
logger.warning(f"业务异常: {exc.message} - 错误码: {exc.error_code}")
return JSONResponse(
status_code=exc.code,
content=error_response(
code=exc.code,
message=exc.message,
errors=[{"field": k, "message": v} for k, v in exc.data.items()] if exc.data else None
)
)
@app.exception_handler(StarletteHTTPException)
async def http_exception_handler(request: Request, exc: StarletteHTTPException):
"""HTTP异常处理"""
logger.warning(f"HTTP异常: {exc.status_code} - {exc.detail}")
return JSONResponse(
status_code=exc.status_code,
content=error_response(
code=exc.status_code,
message=str(exc.detail)
)
)
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
"""请求验证异常处理"""
errors = []
for error in exc.errors():
errors.append({
"field": ".".join(str(loc) for loc in error["loc"]),
"message": error["msg"]
})
logger.warning(f"验证异常: {errors}")
return JSONResponse(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
content=error_response(
code=status.HTTP_422_UNPROCESSABLE_ENTITY,
message="参数验证失败",
errors=errors
)
)
@app.exception_handler(Exception)
async def general_exception_handler(request: Request, exc: Exception):
"""通用异常处理"""
logger.error(f"未处理的异常: {type(exc).__name__} - {str(exc)}", exc_info=True)
return JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content=error_response(
code=status.HTTP_500_INTERNAL_SERVER_ERROR,
message="服务器内部错误" if not settings.DEBUG else str(exc)
)
)
# 注册路由
app.include_router(api_router, prefix=settings.API_V1_PREFIX)
# 健康检查
@app.get("/health", tags=["系统"])
async def health_check():
"""健康检查接口"""
return {
"status": "ok",
"app_name": settings.APP_NAME,
"version": settings.APP_VERSION,
"environment": settings.APP_ENVIRONMENT
}
# 根路径
@app.get("/", tags=["系统"])
async def root():
"""根路径"""
return {
"message": f"欢迎使用{settings.APP_NAME} API",
"version": settings.APP_VERSION,
"docs": "/docs" if settings.DEBUG else None
}
if __name__ == "__main__":
import uvicorn
uvicorn.run(
"app.main:app",
host=settings.HOST,
port=settings.PORT,
reload=settings.DEBUG,
log_level=settings.LOG_LEVEL.lower()
)