178 lines
6.1 KiB
Python
178 lines
6.1 KiB
Python
"""
|
|
Simple Task Definitions
|
|
簡化的任務定義,避免循環導入
|
|
"""
|
|
|
|
from datetime import datetime, date, timedelta
|
|
from sqlalchemy import and_, or_
|
|
from utils.logger import get_logger
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
def send_daily_reminders_task():
|
|
"""發送每日提醒郵件的實際實作"""
|
|
from models import db, TodoItem, TodoUserPref
|
|
from utils.email_service import EmailService
|
|
from utils.notification_service import NotificationService
|
|
|
|
try:
|
|
today = date.today()
|
|
tomorrow = today + timedelta(days=1)
|
|
|
|
# 查找明日到期的待辦事項
|
|
due_tomorrow = db.session.query(TodoItem).filter(
|
|
and_(
|
|
TodoItem.due_date == tomorrow,
|
|
TodoItem.status != 'DONE'
|
|
)
|
|
).all()
|
|
|
|
# 查找已逾期的待辦事項
|
|
overdue = db.session.query(TodoItem).filter(
|
|
and_(
|
|
TodoItem.due_date < today,
|
|
TodoItem.status != 'DONE'
|
|
)
|
|
).all()
|
|
|
|
email_service = EmailService()
|
|
notification_service = NotificationService()
|
|
|
|
sent_count = 0
|
|
|
|
# 處理明日到期提醒
|
|
for todo in due_tomorrow:
|
|
recipients = notification_service.get_notification_recipients(todo)
|
|
for recipient in recipients:
|
|
try:
|
|
# 檢查用戶是否啟用郵件提醒
|
|
user_pref = TodoUserPref.query.filter_by(ad_account=recipient).first()
|
|
if not user_pref or not user_pref.email_reminder_enabled:
|
|
continue
|
|
|
|
if email_service.send_reminder_email(todo, recipient, 'due_tomorrow'):
|
|
sent_count += 1
|
|
except Exception as e:
|
|
logger.error(f"Failed to send due tomorrow reminder to {recipient}: {str(e)}")
|
|
|
|
# 處理逾期提醒
|
|
for todo in overdue:
|
|
recipients = notification_service.get_notification_recipients(todo)
|
|
for recipient in recipients:
|
|
try:
|
|
# 檢查用戶是否啟用郵件提醒
|
|
user_pref = TodoUserPref.query.filter_by(ad_account=recipient).first()
|
|
if not user_pref or not user_pref.email_reminder_enabled:
|
|
continue
|
|
|
|
if email_service.send_reminder_email(todo, recipient, 'overdue'):
|
|
sent_count += 1
|
|
except Exception as e:
|
|
logger.error(f"Failed to send overdue reminder to {recipient}: {str(e)}")
|
|
|
|
# 記錄稽核日誌
|
|
from models import TodoAuditLog
|
|
audit = TodoAuditLog(
|
|
actor_ad='system',
|
|
todo_id=None,
|
|
action='DAILY_REMINDER',
|
|
detail={
|
|
'due_tomorrow_count': len(due_tomorrow),
|
|
'overdue_count': len(overdue),
|
|
'emails_sent': sent_count
|
|
}
|
|
)
|
|
db.session.add(audit)
|
|
db.session.commit()
|
|
|
|
logger.info(f"Daily reminders sent: {sent_count} emails for {len(due_tomorrow + overdue)} todos")
|
|
return {
|
|
'sent_count': sent_count,
|
|
'due_tomorrow': len(due_tomorrow),
|
|
'overdue': len(overdue)
|
|
}
|
|
|
|
except Exception as e:
|
|
logger.error(f"Daily reminders task failed: {str(e)}")
|
|
raise
|
|
|
|
def send_weekly_summary_task():
|
|
"""發送每週摘要報告的實際實作"""
|
|
from models import db, TodoUserPref
|
|
from utils.email_service import EmailService
|
|
from utils.notification_service import NotificationService
|
|
|
|
try:
|
|
# 取得所有啟用週報的用戶
|
|
users = TodoUserPref.query.filter_by(weekly_summary_enabled=True).all()
|
|
|
|
email_service = EmailService()
|
|
notification_service = NotificationService()
|
|
sent_count = 0
|
|
|
|
for user in users:
|
|
try:
|
|
# 準備週報資料
|
|
digest_data = notification_service.prepare_digest(user.ad_account, 'weekly')
|
|
|
|
if email_service.send_digest_email(user.ad_account, digest_data):
|
|
sent_count += 1
|
|
except Exception as e:
|
|
logger.error(f"Failed to send weekly summary to {user.ad_account}: {str(e)}")
|
|
|
|
# 記錄稽核日誌
|
|
from models import TodoAuditLog
|
|
audit = TodoAuditLog(
|
|
actor_ad='system',
|
|
todo_id=None,
|
|
action='WEEKLY_SUMMARY',
|
|
detail={
|
|
'users_count': len(users),
|
|
'emails_sent': sent_count
|
|
}
|
|
)
|
|
db.session.add(audit)
|
|
db.session.commit()
|
|
|
|
logger.info(f"Weekly summary sent: {sent_count} emails to {len(users)} users")
|
|
return {
|
|
'sent_count': sent_count,
|
|
'total_users': len(users)
|
|
}
|
|
|
|
except Exception as e:
|
|
logger.error(f"Weekly summary task failed: {str(e)}")
|
|
raise
|
|
|
|
def cleanup_old_logs_task():
|
|
"""清理舊的日誌記錄的實際實作"""
|
|
from models import db, TodoAuditLog
|
|
|
|
try:
|
|
# 清理30天前的稽核日誌
|
|
thirty_days_ago = datetime.utcnow() - timedelta(days=30)
|
|
deleted_count = TodoAuditLog.query.filter(
|
|
TodoAuditLog.created_at < thirty_days_ago
|
|
).delete()
|
|
|
|
db.session.commit()
|
|
logger.info(f"Cleaned up {deleted_count} old audit logs")
|
|
return {'deleted_count': deleted_count}
|
|
|
|
except Exception as e:
|
|
logger.error(f"Cleanup logs task failed: {str(e)}")
|
|
raise
|
|
|
|
|
|
# 為了與現有代碼兼容,提供簡單的包裝函數
|
|
def send_daily_reminders():
|
|
"""包裝函數,保持與現有代碼兼容"""
|
|
return send_daily_reminders_task()
|
|
|
|
def send_weekly_summary():
|
|
"""包裝函數,保持與現有代碼兼容"""
|
|
return send_weekly_summary_task()
|
|
|
|
def cleanup_old_logs():
|
|
"""包裝函數,保持與現有代碼兼容"""
|
|
return cleanup_old_logs_task() |