Browse Source

群发消息--开发中

master
xie.bx 3 years ago
parent
commit
aec3a5f15a
  1. 2
      im-platform/src/main/java/com/lx/implatform/controller/FriendsController.java
  2. 58
      im-platform/src/main/java/com/lx/implatform/controller/GroupController.java
  3. 14
      im-platform/src/main/java/com/lx/implatform/controller/GroupMessageController.java
  4. 83
      im-platform/src/main/java/com/lx/implatform/entity/Group.java
  5. 83
      im-platform/src/main/java/com/lx/implatform/entity/GroupMember.java
  6. 75
      im-platform/src/main/java/com/lx/implatform/entity/GroupMessage.java
  7. 69
      im-platform/src/main/java/com/lx/implatform/entity/GroupMessageReadPos.java
  8. 16
      im-platform/src/main/java/com/lx/implatform/mapper/GroupMapper.java
  9. 16
      im-platform/src/main/java/com/lx/implatform/mapper/GroupMemberMapper.java
  10. 16
      im-platform/src/main/java/com/lx/implatform/mapper/GroupMessageMapper.java
  11. 16
      im-platform/src/main/java/com/lx/implatform/mapper/GroupMessageReadPosMapper.java
  12. 16
      im-platform/src/main/java/com/lx/implatform/service/IGroupMemberService.java
  13. 16
      im-platform/src/main/java/com/lx/implatform/service/IGroupMessageReadPosService.java
  14. 16
      im-platform/src/main/java/com/lx/implatform/service/IGroupMessageService.java
  15. 30
      im-platform/src/main/java/com/lx/implatform/service/IGroupService.java
  16. 20
      im-platform/src/main/java/com/lx/implatform/service/impl/GroupMemberServiceImpl.java
  17. 20
      im-platform/src/main/java/com/lx/implatform/service/impl/GroupMessageReadPosServiceImpl.java
  18. 20
      im-platform/src/main/java/com/lx/implatform/service/impl/GroupMessageServiceImpl.java
  19. 177
      im-platform/src/main/java/com/lx/implatform/service/impl/GroupServiceImpl.java
  20. 14
      im-platform/src/main/java/com/lx/implatform/service/impl/SingleMessageServiceImpl.java
  21. 22
      im-platform/src/main/java/com/lx/implatform/vo/GroupInviteVO.java
  22. 43
      im-platform/src/main/java/com/lx/implatform/vo/GroupVO.java
  23. 51
      im-platform/src/main/resources/db/db.sql
  24. 12
      im-server/src/main/java/com/lx/implatform/imserver/IMServerApp.java
  25. 11
      im-server/src/main/java/com/lx/implatform/imserver/websocket/WebsocketServer.java

2
im-platform/src/main/java/com/lx/implatform/controller/FriendsController.java

