diff --git a/admin/dashboard/blueprints/contacts.py b/admin/dashboard/blueprints/contacts.py index 107e9ed..0480da9 100644 --- a/admin/dashboard/blueprints/contacts.py +++ b/admin/dashboard/blueprints/contacts.py @@ -7,6 +7,7 @@ from loguru import logger # 创建联系人管理蓝图 contacts_bp = Blueprint('contacts', __name__, url_prefix='/contacts') + # 联系人管理页面 @contacts_bp.route('/') @login_required @@ -14,6 +15,7 @@ def contacts_management(): """通讯录管理页面""" return render_template('contacts_management.html') + # API路由 @contacts_bp.route('/api/all', methods=['GET']) @login_required @@ -32,6 +34,7 @@ def api_contacts_all(): logger.error(f"获取所有联系人信息失败: {e}") return jsonify({"success": False, "error": str(e)}), 500 + @contacts_bp.route('/api/statistics', methods=['GET']) @login_required def api_contacts_statistics(): @@ -40,7 +43,7 @@ def api_contacts_statistics(): server = current_app.dashboard_server # 使用新的联系人分类方法获取统计信息 total, groups, personal, public, official = server.contact_manager.get_contact_statistics() - + return jsonify({ "success": True, "data": { @@ -55,6 +58,7 @@ def api_contacts_statistics(): logger.error(f"获取联系人统计信息失败: {e}") return jsonify({"success": False, "error": str(e)}), 500 + @contacts_bp.route('/api/groups', methods=['GET']) @login_required def api_contacts_groups(): @@ -62,7 +66,7 @@ def api_contacts_groups(): try: server = current_app.dashboard_server group_contacts = server.contact_manager.get_group_contacts() - + return jsonify({ "success": True, "data": { @@ -72,7 +76,8 @@ def api_contacts_groups(): except Exception as e: logger.error(f"获取群组联系人信息失败: {e}") return jsonify({"success": False, "error": str(e)}), 500 - + + @contacts_bp.route('/api/personal', methods=['GET']) @login_required def api_contacts_personal(): @@ -80,7 +85,7 @@ def api_contacts_personal(): try: server = current_app.dashboard_server personal_contacts = server.contact_manager.get_personal_contacts() - + return jsonify({ "success": True, "data": { @@ -91,6 +96,7 @@ def api_contacts_personal(): logger.error(f"获取个人联系人信息失败: {e}") return jsonify({"success": False, "error": str(e)}), 500 + @contacts_bp.route('/api/official', methods=['GET']) @login_required def api_contacts_official(): @@ -98,7 +104,7 @@ def api_contacts_official(): try: server = current_app.dashboard_server official_accounts = server.contact_manager.get_official_accounts() - + return jsonify({ "success": True, "data": { @@ -109,6 +115,7 @@ def api_contacts_official(): logger.error(f"获取公众号联系人信息失败: {e}") return jsonify({"success": False, "error": str(e)}), 500 + @contacts_bp.route('/api/public', methods=['GET']) @login_required def api_contacts_public(): @@ -116,7 +123,7 @@ def api_contacts_public(): try: server = current_app.dashboard_server public_contacts = server.contact_manager.get_public_contacts() - + return jsonify({ "success": True, "data": { @@ -127,6 +134,7 @@ def api_contacts_public(): logger.error(f"获取公共好友信息失败: {e}") return jsonify({"success": False, "error": str(e)}), 500 + @contacts_bp.route('/api/head_images', methods=['GET']) @login_required def api_head_images(): @@ -134,7 +142,7 @@ def api_head_images(): try: server = current_app.dashboard_server head_images = server.contact_manager.get_all_head_images() - + return jsonify({ "success": True, "data": { @@ -145,6 +153,7 @@ def api_head_images(): logger.error(f"获取联系人头像信息失败: {e}") return jsonify({"success": False, "error": str(e)}), 500 + @contacts_bp.route('/api/group_members/', methods=['GET']) @login_required def api_group_members(roomid): @@ -155,8 +164,7 @@ def api_group_members(roomid): """ try: server = current_app.dashboard_server - group_members = server.contact_manager.get_group_members(roomid) - + group_members = server.contact_db.get_chatroom_member_list(roomid) return jsonify({ "success": True, "data": { @@ -182,4 +190,4 @@ def api_contacts_update(): return jsonify({"success": False, "message": "通讯录更新失败"}), 500 except Exception as e: logger.error(f"更新通讯录失败: {e}") - return jsonify({"success": False, "message": f"更新通讯录失败: {str(e)}"}), 500 \ No newline at end of file + return jsonify({"success": False, "message": f"更新通讯录失败: {str(e)}"}), 500 diff --git a/admin/dashboard/server.py b/admin/dashboard/server.py index e0168ea..fa35ab9 100644 --- a/admin/dashboard/server.py +++ b/admin/dashboard/server.py @@ -7,6 +7,7 @@ import sys import threading from loguru import logger +from db.contacts_db import ContactsDBOperator from db.message_storage import MessageStorageDB from db.stats_db import StatsDBOperator from flask import Flask, send_from_directory @@ -40,6 +41,7 @@ class DashboardServer: self.db_manager = robot_instance.db_manager self.stats_db = StatsDBOperator(self.db_manager) self.message_storage = MessageStorageDB(self.db_manager) + self.contact_db: ContactsDBOperator = ContactsDBOperator(self.db_manager) # 获取联系人管理器实例 self.contact_manager = robot_instance.contact_manager self.plugin_manager = robot_instance.plugin_manager diff --git a/admin/dashboard/templates/contacts_management.html b/admin/dashboard/templates/contacts_management.html index 5779134..89a0c2f 100644 --- a/admin/dashboard/templates/contacts_management.html +++ b/admin/dashboard/templates/contacts_management.html @@ -5,99 +5,99 @@ {% block content %}
- - + +
通讯录管理 - + 刷新数据 - + 更新通讯录 + placeholder="搜索联系人..." + {% raw %}v-model="searchQuery" {% endraw %} + style="width: 200px; float: right" + clearable>
- + - - + +
总联系人数
{% raw %}{{ statistics.total }}{% endraw %}
- +
群组数
{% raw %}{{ statistics.groups }}{% endraw %}
- +
个人联系人数
{% raw %}{{ statistics.personal }}{% endraw %}
- +
公众号数
{% raw %}{{ statistics.official }}{% endraw %}
- + - + - + - + - + @@ -105,31 +105,31 @@ - + - + @@ -137,31 +137,31 @@ - + - + @@ -169,10 +169,10 @@ @@ -180,162 +180,168 @@ - + -
+
+ {% raw %}@size-change="handleSizeChange" + @current-change="handleCurrentChange" + :current-page="currentPage" + :page-sizes="[10, 20, 50, 100]" + :page-size="pageSize" {% endraw %} + layout="total, sizes, prev, pager, next, jumper" + {% raw %}:total="groupsList.length" {% endraw %}>
- -
+ +
+ {% raw %}@size-change="handleSizeChange" + @current-change="handleCurrentChange" + :current-page="currentPage" + :page-sizes="[10, 20, 50, 100]" + :page-size="pageSize" {% endraw %} + layout="total, sizes, prev, pager, next, jumper" + {% raw %}:total="personalList.length" {% endraw %}>
- -
+ +
+ {% raw %}@size-change="handleSizeChange" + @current-change="handleCurrentChange" + :current-page="currentPage" + :page-sizes="[10, 20, 50, 100]" + :page-size="pageSize" {% endraw %} + layout="total, sizes, prev, pager, next, jumper" + {% raw %}:total="officialList.length" {% endraw %}>
- -
+ +
+ {% raw %}@size-change="handleSizeChange" + @current-change="handleCurrentChange" + :current-page="currentPage" + :page-sizes="[10, 20, 50, 100]" + :page-size="pageSize" {% endraw %} + layout="total, sizes, prev, pager, next, jumper" + {% raw %}:total="publicList.length" {% endraw %}>
- + - - + + {% raw %}{{ currentGroup.wxid }}{% endraw %} {% raw %}{{ currentGroup.name }}{% endraw %} - +

