Update statistic.py

This commit is contained in:
SengokuCola
2025-06-22 18:22:42 +08:00
parent ca9fa14c30
commit 06927f89a0

View File

@@ -583,19 +583,20 @@ class StatisticOutputTask(AsyncTask):
except Exception as e: except Exception as e:
logger.error(f"收集HFC统计数据失败: {e}") logger.error(f"收集HFC统计数据失败: {e}")
# 计算加权平均时间 # 只对非all_time时段计算加权平均时间all_time需要在历史数据合并后再计算
for period_key in stats: for period_key in stats:
for stat_type in [HFC_AVG_TIME_BY_CHAT, HFC_AVG_TIME_BY_ACTION, HFC_AVG_TIME_BY_VERSION]: if period_key != "all_time": # 跳过all_time等历史数据合并后再计算
for key, time_data in stats[period_key][stat_type].items(): for stat_type in [HFC_AVG_TIME_BY_CHAT, HFC_AVG_TIME_BY_ACTION, HFC_AVG_TIME_BY_VERSION]:
if time_data.get("count", 0) > 0: for key, time_data in stats[period_key][stat_type].items():
count = time_data["count"] if time_data.get("count", 0) > 0:
stats[period_key][stat_type][key] = { count = time_data["count"]
"decision": time_data["decision"] / count, stats[period_key][stat_type][key] = {
"action": time_data["action"] / count, "decision": time_data["decision"] / count,
"total": time_data["total"] / count "action": time_data["action"] / count,
} "total": time_data["total"] / count
else: }
stats[period_key][stat_type][key] = {"decision": 0, "action": 0, "total": 0} else:
stats[period_key][stat_type][key] = {"decision": 0, "action": 0, "total": 0}
return stats return stats
@@ -654,9 +655,14 @@ class StatisticOutputTask(AsyncTask):
if key in [HFC_AVG_TIME_BY_CHAT, HFC_AVG_TIME_BY_ACTION, HFC_AVG_TIME_BY_VERSION] and isinstance(sub_val, dict): if key in [HFC_AVG_TIME_BY_CHAT, HFC_AVG_TIME_BY_ACTION, HFC_AVG_TIME_BY_VERSION] and isinstance(sub_val, dict):
# 对于HFC时间数据需要特殊处理 # 对于HFC时间数据需要特殊处理
if sub_key not in stat["all_time"][key]: if sub_key not in stat["all_time"][key]:
stat["all_time"][key][sub_key] = {"decision": 0, "action": 0, "total": 0} stat["all_time"][key][sub_key] = {"decision": 0, "action": 0, "total": 0, "count": 0}
# 合并嵌套的时间数据 # 如果历史数据是已经计算过的平均值没有count字段需要跳过或重新处理
if "count" not in sub_val:
logger.debug(f"历史数据{key}.{sub_key}是平均值格式,跳过合并以避免错误计算")
continue
# 合并累计的加权时间数据
for time_type, time_val in sub_val.items(): for time_type, time_val in sub_val.items():
if time_type in stat["all_time"][key][sub_key]: if time_type in stat["all_time"][key][sub_key]:
stat["all_time"][key][sub_key][time_type] += time_val stat["all_time"][key][sub_key][time_type] += time_val
@@ -681,6 +687,24 @@ class StatisticOutputTask(AsyncTask):
# 直接合并 # 直接合并
stat["all_time"][key] += val stat["all_time"][key] += val
# 为all_time计算正确的平均时间在历史数据合并后
if "all_time" in stat:
for stat_type in [HFC_AVG_TIME_BY_CHAT, HFC_AVG_TIME_BY_ACTION, HFC_AVG_TIME_BY_VERSION]:
if stat_type in stat["all_time"]:
for key, time_data in stat["all_time"][stat_type].items():
if time_data.get("count", 0) > 0:
count = time_data["count"]
# 计算平均值但保留count字段用于下次合并
avg_data = {
"decision": time_data["decision"] / count,
"action": time_data["action"] / count,
"total": time_data["total"] / count,
"count": count # 保留count字段
}
stat["all_time"][stat_type][key] = avg_data
else:
stat["all_time"][stat_type][key] = {"decision": 0, "action": 0, "total": 0, "count": 0}
# 更新上次完整统计数据的时间戳 # 更新上次完整统计数据的时间戳
local_storage["last_full_statistics"] = { local_storage["last_full_statistics"] = {
"name_mapping": self.name_mapping, "name_mapping": self.name_mapping,
@@ -1143,10 +1167,35 @@ class StatisticOutputTask(AsyncTask):
def _get_chat_display_name(chat_id): def _get_chat_display_name(chat_id):
"""获取聊天显示名称""" """获取聊天显示名称"""
if chat_id in self.name_mapping: try:
return self.name_mapping[chat_id][0] # 首先尝试从chat_stream获取真实群组名称
else: from src.chat.message_receive.chat_stream import get_chat_manager
chat_manager = get_chat_manager()
if chat_id in chat_manager.streams:
stream = chat_manager.streams[chat_id]
if stream.group_info and hasattr(stream.group_info, 'group_name'):
group_name = stream.group_info.group_name
if group_name and group_name.strip():
return group_name.strip()
elif stream.user_info and hasattr(stream.user_info, 'user_nickname'):
user_name = stream.user_info.user_nickname
if user_name and user_name.strip():
return user_name.strip()
# 如果从chat_stream获取失败回退到name_mapping
if chat_id in self.name_mapping:
return self.name_mapping[chat_id][0]
# 最后回退到chat_id
return chat_id return chat_id
except Exception as e:
logger.warning(f"获取聊天显示名称失败: {e}")
# 发生异常时回退到原有逻辑
if chat_id in self.name_mapping:
return self.name_mapping[chat_id][0]
else:
return chat_id
def _generate_overview_section(data, title): def _generate_overview_section(data, title):
"""生成总览部分""" """生成总览部分"""