Files
v6ole ab20bc5a1f Merge branch 'main' into develop
# 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
2026-08-17 09:31:12 +08:00

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}