1ec20ee53e
保存合并前工作树中遗留的进行中改动,避免分支合并时丢失: - scheduler: 填报汇总改为定向推送给支局长/领导(而非广播@all) - router: JWT token 校验修复,bind token(UUID)不被误剥离 - 工作计划/计划列表: 搜索+筛选+分页 UI - 各列表 API 增加 search 参数支持 - docker-compose.backend.yml + backend/.dockerignore 纳入版本管理 Co-Authored-By: Claude <noreply@anthropic.com>
60 lines
2.0 KiB
Python
60 lines
2.0 KiB
Python
"""APScheduler singleton — allows runtime reschedule of notification jobs."""
|
|
|
|
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
|
|
|
_scheduler: AsyncIOScheduler | None = None
|
|
|
|
|
|
def get_scheduler() -> AsyncIOScheduler:
|
|
"""Lazy-init and return the global scheduler."""
|
|
global _scheduler
|
|
if _scheduler is None:
|
|
_scheduler = AsyncIOScheduler(timezone="Asia/Shanghai")
|
|
return _scheduler
|
|
|
|
|
|
async def reschedule_daily_check(hour: int, minute: int):
|
|
"""Update the daily_check cron job to a new time."""
|
|
sched = get_scheduler()
|
|
# Remove and re-add — APScheduler reschedule_job is inconsistent with cron triggers
|
|
try:
|
|
sched.remove_job("daily_check")
|
|
except Exception:
|
|
pass
|
|
from app.services.scheduler import check_daily_reporting
|
|
from app.database import async_session
|
|
|
|
async def _wrapper():
|
|
async with async_session() as db:
|
|
await check_daily_reporting(db)
|
|
|
|
sched.add_job(_wrapper, "cron", hour=hour, minute=minute, id="daily_check", timezone="Asia/Shanghai")
|
|
|
|
|
|
def start_scheduler(notification_hour: int = 17, notification_minute: int = 30):
|
|
"""Start the scheduler with configured notification times."""
|
|
sched = get_scheduler()
|
|
|
|
from app.services.scheduler import check_daily_reporting, check_overdue_plans
|
|
from app.database import async_session
|
|
|
|
async def _daily():
|
|
async with async_session() as db:
|
|
await check_daily_reporting(db)
|
|
|
|
async def _overdue():
|
|
async with async_session() as db:
|
|
await check_overdue_plans(db)
|
|
|
|
sched.add_job(_daily, "cron", hour=notification_hour, minute=notification_minute, id="daily_check", timezone="Asia/Shanghai")
|
|
sched.add_job(_overdue, "cron", hour=9, minute=0, id="overdue_check", timezone="Asia/Shanghai")
|
|
sched.start()
|
|
|
|
|
|
def shutdown_scheduler():
|
|
"""Shutdown the scheduler gracefully."""
|
|
global _scheduler
|
|
if _scheduler is not None:
|
|
_scheduler.shutdown(wait=False)
|
|
_scheduler = None
|