- 日报推送12人(主管+组长+制片+股东) - 周报/月报推送4人(仅股东+主管,含成本信息) - 人均日产出分母改为只算有中期提交的人,与产出口径一致 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
93 lines
3.0 KiB
Python
93 lines
3.0 KiB
Python
"""APScheduler 定时任务 —— 自动生成报告并推送飞书"""
|
||
import asyncio
|
||
import logging
|
||
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||
from database import SessionLocal
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
scheduler = AsyncIOScheduler(timezone="Asia/Shanghai")
|
||
|
||
|
||
async def _run_report_job(report_type: str):
|
||
"""通用报告任务执行器"""
|
||
from services.report_service import (
|
||
generate_daily_report, generate_weekly_report, generate_monthly_report,
|
||
)
|
||
from services.feishu_service import (
|
||
feishu, build_daily_card, build_weekly_card, build_monthly_card,
|
||
)
|
||
from config import DAILY_REPORT_RECEIVERS, REPORT_RECEIVERS
|
||
|
||
logger.info(f"[定时任务] 开始生成{report_type}...")
|
||
db = SessionLocal()
|
||
try:
|
||
if report_type == "日报":
|
||
result = generate_daily_report(db)
|
||
card = build_daily_card(result["title"], result["card_data"])
|
||
receivers = DAILY_REPORT_RECEIVERS
|
||
elif report_type == "周报":
|
||
result = generate_weekly_report(db)
|
||
card = build_weekly_card(result["title"], result["card_data"])
|
||
receivers = REPORT_RECEIVERS
|
||
elif report_type == "月报":
|
||
result = generate_monthly_report(db)
|
||
card = build_monthly_card(result["title"], result["card_data"])
|
||
receivers = REPORT_RECEIVERS
|
||
else:
|
||
logger.error(f"未知报告类型: {report_type}")
|
||
return
|
||
|
||
logger.info(f"[定时任务] {report_type}生成完成,开始推送飞书({len(receivers)}人)...")
|
||
push_result = await feishu.send_report_card_to_all(card, receivers=receivers)
|
||
logger.info(f"[定时任务] {report_type}推送完成: {push_result}")
|
||
|
||
except Exception as e:
|
||
logger.error(f"[定时任务] {report_type}生成/推送失败: {e}", exc_info=True)
|
||
finally:
|
||
db.close()
|
||
|
||
|
||
async def daily_report_job():
|
||
await _run_report_job("日报")
|
||
|
||
|
||
async def weekly_report_job():
|
||
await _run_report_job("周报")
|
||
|
||
|
||
async def monthly_report_job():
|
||
await _run_report_job("月报")
|
||
|
||
|
||
def setup_scheduler():
|
||
"""配置并启动定时任务(通过 DISABLE_SCHEDULER=1 可关闭)"""
|
||
import os
|
||
if os.environ.get("DISABLE_SCHEDULER") == "1":
|
||
logger.info("[定时任务] 已通过 DISABLE_SCHEDULER=1 禁用")
|
||
return
|
||
|
||
# 日报:每天 20:00
|
||
scheduler.add_job(
|
||
daily_report_job, "cron",
|
||
hour=20, minute=0,
|
||
id="daily_report", replace_existing=True,
|
||
)
|
||
# 周报:每周五 20:00
|
||
scheduler.add_job(
|
||
weekly_report_job, "cron",
|
||
day_of_week="fri", hour=20, minute=0,
|
||
id="weekly_report", replace_existing=True,
|
||
)
|
||
# 月报:每月1日 10:00
|
||
scheduler.add_job(
|
||
monthly_report_job, "cron",
|
||
day=1, hour=10, minute=0,
|
||
id="monthly_report", replace_existing=True,
|
||
)
|
||
|
||
scheduler.start()
|
||
logger.info(
|
||
"[定时任务] 已启动 — 日报:每天20:00 | 周报:周五20:00 | 月报:每月1日10:00"
|
||
)
|