fix: 修复了导致增量分析报告发送失败的几个核心问题:

修复报告分发器初始化错误:
在 AutoScheduler 中,初始化 ReportDispatcher 时漏传了 report_generator,导致在尝试生成报告(图片或文本)时出现 'NoneType' object has no attribute 'generate_image_report' 错误。
已更新 AutoScheduler 的构造函数并正确传递 report_generator。
修复 LLM 分析器在增量模式下的数据结构错误:UserTitleAnalyzer 报错:在增量模式下,用户活动数据被简化存储,导致 UserTitleAnalyzer 找不到 'hours' 键(Error: 'hours')。
补全数据维度:更新了 AnalysisApplicationService 的增量数据转换逻辑,保留了完整的每小时活跃分布 (hours) 和回复数 (reply_count)。
统一字段名:增量模式下使用了 nickname 字段以匹配分析器的预期(之前被错误转为了 name)。
增强容错性:优化了 UserTitleAnalyzer 的逻辑,现在它能安全地处理 hours 缺失或旧版本数据 schema,不再会因为找不到键而崩溃。
修复增量数据合并逻辑:
更新了 IncrementalMergeService,现在它能正确合并多个批次中的每小时发言统计和回复数统计,确保最终生成的报告数据准确。
This commit is contained in:
SXP-Simon
2026-02-11 12:54:02 +08:00
parent e292558965
commit ced38e6a9e
5 changed files with 81 additions and 57 deletions
@@ -187,32 +187,36 @@ class UserTitleAnalyzer(BaseAnalyzer):
continue
# 分析用户特征 (此处已基于已清理的 stats)
night_messages = sum(stats["hours"][h] for h in range(6))
avg_chars = (
stats["char_count"] / stats["message_count"]
if stats["message_count"] > 0
else 0
)
# 兼容性处理:优先使用 hours (dict),如果没有则尝试从消息推断或使用空
hours_data = stats.get("hours")
if hours_data is None:
# 尝试兼容旧 schema 或简化版
active_hours = stats.get("active_hours", [])
hours_data = dict.fromkeys(active_hours, 1)
# 安全计算夜间发言数
night_messages = sum(hours_data.get(h, 0) for h in range(6))
message_count = stats.get("message_count", 0)
if message_count <= 0:
continue
avg_chars = stats.get("char_count", 0) / message_count
# 称号所需维度
user_summaries.append(
{
"name": stats["nickname"],
"name": stats.get("nickname", stats.get("name", user_id_str)),
"user_id": user_id_str,
"message_count": stats["message_count"],
"message_count": message_count,
"avg_chars": round(avg_chars, 1),
"emoji_ratio": round(
stats["emoji_count"] / stats["message_count"], 2
)
if stats["message_count"] > 0
else 0,
"night_ratio": round(night_messages / stats["message_count"], 2)
if stats["message_count"] > 0
else 0,
stats.get("emoji_count", 0) / message_count, 2
),
"night_ratio": round(night_messages / message_count, 2),
"reply_ratio": round(
stats["reply_count"] / stats["message_count"], 2
)
if stats["message_count"] > 0
else 0,
stats.get("reply_count", 0) / message_count, 2
),
}
)
@@ -25,18 +25,20 @@ class AutoScheduler:
analysis_service,
bot_manager,
retry_manager,
report_generator=None,
html_render_func=None,
):
self.config_manager = config_manager
self.analysis_service = analysis_service
self.bot_manager = bot_manager
self.retry_manager = retry_manager
self.report_generator = report_generator
self.html_render_func = html_render_func
# 初始化核心组件
self.message_sender = MessageSender(bot_manager, config_manager, retry_manager)
self.report_dispatcher = ReportDispatcher(
config_manager, None, self.message_sender, retry_manager
config_manager, report_generator, self.message_sender, retry_manager
)
if html_render_func:
self.report_dispatcher.set_html_render(html_render_func)