【群聊】群组、群成员、入群申请
群聊是 IM 的多人会话。群聊模块由 yudao-module-im 后端模块的 group 包实现,用户侧前端在 @/views/im/home 的「通讯录 / 聊天」里。
本文涉及群组表 im_group、群成员表 im_group_member、入群申请表 im_group_request 三张表,都通过 group_id 关联:一个群(im_group)有多条成员记录(im_group_member);开启审批后,加群会先落一条申请记录(im_group_request),同意后才成为成员。
- 群组:群的基本信息(群名、群主、公告、头像)与管控开关(全群禁言、进群审批、消息置顶、封禁)。
- 群成员:群里的每个人,记录角色(群主 / 管理员 / 普通)、我的群昵称、禁言到期时间等。
- 入群申请:加群的「申请 / 邀请 — 审批」流程。
# 1. 群组
群组,由 ImGroupController 提供接口。
群成员的三种角色
每个群有唯一群主(owner_user_id),可设若干管理员,其余是普通成员,枚举 ImGroupMemberRoleEnum(1=群主,2=管理员,3=普通成员)。群主可解散群、转让群主、设 / 撤管理员;群主与管理员可移除成员、禁言、审批入群申请、置顶群消息。退群是成员自己离开,解散是群主(或运营)关停整个群。
# 1.1 表结构
省略 creator/create_time/updater/update_time/deleted/tenant_id 等通用字段
CREATE TABLE `im_group` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`name` varchar(255) DEFAULT NULL COMMENT '群名称',
`avatar` varchar(255) DEFAULT NULL COMMENT '群头像',
`notice` varchar(1024) DEFAULT NULL COMMENT '群公告',
`owner_user_id` bigint NOT NULL COMMENT '群主用户编号',
`join_approval` bit(1) NOT NULL DEFAULT b'0' COMMENT '进群是否需审批(false 自由进群,true 需群主/管理员审批)',
`muted_all` bit(1) DEFAULT b'0' COMMENT '是否全群禁言',
`pinned_message_ids` varchar(128) DEFAULT NULL COMMENT '群置顶消息编号列表,逗号分隔',
`banned` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否封禁',
`banned_reason` varchar(255) DEFAULT NULL COMMENT '封禁原因',
`banned_time` datetime DEFAULT NULL COMMENT '封禁时间',
`status` tinyint NOT NULL DEFAULT '0' COMMENT '群状态(0=正常,1=已解散)',
`dissolved_time` datetime DEFAULT NULL COMMENT '解散时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='IM 群组表';
① name、avatar、notice、owner_user_id 是群基本信息。owner_user_id 群主,全群唯一;name 为空时前端按成员昵称拼接展示。
② join_approval、muted_all、pinned_message_ids 是群管控开关:join_approval 进群审批开关;muted_all 全群禁言,开启后仅群主 / 管理员可发言;pinned_message_ids 置顶消息 id 列表(逗号分隔,群主 / 管理员维护,置顶内容详见 《消息》)。
③ banned、banned_reason、banned_time 是运营封禁字段,用户侧不可改,仅运营后台封禁群时写入(详见「运营侧」)。
④ status、dissolved_time:status 群状态(0=正常,1=已解散),群主解散或运营解散后置为已解散并记 dissolved_time。
# 1.2 创建与群设置
创建群聊:在会话页左上「+」→「发起群聊」打开 GroupCreateDialog.vue,勾选好友即可建群(群名默认按成员昵称拼接),对应 ImGroupController 的 createGroup 方法。

群设置:在群会话点右上角进入群设置抽屉(ConversationGroupSide.vue),它聚合了群与成员的几乎所有操作:
- 群信息:群名称、群公告、群头像(群主可改,
updateGroup);我在本群的昵称、群备注、消息免打扰(每个成员各自设置,updateGroupMember)。 - 管控开关:全群禁言(
muteAll)、进群审批(updateGroup改join_approval)——群主 / 管理员可见。 - 群主操作:群管理员设置(
addGroupAdmin/removeGroupAdmin)、转让群主(transferGroupOwner)——仅群主可见。 - 退出 / 解散:普通成员是「退出群聊」(
quitGroup),群主是「解散群聊」(dissolveGroup)。

群消息置顶:群主 / 管理员可右键群消息「置顶」(pinGroupMessage / unpinGroupMessage),置顶后在群聊顶部悬浮展示,点击跳转原消息(定向消息不支持置顶)。

以上变更都会通过 WebSocket 推送同步给相关成员的多端,推送链路详见 《WebSocket 实时推送与离线消息》。
# 2. 群成员
群成员,由 ImGroupMemberController 提供接口。
# 2.1 表结构
省略 creator/create_time/updater/update_time/deleted/tenant_id 等通用字段
CREATE TABLE `im_group_member` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`group_id` bigint NOT NULL COMMENT '群编号',
`user_id` bigint NOT NULL COMMENT '用户编号',
`role` tinyint NOT NULL DEFAULT '3' COMMENT '成员角色(1=群主,2=管理员,3=普通成员)',
`display_user_name` varchar(255) DEFAULT NULL COMMENT '组内显示名(我在本群的昵称)',
`group_remark` varchar(64) DEFAULT NULL COMMENT '群备注(仅自己可见)',
`silent` bit(1) DEFAULT b'0' COMMENT '是否免打扰',
`mute_end_time` datetime DEFAULT NULL COMMENT '禁言到期时间',
`add_source` tinyint DEFAULT NULL COMMENT '加入来源',
`inviter_user_id` bigint DEFAULT NULL COMMENT '邀请人用户编号(主动申请进群时为 NULL)',
`join_time` datetime DEFAULT NULL COMMENT '入群时间',
`status` tinyint NOT NULL DEFAULT '0' COMMENT '成员状态(0=正常,1=已退群)',
`quit_time` datetime DEFAULT NULL COMMENT '退群时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_im_group_member_group_user` (`group_id`, `user_id`)
) ENGINE=InnoDB COMMENT='IM 群成员表';
① group_id、user_id、role 是成员关联与角色。唯一键 (group_id, user_id) 保证一个人在一个群里只有一条记录;role 见上方角色枚举。
② display_user_name、group_remark、silent、mute_end_time 是成员的个人设置与状态:display_user_name 组内显示名(我在本群的昵称,群内可见);group_remark 群备注(仅自己可见,查询他人时后端会置空);silent 免打扰;mute_end_time 禁言到期时间——null 未禁言,未来时间表示禁言中,特殊值 9999-12-31 表示永久禁言。
③ add_source、inviter_user_id、join_time 是入群来源:inviter_user_id 邀请人,主动申请进群时为 null。
④ status、quit_time:成员状态(0=正常,1=已退群)。退群是软删——置为已退群并记 quit_time,记录保留,以便历史消息里仍能显示退群成员的昵称 / 头像。
# 2.2 成员管理
进群会话即可看到成员,群聊列表(GroupList.vue)在通讯录「群聊」分区,支持按群名 / 群备注搜索。

