group_info:

1.创建群组
思路:创建群组需要知道谁创的,群的id,群的名字,群的加入方式,群的头像,群的公告 这些就是我们需要的参数,有部分是可以不传的
前端为:

后端代码:
@RequestMapping(value = "/saveGroup")
@GlobalInterceptor
public ResponseVO saveGroup(HttpServletRequest request,
String groupId,
@NotEmpty String groupName,
String groupNotice,
@NotNull Integer joinType,
MultipartFile avatarFile,
MultipartFile avatarCover) {
TokenUserInfoDto tokenUserInfoDto = getTokenUserInfo(request);
GroupInfo groupInfo = new GroupInfo();
groupInfo.setGroupId(groupId);
groupInfo.setGroupOwnerId(tokenUserInfoDto.getUserId());
groupInfo.setGroupName(groupName);
groupInfo.setGroupNotice(groupNotice);
groupInfo.setJoinType(joinType);
this.groupInfoService.saveGroup(groupInfo, avatarFile, avatarCover);
return getSuccessResponseVO(null);
}
为什么有两个MultipartFile 原因是需要做缩略图
实现层:
思路:创建群聊,需要添加自己为联系人,这是必须的,因为群的人数一定不能为0,所以也要对群人数做限制,聊天则需要有会话,以及会话的关系:以下是两张相关的图:
chat_session:

chat_session_user:

chat_session用来展示最后一句话,前端效果为:

