- 日报/周报/月报改为结构化卡片推送(column_set布局) - 新增 report:daily/weekly/monthly 权限到角色管理 - 产出统计只算中期制作阶段动画秒数 - 效率之星改为跨项目加权通过率 - AI点评补充风险数据源 - 禁用多余admin账号,股东角色加报告权限 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
89 lines
2.8 KiB
Python
89 lines
2.8 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,
|
||
)
|
||
|
||
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"])
|
||
elif report_type == "周报":
|
||
result = generate_weekly_report(db)
|
||
card = build_weekly_card(result["title"], result["card_data"])
|
||
elif report_type == "月报":
|
||
result = generate_monthly_report(db)
|
||
card = build_monthly_card(result["title"], result["card_data"])
|
||
else:
|
||
logger.error(f"未知报告类型: {report_type}")
|
||
return
|
||
|
||
logger.info(f"[定时任务] {report_type}生成完成,开始推送飞书...")
|
||
push_result = await feishu.send_report_card_to_all(card)
|
||
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"
|
||
)
|