diff --git a/admin/dashboard/blueprints/contacts.py b/admin/dashboard/blueprints/contacts.py index ad847ca..1b60816 100644 --- a/admin/dashboard/blueprints/contacts.py +++ b/admin/dashboard/blueprints/contacts.py @@ -124,4 +124,26 @@ def api_contacts_public(): }) except Exception as e: 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): + """获取指定群的成员列表API + + Args: + roomid: 群ID + """ + try: + server = current_app.dashboard_server + group_members = server.contact_manager.get_group_members(roomid) + + return jsonify({ + "success": True, + "data": { + "members": group_members + } + }) + except Exception as e: + logger.error(f"获取群成员列表失败: {e}") return jsonify({"success": False, "error": str(e)}), 500 \ No newline at end of file diff --git a/admin/dashboard/templates/contacts_management.html b/admin/dashboard/templates/contacts_management.html index 515acd3..0ccdbeb 100644 --- a/admin/dashboard/templates/contacts_management.html +++ b/admin/dashboard/templates/contacts_management.html @@ -197,12 +197,48 @@ - + {% raw %}{{ currentGroup.wxid }}{% endraw %} {% raw %}{{ currentGroup.name }}{% endraw %} + + +
+
+

群成员列表

+ + +
+ + + + + + + + +
+ + +
+
@@ -263,7 +299,13 @@ currentGroup: {}, currentUser: {}, currentOfficial: {}, - currentPublic: {} + currentPublic: {}, + // 新增群成员相关数据 + groupMembersList: [], + groupMembersCurrentPage: 1, + groupMembersPageSize: 10, + groupMemberSearchQuery: '', + groupMembersLoading: false }; }, computed: { @@ -436,6 +478,7 @@ viewGroupDetails(group) { this.currentGroup = group; this.groupDetailDialogVisible = true; + this.loadGroupMembers(group.wxid); }, viewUserDetails(user) { this.currentUser = user; @@ -448,6 +491,38 @@ viewPublicDetails(publicFriend) { this.currentPublic = publicFriend; this.publicDetailDialogVisible = true; + }, + // 添加加载群成员的方法 + loadGroupMembers(roomid) { + 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; + this.groupMembersList = Object.entries(members).map(([wxid, name]) => ({ + wxid, + name + })); + } + }) + .catch(error => { + console.error('加载群成员数据失败:', error); + this.$message.error('加载群成员数据失败'); + }) + .finally(() => { + this.groupMembersLoading = false; + }); + }, + + // 群成员分页方法 + handleGroupMembersSizeChange(size) { + this.groupMembersPageSize = size; + }, + handleGroupMembersCurrentChange(page) { + this.groupMembersCurrentPage = page; } } }); @@ -472,5 +547,18 @@ margin-top: 20px; text-align: right; } +.section-title { + margin: 20px 0 15px 0; + border-bottom: 1px solid #ebeef5; + padding-bottom: 10px; + display: flex; + justify-content: space-between; + align-items: center; +} +.section-title h3 { + margin: 0; + font-size: 18px; + color: #303133; +} {% endblock %} \ No newline at end of file diff --git a/robot.py b/robot.py index 479f97f..a7373f9 100644 --- a/robot.py +++ b/robot.py @@ -58,7 +58,7 @@ class Robot(Job): # 初始化联系人管理器并设置联系人 self.contact_manager = ContactManager.get_instance() self.allContacts = self.get_all_contacts() - self.contact_manager.set_contacts(self.allContacts, self.wcf.get_friends()) + self.contact_manager.set_contacts(self.allContacts, self.wcf) self.LOG.info(f"DB+REDIS 连接池开始初始化") # 使用单例模式获取实例 @@ -545,5 +545,5 @@ class Robot(Job): def refresh_contacts(self): """刷新联系人信息""" self.allContacts = self.get_all_contacts() - self.contact_manager.refresh_contacts(self.allContacts, self.wcf.get_friends()) + self.contact_manager.refresh_contacts(self.allContacts, self.wcf) self.LOG.info("联系人信息已刷新") diff --git a/utils/wechat/contact_manager.py b/utils/wechat/contact_manager.py index 4d976b5..3d22b44 100644 --- a/utils/wechat/contact_manager.py +++ b/utils/wechat/contact_manager.py @@ -5,6 +5,8 @@ import logging from typing import Dict, Optional, List, Tuple +from wcferry import Wcf + class ContactManager: """联系人管理器单例类""" @@ -17,6 +19,7 @@ class ContactManager: _initialized = False _logger = logging.getLogger("ContactManager") _friends: List[Dict] = [] + _group_contacts_friends: Dict[str, Dict[str, str]] = {} # 定义公共好友列表 _PUBLIC_FRIENDS = { 'fmessage': '朋友推荐消息', @@ -46,7 +49,7 @@ class ContactManager: cls._instance = ContactManager() return cls._instance - def set_contacts(self, contacts: Dict[str, str], friends: List[Dict]) -> None: + def set_contacts(self, contacts: Dict[str, str], wcf: Wcf) -> None: """设置联系人字典 Args: @@ -62,12 +65,12 @@ class ContactManager: "gender": gender} """ self._contacts = contacts - self._friends = friends + self._friends = wcf.get_friends() self._logger.info(f"联系人信息已更新,共 {len(contacts)} 个联系人") # 分类联系人 - self._classify_contacts() + self._classify_contacts(wcf) - def _classify_contacts(self) -> None: + def _classify_contacts(self, wcf: Wcf) -> None: """将联系人分类为群组、个人联系人、公共好友和公众号""" self._group_contacts = {} self._personal_contacts = {} @@ -84,6 +87,9 @@ class ContactManager: # 判断是否为群组(wxid以@chatroom结尾) elif wxid.endswith('@chatroom'): self._group_contacts[wxid] = nickname + # 如果是群,这处理群列表内容 + self._group_contacts_friends[wxid] = wcf.get_chatroom_members(wxid) + # # 其他为普通好友和群成员 # else: # self._personal_contacts[wxid] = nickname @@ -147,9 +153,31 @@ class ContactManager: """ return self._contacts.get(wxid, wxid) + def get_group_name(self, roomid: str, wxid: str) -> str: + """ + Args: + roomid: 群ID + wxid: 微信ID + + Returns: + 对应的昵称,如果不存在则返回wxid本身 + """ + return self._group_contacts_friends.get(roomid, "").get(wxid, "未知昵称") + + def get_group_members(self, roomid: str) -> Dict[str, str]: + """获取指定群的成员列表 + + Args: + roomid: 群ID + + Returns: + 群成员字典,格式为 {"wxid": "NickName"} + """ + return self._group_contacts_friends.get(roomid, {}) + def update_contact(self, wxid: str, nickname: str) -> None: """更新单个联系人信息 - + Args: wxid: 微信ID nickname: 昵称 @@ -166,30 +194,32 @@ class ContactManager: self._personal_contacts[wxid] = nickname self._logger.debug(f"已更新联系人: {wxid} -> {nickname}") - def refresh_contacts(self, new_contacts: Dict[str, str], friends: List[Dict]) -> None: + def refresh_contacts(self, new_contacts: Dict[str, str], wcf: Wcf) -> None: """刷新联系人信息 - + Args: new_contacts: 新的联系人字典 - friends: 好友清单 contact = { - "wxid": cnt.get("wxid", ""), - "code": cnt.get("code", ""), - "remark": cnt.get("remark", ""), - "name": cnt.get("name", ""), - "country": cnt.get("country", ""), - "province": cnt.get("province", ""), - "city": cnt.get("city", ""), - "gender": gender} + wcf :wcf + """ self._contacts = new_contacts - self._friends = friends + # friends: 好友清单 contact = { + # "wxid": cnt.get("wxid", ""), + # "code": cnt.get("code", ""), + # "remark": cnt.get("remark", ""), + # "name": cnt.get("name", ""), + # "country": cnt.get("country", ""), + # "province": cnt.get("province", ""), + # "city": cnt.get("city", ""), + # "gender": gender} + self._friends = wcf.get_friends() self._logger.info(f"联系人信息已刷新,共 {len(new_contacts)} 个联系人") # 重新分类联系人 - self._classify_contacts() + self._classify_contacts(wcf) def get_contact_statistics(self) -> Tuple[int, int, int, int, int]: """获取联系人统计信息 - + Returns: 包含总联系人数、群组数、个人联系人数、公共好友数和公众号数的元组 """