chat_session_user作用为存储关系
接下来只提供部分代码因为创建群组需要涉及信息发送以及缩略图,缩略图部分会专门讲,并且缩略图基本相似不用过多复述
Date curDate = new Date();
if (StringTools.isEmpty(groupInfo.getGroupId())) {
GroupInfoQuery groupInfoQuery = new GroupInfoQuery();
groupInfoQuery.setGroupOwnerId(groupInfo.getGroupOwnerId());
Integer count = this.groupInfoMapper.selectCount(groupInfoQuery);
SysSettingDto sysSettingDto = redisComponet.getSysSetting();
if (count >= sysSettingDto.getMaxGroupCount()) {
throw new BusinessException("最多只能创建" + sysSettingDto.getMaxGroupCount() + "个群聊");
}
//新增头像必须传
if (null == avatarFile) {
throw new BusinessException(ResponseCodeEnum.CODE_600);
}
groupInfo.setCreateTime(curDate);
groupInfo.setGroupId(StringTools.getGroupId());
this.groupInfoMapper.insert(groupInfo);
//将自己添加为联系人
UserContact userContact = new UserContact();
userContact.setStatus(UserContactStatusEnum.FRIEND.getStatus());
userContact.setContactType(UserContactTypeEnum.GROUP.getType());
userContact.setContactId(groupInfo.getGroupId());
userContact.setUserId(groupInfo.getGroupOwnerId());
userContact.setCreateTime(curDate);
userContact.setLastUpdateTime(curDate);
this.userContactMapper.insert(userContact);
//创建会话
String sessionId = StringTools.getChatSessionId4Group(groupInfo.getGroupId());
ChatSession chatSession = new ChatSession();
chatSession.setSessionId(sessionId);
chatSession.setLastMessage(MessageTypeEnum.GROUP_CREATE.getInitMessage());
chatSession.setLastReceiveTime(curDate.getTime());
this.chatSessionMapper.insert(chatSession);
//创建群主会话
ChatSessionUser chatSessionUser = new ChatSessionUser();
chatSessionUser.setUserId(groupInfo.getGroupOwnerId());
chatSessionUser.setContactId(groupInfo.getGroupId());
chatSessionUser.setContactName(groupInfo.getGroupName());
chatSessionUser.setSessionId(sessionId);
this.chatSessionUserService.add(chatSessionUser);
2.获取我创建的群组:
思路:要获取自己创建的群组最主要就是需要自己的信息,本项目使用token传递个人信息,所以前端需要传递request,群组是列表则需要排序(自己决定),群组本身需要状态也需要自己设置
代码:
@RequestMapping(value = "/loadMyGroup")
@GlobalInterceptor
public ResponseVO loadMyGroup(HttpServletRequest request) {
TokenUserInfoDto tokenUserInfoDto = getTokenUserInfo(request);
GroupInfoQuery infoQuery = new GroupInfoQuery();
infoQuery.setGroupOwnerId(tokenUserInfoDto.getUserId());
infoQuery.setOrderBy("create_time desc");
infoQuery.setStatus(GroupStatusEnum.NORMAL.getStatus());
List<GroupInfo> groupInfoList = this.groupInfoService.findListByParam(infoQuery);
return getSuccessResponseVO(groupInfoList);
}
3.获取群聊详细
前端展示:

思路:用户信息肯定需要获取,群id也一定需要,只需要判断此用户是否在群以及群是否存在,根据群id查询信息即可,实现简单
代码:
@RequestMapping(value = "/getGroupInfo")
@GlobalInterceptor
public ResponseVO getGroupInfo(HttpServletRequest request,
@NotEmpty String groupId) {
GroupInfo groupInfo = getGroupDetailCommon(request, groupId);
UserContactQuery userContactQuery = new UserContactQuery();
userContactQuery.setContactId(groupId);
Integer memberCount = this.userContactService.findCountByParam(userContactQuery);
groupInfo.setMemberCount(memberCount);
return getSuccessResponseVO(groupInfo);
}
4.获取会话详细群信息:
前端展示:

思路:用户信息肯定需要,也需要群的id,要根据群id获取群友以及群信息,获取群信息简单,群友需要user表进行联查实现起来并不困难,mapper层不再展示因为难度不大简单联查
@RequestMapping(value = "/getGroupInfo4Chat")
@GlobalInterceptor
public ResponseVO getGroupInfo4Chat(HttpServletRequest request, @NotEmpty String groupId) {
GroupInfo groupInfo = getGroupDetailCommon(request, groupId);
UserContactQuery userContactQuery = new UserContactQuery();
userContactQuery.setContactId(groupId);
userContactQuery.setQueryUserInfo(true);
userContactQuery.setOrderBy("create_time asc");
userContactQuery.setStatus(UserContactStatusEnum.FRIEND.getStatus());
List<UserContact> userContactList = this.userContactService.findListByParam(userContactQuery);
GroupInfoVO groupInfoVo = new GroupInfoVO();
groupInfoVo.setGroupInfo(groupInfo);
groupInfoVo.setUserContactList(userContactList);
return getSuccessResponseVO(groupInfoVo);
}
5.退群
思路:群主不可以退群(前端群组不可能退群只有解散群主,避免不法分子调接口),退群为当前用户行为,所以需要当前用户信息,以及群id,用来删除contact表中的关系,这部分需要物理删除,直接在数据库中删除此记录,页面session需要显示人数,所以要人数减去退群人数,本功能依旧需要涉及信息所以只提供代码片段
user_contact表:

@RequestMapping(value = "/leaveGroup")
@GlobalInterceptor
public ResponseVO leaveGroup(HttpServletRequest request, @NotEmpty String groupId) {
TokenUserInfoDto tokenUserInfoDto = getTokenUserInfo(request);
groupInfoService.leaveGroup(tokenUserInfoDto.getUserId(), groupId, MessageTypeEnum.LEAVE_GROUP);
return getSuccessResponseVO(null);
}
实现层:
GroupInfo groupInfo = groupInfoMapper.selectByGroupId(groupId);
if (groupInfo == null) {
throw new BusinessException(ResponseCodeEnum.CODE_600);
}
//创建者不能退出群聊,只能解散群
if (userId.equals(groupInfo.getGroupOwnerId())) {
throw new BusinessException(ResponseCodeEnum.CODE_600);
}
Integer count = userContactMapper.deleteByUserIdAndContactId(userId, groupId);
if (count == 0) {
throw new BusinessException(ResponseCodeEnum.CODE_600);
}
UserInfo userInfo = userInfoMapper.selectByUserId(userId);
String sessionId = StringTools.getChatSessionId4Group(groupId);
Date curTime = new Date();
String messageContent = String.format(messageTypeEnum.getInitMessage(), userInfo.getNickName());
//更新会话消息
ChatSession chatSession = new ChatSession();
chatSession.setLastMessage(messageContent);
chatSession.setLastReceiveTime(curTime.getTime());
chatSessionMapper.updateBySessionId(chatSession, sessionId);
解散群:
思路:与退群其实没有差异,唯一的差异就是解散群要把所有的群友与群的关系删除,仅多了这一步,其他不变,也需要把session会话页面删除,相似度过高,不给出代码
添加与移除:
思路:添加与移除功能只有群主可以执行(群管理员),所以需要用户信息判断是否为群主,添加要判断被执行人是否为执行人的朋友关系,移除要判断被执行人是否在群里,所以前端需要传入用户信息,以及群id以及选择操作的类型和被操作人员
代码:
@RequestMapping(value = "/addOrRemoveGroupUser")
@GlobalInterceptor
public ResponseVO addOrRemoveGroupUser(HttpServletRequest request,
@NotEmpty String groupId,
@NotEmpty String selectContacts,
@NotNull Integer opType) {
TokenUserInfoDto tokenUserInfoDto = getTokenUserInfo(request);
groupInfoService.addOrRemoveGroupUser(tokenUserInfoDto, groupId, selectContacts, opType);
return getSuccessResponseVO(null);
}
实现层:
@Override
@Transactional(rollbackFor = Exception.class)
public void addOrRemoveGroupUser(TokenUserInfoDto tokenUserInfoDto, String groupId, String contactIds, Integer opType) {
GroupInfo groupInfo = groupInfoMapper.selectByGroupId(groupId);
if (null == groupInfo || !groupInfo.getGroupOwnerId().equals(tokenUserInfoDto.getUserId())) {
throw new BusinessException(ResponseCodeEnum.CODE_600);
}
String[] contactIdList = contactIds.split(",");
for (String contactId : contactIdList) {
//移除群员
if (Constants.ZERO.equals(opType)) {
groupInfoService.leaveGroup(contactId, groupId, MessageTypeEnum.REMOVE_GROUP);
} else {
userContactService.addContact(contactId, null, groupId, UserContactTypeEnum.GROUP.getType(), null);
}
}
}