看板内容进行优化,同时加入了用户管理模块,将用户信息全局开放,
This commit is contained in:
@@ -12,15 +12,10 @@ class MessageUtil:
|
||||
消息发送工具类,封装了发送文本和文件的方法
|
||||
"""
|
||||
|
||||
def __init__(self, wcf: Wcf, contacts: Optional[dict] = None) -> None:
|
||||
"""
|
||||
初始化消息工具类
|
||||
|
||||
:param wcf: WCFerry实例
|
||||
:param contacts: 联系人字典,格式为 {"wxid": "NickName"}
|
||||
"""
|
||||
# 修改 MessageUtil 类的初始化方法,接受联系人管理器而不是联系人字典
|
||||
def __init__(self, wcf, contact_manager):
|
||||
self.wcf = wcf
|
||||
self.contacts = contacts or {}
|
||||
self.contact_manager = contact_manager
|
||||
self.LOG = logging.getLogger("MessageUtil")
|
||||
|
||||
def send_text_msg(self, msg: str, receiver: str, at_list: str = "") -> None:
|
||||
@@ -71,4 +66,9 @@ class MessageUtil:
|
||||
|
||||
:param contacts: 联系人字典,格式为 {"wxid": "NickName"}
|
||||
"""
|
||||
self.contacts.update(contacts)
|
||||
self.contacts.update(contacts)
|
||||
|
||||
# 修改使用 allContacts 的地方,改为使用 contact_manager
|
||||
# 例如:
|
||||
# 原来的代码: nickname = self.allContacts.get(wxid, wxid)
|
||||
# 修改为: nickname = self.contact_manager.get_nickname(wxid)
|
||||
@@ -7,6 +7,7 @@ from flask import Flask, render_template, request, jsonify, redirect, url_for, s
|
||||
|
||||
from db.connection import DBConnectionManager
|
||||
from db.stats_db import StatsDBOperator
|
||||
from contact_manager import ContactManager # 导入联系人管理器
|
||||
|
||||
|
||||
class DashboardServer:
|
||||
@@ -23,6 +24,8 @@ class DashboardServer:
|
||||
# 修正:使用单例模式获取数据库连接
|
||||
self.db_manager = DBConnectionManager.get_instance()
|
||||
self.stats_db = StatsDBOperator(self.db_manager)
|
||||
# 获取联系人管理器实例
|
||||
self.contact_manager = ContactManager.get_instance()
|
||||
self.app = self._create_app()
|
||||
self._stop_event = threading.Event()
|
||||
self._server = None # 添加:存储服务器实例
|
||||
@@ -77,6 +80,13 @@ class DashboardServer:
|
||||
days = request.args.get('days', 7, type=int)
|
||||
limit = request.args.get('limit', 10, type=int)
|
||||
stats = self.stats_db.get_user_stats(days, limit)
|
||||
|
||||
# 将用户ID转换为名称
|
||||
for item in stats:
|
||||
if 'user_id' in item:
|
||||
user_id = item['user_id']
|
||||
item['user_name'] = self.contact_manager.get_nickname(user_id)
|
||||
|
||||
return jsonify({"success": True, "data": stats})
|
||||
|
||||
@app.route('/api/group_stats')
|
||||
@@ -84,6 +94,13 @@ class DashboardServer:
|
||||
days = request.args.get('days', 7, type=int)
|
||||
limit = request.args.get('limit', 10, type=int)
|
||||
stats = self.stats_db.get_group_stats(days, limit)
|
||||
|
||||
# 将群ID转换为名称
|
||||
for item in stats:
|
||||
if 'group_id' in item:
|
||||
group_id = item['group_id']
|
||||
item['group_name'] = self.contact_manager.get_nickname(group_id)
|
||||
|
||||
return jsonify({"success": True, "data": stats})
|
||||
|
||||
@app.route('/api/error_logs')
|
||||
@@ -104,6 +121,18 @@ class DashboardServer:
|
||||
try:
|
||||
days = request.args.get('days', 7, type=int)
|
||||
summary = self.stats_db.get_dashboard_summary(days)
|
||||
|
||||
# 转换用户和群组ID为名称
|
||||
if 'top_users' in summary:
|
||||
for user in summary['top_users']:
|
||||
if 'user_id' in user:
|
||||
user['user_name'] = self.contact_manager.get_nickname(user['user_id'])
|
||||
|
||||
if 'top_groups' in summary:
|
||||
for group in summary['top_groups']:
|
||||
if 'group_id' in group:
|
||||
group['group_name'] = self.contact_manager.get_nickname(group['group_id'])
|
||||
|
||||
self.logger.info(f"看板主页统计数据: {summary}")
|
||||
return jsonify({"success": True, "data": summary})
|
||||
except Exception as e:
|
||||
@@ -115,6 +144,15 @@ class DashboardServer:
|
||||
days = request.args.get('days', 7, type=int)
|
||||
plugin_name = request.args.get('plugin_name', '')
|
||||
trend = self.stats_db.get_plugin_trend(plugin_name, days)
|
||||
|
||||
# 如果趋势数据中包含用户或群组ID,也进行转换
|
||||
if isinstance(trend, list):
|
||||
for item in trend:
|
||||
if 'user_id' in item:
|
||||
item['user_name'] = self.contact_manager.get_nickname(item['user_id'])
|
||||
if 'group_id' in item:
|
||||
item['group_name'] = self.contact_manager.get_nickname(item['group_id'])
|
||||
|
||||
self.logger.info(f"看板主页/api/plugin_trend: {trend}")
|
||||
return jsonify({"success": True, "data": trend})
|
||||
|
||||
|
||||
@@ -11,11 +11,27 @@
|
||||
<div slot="header">
|
||||
<span>错误日志</span>
|
||||
</div>
|
||||
<el-table :data="errorLogs" style="width: 100%" border>
|
||||
<el-table {% raw %}:data="errorLogs"{% endraw %} style="width: 100%" border>
|
||||
<el-table-column prop="plugin_name" label="插件名称"></el-table-column>
|
||||
<el-table-column prop="command" label="命令"></el-table-column>
|
||||
<el-table-column prop="error_message" label="错误信息" :show-overflow-tooltip="true"></el-table-column>
|
||||
<el-table-column prop="created_at" label="时间"></el-table-column>
|
||||
<el-table-column label="用户">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.user_id">
|
||||
{% raw %}{{ scope.row.user_name || scope.row.user_id }} ({{ scope.row.user_id }}){% endraw %}
|
||||
</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="群组">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.group_id">
|
||||
{% raw %}{{ scope.row.group_name || scope.row.group_id }} ({{ scope.row.group_id }}){% endraw %}
|
||||
</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="primary" @click="viewErrorDetail(scope.row)">查看详情</el-button>
|
||||
|
||||
@@ -11,8 +11,12 @@
|
||||
<div slot="header">
|
||||
<span>群组活跃度排行</span>
|
||||
</div>
|
||||
<el-table :data="groupStats" style="width: 100%" border>
|
||||
<el-table-column prop="group_id" label="群组ID"></el-table-column>
|
||||
<el-table {% raw %}:data="groupStats"{% endraw %} style="width: 100%" border>
|
||||
<el-table-column label="群组信息">
|
||||
<template slot-scope="scope">
|
||||
{% raw %}{{ scope.row.group_name || scope.row.group_id }} ({{ scope.row.group_id }}){% endraw %}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="total_calls" label="调用次数" sortable></el-table-column>
|
||||
<el-table-column prop="used_plugins" label="使用插件数" sortable></el-table-column>
|
||||
<el-table-column prop="unique_users" label="唯一用户数" sortable></el-table-column>
|
||||
|
||||
@@ -61,13 +61,33 @@
|
||||
<!-- 添加热门用户、群组和插件 -->
|
||||
<el-row :gutter="20" style="margin-top: 20px;">
|
||||
<el-col :span="8">
|
||||
<!-- 活跃用户卡片 -->
|
||||
<el-card shadow="hover">
|
||||
<div slot="header">
|
||||
<span>热门用户</span>
|
||||
<span>活跃用户</span>
|
||||
</div>
|
||||
<el-table :data="topUsers" style="width: 100%">
|
||||
<el-table-column prop="user_id" label="用户ID"></el-table-column>
|
||||
<el-table-column prop="total_calls" label="调用次数"></el-table-column>
|
||||
<el-table {% raw %}:data="topUsers"{% endraw %} style="width: 100%">
|
||||
<el-table-column label="用户">
|
||||
<template slot-scope="scope">
|
||||
{% raw %}{{ scope.row.user_name || scope.row.user_id }} ({{ scope.row.user_id }}){% endraw %}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- ... 其他列 ... -->
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<!-- 活跃群组卡片 -->
|
||||
<el-card shadow="hover">
|
||||
<div slot="header">
|
||||
<span>活跃群组</span>
|
||||
</div>
|
||||
<el-table {% raw %}:data="topGroups"{% endraw %} style="width: 100%">
|
||||
<el-table-column label="群组">
|
||||
<template slot-scope="scope">
|
||||
{% raw %}{{ scope.row.group_name || scope.row.group_id }} ({{ scope.row.group_id }}){% endraw %}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- ... 其他列 ... -->
|
||||
</el-table>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
@@ -45,6 +45,82 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-table {% raw %}:data="pluginUsers"{% endraw %} style="width: 100%" border v-if="showUserStats">
|
||||
<el-table-column label="用户">
|
||||
<template slot-scope="scope">
|
||||
{% raw %}{{ scope.row.user_name || scope.row.user_id }} ({{ scope.row.user_id }}){% endraw %}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="total_calls" label="调用次数" sortable>
|
||||
<template slot-scope="scope">
|
||||
{% raw %}{{ parseInt(scope.row.total_calls) || 0 }}{% endraw %}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="success_calls" label="成功次数" sortable>
|
||||
<template slot-scope="scope">
|
||||
{% raw %}{{ parseInt(scope.row.success_calls) || 0 }}{% endraw %}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="failed_calls" label="失败次数" sortable>
|
||||
<template slot-scope="scope">
|
||||
{% raw %}{{ parseInt(scope.row.failed_calls) || 0 }}{% endraw %}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="成功率" sortable>
|
||||
<template slot-scope="scope">
|
||||
{% raw %}{{ parseInt(scope.row.total_calls) > 0 ? ((parseInt(scope.row.success_calls) / parseInt(scope.row.total_calls)) * 100).toFixed(2) : '100.00' }}{% endraw %}%
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="平均响应时间" sortable>
|
||||
<template slot-scope="scope">
|
||||
{% raw %}{{ (scope.row.avg_process_time || 0).toFixed(2) }}{% endraw %}ms
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="primary" {% raw %}@click="viewPluginTrend(scope.row)"{% endraw %}>查看趋势</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-table {% raw %}:data="pluginGroups"{% endraw %} style="width: 100%" border v-if="showGroupStats">
|
||||
<el-table-column label="群组">
|
||||
<template slot-scope="scope">
|
||||
{% raw %}{{ scope.row.group_name || scope.row.group_id }} ({{ scope.row.group_id }}){% endraw %}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="total_calls" label="调用次数" sortable>
|
||||
<template slot-scope="scope">
|
||||
{% raw %}{{ parseInt(scope.row.total_calls) || 0 }}{% endraw %}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="success_calls" label="成功次数" sortable>
|
||||
<template slot-scope="scope">
|
||||
{% raw %}{{ parseInt(scope.row.success_calls) || 0 }}{% endraw %}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="failed_calls" label="失败次数" sortable>
|
||||
<template slot-scope="scope">
|
||||
{% raw %}{{ parseInt(scope.row.failed_calls) || 0 }}{% endraw %}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="成功率" sortable>
|
||||
<template slot-scope="scope">
|
||||
{% raw %}{{ parseInt(scope.row.total_calls) > 0 ? ((parseInt(scope.row.success_calls) / parseInt(scope.row.total_calls)) * 100).toFixed(2) : '100.00' }}{% endraw %}%
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="平均响应时间" sortable>
|
||||
<template slot-scope="scope">
|
||||
{% raw %}{{ (scope.row.avg_process_time || 0).toFixed(2) }}{% endraw %}ms
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="primary" {% raw %}@click="viewPluginTrend(scope.row)"{% endraw %}>查看趋势</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
@@ -12,7 +12,11 @@
|
||||
<span>用户活跃度排行</span>
|
||||
</div>
|
||||
<el-table {% raw %}:data="userStats"{% endraw %} style="width: 100%" border>
|
||||
<el-table-column prop="user_id" label="用户ID"></el-table-column>
|
||||
<el-table-column label="用户信息">
|
||||
<template slot-scope="scope">
|
||||
{% raw %}{{ scope.row.user_name || scope.row.user_id }} ({{ scope.row.user_id }}){% endraw %}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="total_calls" label="调用次数" sortable></el-table-column>
|
||||
<el-table-column prop="success_calls" label="成功次数" sortable></el-table-column>
|
||||
<el-table-column prop="failed_calls" label="失败次数" sortable></el-table-column>
|
||||
|
||||
22
robot.py
22
robot.py
@@ -37,6 +37,7 @@ from robot_cmd.robot_command import PermissionStatus
|
||||
__version__ = "39.2.4.0"
|
||||
|
||||
from sehuatang.shehuatang import pdf_file_path
|
||||
from utils.wechat.contact_manager import ContactManager
|
||||
from xiuren.meitu_dl import meitu_dowload_pub_pic
|
||||
from xiuren.xiuren_pdf import generate_pdf_from_images
|
||||
|
||||
@@ -54,8 +55,11 @@ class Robot(Job):
|
||||
self.LOG = logging.getLogger("Robot")
|
||||
|
||||
self.wxid = self.wcf.get_self_wxid()
|
||||
# 初始化联系人管理器并设置联系人
|
||||
self.contact_manager = ContactManager.get_instance()
|
||||
self.allContacts = self.get_all_contacts()
|
||||
# 修改初始化方法中的这一部分
|
||||
self.contact_manager.set_contacts(self.allContacts)
|
||||
|
||||
self.LOG.info(f"DB+REDIS 连接池开始初始化")
|
||||
# 使用单例模式获取实例
|
||||
self.db_manager = DBConnectionManager.get_instance(
|
||||
@@ -68,8 +72,8 @@ class Robot(Job):
|
||||
self.db_pool = self.db_manager.mysql_pool
|
||||
self.redis_pool = self.db_manager.redis_pool
|
||||
|
||||
# 初始化消息工具类
|
||||
self.message_util = MessageUtil(wcf, self.allContacts)
|
||||
# 初始化消息工具类 - 使用联系人管理器
|
||||
self.message_util = MessageUtil(wcf, self.contact_manager)
|
||||
self.groups = {} # 存储按group_id分组的消息列表,每个group_id最多保留10条消息
|
||||
GroupBotManager.load_local_cache()
|
||||
|
||||
@@ -391,10 +395,11 @@ class Robot(Job):
|
||||
def say_hi_to_new_friend(self, msg: WxMsg) -> None:
|
||||
nickName = re.findall(r"你已添加了(.*),现在可以开始聊天了。", msg.content)
|
||||
if nickName:
|
||||
# 添加了好友,更新好友列表
|
||||
# 添加了好友,更新好友列表和联系人管理器
|
||||
self.allContacts[msg.sender] = nickName[0]
|
||||
self.contact_manager.update_contact(msg.sender, nickName[0])
|
||||
self.send_text_msg(f"Hi {nickName[0]},我自动通过了你的好友请求。", msg.sender)
|
||||
|
||||
|
||||
def send_group_txt_message(self, msg: str, feature: Feature):
|
||||
try:
|
||||
receivers = self.gbm.get_group_list()
|
||||
@@ -545,3 +550,10 @@ class Robot(Job):
|
||||
self.wcf.send_file(pub_path, "45317011307@chatroom")
|
||||
except Exception as e:
|
||||
self.LOG.error(f"xiu_ren_pdf_send error:{e}")
|
||||
|
||||
# 添加一个方法用于刷新联系人信息
|
||||
def refresh_contacts(self):
|
||||
"""刷新联系人信息"""
|
||||
self.allContacts = self.get_all_contacts()
|
||||
self.contact_manager.refresh_contacts(self.allContacts)
|
||||
self.LOG.info("联系人信息已刷新")
|
||||
|
||||
Reference in New Issue
Block a user