diff --git a/admin/dashboard/server.py b/admin/dashboard/server.py index cc7aadc..61e975d 100644 --- a/admin/dashboard/server.py +++ b/admin/dashboard/server.py @@ -152,6 +152,12 @@ class DashboardServer: def errors(): return render_template('errors.html') + + @app.route('/messages') + @login_required + def message_list_page(): + """消息列表页面""" + return render_template('message_list.html') # 在_create_app方法中添加新的路由 @app.route('/robot_management') @login_required @@ -480,7 +486,63 @@ class DashboardServer: self.logger.error(f"添加群组失败: {e}") return jsonify({"success": False, "error": str(e)}), 500 - return app + + @app.route('/api/messages', methods=['GET']) + @login_required + def get_messages(): + """获取消息列表API""" + try: + # 获取查询参数 + group_id = request.args.get('group_id') + start_date = request.args.get('start_date', datetime.now().strftime('%Y-%m-%d')) + end_date = request.args.get('end_date', datetime.now().strftime('%Y-%m-%d')) + search_text = request.args.get('search_text') + page = int(request.args.get('page', 1)) + page_size = int(request.args.get('page_size', 20)) + + # 调用数据库方法获取消息 + result = self.message_storage.get_messages_by_filter( + group_id=group_id, + start_date=start_date, + end_date=end_date, + search_text=search_text, + page=page, + page_size=page_size + ) + + # 处理消息数据,添加群组名称和发送者昵称 + for msg in result['messages']: + # 获取群组名称 + msg['group_name'] = self.contact_manager.get_nickname(msg['group_id']) or msg['group_id'] + + # 获取发送者昵称 + msg['sender_name'] = self.contact_manager.get_nickname(msg['sender']) or msg['sender'] + + return jsonify(result) + except Exception as e: + self.logger.error(f"获取消息列表失败: {e}") + return jsonify({'error': str(e)}), 500 + + @app.route('/api/groups', methods=['GET']) + @login_required + def get_groups(): + """获取群组列表API""" + try: + # 获取机器人管理的群组列表 + groups = [] + for group_id in self.contact_manager.get_contacts(): + if '@chatroom' in group_id: + groups.append({ + 'group_id': group_id, + 'group_name': self.contact_manager.get_nickname(group_id) or group_id + }) + + return jsonify({'groups': groups}) + except Exception as e: + self.logger.error(f"获取群组列表失败: {e}") + return jsonify({'error': str(e)}), 500 + + return app def run(self): """运行服务器""" @@ -504,4 +566,4 @@ class DashboardServer: if self._server: self._server.shutdown() - self.logger.info("服务器已停止") \ No newline at end of file + self.logger.info("服务器已停止") diff --git a/admin/dashboard/templates/base.html b/admin/dashboard/templates/base.html index 4d79fec..27fc24f 100644 --- a/admin/dashboard/templates/base.html +++ b/admin/dashboard/templates/base.html @@ -133,6 +133,11 @@ 群机器人管理 + + + + 消息列表 + diff --git a/db/message_storage.py b/db/message_storage.py index 409fb6f..ee683cd 100644 --- a/db/message_storage.py +++ b/db/message_storage.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- + from datetime import datetime from typing import Dict, List, Optional @@ -107,4 +108,75 @@ class MessageStorageDB(BaseDBOperator): GROUP BY DATE(timestamp) ORDER BY date """ - return self.execute_query(sql, (group_id, days)) or [] \ No newline at end of file + return self.execute_query(sql, (group_id, days)) or [] + + def get_messages_by_filter(self, group_id=None, start_date=None, end_date=None, + search_text=None, page=1, page_size=20) -> Dict: + """按条件筛选消息并支持分页和模糊搜索 + + Args: + group_id: 群组ID,可选 + start_date: 开始日期,格式为YYYY-MM-DD,可选 + end_date: 结束日期,格式为YYYY-MM-DD,可选 + search_text: 搜索文本,可选,用于模糊搜索消息内容 + page: 页码,从1开始 + page_size: 每页记录数 + + Returns: + 包含消息列表和总记录数的字典 + """ + # 构建基础SQL查询 + sql_count = "SELECT COUNT(*) as total FROM messages WHERE 1=1 " + sql_data = """ + SELECT id, group_id, timestamp, sender, content, message_type, + attachment_url, message_id, message_xml, message_thumb + FROM messages + WHERE 1=1 + """ + + # 构建参数列表 + params = [] + + # 添加筛选条件 + if group_id: + sql_count += " AND group_id = %s " + sql_data += " AND group_id = %s " + params.append(group_id) + + if start_date: + sql_count += " AND DATE(timestamp) >= %s " + sql_data += " AND DATE(timestamp) >= %s " + params.append(start_date) + + if end_date: + sql_count += " AND DATE(timestamp) <= %s " + sql_data += " AND DATE(timestamp) <= %s " + params.append(end_date) + + if search_text: + sql_count += " AND content LIKE %s " + sql_data += " AND content LIKE %s " + params.append(f"%{search_text}%") + + # 添加排序和分页 + sql_data += " ORDER BY timestamp DESC " + sql_data += " LIMIT %s OFFSET %s " + + # 计算分页参数 + offset = (page - 1) * page_size + data_params = params.copy() + data_params.extend([page_size, offset]) + + # 执行查询 + count_result = self.execute_query(sql_count, params) + total = count_result[0]['total'] if count_result else 0 + + messages = self.execute_query(sql_data, data_params) or [] + + return { + 'total': total, + 'page': page, + 'page_size': page_size, + 'total_pages': (total + page_size - 1) // page_size, + 'messages': messages + } \ No newline at end of file