这次实际改的是按钮背后的同步逻辑,不是页面文案本身。现在 /contacts/api/update 触发后会:

个人联系人、公众号:已存在就跳过,不存在才写入。
群:不再删库重建,已有群保留;新群会写入。
群成员:已存在就跳过,不存在就写入。
如果成员这次不在群里了,会把 db/contacts_db.py 里的 status 标成 2,前端会显示“已退群”。
如果整个群查不到了,也不再删除群资料,只把该群历史成员标记为“已退群”。
改动在:

robot.py
db/contacts_db.py
我还做了语法校验,py_compile 通过。需要的话我也可以继续帮你把“更新通讯录”按钮的成功提示改成更明确,比如“已完成增量同步,未删除历史数据”。
This commit is contained in:
liuwei
2026-04-15 09:28:44 +08:00
parent 28e038a25c
commit 4cf5a05088
2 changed files with 126 additions and 53 deletions

View File

@@ -630,66 +630,83 @@ class Robot:
async def refresh_contacts_db(self):
"""刷新联系人信息"""
# 获取用户所有的联系人,并保存到数据库
self.LOG.info("开始刷新联系人信息")
# 删除所有的联系人信息
self.contacts_db.delete_all_contacts()
self.LOG.debug("已删除所有的联系人信息")
contacts = await self.ipad_bot.get_contract_list()
self.LOG.debug(f"获取到的联系人:{contacts}")
# 获取联系人详细信息,get_contract_detail每次可以获取20个
# 每次获取20个需要循环获取
# 将联系人列表分成每组20个
batch_size = 20
discovered_groups = set()
for i in range(0, len(contacts), batch_size):
# 获取当前批次的联系人
batch_contacts = contacts[i:i + batch_size]
# 获取这批联系人的详细信息
contact_info = await self.ipad_bot.get_contract_detail(batch_contacts)
self.LOG.debug(f"获取到的联系人详细信息数量:{len(contact_info)}")
self.contacts_db.save_contacts(contact_info, "friends")
friend_contacts = []
official_contacts = []
for contact in contact_info:
user_name = contact.get("UserName")
if isinstance(user_name, dict):
user_name = user_name.get("string", "")
user_name = user_name or ""
if not user_name:
continue
if user_name.endswith("@chatroom"):
discovered_groups.add(user_name)
if not self.contacts_db.get_chatroom_info(user_name):
self.contacts_db.save_chatroom_info(contact)
continue
if user_name.startswith("gh_"):
official_contacts.append(contact)
else:
friend_contacts.append(contact)
if friend_contacts:
self.contacts_db.save_contacts(friend_contacts, "friends", only_insert=True)
if official_contacts:
self.contacts_db.save_contacts(official_contacts, "ghs", only_insert=True)
# 获取群聊列表
groups = self.contacts_db.get_chatroom_list()
# 调用接口完成群成员信息获取与保存逻辑
for group in groups:
# 调用接口获取群成员信息
group_id = group["chatroom_id"]
discovered_groups.add(group_id)
chatroom_info = await self.ipad_bot.get_chatroom_info(group_id)
self.LOG.debug(f"获取到的群成员信息:{chatroom_info}")
if chatroom_info.get("UserName", ""):
# 保存群信息到数据库
self.contacts_db.save_chatroom_info(chatroom_info)
members = await self.ipad_bot.get_chatroom_member_list(group_id)
# 保存群成员信息
if members:
# 清除所有的成员信息, 重新写入。
self.contacts_db.delete_chatroom_members_info(group_id)
# 兼容逻辑已放到save_chatroom_member_simple内部
self.contacts_db.save_chatroom_member_simple(group_id, members)
self.LOG.info(f"member_list: {members}")
# 更新联系人缓存
active_member_wxids = []
for member in members:
wxid = member.get("UserName", "")
nick_name = member.get("NickName", "")
displayName = member.get("DisplayName", "")
small_head_img_url = member.get("SmallHeadImgUrl", "")
# 如果displayName不为空使用displayName
if displayName:
nick_name = displayName
if isinstance(wxid, dict):
wxid = wxid.get("string", "")
if wxid:
self.allContacts[wxid] = nick_name
active_member_wxids.append(wxid)
self.head_images[wxid] = small_head_img_url
self.LOG.info(f"已更新群 {group_id} 的成员信息")
self.contacts_db.mark_chatroom_members_active(group_id, active_member_wxids)
self.contacts_db.mark_chatroom_members_left(group_id, active_member_wxids)
self.contacts_db.save_chatroom_member_simple(group_id, members, only_insert=True)
self.LOG.info(f"已增量同步群 {group_id} 的成员信息")
else:
self.contacts_db.mark_chatroom_members_left(group_id, [])
self.LOG.warning(f"{group_id} 当前未获取到成员列表,已将历史成员标记为已退群")
else:
self.LOG.error(f"获取群 {group_id} 信息失败,证明用户无该群信息,删除群的相关资料")
# 删除群数据库中的群信息
self.contacts_db.delete_chatroom_all_info(group_id)
self.allContacts.pop(group_id)
self.LOG.warning(f"获取群 {group_id} 信息失败,保留群资料并将成员标记为已退群")
self.contacts_db.mark_chatroom_members_left(group_id, [])
for group_id in discovered_groups:
if not self.contacts_db.get_chatroom_info(group_id):
chatroom_info = await self.ipad_bot.get_chatroom_info(group_id)
if chatroom_info.get("UserName", ""):
self.contacts_db.save_chatroom_info(chatroom_info)
members = await self.ipad_bot.get_chatroom_member_list(group_id)
if members:
self.contacts_db.save_chatroom_member_simple(group_id, members, only_insert=True)
friends = await self.ipad_bot.get_contract_list()
self.allContacts = self.get_all_contacts()
self.head_images = self.get_all_head_images()
self.all_chatroom_members = self.contacts_db.get_chatroom_member_list_name_all()
self.contact_manager.set_contacts(self.allContacts, friends, self.head_images,
self.all_chatroom_members)