通讯录群详情新增手动同步群公告按钮
变更项:1) 新增POST接口用于手动同步群公告,仅在手动触发时调用Group/GetChatRoomInfoDetail。2) 同步逻辑采用基础群信息与Detail信息合并后再落库,确保公告可更新且不破坏原有群资料。3) 群详情页公告区域新增同步按钮和加载态,避免重复点击。4) 同步成功后自动刷新当前群资料。5) 补充中文注释说明手动同步链路。
This commit is contained in:
@@ -444,6 +444,73 @@ def api_group_profile(roomid):
|
||||
return jsonify({"success": False, "error": str(e)}), 500
|
||||
|
||||
|
||||
@contacts_bp.route('/api/group_profile/<roomid>/sync_announcement', methods=['POST'])
|
||||
@login_required
|
||||
def api_sync_group_announcement(roomid):
|
||||
"""手动同步指定群公告(调用 /Group/GetChatRoomInfoDetail)。"""
|
||||
try:
|
||||
server = current_app.dashboard_server
|
||||
if not roomid:
|
||||
return jsonify({"success": False, "error": "缺少群ID"}), 400
|
||||
if not getattr(server, "robot", None) or not getattr(server.robot, "ipad_bot", None):
|
||||
return jsonify({"success": False, "error": "机器人实例未初始化"}), 503
|
||||
|
||||
async def fetch_and_merge():
|
||||
# 先拉基础群信息,再拉 Detail 信息,最后合并,避免只用 Detail 导致字段不完整。
|
||||
base_info = await server.robot.ipad_bot.get_chatroom_info(roomid)
|
||||
detail_info = await server.robot.ipad_bot.get_chatroom_announce(roomid)
|
||||
|
||||
merged_info = dict(base_info or {})
|
||||
detail_contact = None
|
||||
if isinstance(detail_info, dict):
|
||||
contact_list = detail_info.get("ContactList")
|
||||
if isinstance(contact_list, list) and contact_list:
|
||||
first = contact_list[0]
|
||||
if isinstance(first, dict):
|
||||
detail_contact = first
|
||||
|
||||
if detail_contact:
|
||||
merged_info.update(detail_contact)
|
||||
if isinstance(detail_info, dict):
|
||||
merged_info.update(detail_info)
|
||||
|
||||
# 统一公告字段命名,供 contacts_db.save_chatroom_info 直接提取入库。
|
||||
announcement = (
|
||||
merged_info.get("ChatRoomAnnouncement")
|
||||
or merged_info.get("Announcement")
|
||||
or merged_info.get("Annoucement")
|
||||
or merged_info.get("AnnouncementContent")
|
||||
or merged_info.get("chatRoomAnnouncement")
|
||||
)
|
||||
if announcement:
|
||||
merged_info["ChatRoomAnnouncement"] = announcement
|
||||
|
||||
# 保底补上群ID,避免少数字段缺失导致无法更新到对应群。
|
||||
if not merged_info.get("UserName"):
|
||||
merged_info["UserName"] = roomid
|
||||
return merged_info
|
||||
|
||||
merged_info = asyncio.run(fetch_and_merge())
|
||||
if not merged_info:
|
||||
return jsonify({"success": False, "error": "获取群详情失败"}), 500
|
||||
|
||||
save_ok = server.contact_db.save_chatroom_info(merged_info)
|
||||
if not save_ok:
|
||||
return jsonify({"success": False, "error": "保存群公告失败"}), 500
|
||||
|
||||
profile = server.contact_db.get_chatroom_profile(roomid)
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "群公告同步成功",
|
||||
"data": {
|
||||
"profile": profile
|
||||
}
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"手动同步群公告失败: {e}")
|
||||
return jsonify({"success": False, "error": str(e)}), 500
|
||||
|
||||
|
||||
@contacts_bp.route('/api/group_member_context/<roomid>/<wxid>', methods=['GET'])
|
||||
@login_required
|
||||
def api_group_member_context(roomid, wxid):
|
||||
|
||||
@@ -210,7 +210,17 @@
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="群公告">
|
||||
<span class="group-announcement">{% raw %}{{ currentGroupProfile.announcement || '暂无群公告' }}{% endraw %}</span>
|
||||
<div class="group-announcement-wrap">
|
||||
<span class="group-announcement">{% raw %}{{ currentGroupProfile.announcement || '暂无群公告' }}{% endraw %}</span>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="primary"
|
||||
plain
|
||||
:loading="groupAnnouncementSyncing"
|
||||
@click="syncCurrentGroupAnnouncement">
|
||||
同步群公告
|
||||
</el-button>
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="机器人状态">
|
||||
<el-tag :type="currentGroup.robot_status === 'enabled' ? 'success' : 'info'">
|
||||
@@ -778,6 +788,8 @@
|
||||
groupPermissionsLoading: false,
|
||||
// 当前群基础资料:用于展示群主、群公告、管理员、成员数等信息。
|
||||
currentGroupProfile: { owner_wxid: '', owner_name: '', announcement: '', member_count: 0, admin_count: 0, admins: [] },
|
||||
// 群公告手动同步按钮的加载态,避免重复点击触发多次请求。
|
||||
groupAnnouncementSyncing: false,
|
||||
groupInsight: null,
|
||||
groupInsightLoading: false,
|
||||
groupMembersList: [], groupMembersCurrentPage: 1, groupMembersPageSize: 10, groupMemberSearchQuery: '', groupMembersLoading: false,
|
||||
@@ -960,6 +972,27 @@
|
||||
this.$message.error('加载群资料失败');
|
||||
});
|
||||
},
|
||||
syncCurrentGroupAnnouncement() {
|
||||
if (!this.currentGroup || !this.currentGroup.wxid) return;
|
||||
this.groupAnnouncementSyncing = true;
|
||||
// 手动触发群公告同步:调用后端 Detail 接口并落库,再刷新当前群资料展示。
|
||||
axios.post(`/contacts/api/group_profile/${this.currentGroup.wxid}/sync_announcement`)
|
||||
.then(response => {
|
||||
if (response.data.success) {
|
||||
this.$message.success(response.data.message || '群公告同步成功');
|
||||
this.loadGroupProfile(this.currentGroup.wxid);
|
||||
} else {
|
||||
this.$message.error(response.data.error || '群公告同步失败');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('同步群公告失败:', error);
|
||||
this.$message.error('同步群公告失败');
|
||||
})
|
||||
.finally(() => {
|
||||
this.groupAnnouncementSyncing = false;
|
||||
});
|
||||
},
|
||||
toggleGroupPermission(permission) {
|
||||
const newStatus = permission.statusBool ? 'enabled' : 'disabled';
|
||||
axios.post(`/robot/api/group/${this.currentGroup.wxid}/permissions`, {
|
||||
@@ -1539,6 +1572,7 @@
|
||||
.detail-card-sub { font-size: 12px; color: #94a3b8; font-weight: 500; }
|
||||
.feature-chip-list { display: flex; gap: 8px; flex-wrap: wrap; min-height: 60px; align-items: flex-start; }
|
||||
.empty-inline, .detail-inline-note { font-size: 12px; color: #64748b; }
|
||||
.group-announcement-wrap { display: flex; gap: 12px; align-items: flex-start; justify-content: space-between; }
|
||||
.group-announcement { white-space: pre-wrap; line-height: 1.7; color: #334155; }
|
||||
.detail-inline-note { margin-top: 12px; line-height: 1.6; }
|
||||
.suggestion-list { display: flex; flex-direction: column; gap: 12px; }
|
||||
|
||||
Reference in New Issue
Block a user