"""管理会计OS — 主入口""" import logging from fastapi import FastAPI, Request, Depends from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse from dotenv import load_dotenv from app.database import init_db from app.api import auth, kpis, templates, maps, dashboard, data, alerts, ai_analysis, alert_rules, users, thresholds, notifications, permissions, action_plans, alignment, org, objectives, versions, budget, cost, predict, reports, security, knowledge, bot_bridge, customer_dashboard, deviation_push, budget_generate, knowledge_articles, kpi_causality, data_quality, bi_reports, entities, bsc_layers from app.utils.cache import clear_all as clear_cache, delete as delete_cache from scripts.erp_sync import run_sync as run_erp_sync from app.auth_middleware import require_auth load_dotenv() # 日志配置 logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s", datefmt="%Y-%m-%d %H:%M:%S", ) logger = logging.getLogger("cma") app = FastAPI(title="管理会计OS API", version="1.0.0", docs_url="/docs") app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.include_router(auth.router) app.include_router(kpis.router) app.include_router(templates.router) app.include_router(maps.router) app.include_router(dashboard.router) app.include_router(data.router) app.include_router(alerts.router) app.include_router(ai_analysis.router) app.include_router(alert_rules.router) app.include_router(users.router) app.include_router(thresholds.router) app.include_router(notifications.router) app.include_router(permissions.router) app.include_router(action_plans.router) app.include_router(alignment.router) app.include_router(org.router) app.include_router(objectives.router) app.include_router(versions.router) app.include_router(budget.router) app.include_router(cost.router) app.include_router(predict.router) app.include_router(reports.router) app.include_router(security.router) app.include_router(knowledge.router) app.include_router(bot_bridge.router) app.include_router(customer_dashboard.router) app.include_router(deviation_push.router) app.include_router(budget_generate.router) app.include_router(knowledge_articles.router) app.include_router(kpi_causality.router) app.include_router(data_quality.router) app.include_router(bi_reports.router) app.include_router(entities.router) app.include_router(bsc_layers.router) @app.exception_handler(Exception) async def global_exception_handler(request: Request, exc: Exception): logger.error(f"未捕获异常: {exc}", exc_info=True) return JSONResponse(status_code=500, content={"detail": "服务器内部错误"}) @app.on_event("startup") def startup(): init_db() logger.info("管理会计OS后端启动完成") @app.post("/api/cma/admin/erp-sync") def admin_erp_sync(user=Depends(require_auth), kpi_codes: str = None): """手动触发ERP数据同步""" kpi_list = kpi_codes.split(",") if kpi_codes else None try: run_erp_sync(dry_run=False, kpi_codes=kpi_list, use_api=True) return {"message": "ERP同步完成", "kpis": kpi_list} except Exception as e: return JSONResponse(status_code=500, content={"detail": f"同步失败: {str(e)}"}) @app.get("/api/cma/admin/erp-sync/dry-run") def admin_erp_sync_dry_run(user=Depends(require_auth), kpi_codes: str = None): "试运行,不写入数据库""" kpi_list = kpi_codes.split(",") if kpi_codes else None try: run_erp_sync(dry_run=True, kpi_codes=kpi_list, use_api=True) return {"message": "试运行完成"} except Exception as e: return JSONResponse(status_code=500, content={"detail": f"试运行失败: {str(e)}"}) @app.post("/api/cma/admin/alerts/check") def admin_check_alerts(): """手动触发预警检查""" from app.database import get_session_local from scripts.alert_generator import generate_and_push db = get_session_local()() try: result = generate_and_push(db) return {"message": "预警检查完成", "result": result} except Exception as e: return JSONResponse(status_code=500, content={"detail": f"检查失败: {str(e)}"}) finally: db.close() @app.post("/api/cma/admin/cache/clear") def admin_clear_cache(module: str = None): """清空缓存,指定module则只清该模块""" if module: delete_cache(module) return {"message": f"缓存已清空: {module}"} else: clear_cache() return {"message": "全部缓存已清空"} @app.get("/health") def health(): return {"status": "ok", "version": "1.0.0"}