@ -55,7 +55,7 @@ public class FriendsController {
@PutMapping("/update") @PutMapping("/update")
@ApiOperation(value = "更新好友信息",notes="更新好友头像或昵称") @ApiOperation(value = "更新好友信息",notes="更新好友头像或昵称")
public Result delFriends(@Valid @RequestBody FriendsVO vo){ public Result modifyFriends(@Valid @RequestBody FriendsVO vo){
friendsService.update(vo); friendsService.update(vo);
return ResultUtils.success(); return ResultUtils.success();
} }

58
im-platform/src/main/java/com/lx/implatform/controller/GroupController.java

@ -0,0 +1,58 @@
package com.lx.implatform.controller;
import com.lx.common.result.Result;
import com.lx.common.result.ResultUtils;
import com.lx.implatform.service.IGroupService;
import com.lx.implatform.vo.GroupInviteVO;
import com.lx.implatform.vo.GroupVO;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
@RestController
@RequestMapping("/group")
public class GroupController {
@Autowired
private IGroupService groupService;
@ApiOperation(value = "创建群聊",notes="创建群聊")
@PostMapping("/create")
public Result<GroupVO> createGroup(@NotEmpty(message = "群名不能为空") @RequestParam String groupName){
return ResultUtils.success(groupService.createGroup(groupName));
}
@ApiOperation(value = "修改群聊信息",notes="修改群聊信息")
@PutMapping("/modify")
public Result<GroupVO> modifyGroup(@Valid @RequestBody GroupVO vo){
return ResultUtils.success(groupService.modifyGroup(vo));
}
@ApiOperation(value = "修改群聊信息",notes="修改群聊信息")
@DeleteMapping("/delete/{groupId}")
public Result<GroupVO> deleteGroup(@NotNull(message = "群聊id不能为空") @PathVariable Long groupId){
groupService.deleteGroup(groupId);
return ResultUtils.success();
}
@ApiOperation(value = "查询群聊列表",notes="查询群聊列表")
@GetMapping("/list")
public Result<List<GroupVO>> findGroups(){
return ResultUtils.success(groupService.findGroups());
}
@ApiOperation(value = "邀请进群",notes="邀请好友进群")
@PostMapping("/invite")
public Result invite(@Valid @RequestBody GroupInviteVO vo){
groupService.invite(vo);
return ResultUtils.success();
}
}

14
im-platform/src/main/java/com/lx/implatform/controller/GroupMessageController.java

@ -0,0 +1,14 @@
package com.lx.implatform.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/group/message")
public class GroupMessageController {
}

83
im-platform/src/main/java/com/lx/implatform/entity/Group.java

@ -0,0 +1,83 @@
package com.lx.implatform.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.Version;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
*
* @author blue
* @since 2022-10-31
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("group")
public class Group extends Model<Group> {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 群名字
*/
private String name;
/**
* 群主id
*/
@TableField("owner_id")
private Long ownerId;
/**
* 头像
*/
@TableField("head_image")
private String headImage;
/**
* 头像缩略图
*/
@TableField("head_image_thumb")
private String headImageThumb;
/**
* 群公告
*/
@TableField("notice")
private String notice;
/**
* 群备注
*/
@TableField("remark")
private String remark;
/**
* 创建时间
*/
@TableField("created_time")
private Date createdTime;
@Override
protected Serializable pkVal() {
return this.id;
}
}

83
im-platform/src/main/java/com/lx/implatform/entity/GroupMember.java

@ -0,0 +1,83 @@
package com.lx.implatform.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.Version;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 群成员
* </p>
*
* @author blue
* @since 2022-10-31
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("group_member")
public class GroupMember extends Model<GroupMember> {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 群id
*/
@TableField("group_id")
private Long groupId;
/**
* 用户id
*/
@TableField("user_id")
private Long userId;
/**
* 群内显示名称
*/
@TableField("user_id")
private String aliasName;
/**
* 头像
*/
@TableField("head_image")
private String headImage;
/**
* 备注
*/
@TableField("remarks")
private String remarks;
/**
* 创建时间
*/
@TableField("created_time")
private Date createdTime;
@Override
protected Serializable pkVal() {
return this.id;
}
}

75
im-platform/src/main/java/com/lx/implatform/entity/GroupMessage.java

@ -0,0 +1,75 @@
package com.lx.implatform.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.Version;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 群消息
* </p>
*
* @author blue
* @since 2022-10-31
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("group_message")
public class GroupMessage extends Model<GroupMessage> {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 群id
*/
@TableField("group_id")
private Long groupId;
/**
* 发送用户id
*/
@TableField("send_user_id")
private Long sendUserId;
/**
* 发送内容
*/
@TableField("content")
private String content;
/**
* 消息类型 0:文字 1:图片 2:文件
*/
@TableField("type")
private Boolean type;
/**
* 发送时间
*/
@TableField("send_time")
private Date sendTime;
@Override
protected Serializable pkVal() {
return this.id;
}
}

69
im-platform/src/main/java/com/lx/implatform/entity/GroupMessageReadPos.java

@ -0,0 +1,69 @@
package com.lx.implatform.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.Version;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 群消息读取位置
* </p>
*
* @author blue
* @since 2022-10-31
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("group_message_read_pos")
public class GroupMessageReadPos extends Model<GroupMessageReadPos> {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 群id
*/
@TableField("group_id")
private Long groupId;
/**
* 用户id
*/
@TableField("user_id")
private Long userId;
/**
* 已读取消息的最大消息id
*/
@TableField("read_pos")
private Long readPos;
/**
* 最后读取时间
*/
@TableField("last_read_time")
private Date lastReadTime;
@Override
protected Serializable pkVal() {
return this.id;
}
}

16
im-platform/src/main/java/com/lx/implatform/mapper/GroupMapper.java

@ -0,0 +1,16 @@
package com.lx.implatform.mapper;
import com.lx.implatform.entity.Group;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author blue
* @since 2022-10-31
*/
public interface GroupMapper extends BaseMapper<Group> {
}

16
im-platform/src/main/java/com/lx/implatform/mapper/GroupMemberMapper.java

@ -0,0 +1,16 @@
package com.lx.implatform.mapper;
import com.lx.implatform.entity.GroupMember;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 群成员 Mapper 接口
* </p>
*
* @author blue
* @since 2022-10-31
*/
public interface GroupMemberMapper extends BaseMapper<GroupMember> {
}

16
im-platform/src/main/java/com/lx/implatform/mapper/GroupMessageMapper.java

@ -0,0 +1,16 @@
package com.lx.implatform.mapper;
import com.lx.implatform.entity.GroupMessage;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 群消息 Mapper 接口
* </p>
*
* @author blue
* @since 2022-10-31
*/
public interface GroupMessageMapper extends BaseMapper<GroupMessage> {
}

16
im-platform/src/main/java/com/lx/implatform/mapper/GroupMessageReadPosMapper.java

@ -0,0 +1,16 @@
package com.lx.implatform.mapper;
import com.lx.implatform.entity.GroupMessageReadPos;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 群消息读取位置 Mapper 接口
* </p>
*
* @author blue
* @since 2022-10-31
*/
public interface GroupMessageReadPosMapper extends BaseMapper<GroupMessageReadPos> {
}

16
im-platform/src/main/java/com/lx/implatform/service/IGroupMemberService.java

@ -0,0 +1,16 @@
package com.lx.implatform.service;
import com.lx.implatform.entity.GroupMember;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 群成员 服务类
* </p>
*
* @author blue
* @since 2022-10-31
*/
public interface IGroupMemberService extends IService<GroupMember> {
}

16
im-platform/src/main/java/com/lx/implatform/service/IGroupMessageReadPosService.java

@ -0,0 +1,16 @@
package com.lx.implatform.service;
import com.lx.implatform.entity.GroupMessageReadPos;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 群消息读取位置 服务类
* </p>
*
* @author blue
* @since 2022-10-31
*/
public interface IGroupMessageReadPosService extends IService<GroupMessageReadPos> {
}

16
im-platform/src/main/java/com/lx/implatform/service/IGroupMessageService.java

@ -0,0 +1,16 @@
package com.lx.implatform.service;
import com.lx.implatform.entity.GroupMessage;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 群消息 服务类
* </p>
*
* @author blue
* @since 2022-10-31
*/
public interface IGroupMessageService extends IService<GroupMessage> {
}

30
im-platform/src/main/java/com/lx/implatform/service/IGroupService.java

@ -0,0 +1,30 @@
package com.lx.implatform.service;
import com.lx.implatform.entity.Group;
import com.baomidou.mybatisplus.extension.service.IService;
import com.lx.implatform.vo.GroupInviteVO;
import com.lx.implatform.vo.GroupVO;
import java.util.List;
/**
* <p>
* 服务类
* </p>
*
* @author blue
* @since 2022-10-31
*/
public interface IGroupService extends IService<Group> {
GroupVO createGroup(String groupName);
GroupVO modifyGroup(GroupVO vo);
void deleteGroup(Long groupId);
List<GroupVO> findGroups();
void invite(GroupInviteVO vo);
}

20
im-platform/src/main/java/com/lx/implatform/service/impl/GroupMemberServiceImpl.java

@ -0,0 +1,20 @@
package com.lx.implatform.service.impl;
import com.lx.implatform.entity.GroupMember;
import com.lx.implatform.mapper.GroupMemberMapper;
import com.lx.implatform.service.IGroupMemberService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 群成员 服务实现类
* </p>
*
* @author blue
* @since 2022-10-31
*/
@Service
public class GroupMemberServiceImpl extends ServiceImpl<GroupMemberMapper, GroupMember> implements IGroupMemberService {
}

20
im-platform/src/main/java/com/lx/implatform/service/impl/GroupMessageReadPosServiceImpl.java

@ -0,0 +1,20 @@
package com.lx.implatform.service.impl;
import com.lx.implatform.entity.GroupMessageReadPos;
import com.lx.implatform.mapper.GroupMessageReadPosMapper;
import com.lx.implatform.service.IGroupMessageReadPosService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 群消息读取位置 服务实现类
* </p>
*
* @author blue
* @since 2022-10-31
*/
@Service
public class GroupMessageReadPosServiceImpl extends ServiceImpl<GroupMessageReadPosMapper, GroupMessageReadPos> implements IGroupMessageReadPosService {
}

20
im-platform/src/main/java/com/lx/implatform/service/impl/GroupMessageServiceImpl.java

@ -0,0 +1,20 @@
package com.lx.implatform.service.impl;
import com.lx.implatform.entity.GroupMessage;
import com.lx.implatform.mapper.GroupMessageMapper;
import com.lx.implatform.service.IGroupMessageService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 群消息 服务实现类
* </p>
*
* @author blue
* @since 2022-10-31
*/
@Service
public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, GroupMessage> implements IGroupMessageService {
}

177
im-platform/src/main/java/com/lx/implatform/service/impl/GroupServiceImpl.java

@ -0,0 +1,177 @@
package com.lx.implatform.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lx.common.enums.ResultCode;
import com.lx.common.util.BeanUtils;
import com.lx.implatform.entity.Friends;
import com.lx.implatform.entity.Group;
import com.lx.implatform.entity.GroupMember;
import com.lx.implatform.entity.User;
import com.lx.implatform.exception.GlobalException;
import com.lx.implatform.mapper.GroupMapper;
import com.lx.implatform.service.IFriendsService;
import com.lx.implatform.service.IGroupMemberService;
import com.lx.implatform.service.IGroupService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lx.implatform.service.IUserService;
import com.lx.implatform.session.SessionContext;
import com.lx.implatform.session.UserSession;
import com.lx.implatform.vo.GroupInviteVO;
import com.lx.implatform.vo.GroupVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements IGroupService {
@Autowired
private IUserService userService;
@Autowired
private IGroupMemberService groupMemberService;
@Autowired
private IFriendsService friendsService;
/**
* 创建新群聊
*
* @return GroupVO
* @Param groupName 群聊名称
**/
@Transactional
@Override
public GroupVO createGroup(String groupName) {
UserSession session = SessionContext.getSession();
User user = userService.getById(session.getId());
// 保存群组数据
Group group = new Group();
group.setName(groupName);
group.setOwnerId(user.getId());
group.setHeadImage(user.getHeadImage());
group.setHeadImageThumb(user.getHeadImageThumb());
this.save(group);
// 把群主加入群
GroupMember groupMember = new GroupMember();
groupMember.setGroupId(group.getId());
groupMember.setUserId(user.getId());
groupMember.setAliasName(user.getNickName());
groupMember.setHeadImage(user.getHeadImageThumb());
groupMemberService.save(groupMember);
GroupVO vo = BeanUtils.copyProperties(group, GroupVO.class);
return vo;
}
/**
* 修改群聊信息
*
* @Param GroupVO 群聊信息
* @return GroupVO
**/
@Override
public GroupVO modifyGroup(GroupVO vo) {
UserSession session = SessionContext.getSession();
// 校验是不是群主,只有群主能改信息
Group group = this.getById(vo.getId());
if(group.getOwnerId() != session.getId()){
throw new GlobalException(ResultCode.PROGRAM_ERROR,"您不是群主,不可修改群信息");
}
// 保存群信息
group = BeanUtils.copyProperties(vo,Group.class);
this.save(group);
return vo;
}
/**
* 删除群聊
*
* @Param groupId 群聊id
* @return void
**/
@Transactional
@Override
public void deleteGroup(Long groupId) {
UserSession session = SessionContext.getSession();
Group group = this.getById(groupId);
if(group == null){
throw new GlobalException(ResultCode.PROGRAM_ERROR,"群组不存在");
}
if(group.getOwnerId() != session.getId()){
throw new GlobalException(ResultCode.PROGRAM_ERROR,"只有群主才有权限解除群聊");
}
// 删除群数据
this.removeById(groupId);
// 删除成员数据
QueryWrapper<GroupMember> wrapper = new QueryWrapper();
wrapper.lambda().eq(GroupMember::getGroupId,groupId);
groupMemberService.remove(wrapper);
}
/**
* 查询当前用户的所有群聊
*
* @return List<GroupVO>
**/
@Override
public List<GroupVO> findGroups() {
UserSession session = SessionContext.getSession();
// 查询当前用户的群id列表
QueryWrapper<GroupMember> memberWrapper = new QueryWrapper();
memberWrapper.lambda().eq(GroupMember::getUserId, session.getId());
List<GroupMember> groupMembers = groupMemberService.list(memberWrapper);
// 拉取群信息
List<Long> ids = groupMembers.stream().map((gm -> gm.getGroupId())).collect(Collectors.toList());
QueryWrapper<Group> groupWrapper = new QueryWrapper();
groupWrapper.lambda().in(Group::getId, ids);
List<Group> groups = this.list(groupWrapper);
// 转vo
List<GroupVO> vos = groups.stream().map(g -> {
GroupVO vo = BeanUtils.copyProperties(g, GroupVO.class);
return vo;
}).collect(Collectors.toList());
return vos;
}
/**
* 邀请好友进群
*
* @return
* @Param GroupInviteVO 群id好友id列表
**/
@Override
public void invite(GroupInviteVO vo) {
UserSession session = SessionContext.getSession();
// 已经在群里面用户,不可重复加入
QueryWrapper<GroupMember> wrapper = new QueryWrapper();
wrapper.lambda().eq(GroupMember::getId, vo.getGroupId())
.in(GroupMember::getUserId, vo.getFriendIds());
if(groupMemberService.count(wrapper)>0){
throw new GlobalException(ResultCode.PROGRAM_ERROR, "部分用户已经在群中,邀请失败");
}
// 找出好友信息
List<Friends> friends = friendsService.findFriendsByUserId(session.getId());
List<Friends> friendsList = vo.getFriendIds().stream().map(id ->
friends.stream().filter(f -> f.getFriendId().equals(id)).findFirst().get()).collect(Collectors.toList());
if (friendsList.size() != vo.getFriendIds().size()) {
throw new GlobalException(ResultCode.PROGRAM_ERROR, "部分用户不是您的好友,邀请失败");
}
// 批量保存成员数据
List<GroupMember> groupMembers = friendsList.stream()
.map(f -> {
GroupMember groupMember = new GroupMember();
groupMember.setGroupId(vo.getGroupId());
groupMember.setUserId(f.getFriendId());
groupMember.setAliasName(f.getFriendNickName());
groupMember.setHeadImage(f.getFriendHeadImage());
return groupMember;
}).collect(Collectors.toList());
if(!groupMembers.isEmpty()) {
groupMemberService.saveBatch(groupMembers);
}
}
}

14
im-platform/src/main/java/com/lx/implatform/service/impl/SingleMessageServiceImpl.java

@ -23,14 +23,7 @@ import java.util.Date;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/**
* <p>
* 单人消息服务实现类
* </p>
*
* @author blue
* @since 2022-10-01
*/
@Service @Service
public class SingleMessageServiceImpl extends ServiceImpl<SingleMessageMapper, SingleMessage> implements ISingleMessageService { public class SingleMessageServiceImpl extends ServiceImpl<SingleMessageMapper, SingleMessage> implements ISingleMessageService {
@ -41,20 +34,17 @@ public class SingleMessageServiceImpl extends ServiceImpl<SingleMessageMapper, S
@Override @Override
public void sendMessage(SingleMessageVO vo) { public void sendMessage(SingleMessageVO vo) {
Long userId = SessionContext.getSession().getId(); Long userId = SessionContext.getSession().getId();
Boolean isFriends = friendsService.isFriends(userId,vo.getRecvUserId()); Boolean isFriends = friendsService.isFriends(userId,vo.getRecvUserId());
if(!isFriends){ if(!isFriends){
throw new GlobalException(ResultCode.PROGRAM_ERROR,"您已不是对方好友,无法发送消息"); throw new GlobalException(ResultCode.PROGRAM_ERROR,"您已不是对方好友,无法发送消息");
} }
// 保存消息 // 保存消息
SingleMessage msg = BeanUtils.copyProperties(vo,SingleMessage.class); SingleMessage msg = BeanUtils.copyProperties(vo,SingleMessage.class);
msg.setSendUserId(userId); msg.setSendUserId(userId);
msg.setStatus(MessageStatusEnum.UNREAD.getCode()); msg.setStatus(MessageStatusEnum.UNREAD.getCode());
msg.setSendTime(new Date()); msg.setSendTime(new Date());
this.save(msg); this.save(msg);
// 获取对方连接的channelId // 获取对方连接的channelId
String key = RedisKey.IM_USER_SERVER_ID+msg.getRecvUserId(); String key = RedisKey.IM_USER_SERVER_ID+msg.getRecvUserId();
String serverId = (String)redisTemplate.opsForValue().get(key); String serverId = (String)redisTemplate.opsForValue().get(key);
@ -80,7 +70,6 @@ public class SingleMessageServiceImpl extends ServiceImpl<SingleMessageMapper, S
queryWrapper.lambda().eq(SingleMessage::getRecvUserId,userId) queryWrapper.lambda().eq(SingleMessage::getRecvUserId,userId)
.eq(SingleMessage::getStatus,MessageStatusEnum.UNREAD); .eq(SingleMessage::getStatus,MessageStatusEnum.UNREAD);
List<SingleMessage> messages = this.list(queryWrapper); List<SingleMessage> messages = this.list(queryWrapper);
// 上传至redis,等待推送 // 上传至redis,等待推送
if(!messages.isEmpty()){ if(!messages.isEmpty()){
List<SingleMessageInfo> infos = messages.stream().map(m->{ List<SingleMessageInfo> infos = messages.stream().map(m->{
@ -90,6 +79,5 @@ public class SingleMessageServiceImpl extends ServiceImpl<SingleMessageMapper, S
String sendKey = RedisKey.IM_UNREAD_MESSAGE + serverId; String sendKey = RedisKey.IM_UNREAD_MESSAGE + serverId;
redisTemplate.opsForList().rightPushAll(sendKey,infos.toArray()); redisTemplate.opsForList().rightPushAll(sendKey,infos.toArray());
} }
} }
} }

22
im-platform/src/main/java/com/lx/implatform/vo/GroupInviteVO.java

@ -0,0 +1,22 @@
package com.lx.implatform.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
@Data
@ApiModel("邀请好友进群请求VO")
public class GroupInviteVO {
@NotNull(message = "群id不可为空")
@ApiModelProperty(value = "群id")
private Long groupId;
@NotEmpty(message = "群id不可为空")
@ApiModelProperty(value = "好友id列表不可为空")
private List<Long> friendIds;
}

43
im-platform/src/main/java/com/lx/implatform/vo/GroupVO.java

@ -0,0 +1,43 @@
package com.lx.implatform.vo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Date;
@Data
@ApiModel("群信息VO")
public class GroupVO {
@NotNull(message = "群id不可为空")
@ApiModelProperty(value = "群id")
private Long id;
@NotEmpty(message = "群名称不可为空")
@ApiModelProperty(value = "群名称")
private String name;
@NotEmpty(message = "群主id不可为空")
@ApiModelProperty(value = "群主id")
private Long ownerId;
@ApiModelProperty(value = "头像")
private String headImage;
@ApiModelProperty(value = "头像缩略图")
private String headImageThumb;
@ApiModelProperty(value = "群公告")
private String notice;
@ApiModelProperty(value = "群备注")
private String remark;
}

51
im-platform/src/main/resources/db/db.sql

@ -12,7 +12,7 @@ create table `user`(
`created_time` datetime DEFAULT CURRENT_TIMESTAMP comment '创建时间', `created_time` datetime DEFAULT CURRENT_TIMESTAMP comment '创建时间',
unique key `idx_user_name`(user_name), unique key `idx_user_name`(user_name),
key `idx_nick_name`(nick_name) key `idx_nick_name`(nick_name)
); ) ENGINE=InnoDB CHARSET=utf8mb3 comment '用户';
create table `friends`( create table `friends`(
`id` bigint not null auto_increment primary key comment 'id', `id` bigint not null auto_increment primary key comment 'id',
@ -23,8 +23,7 @@ create table `friends`(
`created_time` datetime DEFAULT CURRENT_TIMESTAMP comment '创建时间', `created_time` datetime DEFAULT CURRENT_TIMESTAMP comment '创建时间',
key `idx_user_id` (`user_id`), key `idx_user_id` (`user_id`),
key `idx_friend_id` (`friend_id`) key `idx_friend_id` (`friend_id`)
); ) ENGINE=InnoDB CHARSET=utf8mb3 comment '好友';
create table `single_message`( create table `single_message`(
`id` bigint not null auto_increment primary key comment 'id', `id` bigint not null auto_increment primary key comment 'id',
@ -35,4 +34,48 @@ create table `single_message`(
`status` tinyint(1) NOT NULL comment '状态 0:未读 1:已读 ', `status` tinyint(1) NOT NULL comment '状态 0:未读 1:已读 ',
`send_time` datetime DEFAULT CURRENT_TIMESTAMP comment '发送时间', `send_time` datetime DEFAULT CURRENT_TIMESTAMP comment '发送时间',
key `idx_send_recv_user_id` (`send_user_id`,`recv_user_id`) key `idx_send_recv_user_id` (`send_user_id`,`recv_user_id`)
); )ENGINE=InnoDB CHARSET=utf8mb3 comment '私聊消息';
create table `group`(
`id` bigint not null auto_increment primary key comment 'id',
`name` varchar(255) not null comment '群名字',
`owner_id` bigint not null comment '群主id',
`head_image` varchar(255) default '' comment '群头像',
`head_image_thumb` varchar(255) default '' comment '群头像缩略图',
`notice` text comment '群公告',
`remark` varchar(255) default '' comment '群备注',
`created_time` datetime DEFAULT CURRENT_TIMESTAMP comment '创建时间'
)ENGINE=InnoDB comment '';
create table `group_member`(
`id` bigint not null auto_increment primary key comment 'id',
`group_id` bigint not null comment '群id',
`user_id` bigint not null comment '用户id',
`alias_name` varchar(255) DEFAULT '' comment '组内显示名称',
`head_image` varchar(255) default '' comment '用户头像',
`remarks` varchar(255) DEFAULT '' comment '备注',
`created_time` datetime DEFAULT CURRENT_TIMESTAMP comment '创建时间',
key `idx_group_id`(`group_id`),
key `idx_user_id`(`user_id`)
)ENGINE=InnoDB comment '群成员';
create table `group_message`(
`id` bigint not null auto_increment primary key comment 'id',
`group_id` bigint not null comment '群id',
`send_user_id` bigint not null comment '发送用户id',
`content` text comment '发送内容',
`type` tinyint(1) NOT NULL comment '消息类型 0:文字 1:图片 2:文件',
`send_time` datetime DEFAULT CURRENT_TIMESTAMP comment '发送时间',
key `idx_group_id` (group_id)
)ENGINE=InnoDB CHARSET=utf8mb3 comment '群消息';
create table `group_message_read_pos`(
`id` bigint not null auto_increment primary key comment 'id',
`group_id` bigint not null comment '群id',
`user_id` bigint not null comment '用户id',
`read_pos` bigint default 0 comment '已读取消息的最大消息id',
`last_read_time` datetime DEFAULT CURRENT_TIMESTAMP comment '最后读取时间',
key `idx_user_id`(`user_id`)
)ENGINE=InnoDB CHARSET=utf8mb3 comment '群消息读取位置';

12
im-server/src/main/java/com/lx/implatform/imserver/IMServerApp.java

@ -15,18 +15,12 @@ import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling @EnableScheduling
@ComponentScan(basePackages={"com.lx"}) @ComponentScan(basePackages={"com.lx"})
@SpringBootApplication @SpringBootApplication
public class IMServerApp implements CommandLineRunner { public class IMServerApp {
@Value("${websocket.port}")
private int port;
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(IMServerApp.class); SpringApplication.run(IMServerApp.class);
} }
public void run(String... args) throws Exception {
new WebsocketServer().start(port);
}
} }

11
im-server/src/main/java/com/lx/implatform/imserver/websocket/WebsocketServer.java

@ -11,14 +11,25 @@ import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler; import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler; import io.netty.handler.timeout.IdleStateHandler;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@Component
public class WebsocketServer { public class WebsocketServer {
public static String LOCAL_SERVER_ID = UUID.randomUUID().toString(); public static String LOCAL_SERVER_ID = UUID.randomUUID().toString();
@Value("${websocket.port}")
private int port;
@PostConstruct
public void init(){
this.start(port);
}
public void start(int port) { public void start(int port) {
// 服务端启动辅助类,用于设置TCP相关参数 // 服务端启动辅助类,用于设置TCP相关参数
ServerBootstrap bootstrap = new ServerBootstrap(); ServerBootstrap bootstrap = new ServerBootstrap();

Loading…
Cancel
Save