群成员列表

+ placeholder="搜索群成员..." + {% raw %}v-model="groupMemberSearchQuery" {% endraw %} + style="width: 200px; float: right; margin-bottom: 10px;" + clearable>
- - + + - + -
+
+ {% raw %}@size-change="handleGroupMembersSizeChange" + @current-change="handleGroupMembersCurrentChange" + :current-page="groupMembersCurrentPage" + :page-sizes="[10, 20, 50, 100]" + :page-size="groupMembersPageSize" {% endraw %} + layout="total, sizes, prev, pager, next, jumper" + {% raw %}:total="groupMembersList.length" {% endraw %}>
- + - +
- - + +
- + {% raw %}{{ currentUser.wxid }}{% endraw %} {% raw %}{{ currentUser.name }}{% endraw %}
- + - +
- - + +
- - {% raw %}{{ currentOfficial.wxid }}{% endraw %} - {% raw %}{{ currentOfficial.name }}{% endraw %} + + {% raw %}{{ currentOfficial.wxid }}{% endraw %} + + {% raw %}{{ currentOfficial.name }}{% endraw %} +
- + - +
- - + +
- + {% raw %}{{ currentPublic.wxid }}{% endraw %} {% raw %}{{ currentPublic.name }}{% endraw %} @@ -392,9 +398,9 @@ this.currentPage * this.pageSize ); } - - return this.groupsList.filter(group => - group.wxid.toLowerCase().includes(query) || + + return this.groupsList.filter(group => + group.wxid.toLowerCase().includes(query) || group.name.toLowerCase().includes(query) ).slice( (this.currentPage - 1) * this.pageSize, @@ -409,9 +415,9 @@ this.currentPage * this.pageSize ); } - - return this.personalList.filter(user => - user.wxid.toLowerCase().includes(query) || + + return this.personalList.filter(user => + user.wxid.toLowerCase().includes(query) || user.name.toLowerCase().includes(query) ).slice( (this.currentPage - 1) * this.pageSize, @@ -426,9 +432,9 @@ this.currentPage * this.pageSize ); } - - return this.officialList.filter(official => - official.wxid.toLowerCase().includes(query) || + + return this.officialList.filter(official => + official.wxid.toLowerCase().includes(query) || official.name.toLowerCase().includes(query) ).slice( (this.currentPage - 1) * this.pageSize, @@ -443,9 +449,9 @@ this.currentPage * this.pageSize ); } - - return this.publicList.filter(item => - item.wxid.toLowerCase().includes(query) || + + return this.publicList.filter(item => + item.wxid.toLowerCase().includes(query) || item.name.toLowerCase().includes(query) ).slice( (this.currentPage - 1) * this.pageSize, @@ -461,9 +467,9 @@ this.groupMembersCurrentPage * this.groupMembersPageSize ); } - - return this.groupMembersList.filter(member => - member.wxid.toLowerCase().includes(query) || + + return this.groupMembersList.filter(member => + member.wxid.toLowerCase().includes(query) || (member.name && member.name.toLowerCase().includes(query)) ).slice( (this.groupMembersCurrentPage - 1) * this.groupMembersPageSize, @@ -478,7 +484,7 @@ methods: { loadContactsData() { // 修改API请求路径,从 /api/contacts/ 改为 /contacts/api/ - + // 加载统计数据 axios.get('/contacts/api/statistics') .then(response => { @@ -490,7 +496,7 @@ console.error('加载联系人统计数据失败:', error); this.$message.error('加载联系人统计数据失败'); }); - + // 加载群组数据 axios.get('/contacts/api/groups') .then(response => { @@ -506,7 +512,7 @@ console.error('加载群组数据失败:', error); this.$message.error('加载群组数据失败'); }); - + // 加载个人联系人数据 axios.get('/contacts/api/personal') .then(response => { @@ -522,7 +528,7 @@ console.error('加载个人联系人数据失败:', error); this.$message.error('加载个人联系人数据失败'); }); - + // 加载公众号数据 axios.get('/contacts/api/official') .then(response => { @@ -538,7 +544,7 @@ console.error('加载公众号数据失败:', error); this.$message.error('加载公众号数据失败'); }); - + // 加载公共好友数据 axios.get('/contacts/api/public') .then(response => { @@ -579,7 +585,7 @@ }) .catch(() => { this.$message.error('通讯录更新请求失败'); - }); + }); }, refreshContacts() { this.loadContactsData(); @@ -620,16 +626,16 @@ this.groupMembersLoading = true; this.groupMembersList = []; this.groupMembersCurrentPage = 1; - + axios.get(`/contacts/api/group_members/${roomid}`) .then(response => { if (response.data.success) { const members = response.data.data.members; console.log('获取到的群成员数据:', members); // 添加调试日志 - - this.groupMembersList = Object.entries(members).map(([wxid, name]) => ({ - wxid, - name: name || wxid // 确保name不为空 + + this.groupMembersList = data.map(item => ({ + wxid: item.wxid, + name: item.display_name || item.nick_name || item.wxid, })); console.log('处理后的群成员列表:', this.groupMembersList); // 添加调试日志 } else { @@ -645,7 +651,7 @@ this.groupMembersLoading = false; }); }, - + // 群成员分页方法 handleGroupMembersSizeChange(size) { this.groupMembersPageSize = size; @@ -658,36 +664,41 @@ {% endblock %} \ No newline at end of file