成员相关操作都在群设置抽屉里完成:
- 邀请成员:所有成员都能点「添加」邀请好友入群(
inviteGroupMember);若群开启了进群审批且邀请人是普通成员,则邀请会转为待审批(见第 3 节)。 - 移除成员:群主 / 管理员点「移出」踢人(
removeGroupMember);管理员不能移除其他管理员,群主不能被移除。 - 设 / 撤管理员、转让群主:群主在群设置里操作。
- 禁言成员:群主 / 管理员在成员消息上发起禁言(
muteMember/cancelMuteMember),可选 10 分钟 ~ 30 天或永久。

# 3. 入群申请
入群申请,由 ImGroupRequestController 提供接口。它覆盖两条加群路径:用户主动申请 和 被他人邀请待审批,用 inviter_user_id 是否为空区分。
# 3.1 表结构
省略 creator/create_time/updater/update_time/deleted/tenant_id 等通用字段
CREATE TABLE `im_group_request` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`group_id` bigint NOT NULL COMMENT '群编号',
`user_id` bigint NOT NULL COMMENT '申请人 / 被邀请人用户编号',
`inviter_user_id` bigint DEFAULT NULL COMMENT '邀请人用户编号(NULL=主动申请,非 NULL=被邀请待审批)',
`apply_content` varchar(255) DEFAULT NULL COMMENT '申请理由',
`add_source` tinyint DEFAULT NULL COMMENT '加入来源',
`handle_result` tinyint NOT NULL DEFAULT '0' COMMENT '处理结果(0=未处理,1=同意,2=拒绝)',
`handle_user_id` bigint DEFAULT NULL COMMENT '处理人用户编号(群主 / 管理员)',
`handle_content` varchar(255) DEFAULT NULL COMMENT '处理理由',
`handle_time` datetime DEFAULT NULL COMMENT '处理时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_im_group_request` (`group_id`, `user_id`, `tenant_id`)
) ENGINE=InnoDB COMMENT='IM 加群申请记录表';
① group_id、user_id、inviter_user_id 是申请三方。唯一键 (group_id, user_id) 保证同一人对同一群只保留一条,重复申请覆盖重置为未处理。inviter_user_id 区分路径:null=用户主动申请;非 null=被该邀请人邀请、待审批。
② apply_content、add_source 是申请理由与来源(枚举 ImGroupAddSourceEnum:搜索 / 邀请 / 扫码 / 分享链接,当前主要用邀请)。
③ handle_result、handle_user_id、handle_content、handle_time 是处理信息,由群主 / 管理员处理时回写。handle_result 的状态流转:
| 处理结果 | 含义 | 可执行操作 |
|---|---|---|
| 0 未处理 | 等待群主 / 管理员处理 | 同意(agreeGroupRequest)、拒绝(refuseGroupRequest) |
| 1 同意 | 已入群 | — |
| 2 拒绝 | 已拒绝 | — |
什么时候会产生申请记录(方法在 ImGroupRequestServiceImpl):
- 主动申请(
applyJoinGroup):群开启进群审批时,落im_group_request待处理;关闭审批时直接入群、不产生申请记录。 - 邀请待审批:普通成员邀请他人入群、且群开启审批时,落一条
inviter_user_id非空的申请待处理;群主 / 管理员邀请则直接入群。 - 同意 / 拒绝(
agreeGroupRequest/refuseGroupRequest,仅群主 / 管理员):同意则成员入群,拒绝可附理由,结果推送给申请人。
# 3.2 申请与审批
群主 / 管理员在群设置的「进群申请」入口(GroupRequestListDialog.vue)处理待审批的申请,可「确认」或「拒绝」(拒绝可填理由)。未处理的申请会以红点提示。

# 4. 运营侧
运营侧在 [IM 即时通讯 -> 群聊管理] 下,对应 @/views/im/manager/group 目录。与好友不同,群聊运营侧除了查询,还带封禁 / 解封 / 解散的管控能力:
- 群聊列表:分页查看全部群、群详情(ImGroupManagerController 的
getGroupPage/getGroup,权限im:manager:group:query),可看群主、成员数、封禁 / 解散状态。 - 封禁 / 解封:对违规群封禁(
banGroup)或解封(unbanGroup),写入im_group的banned/banned_reason/banned_time,权限im:manager:group:ban。 - 解散群:运营强制解散群(
dissolveGroup,权限im:manager:group:dissolve)。 - 群成员 / 加群申请:ImGroupMemberManagerController、ImGroupRequestManagerController 提供只读分页查询。

