646 lines
30 KiB
Python
646 lines
30 KiB
Python
import json
|
||
from chat_session import ChatSessionManager
|
||
from file import ObjectFileManager
|
||
from tools import from_string, from_datetime, format_timestamp, DatabaseManager
|
||
from flask import jsonify
|
||
|
||
|
||
class MessageRender:
|
||
"""消息处理类"""
|
||
|
||
@staticmethod
|
||
def format_timestamp(timestamp_str):
|
||
"""格式化时间戳"""
|
||
if not timestamp_str:
|
||
return '未知时间'
|
||
|
||
try:
|
||
timestamp = int(timestamp_str[:-3])
|
||
return format_timestamp(timestamp)
|
||
except ValueError:
|
||
return '未知时间'
|
||
|
||
@staticmethod
|
||
def process_message_content(message_data):
|
||
"""处理消息内容"""
|
||
content = message_data['content']
|
||
msg_type = message_data['type']
|
||
|
||
if msg_type == 'text':
|
||
message_data['display_content'] = content
|
||
elif msg_type in ['image', 'file', 'video', 'voice']:
|
||
message_data['display_content'] = f'[{msg_type}] {content}'
|
||
elif msg_type == 'mixed':
|
||
try:
|
||
mixed_content = json.loads(content)
|
||
display_parts = []
|
||
for item in mixed_content:
|
||
msg_type, item_content = item
|
||
if msg_type == 'text':
|
||
display_parts.append(item_content)
|
||
else:
|
||
display_parts.append(f'[{msg_type}]')
|
||
message_data['display_content'] = ' '.join(display_parts)
|
||
except ValueError:
|
||
message_data['display_content'] = '[混合消息]'
|
||
elif msg_type == 'chatrecord':
|
||
try:
|
||
chatrecord_data = json.loads(content)
|
||
if 'chatrecord' in chatrecord_data and 'title' in chatrecord_data['chatrecord']:
|
||
message_data['display_content'] = f'[聊天记录] {chatrecord_data["chatrecord"]["title"]}'
|
||
message_data['chatrecord_data'] = chatrecord_data
|
||
else:
|
||
message_data['display_content'] = '[聊天记录]'
|
||
except ValueError:
|
||
message_data['display_content'] = '[聊天记录]'
|
||
else:
|
||
message_data['display_content'] = f'[{msg_type}] {content}'
|
||
|
||
return message_data
|
||
|
||
|
||
class ReportService:
|
||
"""报告服务类"""
|
||
|
||
def __init__(self, db: DatabaseManager):
|
||
self.db = db
|
||
self.execute_query = self.db.execute_query
|
||
|
||
def get_message_count_by_time_range(self, start_timestamp, end_timestamp):
|
||
"""获取指定时间范围内的消息数量"""
|
||
result = self.execute_query('''
|
||
SELECT COUNT(*) as count
|
||
FROM message
|
||
WHERE time >= ?
|
||
AND time <= ?
|
||
''', (f"{start_timestamp}000", f"{end_timestamp}999"), fetch_all=False)
|
||
return result["count"]
|
||
|
||
def get_active_users_by_time_range(self, start_timestamp, end_timestamp):
|
||
"""获取指定时间范围内的活跃用户数量"""
|
||
result = self.execute_query('''
|
||
SELECT COUNT(DISTINCT sender) as count
|
||
FROM message
|
||
WHERE time >= ?
|
||
AND time <= ?
|
||
''', (f"{start_timestamp}000", f"{end_timestamp}999"), fetch_all=False)
|
||
return result["count"]
|
||
|
||
def get_active_sub_users_by_time_range(self, start_timestamp, end_timestamp):
|
||
"""获取指定时间范围内的活跃用户数量"""
|
||
result = self.execute_query('''
|
||
SELECT COUNT(DISTINCT sender) as count
|
||
FROM message
|
||
WHERE time >= ?
|
||
AND time <= ?
|
||
''', (f"{start_timestamp}000", f"{end_timestamp}999"), fetch_all=False)
|
||
return result["count"]
|
||
|
||
def get_qa_count_by_time_range(self, start_timestamp, end_timestamp):
|
||
"""获取指定时间范围内的QA记录数量"""
|
||
result = self.execute_query('''
|
||
SELECT COUNT(*) as count
|
||
FROM qa
|
||
WHERE start_time >= ?
|
||
AND end_time <= ?
|
||
''', (f"{start_timestamp}000", f"{end_timestamp}999"), fetch_all=False)
|
||
return result["count"]
|
||
|
||
def get_non_answer_qa_count_by_time_range(self, start_timestamp, end_timestamp):
|
||
"""获取指定时间范围内的QA记录数量"""
|
||
result = self.execute_query('''
|
||
SELECT COUNT(*) as count
|
||
FROM qa
|
||
WHERE start_time >= ?
|
||
AND end_time <= ?
|
||
AND answer = '[]'
|
||
''', (f"{start_timestamp}000", f"{end_timestamp}999"), fetch_all=False)
|
||
return result["count"]
|
||
|
||
def get_qa_count_by_time_range_sub(self, start_timestamp, end_timestamp):
|
||
"""获取指定时间范围内的QA记录数量"""
|
||
result = self.execute_query('''
|
||
SELECT COUNT(*) as count
|
||
FROM qa as q
|
||
inner join subscribe as s on q.groupId = s.id
|
||
WHERE start_time >= ?
|
||
AND end_time <= ?
|
||
''', (f"{start_timestamp}000", f"{end_timestamp}999"), fetch_all=False)
|
||
return result["count"]
|
||
|
||
def get_non_answer_qa_count_by_time_range_sub(self, start_timestamp, end_timestamp):
|
||
"""获取指定时间范围内的QA记录数量"""
|
||
result = self.execute_query('''
|
||
SELECT COUNT(*) as count
|
||
FROM qa as q
|
||
inner join subscribe as s on q.groupId = s.id
|
||
WHERE start_time >= ?
|
||
AND end_time <= ?
|
||
AND answer = '[]'
|
||
''', (f"{start_timestamp}000", f"{end_timestamp}999"), fetch_all=False)
|
||
return result["count"]
|
||
|
||
def get_group_activity_data(self, start_timestamp, end_timestamp):
|
||
"""获取群组活跃度数据"""
|
||
return self.execute_query('''
|
||
SELECT g.id, g.name, COUNT(m.id) as message_count
|
||
FROM "group" g
|
||
LEFT JOIN message m ON g.id = m.receiver AND m.time >= ? AND m.time <= ?
|
||
GROUP BY g.id, g.name
|
||
ORDER BY message_count DESC
|
||
''', (f"{start_timestamp}000", f"{end_timestamp}999"))
|
||
|
||
def get_subscribe_activity_data(self, start_timestamp, end_timestamp):
|
||
"""获取订阅活跃度数据"""
|
||
return self.execute_query('''
|
||
SELECT s.id, s.name, COUNT(m.id) as message_count
|
||
FROM subscribe s
|
||
LEFT JOIN message m ON s.id = m.receiver AND m.time >= ? AND m.time <= ?
|
||
GROUP BY s.id, s.name
|
||
ORDER BY message_count DESC
|
||
''', (f"{start_timestamp}000", f"{end_timestamp}999"))
|
||
|
||
def get_recent_messages_by_time_range(self, start_timestamp, end_timestamp, limit=100):
|
||
"""获取指定时间范围内的最近消息"""
|
||
return self.execute_query('''
|
||
SELECT content
|
||
FROM message
|
||
WHERE time >= ?
|
||
AND time <= ?
|
||
AND type NOT IN ('disagree', 'agree', 'weapp', 'link')
|
||
ORDER BY time
|
||
LIMIT ?
|
||
''', (f"{start_timestamp}000", f"{end_timestamp}999", limit))
|
||
|
||
def get_hourly_activity_data(self, start_timestamp, end_timestamp):
|
||
"""获取按小时统计的消息量"""
|
||
return self.execute_query('''
|
||
SELECT strftime('%H',
|
||
datetime(substr(time, 0, 11), 'unixepoch', '+8 hours')) as hour,
|
||
COUNT(*) as count
|
||
FROM message
|
||
WHERE time >= ?
|
||
AND time <= ?
|
||
GROUP BY hour
|
||
ORDER BY hour
|
||
''', (f"{start_timestamp}000", f"{end_timestamp}999"))
|
||
|
||
def get_group_count(self):
|
||
"""获取群组总数"""
|
||
result = self.execute_query('SELECT COUNT(*) as count FROM "group"', fetch_all=False)
|
||
return result["count"]
|
||
|
||
def get_member_count(self):
|
||
"""获取成员总数"""
|
||
result = self.execute_query('SELECT COUNT(*) as count FROM user', fetch_all=False)
|
||
return result["count"]
|
||
|
||
def get_sub_member_count(self):
|
||
"""获取成员总数"""
|
||
result = self.execute_query(
|
||
'SELECT COUNT(distinct m.userId) as count FROM member as m inner join subscribe as s on m.groupId = s.id ',
|
||
fetch_all=False)
|
||
return result["count"]
|
||
|
||
def get_subscribe_count(self):
|
||
"""获取订阅总数"""
|
||
result = self.execute_query('SELECT COUNT(*) as count FROM subscribe', fetch_all=False)
|
||
return result["count"]
|
||
|
||
def get_qa_count(self):
|
||
"""获取指定时间范围内的QA记录总数"""
|
||
result = self.execute_query('''
|
||
SELECT COUNT(*) as count
|
||
FROM qa
|
||
|
||
''', fetch_all=False)
|
||
return result["count"]
|
||
|
||
def get_weekly_messages(self, start_timestamp, end_timestamp, limit=200):
|
||
"""获取本周消息用于分类分析"""
|
||
return self.execute_query('''
|
||
SELECT content
|
||
FROM message
|
||
WHERE time >= ?
|
||
AND time <= ?
|
||
AND type NOT IN ('disagree', 'agree', 'weapp', 'link')
|
||
ORDER BY time
|
||
LIMIT ?
|
||
''', (f"{start_timestamp}000", f"{end_timestamp}999", limit))
|
||
|
||
# 通用数据查询方法 (整合剩余数据库查询)
|
||
def get_messages_by_ids(self, message_ids):
|
||
"""根据消息ID列表获取消息内容"""
|
||
if not message_ids:
|
||
return []
|
||
|
||
placeholders = ','.join(['?'] * len(message_ids))
|
||
query = f"""
|
||
SELECT m.id, m.content, m.type, m.sender, m.receiver,u.name as sender_name,
|
||
datetime(substr(time,0,11), 'unixepoch','+8 hours') as formatted_time
|
||
FROM message m
|
||
left join user u on m.sender = u.id
|
||
WHERE m.id IN ({placeholders})
|
||
AND type NOT IN ('disagree', 'agree', 'weapp', 'link')
|
||
ORDER BY formatted_time
|
||
"""
|
||
return self.execute_query(query, message_ids)
|
||
|
||
def get_messages(self, limit=100, offset=0, group_id=None):
|
||
"""获取消息列表"""
|
||
query = '''
|
||
SELECT m.*,
|
||
u.name as sender_name,
|
||
g.name as group_name,
|
||
datetime(substr(time, 0, 11), 'unixepoch', '+8 hours') as formatted_time
|
||
FROM message m
|
||
LEFT JOIN user u ON m.sender = u.id
|
||
LEFT JOIN "group" g ON m.receiver = g.id
|
||
WHERE m.type NOT IN ('disagree', 'agree', 'weapp', 'link')
|
||
AND m.toType = 1
|
||
'''
|
||
params = []
|
||
|
||
if group_id:
|
||
query += ' AND m.receiver = ?'
|
||
params.append(group_id)
|
||
|
||
query += ' ORDER BY formatted_time DESC LIMIT ? OFFSET ?'
|
||
params.extend([limit, offset])
|
||
|
||
return self.execute_query(query, params)
|
||
|
||
def get_all_users(self):
|
||
"""获取所有用户"""
|
||
return self.execute_query('SELECT * FROM user ORDER BY name')
|
||
|
||
def get_all_groups(self):
|
||
"""获取所有群组"""
|
||
return self.execute_query('SELECT * FROM "group" ORDER BY id')
|
||
|
||
def get_all_subscribes(self):
|
||
"""获取所有订阅"""
|
||
return self.execute_query('SELECT * FROM subscribe ORDER BY id')
|
||
|
||
def get_subscribe_messages(self, subscribe_id, limit=100, offset=0):
|
||
"""获取指定订阅的消息"""
|
||
if not subscribe_id:
|
||
query = '''
|
||
SELECT m.*,
|
||
u.name as sender_name,
|
||
datetime(substr(m.time, 0, 11), 'unixepoch', '+8 hours') as formatted_time
|
||
FROM message m
|
||
LEFT JOIN user u ON m.sender = u.id
|
||
WHERE m.toType = 1
|
||
AND m.type NOT IN ('disagree', 'agree', 'weapp', 'link')
|
||
ORDER BY formatted_time DESC
|
||
LIMIT ? OFFSET ? \
|
||
'''
|
||
return self.execute_query(query, (limit, offset))
|
||
else:
|
||
query = '''
|
||
SELECT m.*,
|
||
u.name as sender_name,
|
||
datetime(substr(m.time, 0, 11), 'unixepoch', '+8 hours') as formatted_time
|
||
FROM message m
|
||
LEFT JOIN user u ON m.sender = u.id
|
||
WHERE m.receiver = ?
|
||
AND m.type NOT IN ('disagree', 'agree', 'weapp', 'link')
|
||
ORDER BY formatted_time DESC
|
||
LIMIT ? OFFSET ? \
|
||
'''
|
||
return self.execute_query(query, (subscribe_id, limit, offset))
|
||
|
||
def get_subscribe_message_count(self, subscribe_id):
|
||
"""获取指定订阅的消息统计"""
|
||
subscribe_messages_total = self.execute_query('''
|
||
SELECT COUNT(*) as count
|
||
FROM message
|
||
WHERE receiver = ?
|
||
AND type NOT IN ('disagree', 'agree', 'weapp', 'link')
|
||
''', (subscribe_id,), fetch_all=False)['count']
|
||
lastest_time = self.execute_query('''
|
||
SELECT datetime(substr(time, 0, 11), 'unixepoch', '+8 hours') as formatted_time
|
||
FROM message
|
||
WHERE receiver = ?
|
||
AND type NOT IN ('disagree', 'agree', 'weapp', 'link')
|
||
ORDER BY formatted_time DESC
|
||
LIMIT 1
|
||
''', (subscribe_id,), fetch_all=False)
|
||
lastest_time = lastest_time['formatted_time'] if lastest_time else ""
|
||
return {'total': subscribe_messages_total, 'lastest_time': lastest_time}
|
||
|
||
def get_group_messages(self, group_id, limit=100, offset=0):
|
||
"""获取指定群组的消息"""
|
||
if not group_id:
|
||
query = '''
|
||
SELECT m.*,
|
||
u.name as sender_name,
|
||
datetime(substr(m.time, 0, 11), 'unixepoch', '+8 hours') as formatted_time
|
||
FROM message m
|
||
LEFT JOIN user u ON m.sender = u.id
|
||
WHERE m.toType = 1
|
||
AND m.type NOT IN ('disagree', 'agree', 'weapp', 'link')
|
||
ORDER BY formatted_time DESC
|
||
LIMIT ? OFFSET ? \
|
||
'''
|
||
return self.execute_query(query, (limit, offset))
|
||
else:
|
||
query = '''
|
||
SELECT m.*,
|
||
u.name as sender_name,
|
||
datetime(substr(m.time, 0, 11), 'unixepoch', '+8 hours') as formatted_time
|
||
FROM message m
|
||
LEFT JOIN user u ON m.sender = u.id
|
||
WHERE m.receiver = ?
|
||
AND m.type NOT IN ('disagree', 'agree', 'weapp', 'link')
|
||
ORDER BY formatted_time DESC
|
||
LIMIT ? OFFSET ? \
|
||
'''
|
||
return self.execute_query(query, (group_id, limit, offset))
|
||
|
||
def get_group_message_count(self, group_id):
|
||
"""获取指定群组的消息"""
|
||
|
||
group_messages_total = self.execute_query('''
|
||
SELECT COUNT(*) as count
|
||
FROM message
|
||
WHERE receiver = ?
|
||
AND type NOT IN ('disagree', 'agree', 'weapp', 'link')
|
||
''', (group_id,), fetch_all=False)['count']
|
||
lastest_time = self.execute_query('''
|
||
SELECT datetime(substr(time, 0, 11), 'unixepoch', '+8 hours') as formatted_time
|
||
FROM message
|
||
WHERE receiver = ?
|
||
AND type NOT IN ('disagree', 'agree', 'weapp', 'link')
|
||
ORDER BY formatted_time DESC
|
||
LIMIT 1
|
||
''', (group_id,), fetch_all=False)
|
||
lastest_time = lastest_time['formatted_time'] if lastest_time else ""
|
||
return {'total': group_messages_total, 'lastest_time': lastest_time}
|
||
|
||
def get_statistics(self):
|
||
"""获取统计数据"""
|
||
user_count = self.execute_query('SELECT COUNT(*) as count FROM user', fetch_all=False)['count']
|
||
group_count = self.execute_query('SELECT COUNT(*) as count FROM "group"', fetch_all=False)['count']
|
||
message_count = self.execute_query('SELECT COUNT(*) as count FROM message', fetch_all=False)['count']
|
||
file_count = self.execute_query('SELECT COUNT(*) as count FROM file', fetch_all=False)['count']
|
||
latest_time_result = self.execute_query('SELECT MAX(time) as latest_time FROM message', fetch_all=False)
|
||
latest_time = latest_time_result['latest_time'] if latest_time_result else None
|
||
|
||
return {
|
||
'user_count': user_count,
|
||
'group_count': group_count,
|
||
'message_count': message_count,
|
||
'file_count': file_count,
|
||
'latest_time': latest_time
|
||
}
|
||
|
||
def get_v2_statistics(self):
|
||
"""获取v2版本统计数据(包含订阅信息)"""
|
||
user_count = self.execute_query(
|
||
'SELECT COUNT(*) as count FROM user as u inner join member as m on u.id = m.userId inner join subscribe as s on m.groupId = s.id',
|
||
fetch_all=False)['count']
|
||
subscribe_count = self.execute_query('SELECT COUNT(*) as count FROM subscribe', fetch_all=False)['count']
|
||
message_count = \
|
||
self.execute_query(
|
||
'SELECT COUNT(*) as count FROM message as m inner join subscribe as s on m.receiver = s.id',
|
||
fetch_all=False)['count']
|
||
file_count = self.execute_query(
|
||
'SELECT COUNT(*) as count FROM file as f inner join message as m on f.id = m.content inner join subscribe as s on m.receiver = s.id',
|
||
fetch_all=False)['count']
|
||
latest_time_result = self.execute_query('SELECT MAX(time) as latest_time FROM message', fetch_all=False)
|
||
latest_time = latest_time_result['latest_time'] if latest_time_result else None
|
||
|
||
return {
|
||
'user_count': user_count,
|
||
'group_count': subscribe_count,
|
||
'message_count': message_count,
|
||
'file_count': file_count,
|
||
'latest_time': latest_time
|
||
}
|
||
|
||
def search_messages(self, keyword, limit=100, group_id=None):
|
||
"""搜索消息"""
|
||
if group_id:
|
||
query = '''
|
||
SELECT m.*,
|
||
u.name as sender_name,
|
||
g.name as group_name,
|
||
datetime(substr(m.time, 0, 11), 'unixepoch', '+8 hours') as formatted_time
|
||
FROM message m
|
||
LEFT JOIN user u ON m.sender = u.id
|
||
LEFT JOIN "group" g ON m.receiver = g.id
|
||
WHERE m.content LIKE ?
|
||
AND m.type NOT IN ('disagree', 'agree', 'weapp', 'link')
|
||
AND m.receiver = ?
|
||
ORDER BY formatted_time
|
||
LIMIT ? \
|
||
'''
|
||
return self.execute_query(query, (f'%{keyword}%', group_id, limit))
|
||
else:
|
||
query = '''
|
||
SELECT m.*,
|
||
u.name as sender_name,
|
||
g.name as group_name,
|
||
datetime(substr(m.time, 0, 11), 'unixepoch', '+8 hours') as formatted_time
|
||
FROM message m
|
||
LEFT JOIN user u ON m.sender = u.id
|
||
LEFT JOIN "group" g ON m.receiver = g.id
|
||
WHERE m.content LIKE ?
|
||
AND m.type NOT IN ('disagree', 'agree', 'weapp', 'link')
|
||
ORDER BY formatted_time
|
||
LIMIT ? \
|
||
'''
|
||
return self.execute_query(query, (f'%{keyword}%', limit))
|
||
|
||
def search_subscribe_messages(self, keyword, limit=100, subscribe_id=None):
|
||
"""搜索订阅消息"""
|
||
if subscribe_id:
|
||
query = '''
|
||
SELECT m.*,
|
||
u.name as sender_name,
|
||
s.name as subscribe_name,
|
||
datetime(substr(m.time, 0, 11), 'unixepoch', '+8 hours') as formatted_time
|
||
FROM message m
|
||
LEFT JOIN user u ON m.sender = u.id
|
||
LEFT JOIN subscribe s ON m.receiver = s.id
|
||
WHERE m.content LIKE ?
|
||
AND m.type NOT IN ('disagree', 'agree', 'weapp', 'link')
|
||
AND m.receiver = ?
|
||
ORDER BY formatted_time
|
||
LIMIT ? \
|
||
'''
|
||
return self.execute_query(query, (f'%{keyword}%', subscribe_id, limit))
|
||
else:
|
||
query = '''
|
||
SELECT m.*,
|
||
u.name as sender_name,
|
||
s.name as subscribe_name,
|
||
datetime(substr(m.time, 0, 11), 'unixepoch', '+8 hours') as formatted_time
|
||
FROM message m
|
||
LEFT JOIN user u ON m.sender = u.id
|
||
LEFT JOIN subscribe s ON m.receiver = s.id
|
||
WHERE m.content LIKE ?
|
||
AND m.type NOT IN ('disagree', 'agree', 'weapp', 'link')
|
||
ORDER BY formatted_time
|
||
LIMIT ? \
|
||
'''
|
||
return self.execute_query(query, (f'%{keyword}%', limit))
|
||
|
||
def get_all_qa(self):
|
||
"""获取所有QA记录"""
|
||
return self.execute_query('SELECT * FROM qa ORDER BY id DESC')
|
||
|
||
def get_qa_by_id(self, qa_id):
|
||
"""根据ID获取QA记录"""
|
||
return self.execute_query('SELECT * FROM qa WHERE id = ?', (qa_id,), fetch_all=False)
|
||
|
||
def check_qa_exists(self, qa_id):
|
||
"""检查QA记录是否存在"""
|
||
result = self.execute_query('SELECT id FROM qa WHERE id = ?', (qa_id,), fetch_all=False)
|
||
return result is not None
|
||
|
||
# 报告生成方法 (原ReportGenerator功能)
|
||
@staticmethod
|
||
def get_date_range(date_str):
|
||
"""获取日期范围"""
|
||
target_date = from_string(date_str).to_datetime()
|
||
start_timestamp = int(from_string(date_str).start_of_day().to_timestamp())
|
||
end_timestamp = int(from_string(date_str).end_of_day().to_timestamp())
|
||
return target_date, start_timestamp, end_timestamp
|
||
|
||
@staticmethod
|
||
def get_previous_day_range(target_date):
|
||
"""获取前一天日期范围"""
|
||
yesterday_date = from_datetime(target_date).days_ago(1)
|
||
yesterday_start = int(yesterday_date.start_of_day().to_timestamp())
|
||
yesterday_end = int(yesterday_date.end_of_day().to_timestamp())
|
||
return yesterday_start, yesterday_end
|
||
|
||
@staticmethod
|
||
def calculate_change_rate(current, previous):
|
||
"""计算变化率"""
|
||
if previous > 0:
|
||
return (current - previous) / previous * 100
|
||
return 0
|
||
|
||
@staticmethod
|
||
def analyze_hot_topics(messages):
|
||
"""分析热点话题"""
|
||
keyword_patterns = ['季度报告', 'ESG', '股东大会', '披露', '系统', '操作', '政策']
|
||
topic_counts = {}
|
||
|
||
for msg in messages:
|
||
content = msg['content']
|
||
for keyword in keyword_patterns:
|
||
if keyword in content:
|
||
topic_counts[keyword] = topic_counts.get(keyword, 0) + 1
|
||
|
||
# 排序并取前3个热点
|
||
sorted_topics = sorted(topic_counts.items(), key=lambda x: x[1], reverse=True)
|
||
return [f"{topic} (提及{count}次)" for topic, count in sorted_topics[:3]]
|
||
|
||
@staticmethod
|
||
def analyze_category_breakdown(messages):
|
||
"""分析问题分类"""
|
||
category_counts = {
|
||
'信息披露类': 0.0,
|
||
'公司治理与法规': 0.0,
|
||
'业务操作与系统': 0.0,
|
||
'其他': 0.0
|
||
}
|
||
|
||
category_keywords = {
|
||
'信息披露类': ['披露', '报告', '公告', '季报', '年报', 'ESG'],
|
||
'公司治理与法规': ['法规', '合规', '治理', '政策', '规定', '要求'],
|
||
'业务操作与系统': ['系统', '操作', '填报', '上传', '下载', '登录']
|
||
}
|
||
|
||
for msg in messages:
|
||
content = msg['content']
|
||
categorized = False
|
||
for category, keywords in category_keywords.items():
|
||
for keyword in keywords:
|
||
if keyword in content:
|
||
category_counts[category] += 1
|
||
categorized = True
|
||
break
|
||
if categorized:
|
||
break
|
||
if not categorized:
|
||
category_counts['其他'] += 1
|
||
|
||
# 计算百分比
|
||
total_categorized = sum(category_counts.values())
|
||
if total_categorized > 0:
|
||
for category in category_counts:
|
||
category_counts[category] = round(category_counts[category] / total_categorized * 100, 1)
|
||
|
||
return category_counts
|
||
|
||
@staticmethod
|
||
def generate_group_activity_chart(group_activity_data):
|
||
"""生成分群活跃度直方图"""
|
||
if not group_activity_data:
|
||
return "暂无数据"
|
||
|
||
# 获取前10个群组的数据
|
||
top_groups = group_activity_data[:10]
|
||
max_count = max(group['message_count'] for group in top_groups) if top_groups else 1
|
||
|
||
chart = ""
|
||
for group in top_groups:
|
||
group_name = group['name'] # 限制名称长度
|
||
count = group['message_count']
|
||
# 计算柱状图长度(最大50个字符)
|
||
bar_length = int((count / max_count) * 50) if max_count > 0 else 0
|
||
bar = "█" * bar_length
|
||
chart += f"{group_name:<15} | {bar} {count}\n"
|
||
|
||
return chart
|
||
|
||
def generate_hourly_activity_chart(self, start_timestamp, end_timestamp):
|
||
"""生成活跃时段直方图"""
|
||
# 获取按小时统计的消息量
|
||
hourly_data = self.get_hourly_activity_data(start_timestamp, end_timestamp)
|
||
|
||
if not hourly_data:
|
||
return "暂无数据"
|
||
|
||
# 创建24小时的完整数据
|
||
hour_counts = {str(i).zfill(2): 0 for i in range(24)}
|
||
for data in hourly_data:
|
||
hour_counts[data['hour']] = data['count']
|
||
|
||
max_count = max(hour_counts.values()) if hour_counts else 1
|
||
|
||
chart = ""
|
||
for hour in sorted(hour_counts.keys()):
|
||
count = hour_counts[hour]
|
||
# 计算柱状图长度(最大30个字符)
|
||
bar_length = int((count / max_count) * 30) if max_count > 0 else 0
|
||
bar = "█" * bar_length
|
||
chart += f"{hour}:00 | {bar} {count}\n"
|
||
|
||
return chart
|
||
|
||
|
||
def api_response(success=True, data=None, error=None, status_code=200, content=None):
|
||
"""统一的API响应格式"""
|
||
response = {'success': success}
|
||
if error:
|
||
response['error'] = str(error)
|
||
if data:
|
||
response.update(data)
|
||
if content:
|
||
response["data"] = content
|
||
return jsonify(response), status_code
|
||
|
||
|
||
ofm = ObjectFileManager()
|
||
db_manager = DatabaseManager('db/data', online_db_uri="zysl-log/wework/chat_msg/db/data.db")
|
||
report_service = ReportService(db_manager)
|
||
message_processor = MessageRender()
|
||
chat_session = ChatSessionManager(db_manager)
|