""" 周报生成器 - 生成7天内的汽车后市场情报报告 """ import os import sys from datetime import datetime, timedelta from loguru import logger # 添加父目录到路径 current_dir = os.path.dirname(os.path.abspath(__file__)) parent_dir = os.path.dirname(os.path.dirname(current_dir)) if parent_dir not in sys.path: sys.path.insert(0, parent_dir) from applications.reporter.base_reporter import BaseReporter, AIAnalysisDataSource from applications.reporter.dingtalk_webhook import DingTalkWebhook from utils.mysql_agent import MySQLAgent from config import Config class WeeklyReporter(BaseReporter): """周报生成器""" def __init__(self, dingtalk_webhook: str = None): """ 初始化周报生成器 Args: dingtalk_webhook: 钉钉Webhook地址(可选) """ super().__init__() # 初始化数据库连接 db_agent = MySQLAgent(Config.MYSQL_CONFIG) # 添加AI分析结果数据源(已筛选是否相关=1) self.add_data_source(AIAnalysisDataSource(db_agent)) self.logger = logger.bind(module="WeeklyReporter") # 初始化钉钉推送(如果提供了webhook) self.dingtalk_webhook = dingtalk_webhook or getattr(Config, 'DINGTALK_WEBHOOK', None) self.dingtalk_client = None if self.dingtalk_webhook: self.dingtalk_client = DingTalkWebhook(self.dingtalk_webhook) self.logger.info("已启用钉钉推送功能") def generate(self, output_dir: str = "output/reports/weekly", template_path: str = None, save_markdown: bool = True, send_dingtalk: bool = True) -> dict: """ 生成周报 Args: output_dir: 输出目录 template_path: 可选的外部HTML模板路径 save_markdown: 是否保存Markdown文件 send_dingtalk: 是否发送到钉钉 Returns: 包含生成文件路径的字典 """ self.logger.info("开始生成周报") # 计算时间范围:7天内 end_time = datetime.now() start_time = end_time - timedelta(days=7) self.logger.info(f"时间范围: {start_time.strftime('%Y-%m-%d %H:%M:%S')} 至 {end_time.strftime('%Y-%m-%d %H:%M:%S')}") # 收集数据 articles = self.collect_data(start_time, end_time) # 生成报告内容(generate_report_content会自动处理空数据情况) markdown_content = f"""# 汽车后市场情报周报 ## 报告时间 **生成时间**: {end_time.strftime('%Y-%m-%d %H:%M:%S')} **时间范围**: {start_time.strftime('%Y-%m-%d %H:%M:%S')} 至 {end_time.strftime('%Y-%m-%d %H:%M:%S')} {self.generate_report_content(articles, report_type="周报")} """ # 生成HTML报告 html_content = self.generate_html_report(markdown_content, template_path=template_path) # 保存报告 os.makedirs(output_dir, exist_ok=True) timestamp = end_time.strftime('%Y%m%d_%H%M%S') result = {} # 保存HTML报告 html_filename = f"weekly_report_{timestamp}.html" html_path = os.path.join(output_dir, html_filename) self.save_report(html_content, html_path) result['html_path'] = html_path self.logger.info(f"HTML报告已保存: {html_path}") # 保存Markdown报告 markdown_path = None if save_markdown: markdown_filename = f"weekly_report_{timestamp}.md" markdown_path = os.path.join(output_dir, markdown_filename) self.save_markdown_report(markdown_content, markdown_path) result['markdown_path'] = markdown_path self.logger.info(f"Markdown报告已保存: {markdown_path}") # 发送到钉钉 if send_dingtalk and self.dingtalk_client: title = f"汽车后市场情报周报 - {start_time.strftime('%Y-%m-%d')} 至 {end_time.strftime('%Y-%m-%d')}" success = self.dingtalk_client.send_report(title, markdown_content, markdown_path) result['dingtalk_sent'] = success if success: self.logger.info("报告已推送到钉钉群") else: self.logger.warning("报告推送到钉钉群失败") self.logger.info(f"周报生成完成") return result def main(): """主函数""" try: reporter = WeeklyReporter() result = reporter.generate() print(f"周报已生成:") print(f" HTML: {result.get('html_path')}") if 'markdown_path' in result: print(f" Markdown: {result.get('markdown_path')}") if 'dingtalk_sent' in result: print(f" 钉钉推送: {'成功' if result.get('dingtalk_sent') else '失败'}") except Exception as e: logger.error(f"生成周报失败: {str(e)}", exc_info=True) raise if __name__ == "__main__": main()