ab20bc5a1f
# Conflicts: # backend/app/api/key_visits.py # backend/app/api/mini_business.py # backend/app/api/visits.py # backend/app/api/work_plans.py # backend/app/main.py # backend/app/models/__init__.py # backend/app/schemas/key_visit.py # backend/app/schemas/mini_business.py # backend/app/schemas/work_plan.py # backend/app/services/light_board.py # frontend/src/components/DesktopLayout.vue # frontend/src/stores/theme.ts # frontend/src/views/desktop/ManagerWorkspace.vue # frontend/src/views/desktop/WorkPlans.vue # frontend/src/views/mobile/KeyVisitForm.vue # frontend/src/views/mobile/LeaveForm.vue # frontend/src/views/mobile/PlansList.vue # frontend/src/views/mobile/VisitForm.vue # frontend/src/views/mobile/WorkPlanForm.vue
83 lines
2.9 KiB
Python
83 lines
2.9 KiB
Python
from contextlib import asynccontextmanager
|
|
from fastapi import FastAPI
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from sqlalchemy import select
|
|
from app.config import settings, validate_security_settings
|
|
from app.database import engine, async_session
|
|
from app.api import router as api_router
|
|
from app.api import auth, users, customers, visits, work_plans, mini_business, mini_business_logs, key_visits
|
|
from app.api import dashboard, upload, export, import_data, wecom, daily_notes, ai_summary, system_config, leaves, audit
|
|
from app.models.system_config import SystemConfig
|
|
from app.services.holidays import refresh_holidays
|
|
from app.services.scheduler_manager import start_scheduler, shutdown_scheduler
|
|
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(app: FastAPI):
|
|
validate_security_settings()
|
|
# Read notification_time from DB (or use default 17:30)
|
|
notification_hour, notification_minute = 17, 30
|
|
async with async_session() as db:
|
|
row = await db.get(SystemConfig, "notification_time")
|
|
if row and row.value:
|
|
try:
|
|
parts = row.value.strip().split(":")
|
|
notification_hour, notification_minute = int(parts[0]), int(parts[1])
|
|
except (ValueError, IndexError):
|
|
pass
|
|
# Auto-refresh Chinese holiday data from API on startup
|
|
try:
|
|
await refresh_holidays(db)
|
|
except Exception:
|
|
pass # Use cached data if API unavailable
|
|
|
|
# Start daily reporting scheduler
|
|
start_scheduler(notification_hour, notification_minute)
|
|
|
|
yield
|
|
|
|
# Shutdown
|
|
shutdown_scheduler()
|
|
await engine.dispose()
|
|
|
|
|
|
app = FastAPI(
|
|
title=settings.APP_NAME,
|
|
version="0.1.0",
|
|
lifespan=lifespan,
|
|
)
|
|
|
|
# CORS
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=settings.CORS_ORIGINS,
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
# Mount all routers
|
|
app.include_router(auth.router, prefix="/api")
|
|
app.include_router(users.router, prefix="/api")
|
|
app.include_router(customers.router, prefix="/api")
|
|
app.include_router(visits.router, prefix="/api")
|
|
app.include_router(work_plans.router, prefix="/api")
|
|
app.include_router(mini_business.router, prefix="/api")
|
|
app.include_router(mini_business_logs.router, prefix="/api")
|
|
app.include_router(key_visits.router, prefix="/api")
|
|
app.include_router(dashboard.router, prefix="/api")
|
|
app.include_router(leaves.router, prefix="/api")
|
|
app.include_router(upload.router, prefix="/api")
|
|
app.include_router(export.router, prefix="/api")
|
|
app.include_router(import_data.router, prefix="/api")
|
|
app.include_router(wecom.router, prefix="/api")
|
|
app.include_router(daily_notes.router, prefix="/api")
|
|
app.include_router(ai_summary.router, prefix="/api")
|
|
app.include_router(system_config.router, prefix="/api")
|
|
app.include_router(audit.router, prefix="/api")
|
|
|
|
|
|
@app.get("/health")
|
|
async def health_check():
|
|
return {"status": "ok", "app": settings.APP_NAME}
|