好友管理
This commit is contained in:
parent
98f25179d3
commit
5a435dd19c
@ -15,6 +15,11 @@
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.belerweb</groupId>
|
||||
<artifactId>pinyin4j</artifactId>
|
||||
<version>2.5.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qiniu</groupId>
|
||||
<artifactId>qiniu-java-sdk</artifactId>
|
||||
|
@ -15,12 +15,11 @@ public class ServiceException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 3447728300174142127L;
|
||||
|
||||
public static final String DEFAULT_MESSAGE = "网络错误,请稍后重试!";
|
||||
|
||||
/**
|
||||
* 异常消息
|
||||
*/
|
||||
private String msg = DEFAULT_MESSAGE;
|
||||
private String msg = ResultCode.ERROR.message();
|
||||
|
||||
/**
|
||||
* 错误码
|
||||
|
@ -0,0 +1 @@
|
||||
|
@ -0,0 +1,39 @@
|
||||
package cn.lili.modules.im.entity.dos;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@TableName("li_friend")
|
||||
public class Friend {
|
||||
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private String id;
|
||||
|
||||
// 用户ID
|
||||
private String userId;
|
||||
|
||||
// 好友ID
|
||||
private String friendId;
|
||||
|
||||
// 好友昵称
|
||||
private String nickname;
|
||||
|
||||
// 好友头像
|
||||
private String avatar;
|
||||
|
||||
// 好友备注
|
||||
private String remark;
|
||||
|
||||
// 关系状态 (0:待确认 1:已确认 2:已拒绝 3:已解除)
|
||||
private Integer status;
|
||||
|
||||
// 创建时间
|
||||
private Date createTime;
|
||||
|
||||
// 更新时间
|
||||
private Date updateTime;
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package cn.lili.modules.im.entity.dos;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@TableName("li_im_group")
|
||||
public class ImGroup {
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private String id;
|
||||
|
||||
// 群名称
|
||||
private String name;
|
||||
|
||||
// 群头像
|
||||
private String avatar;
|
||||
|
||||
// 群公告
|
||||
private String notice;
|
||||
|
||||
// 群主ID
|
||||
private String ownerId;
|
||||
|
||||
// 创建时间
|
||||
private Date createTime;
|
||||
|
||||
// 更新时间
|
||||
private Date updateTime;
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package cn.lili.modules.im.entity.dos;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@TableName("li_im_group_member")
|
||||
public class ImGroupMember {
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private String id;
|
||||
|
||||
// 群ID
|
||||
private String groupId;
|
||||
|
||||
// 成员ID
|
||||
private String memberId;
|
||||
|
||||
// 成员昵称
|
||||
private String nickname;
|
||||
|
||||
// 成员角色(0:普通成员 1:管理员 2:群主)
|
||||
private Integer role;
|
||||
|
||||
// 是否被禁言(0:否 1:是)
|
||||
private Integer isMuted;
|
||||
|
||||
// 禁言结束时间
|
||||
private Date muteEndTime;
|
||||
|
||||
// 加入时间
|
||||
private Date joinTime;
|
||||
|
||||
// 更新时间
|
||||
private Date updateTime;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package cn.lili.modules.im.entity.vo;
|
||||
|
||||
import cn.lili.modules.im.entity.dos.Friend;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class FriendVO extends Friend {
|
||||
// 从 li_member 表获取的字段
|
||||
private String username;
|
||||
private String nickname;
|
||||
private String face; // 头像
|
||||
private String mobile;
|
||||
private String email;
|
||||
private String region;
|
||||
private String gender;
|
||||
private Date birthday;
|
||||
// 昵称首字母(用于排序)
|
||||
private String firstLetter;
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package cn.lili.modules.im.mapper;
|
||||
|
||||
|
||||
import cn.lili.modules.im.entity.dos.Friend;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.mapstruct.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface FriendMapper extends BaseMapper<Friend> {
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package cn.lili.modules.im.mapper;
|
||||
|
||||
import cn.lili.modules.im.entity.dos.ImGroup;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
public interface ImGroupMapper extends BaseMapper<ImGroup> {
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package cn.lili.modules.im.mapper;
|
||||
|
||||
import cn.lili.modules.im.entity.dos.ImGroupMember;
|
||||
import cn.lili.modules.im.entity.dos.ImMessage;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
public interface ImGroupMemberMapper extends BaseMapper<ImGroupMember> {
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package cn.lili.modules.im.service;
|
||||
|
||||
|
||||
import cn.lili.modules.im.entity.dos.Friend;
|
||||
|
||||
import cn.lili.modules.im.entity.vo.FriendVO;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
|
||||
public interface FriendService extends IService<Friend> {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
* 获取互相关注的好友列表(包含详细信息)
|
||||
|
||||
* @param userId 用户ID
|
||||
|
||||
* @return 好友列表
|
||||
|
||||
*/
|
||||
|
||||
List<FriendVO> getMutualFriends(String userId);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
* 获取好友详细信息
|
||||
|
||||
* @param friendId 好友ID
|
||||
|
||||
* @return 好友详细信息
|
||||
|
||||
*/
|
||||
|
||||
FriendVO getFriendDetails(String friendId);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
* 解除好友关系
|
||||
|
||||
* @param userId 用户ID
|
||||
|
||||
* @param friendId 好友ID
|
||||
|
||||
*/
|
||||
|
||||
void removeFriend(String userId, String friendId);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
* 添加好友
|
||||
|
||||
* @param userId 用户ID
|
||||
|
||||
* @param friendId 好友ID
|
||||
|
||||
*/
|
||||
|
||||
void addFriend(String userId, String friendId);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
* 更新好友备注
|
||||
|
||||
* @param userId 用户ID
|
||||
|
||||
* @param friendId 好友ID
|
||||
|
||||
* @param remark 备注
|
||||
|
||||
*/
|
||||
|
||||
void updateRemark(String userId, String friendId, String remark);
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package cn.lili.modules.im.service;
|
||||
|
||||
import cn.lili.modules.im.entity.dos.ImGroup;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import java.util.List;
|
||||
|
||||
public interface ImGroupService extends IService<ImGroup> {
|
||||
|
||||
/**
|
||||
* 创建群聊
|
||||
* @param groupName 群名称
|
||||
* @param memberIds 邀请的成员ID列表
|
||||
* @return 群聊信息
|
||||
*/
|
||||
ImGroup createGroup(String groupName, List<String> memberIds);
|
||||
|
||||
/**
|
||||
* 解散群聊
|
||||
* @param groupId 群ID
|
||||
*/
|
||||
void dismissGroup(String groupId);
|
||||
|
||||
/**
|
||||
* 邀请成员
|
||||
* @param groupId 群ID
|
||||
* @param memberIds 成员ID列表
|
||||
*/
|
||||
void inviteMembers(String groupId, List<String> memberIds);
|
||||
|
||||
/**
|
||||
* 设置管理员
|
||||
* @param groupId 群ID
|
||||
* @param memberId 成员ID
|
||||
*/
|
||||
void setAdmin(String groupId, String memberId);
|
||||
|
||||
/**
|
||||
* 取消管理员
|
||||
* @param groupId 群ID
|
||||
* @param memberId 成员ID
|
||||
*/
|
||||
void removeAdmin(String groupId, String memberId);
|
||||
|
||||
/**
|
||||
* 禁言成员
|
||||
* @param groupId 群ID
|
||||
* @param memberId 成员ID
|
||||
* @param duration 禁言时长(分钟)
|
||||
*/
|
||||
void muteMember(String groupId, String memberId, Integer duration);
|
||||
|
||||
/**
|
||||
* 解除成员禁言
|
||||
* @param groupId 群ID
|
||||
* @param memberId 成员ID
|
||||
*/
|
||||
void unmuteMember(String groupId, String memberId);
|
||||
}
|
@ -0,0 +1,344 @@
|
||||
package cn.lili.modules.im.serviceimpl;
|
||||
import cn.lili.common.security.context.UserContext;
|
||||
import cn.lili.common.security.enums.UserEnums;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.common.utils.StringUtils;
|
||||
import cn.lili.modules.im.entity.dos.Friend;
|
||||
import cn.lili.modules.im.entity.vo.FriendVO;
|
||||
import cn.lili.modules.im.mapper.FriendMapper;
|
||||
import cn.lili.modules.im.service.FriendService;
|
||||
|
||||
import cn.lili.modules.member.entity.dos.Member;
|
||||
import cn.lili.modules.member.mapper.MemberMapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.sourceforge.pinyin4j.PinyinHelper;
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
|
||||
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static cn.hutool.extra.pinyin.PinyinUtil.getFirstLetter;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class FriendServiceImpl extends ServiceImpl<FriendMapper, Friend> implements FriendService {
|
||||
@Autowired
|
||||
private MemberMapper memberMapper;
|
||||
|
||||
@Override
|
||||
public List<FriendVO> getMutualFriends(String userId) {
|
||||
// 获取好友关系列表
|
||||
LambdaQueryWrapper<Friend> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(Friend::getUserId, userId)
|
||||
.eq(Friend::getStatus, 1); // 已确认的好友关系
|
||||
List<Friend> friends = this.list(queryWrapper);
|
||||
|
||||
|
||||
// 转换为 FriendVO 列表
|
||||
List<FriendVO> friendVOs = new ArrayList<>();
|
||||
for (Friend friend : friends) {
|
||||
FriendVO friendVO = new FriendVO();
|
||||
BeanUtils.copyProperties(friend, friendVO);
|
||||
|
||||
// 查询好友的详细信息
|
||||
Member member = memberMapper.selectById(friend.getFriendId());
|
||||
if (member != null) {
|
||||
// 复制会员信息到 VO
|
||||
friendVO.setUsername(member.getUsername());
|
||||
friendVO.setNickname(member.getNickName());
|
||||
friendVO.setFace(member.getFace());
|
||||
friendVO.setMobile(member.getMobile());
|
||||
friendVO.setEmail(member.getRegion());
|
||||
friendVO.setGender(member.getGradeId());
|
||||
friendVO.setBirthday(member.getBirthday());
|
||||
// 设置昵称首字母
|
||||
String firstLetter = getFirstLetter(member.getNickName());
|
||||
friendVO.setFirstLetter(firstLetter);
|
||||
}
|
||||
|
||||
friendVOs.add(friendVO);
|
||||
}
|
||||
// 按照昵称首字母排序
|
||||
Collections.sort(friendVOs, (a, b) -> {
|
||||
String letterA = a.getFirstLetter() != null ? a.getFirstLetter() : "#";
|
||||
String letterB = b.getFirstLetter() != null ? b.getFirstLetter() : "#";
|
||||
return letterA.compareTo(letterB);
|
||||
});
|
||||
|
||||
|
||||
return friendVOs;
|
||||
}
|
||||
/**
|
||||
* 获取字符串的首字母
|
||||
* @param str 字符串
|
||||
* @return 首字母(大写)
|
||||
*/
|
||||
private String getFirstLetter(String str) {
|
||||
if (StringUtils.isEmpty(str)) {
|
||||
return "#";
|
||||
}
|
||||
|
||||
try {
|
||||
// 创建 HanyuPinyinOutputFormat 对象
|
||||
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
|
||||
// 设置拼音小写
|
||||
format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
|
||||
// 设置声调不输出
|
||||
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
|
||||
|
||||
// 取第一个字符
|
||||
char firstChar = str.charAt(0);
|
||||
// 判断是否为汉字
|
||||
if (Character.toString(firstChar).matches("[\\u4E00-\\u9FA5]+")) {
|
||||
// 如果是汉字,转换为拼音
|
||||
String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(firstChar, format);
|
||||
if (pinyinArray != null && pinyinArray.length > 0) {
|
||||
return pinyinArray[0].substring(0, 1).toUpperCase();
|
||||
}
|
||||
} else if (Character.toString(firstChar).matches("[a-zA-Z]")) {
|
||||
// 如果是字母,直接返回大写
|
||||
return String.valueOf(firstChar).toUpperCase();
|
||||
}
|
||||
|
||||
// 其他情况返回 #
|
||||
return "#";
|
||||
} catch (BadHanyuPinyinOutputFormatCombination e) {
|
||||
log.error("获取拼音首字母失败", e);
|
||||
return "#";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FriendVO getFriendDetails(String friendId) {
|
||||
String userId = UserContext.getCurrentUser().getId();
|
||||
|
||||
// 查询好友关系
|
||||
LambdaQueryWrapper<Friend> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(Friend::getUserId, userId)
|
||||
.eq(Friend::getFriendId, friendId);
|
||||
Friend friend = this.getOne(queryWrapper);
|
||||
|
||||
if (friend == null) {
|
||||
throw new ServiceException("好友关系不存在");
|
||||
}
|
||||
|
||||
// 转换为 VO 并查询详细信息
|
||||
FriendVO friendVO = new FriendVO();
|
||||
BeanUtils.copyProperties(friend, friendVO);
|
||||
|
||||
// 查询好友的详细信息
|
||||
Member member = memberMapper.selectById(friendId);
|
||||
if (member != null) {
|
||||
// 复制会员信息到 VO
|
||||
friendVO.setUsername(member.getUsername());
|
||||
friendVO.setNickname(member.getNickName());
|
||||
friendVO.setFace(member.getFace());
|
||||
friendVO.setMobile(member.getMobile());
|
||||
friendVO.setEmail(member.getRegion());
|
||||
friendVO.setGender(member.getGradeId());
|
||||
friendVO.setBirthday(member.getBirthday());
|
||||
}
|
||||
|
||||
return friendVO;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
|
||||
public void removeFriend(String userId, String friendId) {
|
||||
|
||||
// 删除双向的好友关系
|
||||
|
||||
LambdaQueryWrapper<Friend> queryWrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
queryWrapper.and(wrapper -> wrapper
|
||||
|
||||
.or(w -> w.eq(Friend::getUserId, userId).eq(Friend::getFriendId, friendId))
|
||||
|
||||
.or(w -> w.eq(Friend::getUserId, friendId).eq(Friend::getFriendId, userId))
|
||||
|
||||
);
|
||||
|
||||
|
||||
|
||||
if (!this.remove(queryWrapper)) {
|
||||
|
||||
throw new ServiceException("解除好友关系失败");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
|
||||
public void addFriend(String userId, String friendId) {
|
||||
|
||||
// 检查用户ID是否存在
|
||||
|
||||
if (!isUserExists(userId)) {
|
||||
|
||||
throw new ServiceException("用户ID不存在");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 检查好友ID是否存在
|
||||
|
||||
if (!isUserExists(friendId)) {
|
||||
|
||||
throw new ServiceException("好友ID不存在");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 检查是否已经是好友
|
||||
|
||||
if (checkFriendship(userId, friendId)) {
|
||||
|
||||
throw new ServiceException("已经是好友关系");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 创建好友关系
|
||||
|
||||
Friend friend = new Friend();
|
||||
|
||||
friend.setUserId(userId);
|
||||
|
||||
friend.setFriendId(friendId);
|
||||
|
||||
friend.setStatus(1);
|
||||
|
||||
friend.setCreateTime(new Date());
|
||||
|
||||
friend.setUpdateTime(new Date());
|
||||
|
||||
|
||||
|
||||
// 保存双向好友关系
|
||||
|
||||
if (!this.save(friend)) {
|
||||
|
||||
throw new ServiceException("添加好友失败");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 创建反向好友关系
|
||||
|
||||
Friend reverseFriend = new Friend();
|
||||
|
||||
reverseFriend.setUserId(friendId);
|
||||
|
||||
reverseFriend.setFriendId(userId);
|
||||
|
||||
reverseFriend.setStatus(1);
|
||||
|
||||
reverseFriend.setCreateTime(new Date());
|
||||
|
||||
reverseFriend.setUpdateTime(new Date());
|
||||
|
||||
|
||||
|
||||
if (!this.save(reverseFriend)) {
|
||||
|
||||
throw new ServiceException("添加好友失败");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean isUserExists(String userId) {
|
||||
|
||||
return memberMapper.selectById(userId) != null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
|
||||
public void updateRemark(String userId, String friendId, String remark) {
|
||||
|
||||
LambdaQueryWrapper<Friend> queryWrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
queryWrapper.eq(Friend::getUserId, userId)
|
||||
|
||||
.eq(Friend::getFriendId, friendId);
|
||||
|
||||
|
||||
|
||||
Friend friend = this.getOne(queryWrapper);
|
||||
|
||||
if (friend == null) {
|
||||
|
||||
throw new ServiceException("好友关系不存在");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
friend.setRemark(remark);
|
||||
|
||||
friend.setUpdateTime(new Date());
|
||||
|
||||
|
||||
|
||||
if (!this.updateById(friend)) {
|
||||
|
||||
throw new ServiceException("更新好友备注失败");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
* 检查是否已经是好友关系
|
||||
|
||||
*/
|
||||
|
||||
private boolean checkFriendship(String userId, String friendId) {
|
||||
|
||||
LambdaQueryWrapper<Friend> queryWrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
queryWrapper.eq(Friend::getUserId, userId)
|
||||
|
||||
.eq(Friend::getFriendId, friendId)
|
||||
|
||||
.eq(Friend::getStatus, 1);
|
||||
|
||||
return this.count(queryWrapper) > 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,218 @@
|
||||
package cn.lili.modules.im.serviceimpl;
|
||||
|
||||
import cn.lili.common.security.context.UserContext;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.modules.im.entity.dos.ImGroup;
|
||||
import cn.lili.modules.im.entity.dos.ImGroupMember;
|
||||
import cn.lili.modules.im.mapper.ImGroupMapper;
|
||||
import cn.lili.modules.im.mapper.ImGroupMemberMapper;
|
||||
import cn.lili.modules.im.service.ImGroupService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ImGroupServiceImpl extends ServiceImpl<ImGroupMapper, ImGroup> implements ImGroupService {
|
||||
|
||||
private final ImGroupMemberMapper groupMemberMapper;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ImGroup createGroup(String groupName, List<String> memberIds) {
|
||||
String currentUserId = UserContext.getCurrentUser().getId();
|
||||
|
||||
// 创建群组
|
||||
ImGroup group = new ImGroup();
|
||||
group.setName(groupName);
|
||||
group.setOwnerId(currentUserId);
|
||||
group.setCreateTime(new Date());
|
||||
group.setUpdateTime(new Date());
|
||||
|
||||
if (!this.save(group)) {
|
||||
throw new ServiceException("创建群聊失败");
|
||||
}
|
||||
|
||||
// 添加群主为成员
|
||||
addGroupMember(group.getId(), currentUserId, 2);
|
||||
|
||||
// 添加其他成员
|
||||
if (memberIds != null && !memberIds.isEmpty()) {
|
||||
for (String memberId : memberIds) {
|
||||
addGroupMember(group.getId(), memberId, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void dismissGroup(String groupId) {
|
||||
String currentUserId = UserContext.getCurrentUser().getId();
|
||||
|
||||
// 检查是否是群主
|
||||
ImGroupMember owner = getGroupMember(groupId, currentUserId);
|
||||
if (owner == null || owner.getRole() != 2) {
|
||||
throw new ServiceException("只有群主能解散群聊");
|
||||
}
|
||||
|
||||
// 删除群成员
|
||||
LambdaQueryWrapper<ImGroupMember> memberWrapper = new LambdaQueryWrapper<>();
|
||||
memberWrapper.eq(ImGroupMember::getGroupId, groupId);
|
||||
groupMemberMapper.delete(memberWrapper);
|
||||
|
||||
// 删除群组
|
||||
this.removeById(groupId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void inviteMembers(String groupId, List<String> memberIds) {
|
||||
String currentUserId = UserContext.getCurrentUser().getId();
|
||||
|
||||
// 检查权限
|
||||
ImGroupMember operator = getGroupMember(groupId, currentUserId);
|
||||
if (operator == null || operator.getRole() < 1) {
|
||||
throw new ServiceException("没有邀请权限");
|
||||
}
|
||||
|
||||
// 添加成员
|
||||
for (String memberId : memberIds) {
|
||||
if (getGroupMember(groupId, memberId) == null) {
|
||||
addGroupMember(groupId, memberId, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void setAdmin(String groupId, String memberId) {
|
||||
String currentUserId = UserContext.getCurrentUser().getId();
|
||||
|
||||
// 检查是否是群主
|
||||
ImGroupMember owner = getGroupMember(groupId, currentUserId);
|
||||
if (owner == null || owner.getRole() != 2) {
|
||||
throw new ServiceException("只有群主能设置管理员");
|
||||
}
|
||||
|
||||
// 设置管理员
|
||||
ImGroupMember member = getGroupMember(groupId, memberId);
|
||||
if (member == null) {
|
||||
throw new ServiceException("该成员不在群中");
|
||||
}
|
||||
|
||||
member.setRole(1);
|
||||
member.setUpdateTime(new Date());
|
||||
groupMemberMapper.updateById(member);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void removeAdmin(String groupId, String memberId) {
|
||||
String currentUserId = UserContext.getCurrentUser().getId();
|
||||
|
||||
// 检查是否是群主
|
||||
ImGroupMember owner = getGroupMember(groupId, currentUserId);
|
||||
if (owner == null || owner.getRole() != 2) {
|
||||
throw new ServiceException("只有群主能取消管理员");
|
||||
}
|
||||
|
||||
// 取消管理员
|
||||
ImGroupMember member = getGroupMember(groupId, memberId);
|
||||
if (member == null) {
|
||||
throw new ServiceException("该成员不在群中");
|
||||
}
|
||||
|
||||
member.setRole(0);
|
||||
member.setUpdateTime(new Date());
|
||||
groupMemberMapper.updateById(member);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void muteMember(String groupId, String memberId, Integer duration) {
|
||||
String currentUserId = UserContext.getCurrentUser().getId();
|
||||
|
||||
// 检查操作权限
|
||||
ImGroupMember operator = getGroupMember(groupId, currentUserId);
|
||||
if (operator == null || operator.getRole() < 1) {
|
||||
throw new ServiceException("没有禁言权限");
|
||||
}
|
||||
|
||||
// 检查被禁言成员
|
||||
ImGroupMember member = getGroupMember(groupId, memberId);
|
||||
if (member == null) {
|
||||
throw new ServiceException("该成员不在群中");
|
||||
}
|
||||
|
||||
// 管理员不能禁言群主和其他管理员
|
||||
if (operator.getRole() == 1 && member.getRole() > 0) {
|
||||
throw new ServiceException("没有权限禁言该成员");
|
||||
}
|
||||
|
||||
// 设置禁言
|
||||
member.setIsMuted(1);
|
||||
member.setMuteEndTime(new Date(System.currentTimeMillis() + duration * 60 * 1000));
|
||||
member.setUpdateTime(new Date());
|
||||
groupMemberMapper.updateById(member);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void unmuteMember(String groupId, String memberId) {
|
||||
String currentUserId = UserContext.getCurrentUser().getId();
|
||||
|
||||
// 检查操作权限
|
||||
ImGroupMember operator = getGroupMember(groupId, currentUserId);
|
||||
if (operator == null || operator.getRole() < 1) {
|
||||
throw new ServiceException("没有解除禁言权限");
|
||||
}
|
||||
|
||||
// 检查被解除禁言成员
|
||||
ImGroupMember member = getGroupMember(groupId, memberId);
|
||||
if (member == null) {
|
||||
throw new ServiceException("该成员不在群中");
|
||||
}
|
||||
|
||||
// 管理员不能解除群主和其他管理员的禁言
|
||||
if (operator.getRole() == 1 && member.getRole() > 0) {
|
||||
throw new ServiceException("没有权限解除该成员的禁言");
|
||||
}
|
||||
|
||||
// 解除禁言
|
||||
member.setIsMuted(0);
|
||||
member.setMuteEndTime(null);
|
||||
member.setUpdateTime(new Date());
|
||||
groupMemberMapper.updateById(member);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加群成员
|
||||
*/
|
||||
private void addGroupMember(String groupId, String memberId, Integer role) {
|
||||
ImGroupMember member = new ImGroupMember();
|
||||
member.setGroupId(groupId);
|
||||
member.setMemberId(memberId);
|
||||
member.setRole(role);
|
||||
member.setIsMuted(0);
|
||||
member.setJoinTime(new Date());
|
||||
member.setUpdateTime(new Date());
|
||||
groupMemberMapper.insert(member);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取群成员信息
|
||||
*/
|
||||
private ImGroupMember getGroupMember(String groupId, String memberId) {
|
||||
LambdaQueryWrapper<ImGroupMember> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(ImGroupMember::getGroupId, groupId)
|
||||
.eq(ImGroupMember::getMemberId, memberId);
|
||||
return groupMemberMapper.selectOne(queryWrapper);
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.mapstruct.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -17,7 +18,9 @@ import java.util.List;
|
||||
*
|
||||
* @author Bulbasaur
|
||||
* @since 2020-02-25 14:10:16
|
||||
* @
|
||||
*/
|
||||
@Mapper
|
||||
public interface MemberMapper extends BaseMapper<Member> {
|
||||
|
||||
/**
|
||||
|
100
im-api/src/main/java/cn/lili/controller/im/FriendController.java
Normal file
100
im-api/src/main/java/cn/lili/controller/im/FriendController.java
Normal file
@ -0,0 +1,100 @@
|
||||
package cn.lili.controller.im;
|
||||
|
||||
import cn.lili.common.enums.ResultCode;
|
||||
import cn.lili.common.enums.ResultUtil;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.common.security.AuthUser;
|
||||
import cn.lili.common.security.context.UserContext;
|
||||
import cn.lili.common.vo.ResultMessage;
|
||||
import cn.lili.modules.im.entity.dos.Friend;
|
||||
import cn.lili.modules.im.entity.vo.FriendVO;
|
||||
import cn.lili.modules.im.service.FriendService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
* @author Chopper
|
||||
|
||||
*/
|
||||
|
||||
@RestController
|
||||
|
||||
@Api(tags = "好友管理接口")
|
||||
|
||||
@RequestMapping("/im/friend")
|
||||
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
|
||||
public class FriendController {
|
||||
|
||||
|
||||
|
||||
private final FriendService friendService;
|
||||
|
||||
|
||||
@GetMapping("/mutual")
|
||||
@ApiOperation(value = "查看所有互相关注好友")
|
||||
public ResultMessage<List<FriendVO>> getMutualFriends() {
|
||||
AuthUser currentUser = UserContext.getCurrentUser();
|
||||
if (currentUser == null) {
|
||||
throw new ServiceException(ResultCode.USER_NOT_LOGIN);
|
||||
}
|
||||
List<FriendVO> friends = friendService.getMutualFriends(currentUser.getId());
|
||||
return ResultUtil.data(friends);
|
||||
}
|
||||
|
||||
@GetMapping("/{friendId}")
|
||||
@ApiOperation(value = "查看好友资料")
|
||||
public ResultMessage<FriendVO> getFriendDetails(@PathVariable String friendId) {
|
||||
AuthUser currentUser = UserContext.getCurrentUser();
|
||||
if (currentUser == null) {
|
||||
throw new ServiceException(ResultCode.USER_NOT_LOGIN);
|
||||
}
|
||||
FriendVO friend = friendService.getFriendDetails(friendId);
|
||||
return ResultUtil.data(friend);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{friendId}")
|
||||
@ApiOperation(value = "解除好友关系")
|
||||
public ResultMessage<Object> removeFriend(@PathVariable String friendId) {
|
||||
AuthUser currentUser = UserContext.getCurrentUser();
|
||||
if (currentUser == null) {
|
||||
throw new ServiceException(ResultCode.USER_NOT_LOGIN);
|
||||
}
|
||||
friendService.removeFriend(currentUser.getId(), friendId);
|
||||
return ResultUtil.success();
|
||||
}
|
||||
|
||||
@PostMapping("/add/{friendId}")
|
||||
@ApiOperation(value = "添加好友")
|
||||
public ResultMessage<Object> addFriend(@PathVariable String friendId) {
|
||||
AuthUser currentUser = UserContext.getCurrentUser();
|
||||
if (currentUser == null) {
|
||||
throw new ServiceException(ResultCode.USER_NOT_LOGIN);
|
||||
}
|
||||
friendService.addFriend(currentUser.getId(), friendId);
|
||||
return ResultUtil.success();
|
||||
}
|
||||
|
||||
@PutMapping("/remark/{friendId}")
|
||||
@ApiOperation(value = "更新好友备注")
|
||||
public ResultMessage<Object> updateRemark(@PathVariable String friendId, @RequestParam String remark) {
|
||||
AuthUser currentUser = UserContext.getCurrentUser();
|
||||
if (currentUser == null) {
|
||||
throw new ServiceException(ResultCode.USER_NOT_LOGIN);
|
||||
}
|
||||
friendService.updateRemark(currentUser.getId(), friendId, remark);
|
||||
return ResultUtil.success();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package cn.lili.controller.im;
|
||||
|
||||
|
||||
|
||||
import cn.lili.common.enums.ResultUtil;
|
||||
import cn.lili.common.vo.ResultMessage;
|
||||
import cn.lili.modules.im.entity.dos.ImGroup;
|
||||
import cn.lili.modules.im.service.ImGroupService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@Api(tags = "群聊管理接口")
|
||||
@RequestMapping("/im/group")
|
||||
@RequiredArgsConstructor
|
||||
public class ImGroupController {
|
||||
|
||||
private final ImGroupService imGroupService;
|
||||
|
||||
@PostMapping
|
||||
@ApiOperation(value = "创建群聊")
|
||||
public ResultMessage<ImGroup> createGroup(@RequestParam String groupName,
|
||||
@RequestParam(required = false) List<String> memberIds) {
|
||||
ImGroup group = imGroupService.createGroup(groupName, memberIds);
|
||||
return ResultUtil.data(group);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{groupId}")
|
||||
@ApiOperation(value = "解散群聊")
|
||||
public ResultMessage<Void> dismissGroup(@PathVariable String groupId) {
|
||||
imGroupService.dismissGroup(groupId);
|
||||
return ResultUtil.success();
|
||||
}
|
||||
|
||||
@PostMapping("/{groupId}/invite")
|
||||
@ApiOperation(value = "邀请成员")
|
||||
public ResultMessage<Void> inviteMembers(@PathVariable String groupId,
|
||||
@RequestParam List<String> memberIds) {
|
||||
imGroupService.inviteMembers(groupId, memberIds);
|
||||
return ResultUtil.success();
|
||||
}
|
||||
|
||||
@PostMapping("/{groupId}/admin/{memberId}")
|
||||
@ApiOperation(value = "设置管理员")
|
||||
public ResultMessage<Void> setAdmin(@PathVariable String groupId,
|
||||
@PathVariable String memberId) {
|
||||
imGroupService.setAdmin(groupId, memberId);
|
||||
return ResultUtil.success();
|
||||
}
|
||||
|
||||
@DeleteMapping("/{groupId}/admin/{memberId}")
|
||||
@ApiOperation(value = "取消管理员")
|
||||
public ResultMessage<Void> removeAdmin(@PathVariable String groupId,
|
||||
@PathVariable String memberId) {
|
||||
imGroupService.removeAdmin(groupId, memberId);
|
||||
return ResultUtil.success();
|
||||
}
|
||||
|
||||
@PostMapping("/{groupId}/mute/{memberId}")
|
||||
@ApiOperation(value = "禁言成员")
|
||||
public ResultMessage<Void> muteMember(@PathVariable String groupId,
|
||||
@PathVariable String memberId,
|
||||
@RequestParam Integer duration) {
|
||||
imGroupService.muteMember(groupId, memberId, duration);
|
||||
return ResultUtil.success();
|
||||
}
|
||||
|
||||
@DeleteMapping("/{groupId}/mute/{memberId}")
|
||||
@ApiOperation(value = "解除成员禁言")
|
||||
public ResultMessage<Void> unmuteMember(@PathVariable String groupId,
|
||||
@PathVariable String memberId) {
|
||||
imGroupService.unmuteMember(groupId, memberId);
|
||||
return ResultUtil.success();
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
|
@ -0,0 +1 @@
|
||||
|
Loading…
x
Reference in New Issue
Block a user