mirror of
https://github.com/zongzibinbin/MallChat.git
synced 2026-03-14 22:23:42 +08:00
单聊群聊功能提交
This commit is contained in:
@@ -9,6 +9,9 @@ import com.abin.mallchat.common.common.utils.CursorUtils;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 会话列表 服务实现类
|
||||
@@ -71,4 +74,18 @@ public class ContactDao extends ServiceImpl<ContactMapper, Contact> {
|
||||
wrapper.eq(Contact::getUid, uid);
|
||||
}, Contact::getActiveTime);
|
||||
}
|
||||
|
||||
public List<Contact> getByRoomIds(List<Long> roomIds, Long uid) {
|
||||
return lambdaQuery()
|
||||
.eq(Contact::getRoomId, roomIds)
|
||||
.eq(Contact::getUid, uid)
|
||||
.list();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新所有人的会话时间,没有就直接插入
|
||||
*/
|
||||
public void refreshOrCreateActiveTime(Long roomId, List<Long> memberUidList, Long msgId, Date activeTime) {
|
||||
baseMapper.refreshOrCreateActiveTime(roomId, memberUidList, msgId, activeTime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package com.abin.mallchat.common.chat.dao;
|
||||
|
||||
import com.abin.mallchat.common.chat.domain.entity.GroupMember;
|
||||
import com.abin.mallchat.common.chat.domain.enums.GroupRoleEnum;
|
||||
import com.abin.mallchat.common.chat.mapper.GroupMemberMapper;
|
||||
import com.abin.mallchat.common.chat.service.IGroupMemberService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 群成员表 服务实现类
|
||||
@@ -15,6 +18,36 @@ import org.springframework.stereotype.Service;
|
||||
* @since 2023-07-16
|
||||
*/
|
||||
@Service
|
||||
public class GroupMemberDao extends ServiceImpl<GroupMemberMapper, GroupMember> implements IGroupMemberService {
|
||||
public class GroupMemberDao extends ServiceImpl<GroupMemberMapper, GroupMember> {
|
||||
|
||||
public List<Long> getMemberUidList(Long groupId) {
|
||||
List<GroupMember> list = lambdaQuery()
|
||||
.eq(GroupMember::getGroupId, groupId)
|
||||
.select(GroupMember::getUid)
|
||||
.list();
|
||||
return list.stream().map(GroupMember::getUid).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<Long> getMemberBatch(Long groupId, List<Long> uidList) {
|
||||
List<GroupMember> list = lambdaQuery()
|
||||
.eq(GroupMember::getGroupId, groupId)
|
||||
.in(GroupMember::getUid, uidList)
|
||||
.select(GroupMember::getUid)
|
||||
.list();
|
||||
return list.stream().map(GroupMember::getUid).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public GroupMember getMember(Long groupId, Long uid) {
|
||||
return lambdaQuery()
|
||||
.eq(GroupMember::getGroupId, groupId)
|
||||
.eq(GroupMember::getUid, uid)
|
||||
.one();
|
||||
}
|
||||
|
||||
public List<GroupMember> getSelfGroup(Long uid) {
|
||||
return lambdaQuery()
|
||||
.eq(GroupMember::getUid, uid)
|
||||
.eq(GroupMember::getRole, GroupRoleEnum.LEADER.getType())
|
||||
.list();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,9 @@ import com.abin.mallchat.common.common.utils.CursorUtils;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 消息表 服务实现类
|
||||
@@ -52,4 +55,11 @@ public class MessageDao extends ServiceImpl<MessageMapper, Message> {
|
||||
.set(Message::getStatus, MessageStatusEnum.DELETE.getStatus())
|
||||
.update();
|
||||
}
|
||||
|
||||
public Integer getUnReadCount(Long roomId, Date readTime) {
|
||||
return lambdaQuery()
|
||||
.eq(Message::getRoomId, roomId)
|
||||
.gt(Objects.nonNull(readTime), Message::getCreateTime, readTime)
|
||||
.count();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 房间表 服务实现类
|
||||
@@ -17,4 +19,11 @@ import org.springframework.stereotype.Service;
|
||||
@Service
|
||||
public class RoomDao extends ServiceImpl<RoomMapper, Room> implements IService<Room> {
|
||||
|
||||
public void refreshActiveTime(Long roomId, Long msgId, Date msgTime) {
|
||||
lambdaUpdate()
|
||||
.eq(Room::getId, roomId)
|
||||
.set(Room::getLastMsgId, msgId)
|
||||
.set(Room::getActiveTime, msgTime)
|
||||
.update();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.List;
|
||||
public class RoomFriendDao extends ServiceImpl<RoomFriendMapper, RoomFriend> {
|
||||
|
||||
public RoomFriend getByKey(String key) {
|
||||
return lambdaQuery().eq(RoomFriend::getKey, key).one();
|
||||
return lambdaQuery().eq(RoomFriend::getRoomKey, key).one();
|
||||
}
|
||||
|
||||
public void restoreRoom(Long id) {
|
||||
@@ -32,7 +32,13 @@ public class RoomFriendDao extends ServiceImpl<RoomFriendMapper, RoomFriend> {
|
||||
|
||||
public List<RoomFriend> listByRoomIds(List<Long> roomIds) {
|
||||
return lambdaQuery()
|
||||
.eq(RoomFriend::getRoomId, roomIds)
|
||||
.in(RoomFriend::getRoomId, roomIds)
|
||||
.list();
|
||||
}
|
||||
|
||||
public RoomFriend getByRoomId(Long roomID) {
|
||||
return lambdaQuery()
|
||||
.eq(RoomFriend::getRoomId, roomID)
|
||||
.one();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,4 +23,10 @@ public class RoomGroupDao extends ServiceImpl<RoomGroupMapper, RoomGroup> {
|
||||
.in(RoomGroup::getRoomId, roomIds)
|
||||
.list();
|
||||
}
|
||||
|
||||
public RoomGroup getByRoomId(Long roomId) {
|
||||
return lambdaQuery()
|
||||
.eq(RoomGroup::getRoomId, roomId)
|
||||
.one();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package com.abin.mallchat.common.chat.domain.dto;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Description: 房间详情
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
@@ -16,4 +19,27 @@ public class RoomBaseInfo {
|
||||
private String name;
|
||||
@ApiModelProperty("会话头像")
|
||||
private String avatar;
|
||||
/**
|
||||
* 房间类型 1群聊 2单聊
|
||||
*/
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 是否全员展示 0否 1是
|
||||
*
|
||||
* @see com.abin.mallchat.common.chat.domain.enums.HotFlagEnum
|
||||
*/
|
||||
private Integer hotFlag;
|
||||
|
||||
/**
|
||||
* 群最后消息的更新时间
|
||||
*/
|
||||
@TableField("active_time")
|
||||
private Date activeTime;
|
||||
|
||||
/**
|
||||
* 最后一条消息id
|
||||
*/
|
||||
@TableField("last_msg_id")
|
||||
private Long lastMsgId;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -47,13 +47,13 @@ public class Contact implements Serializable {
|
||||
* 阅读到的时间
|
||||
*/
|
||||
@TableField("read_time")
|
||||
private LocalDateTime readTime;
|
||||
private Date readTime;
|
||||
|
||||
/**
|
||||
* 会话内消息最后更新的时间(只有普通会话需要维护,全员会话不需要维护)
|
||||
*/
|
||||
@TableField("active_time")
|
||||
private LocalDateTime activeTime;
|
||||
private Date activeTime;
|
||||
|
||||
/**
|
||||
* 最后一条消息id
|
||||
@@ -65,13 +65,13 @@ public class Contact implements Serializable {
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("create_time")
|
||||
private LocalDateTime createTime;
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@TableField("update_time")
|
||||
private LocalDateTime updateTime;
|
||||
private Date updateTime;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -4,11 +4,10 @@ import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -21,6 +20,9 @@ import java.time.LocalDateTime;
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@TableName("group_member")
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class GroupMember implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@@ -32,10 +34,10 @@ public class GroupMember implements Serializable {
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 房间id
|
||||
* 群组id
|
||||
*/
|
||||
@TableField("room_id")
|
||||
private Long roomId;
|
||||
@TableField("group_id")
|
||||
private Long groupId;
|
||||
|
||||
/**
|
||||
* 成员uid
|
||||
@@ -44,7 +46,9 @@ public class GroupMember implements Serializable {
|
||||
private Long uid;
|
||||
|
||||
/**
|
||||
* 成员角色1群主 2管理员 3普通成员
|
||||
* 成员角色1群主(可撤回,可移除,可解散) 2管理员(可撤回,可移除) 3普通成员
|
||||
*
|
||||
* @see com.abin.mallchat.common.chat.domain.enums.GroupRoleEnum
|
||||
*/
|
||||
@TableField("role")
|
||||
private Integer role;
|
||||
@@ -53,13 +57,13 @@ public class GroupMember implements Serializable {
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("create_time")
|
||||
private LocalDateTime createTime;
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@TableField("update_time")
|
||||
private LocalDateTime updateTime;
|
||||
private Date updateTime;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -32,6 +32,8 @@ public class Room implements Serializable {
|
||||
|
||||
/**
|
||||
* 房间类型 1群聊 2单聊
|
||||
*
|
||||
* @see com.abin.mallchat.common.chat.domain.enums.RoomTypeEnum
|
||||
*/
|
||||
@TableField("type")
|
||||
private Integer type;
|
||||
@@ -48,7 +50,13 @@ public class Room implements Serializable {
|
||||
* 群最后消息的更新时间(热点群不需要写扩散,更新这里就行)
|
||||
*/
|
||||
@TableField("active_time")
|
||||
private LocalDateTime activeTime;
|
||||
private Date activeTime;
|
||||
|
||||
/**
|
||||
* 最后一条消息id
|
||||
*/
|
||||
@TableField("last_msg_id")
|
||||
private Long lastMsgId;
|
||||
|
||||
/**
|
||||
* 额外信息(根据不同类型房间有不同存储的东西)
|
||||
@@ -60,13 +68,13 @@ public class Room implements Serializable {
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("create_time")
|
||||
private LocalDateTime createTime;
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@TableField("update_time")
|
||||
private LocalDateTime updateTime;
|
||||
private Date updateTime;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -52,8 +52,8 @@ public class RoomFriend implements Serializable {
|
||||
/**
|
||||
* 房间key由两个uid拼接,先做排序uid1_uid2
|
||||
*/
|
||||
@TableField("key")
|
||||
private String key;
|
||||
@TableField("room_key")
|
||||
private String roomKey;
|
||||
|
||||
/**
|
||||
* 房间状态 0正常 1禁用(删好友了禁用)
|
||||
@@ -65,12 +65,12 @@ public class RoomFriend implements Serializable {
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("create_time")
|
||||
private LocalDateTime createTime;
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@TableField("update_time")
|
||||
private LocalDateTime updateTime;
|
||||
private Date updateTime;
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -63,13 +63,13 @@ public class RoomGroup implements Serializable {
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("create_time")
|
||||
private LocalDateTime createTime;
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@TableField("update_time")
|
||||
private LocalDateTime updateTime;
|
||||
private Date updateTime;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.abin.mallchat.common.chat.domain.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Description: 成员角色枚举
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-19
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum GroupRoleEnum {
|
||||
LEADER(1, "群主"),
|
||||
MANAGER(2, "管理"),
|
||||
MEMBER(3, "普通成员"),
|
||||
;
|
||||
|
||||
private final Integer type;
|
||||
private final String desc;
|
||||
|
||||
private static Map<Integer, GroupRoleEnum> cache;
|
||||
|
||||
static {
|
||||
cache = Arrays.stream(GroupRoleEnum.values()).collect(Collectors.toMap(GroupRoleEnum::getType, Function.identity()));
|
||||
}
|
||||
|
||||
public static GroupRoleEnum of(Integer type) {
|
||||
return cache.get(type);
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ public enum MessageTypeEnum {
|
||||
SOUND(5, "语音"),
|
||||
VIDEO(6, "视频"),
|
||||
EMOJI(7, "表情"),
|
||||
SYSTEM(8, "系统消息"),
|
||||
;
|
||||
|
||||
private final Integer type;
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.abin.mallchat.common.chat.domain.vo.response;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Description: 消息
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-23
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ChatMessageResp {
|
||||
|
||||
@ApiModelProperty("发送者信息")
|
||||
private UserInfo fromUser;
|
||||
@ApiModelProperty("消息详情")
|
||||
private Message message;
|
||||
|
||||
@Data
|
||||
public static class UserInfo {
|
||||
@ApiModelProperty("用户id")
|
||||
private Long uid;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class Message {
|
||||
@ApiModelProperty("消息id")
|
||||
private Long id;
|
||||
@ApiModelProperty("消息发送时间")
|
||||
private Date sendTime;
|
||||
@ApiModelProperty("消息类型 1正常文本 2.撤回消息")
|
||||
private Integer type;
|
||||
@ApiModelProperty("消息内容不同的消息类型,内容体不同,见https://www.yuque.com/snab/mallcaht/rkb2uz5k1qqdmcmd")
|
||||
private Object body;
|
||||
@ApiModelProperty("消息标记")
|
||||
private MessageMark messageMark;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class MessageMark {
|
||||
@ApiModelProperty("点赞数")
|
||||
private Integer likeCount;
|
||||
@ApiModelProperty("该用户是否已经点赞 0否 1是")
|
||||
private Integer userLike;
|
||||
@ApiModelProperty("举报数")
|
||||
private Integer dislikeCount;
|
||||
@ApiModelProperty("该用户是否已经举报 0否 1是")
|
||||
private Integer userDislike;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,10 @@ package com.abin.mallchat.common.chat.mapper;
|
||||
|
||||
import com.abin.mallchat.common.chat.domain.entity.Contact;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -13,4 +17,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
*/
|
||||
public interface ContactMapper extends BaseMapper<Contact> {
|
||||
|
||||
void refreshOrCreateActiveTime(@Param("roomId") Long roomId, @Param("memberUidList") List<Long> memberUidList, @Param("msgId") Long msgId, @Param("activeTime") Date activeTime);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.abin.mallchat.common.chat.service;
|
||||
|
||||
import com.abin.mallchat.common.chat.domain.entity.RoomFriend;
|
||||
import com.abin.mallchat.common.chat.domain.entity.RoomGroup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -15,4 +16,9 @@ public interface RoomService {
|
||||
* 创建一个单聊房间
|
||||
*/
|
||||
RoomFriend createFriendRoom(List<Long> uidList);
|
||||
|
||||
/**
|
||||
* 创建一个群聊房间
|
||||
*/
|
||||
RoomGroup createGroupRoom(Long uid);
|
||||
}
|
||||
|
||||
@@ -3,9 +3,11 @@ package com.abin.mallchat.common.chat.service.adapter;
|
||||
import com.abin.mallchat.common.chat.domain.entity.Contact;
|
||||
import com.abin.mallchat.common.chat.domain.entity.Room;
|
||||
import com.abin.mallchat.common.chat.domain.entity.RoomFriend;
|
||||
import com.abin.mallchat.common.chat.domain.entity.RoomGroup;
|
||||
import com.abin.mallchat.common.chat.domain.enums.HotFlagEnum;
|
||||
import com.abin.mallchat.common.chat.domain.enums.RoomTypeEnum;
|
||||
import com.abin.mallchat.common.common.domain.enums.NormalOrNoEnum;
|
||||
import com.abin.mallchat.common.user.domain.entity.User;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -41,7 +43,7 @@ public class ChatAdapter {
|
||||
roomFriend.setRoomId(roomId);
|
||||
roomFriend.setUid1(collect.get(0));
|
||||
roomFriend.setUid2(collect.get(1));
|
||||
roomFriend.setKey(generateRoomKey(uidList));
|
||||
roomFriend.setRoomKey(generateRoomKey(uidList));
|
||||
roomFriend.setStatus(NormalOrNoEnum.NORMAL.getStatus());
|
||||
return roomFriend;
|
||||
}
|
||||
@@ -65,4 +67,12 @@ public class ChatAdapter {
|
||||
public static Long getFriendUid(RoomFriend roomFriend, Long uid) {
|
||||
return Objects.equals(uid, roomFriend.getUid1()) ? roomFriend.getUid2() : roomFriend.getUid1();
|
||||
}
|
||||
|
||||
public static RoomGroup buildGroupRoom(User user, Long roomId) {
|
||||
RoomGroup roomGroup = new RoomGroup();
|
||||
roomGroup.setName(user.getName() + "的群组");
|
||||
roomGroup.setAvatar(user.getAvatar());
|
||||
roomGroup.setRoomId(roomId);
|
||||
return roomGroup;
|
||||
}
|
||||
}
|
||||
|
||||
44
mallchat-common/src/main/java/com/abin/mallchat/common/chat/service/cache/GroupMemberCache.java
vendored
Normal file
44
mallchat-common/src/main/java/com/abin/mallchat/common/chat/service/cache/GroupMemberCache.java
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
package com.abin.mallchat.common.chat.service.cache;
|
||||
|
||||
import com.abin.mallchat.common.chat.dao.GroupMemberDao;
|
||||
import com.abin.mallchat.common.chat.dao.MessageDao;
|
||||
import com.abin.mallchat.common.chat.dao.RoomGroupDao;
|
||||
import com.abin.mallchat.common.chat.domain.entity.RoomGroup;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Description: 群成员相关缓存
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-27
|
||||
*/
|
||||
@Component
|
||||
public class GroupMemberCache {
|
||||
|
||||
@Autowired
|
||||
private MessageDao messageDao;
|
||||
@Autowired
|
||||
private RoomGroupDao roomGroupDao;
|
||||
@Autowired
|
||||
private GroupMemberDao groupMemberDao;
|
||||
|
||||
@Cacheable(cacheNames = "member", key = "'groupMember'+#roomId")
|
||||
public List<Long> getMemberUidList(Long roomId) {
|
||||
RoomGroup roomGroup = roomGroupDao.getByRoomId(roomId);
|
||||
if (Objects.isNull(roomGroup)) {
|
||||
return null;
|
||||
}
|
||||
return groupMemberDao.getMemberUidList(roomGroup.getId());
|
||||
}
|
||||
|
||||
@CacheEvict(cacheNames = "member", key = "'groupMember'+#roomId")
|
||||
public List<Long> evictMemberUidList(Long roomId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
42
mallchat-common/src/main/java/com/abin/mallchat/common/chat/service/cache/HotRoomCache.java
vendored
Normal file
42
mallchat-common/src/main/java/com/abin/mallchat/common/chat/service/cache/HotRoomCache.java
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
package com.abin.mallchat.common.chat.service.cache;
|
||||
|
||||
import cn.hutool.core.lang.Pair;
|
||||
import com.abin.mallchat.common.common.constant.RedisKey;
|
||||
import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq;
|
||||
import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp;
|
||||
import com.abin.mallchat.common.common.utils.CursorUtils;
|
||||
import com.abin.mallchat.common.common.utils.RedisUtils;
|
||||
import org.springframework.data.redis.core.ZSetOperations;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Description: 全局房间
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-07-23
|
||||
*/
|
||||
@Component
|
||||
public class HotRoomCache {
|
||||
|
||||
/**
|
||||
* 获取热门群聊翻页
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public CursorPageBaseResp<Pair<Long, Double>> getRoomCursorPage(CursorPageBaseReq pageBaseReq) {
|
||||
return CursorUtils.getCursorPageByRedis(pageBaseReq, RedisKey.getKey(RedisKey.HOT_ROOM_ZET), Long::parseLong);
|
||||
}
|
||||
|
||||
public Set<ZSetOperations.TypedTuple<String>> getRoomRange(Double hotStart, Double hotEnd) {
|
||||
return RedisUtils.zRangeByScoreWithScores(RedisKey.getKey(RedisKey.HOT_ROOM_ZET), hotStart, hotEnd);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新热门群聊的最新时间
|
||||
*/
|
||||
public void refreshActiveTime(Long roomId, Date refreshTime) {
|
||||
RedisUtils.zAdd(RedisKey.getKey(RedisKey.HOT_ROOM_ZET), roomId, (double) refreshTime.getTime());
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package com.abin.mallchat.common.chat.service.cache;
|
||||
|
||||
import com.abin.mallchat.common.chat.dao.MessageDao;
|
||||
import com.abin.mallchat.common.chat.domain.entity.Message;
|
||||
import com.abin.mallchat.common.common.utils.CursorUtils;
|
||||
import com.abin.mallchat.common.user.dao.BlackDao;
|
||||
import com.abin.mallchat.common.user.dao.RoleDao;
|
||||
import com.abin.mallchat.common.user.dao.UserDao;
|
||||
@@ -19,8 +18,6 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
public class MsgCache {
|
||||
|
||||
@Autowired
|
||||
private CursorUtils cursorUtils;
|
||||
@Autowired
|
||||
private UserDao userDao;
|
||||
@Autowired
|
||||
|
||||
@@ -23,8 +23,8 @@ public class RoomGroupCache extends AbstractRedisStringCache<Long, RoomGroup> {
|
||||
private RoomGroupDao roomGroupDao;
|
||||
|
||||
@Override
|
||||
protected String getKey(Long groupId) {
|
||||
return RedisKey.getKey(RedisKey.GROUP_INFO_STRING, groupId);
|
||||
protected String getKey(Long roomId) {
|
||||
return RedisKey.getKey(RedisKey.GROUP_INFO_STRING, roomId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
package com.abin.mallchat.common.chat.service.impl;
|
||||
|
||||
import com.abin.mallchat.common.chat.dao.GroupMemberDao;
|
||||
import com.abin.mallchat.common.chat.dao.RoomDao;
|
||||
import com.abin.mallchat.common.chat.dao.RoomFriendDao;
|
||||
import com.abin.mallchat.common.chat.dao.RoomGroupDao;
|
||||
import com.abin.mallchat.common.chat.domain.entity.GroupMember;
|
||||
import com.abin.mallchat.common.chat.domain.entity.Room;
|
||||
import com.abin.mallchat.common.chat.domain.entity.RoomFriend;
|
||||
import com.abin.mallchat.common.chat.domain.entity.RoomGroup;
|
||||
import com.abin.mallchat.common.chat.domain.enums.GroupRoleEnum;
|
||||
import com.abin.mallchat.common.chat.domain.enums.RoomTypeEnum;
|
||||
import com.abin.mallchat.common.chat.service.RoomService;
|
||||
import com.abin.mallchat.common.chat.service.adapter.ChatAdapter;
|
||||
import com.abin.mallchat.common.common.domain.enums.NormalOrNoEnum;
|
||||
import com.abin.mallchat.common.common.utils.AssertUtil;
|
||||
import com.abin.mallchat.common.user.domain.entity.User;
|
||||
import com.abin.mallchat.common.user.service.cache.UserInfoCache;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -28,6 +35,12 @@ public class RoomServiceImpl implements RoomService {
|
||||
private RoomFriendDao roomFriendDao;
|
||||
@Autowired
|
||||
private RoomDao roomDao;
|
||||
@Autowired
|
||||
private GroupMemberDao groupMemberDao;
|
||||
@Autowired
|
||||
private UserInfoCache userInfoCache;
|
||||
@Autowired
|
||||
private RoomGroupDao roomGroupDao;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@@ -40,12 +53,32 @@ public class RoomServiceImpl implements RoomService {
|
||||
if (Objects.nonNull(roomFriend)) { //如果存在房间就恢复,适用于恢复好友场景
|
||||
restoreRoomIfNeed(roomFriend);
|
||||
} else {//新建房间
|
||||
Room room = createRoom(RoomTypeEnum.GROUP);
|
||||
Room room = createRoom(RoomTypeEnum.FRIEND);
|
||||
roomFriend = createFriendRoom(room.getId(), uidList);
|
||||
}
|
||||
return roomFriend;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public RoomGroup createGroupRoom(Long uid) {
|
||||
List<GroupMember> selfGroup = groupMemberDao.getSelfGroup(uid);
|
||||
AssertUtil.isEmpty(selfGroup, "每个人只能创建一个群");
|
||||
User user = userInfoCache.get(uid);
|
||||
Room room = createRoom(RoomTypeEnum.GROUP);
|
||||
//插入群
|
||||
RoomGroup roomGroup = ChatAdapter.buildGroupRoom(user, room.getId());
|
||||
roomGroupDao.save(roomGroup);
|
||||
//插入群主
|
||||
GroupMember leader = GroupMember.builder()
|
||||
.role(GroupRoleEnum.LEADER.getType())
|
||||
.groupId(roomGroup.getId())
|
||||
.uid(uid)
|
||||
.build();
|
||||
groupMemberDao.save(leader);
|
||||
return roomGroup;
|
||||
}
|
||||
|
||||
private RoomFriend createFriendRoom(Long roomId, List<Long> uidList) {
|
||||
RoomFriend insert = ChatAdapter.buildFriendRoom(roomId, uidList);
|
||||
roomFriendDao.save(insert);
|
||||
|
||||
@@ -16,6 +16,11 @@ public class RedisKey {
|
||||
*/
|
||||
public static final String OFFLINE_UID_ZET = "offline";
|
||||
|
||||
/**
|
||||
* 热门房间列表
|
||||
*/
|
||||
public static final String HOT_ROOM_ZET = "hotRoom";
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.abin.mallchat.common.common.event;
|
||||
|
||||
import com.abin.mallchat.common.chat.domain.entity.GroupMember;
|
||||
import com.abin.mallchat.common.chat.domain.entity.RoomGroup;
|
||||
import lombok.Getter;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
public class GroupMemberAddEvent extends ApplicationEvent {
|
||||
|
||||
private final List<GroupMember> memberList;
|
||||
private final RoomGroup roomGroup;
|
||||
private final Long inviteUid;
|
||||
|
||||
public GroupMemberAddEvent(Object source, RoomGroup roomGroup, List<GroupMember> memberList, Long inviteUid) {
|
||||
super(source);
|
||||
this.memberList = memberList;
|
||||
this.roomGroup = roomGroup;
|
||||
this.inviteUid = inviteUid;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.abin.mallchat.common.common.event;
|
||||
|
||||
import com.abin.mallchat.common.user.domain.enums.WSBaseResp;
|
||||
import com.abin.mallchat.common.user.domain.enums.WSPushTypeEnum;
|
||||
import lombok.Getter;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
public class WSPushEvent extends ApplicationEvent {
|
||||
/**
|
||||
* 推送的ws消息
|
||||
*/
|
||||
private final WSBaseResp<?> wsBaseMsg;
|
||||
/**
|
||||
* 推送的uid
|
||||
*/
|
||||
private final List<Long> uidList;
|
||||
|
||||
/**
|
||||
* 推送类型 1个人 2全员
|
||||
*
|
||||
* @see com.abin.mallchat.common.user.domain.enums.WSPushTypeEnum
|
||||
*/
|
||||
private final Integer pushType;
|
||||
|
||||
public WSPushEvent(Object source, Long uid, WSBaseResp<?> wsBaseMsg) {
|
||||
super(source);
|
||||
this.uidList = Collections.singletonList(uid);
|
||||
this.wsBaseMsg = wsBaseMsg;
|
||||
this.pushType = WSPushTypeEnum.USER.getType();
|
||||
}
|
||||
|
||||
public WSPushEvent(Object source, List<Long> uidList, WSBaseResp<?> wsBaseMsg) {
|
||||
super(source);
|
||||
this.uidList = uidList;
|
||||
this.wsBaseMsg = wsBaseMsg;
|
||||
this.pushType = WSPushTypeEnum.USER.getType();
|
||||
}
|
||||
|
||||
public WSPushEvent(Object source, WSBaseResp<?> wsBaseMsg) {
|
||||
super(source);
|
||||
this.uidList = new ArrayList<>();
|
||||
this.wsBaseMsg = wsBaseMsg;
|
||||
this.pushType = WSPushTypeEnum.ALL.getType();
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.springframework.data.redis.core.ZSetOperations;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
@@ -55,10 +56,18 @@ public class CursorUtils {
|
||||
Page<T> page = mapper.page(request.plusPage(), wrapper);
|
||||
String cursor = Optional.ofNullable(CollectionUtil.getLast(page.getRecords()))
|
||||
.map(cursorColumn)
|
||||
.map(String::valueOf)
|
||||
.map(CursorUtils::parseCursor)
|
||||
.orElse(null);
|
||||
Boolean isLast = page.getRecords().size() != request.getPageSize();
|
||||
return new CursorPageBaseResp<>(cursor, isLast, page.getRecords());
|
||||
}
|
||||
|
||||
private static String parseCursor(Object o) {
|
||||
if (o instanceof Date) {
|
||||
return String.valueOf(((Date) o).getTime());
|
||||
} else {
|
||||
return o.toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -849,6 +849,10 @@ public class RedisUtils {
|
||||
return stringRedisTemplate.opsForZSet().range(key, start, end);
|
||||
}
|
||||
|
||||
public static Set<String> zAll(String key) {
|
||||
return stringRedisTemplate.opsForZSet().range(key, 0, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取集合元素, 并且把score值也获取
|
||||
*
|
||||
@@ -882,8 +886,14 @@ public class RedisUtils {
|
||||
* @param max 最大值
|
||||
* @return
|
||||
*/
|
||||
public Set<TypedTuple<String>> zRangeByScoreWithScores(String key,
|
||||
double min, double max) {
|
||||
public static Set<TypedTuple<String>> zRangeByScoreWithScores(String key,
|
||||
Double min, Double max) {
|
||||
if (Objects.isNull(min)) {
|
||||
min = Double.MIN_VALUE;
|
||||
}
|
||||
if (Objects.isNull(max)) {
|
||||
max = Double.MAX_VALUE;
|
||||
}
|
||||
return stringRedisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ public class UserApplyDao extends ServiceImpl<UserApplyMapper, UserApply> {
|
||||
return lambdaQuery()
|
||||
.eq(UserApply::getTargetId, uid)
|
||||
.eq(UserApply::getType, ApplyTypeEnum.ADD_FRIEND.getCode())
|
||||
.orderByAsc(UserApply::getCreateTime)
|
||||
.orderByDesc(UserApply::getCreateTime)
|
||||
.page(page);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
package com.abin.mallchat.common.user.dao;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.abin.mallchat.common.common.domain.enums.NormalOrNoEnum;
|
||||
import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq;
|
||||
import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp;
|
||||
import com.abin.mallchat.common.common.utils.CursorUtils;
|
||||
import com.abin.mallchat.common.user.domain.entity.User;
|
||||
import com.abin.mallchat.common.user.domain.enums.ChatActiveStatusEnum;
|
||||
import com.abin.mallchat.common.user.mapper.UserMapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -47,7 +53,7 @@ public class UserDao extends ServiceImpl<UserMapper, User> {
|
||||
public List<User> getMemberList() {
|
||||
return lambdaQuery()
|
||||
.eq(User::getStatus, NormalOrNoEnum.NORMAL.getStatus())
|
||||
.orderByDesc(User::getUpdateTime)//最近活跃的1000个人,可以用lastOptTime字段,但是该字段没索引,updateTime可平替
|
||||
.orderByDesc(User::getLastOptTime)//最近活跃的1000个人,可以用lastOptTime字段,但是该字段没索引,updateTime可平替
|
||||
.last("limit 1000")//毕竟是大群聊,人数需要做个限制
|
||||
.select(User::getId, User::getName, User::getAvatar)
|
||||
.list();
|
||||
@@ -62,4 +68,23 @@ public class UserDao extends ServiceImpl<UserMapper, User> {
|
||||
.list();
|
||||
|
||||
}
|
||||
|
||||
public Integer getOnlineCount() {
|
||||
return getOnlineCount(null);
|
||||
}
|
||||
|
||||
public Integer getOnlineCount(List<Long> memberUidList) {
|
||||
return lambdaQuery()
|
||||
.eq(User::getActiveStatus, ChatActiveStatusEnum.ONLINE.getStatus())
|
||||
.in(CollectionUtil.isNotEmpty(memberUidList), User::getId, memberUidList)
|
||||
.count();
|
||||
}
|
||||
|
||||
public CursorPageBaseResp<User> getCursorPage(List<Long> memberUidList, CursorPageBaseReq request, ChatActiveStatusEnum online) {
|
||||
return CursorUtils.getCursorPageByMysql(this, request, wrapper -> {
|
||||
wrapper.eq(User::getActiveStatus, online.getStatus());//筛选上线或者离线的
|
||||
wrapper.in(CollectionUtils.isNotEmpty(memberUidList), User::getId, memberUidList);//普通群对uid列表做限制
|
||||
}, User::getLastOptTime);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ public class User implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Long UID_SYSTEM = 1L;//系统uid
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
|
||||
@@ -8,7 +8,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -71,13 +71,13 @@ public class UserApply implements Serializable {
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("create_time")
|
||||
private LocalDateTime createTime;
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@TableField("update_time")
|
||||
private LocalDateTime updateTime;
|
||||
private Date updateTime;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -47,13 +47,13 @@ public class UserFriend implements Serializable {
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("create_time")
|
||||
private LocalDateTime createTime;
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@TableField("update_time")
|
||||
private LocalDateTime updateTime;
|
||||
private Date updateTime;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -47,11 +47,11 @@ public class UserRole implements Serializable {
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("create_time")
|
||||
private LocalDateTime createTime;
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@TableField("update_time")
|
||||
private LocalDateTime updateTime;
|
||||
private Date updateTime;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.abin.mallchat.common.user.domain.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Description: 场景枚举
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-06-20
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum OssSceneEnum {
|
||||
CHAT(1, "聊天", "/chat"),
|
||||
EMOJI(2, "表情包", "/emoji"),
|
||||
;
|
||||
|
||||
private final Integer type;
|
||||
private final String desc;
|
||||
private final String path;
|
||||
|
||||
private static final Map<Integer, OssSceneEnum> cache;
|
||||
|
||||
static {
|
||||
cache = Arrays.stream(OssSceneEnum.values()).collect(Collectors.toMap(OssSceneEnum::getType, Function.identity()));
|
||||
}
|
||||
|
||||
public static OssSceneEnum of(Integer type) {
|
||||
return cache.get(type);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.abin.mallchat.common.user.domain.enums;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Description: ws的基本返回信息体
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-19
|
||||
*/
|
||||
@Data
|
||||
public class WSBaseResp<T> {
|
||||
/**
|
||||
* ws推送给前端的消息
|
||||
*
|
||||
* @see WSRespTypeEnum
|
||||
*/
|
||||
private Integer type;
|
||||
private T data;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.abin.mallchat.common.user.domain.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-07-29
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum WSPushTypeEnum {
|
||||
USER(1, "个人"),
|
||||
ALL(2, "全部连接用户"),
|
||||
;
|
||||
|
||||
private final Integer type;
|
||||
private final String desc;
|
||||
|
||||
private static Map<Integer, WSPushTypeEnum> cache;
|
||||
|
||||
static {
|
||||
cache = Arrays.stream(WSPushTypeEnum.values()).collect(Collectors.toMap(WSPushTypeEnum::getType, Function.identity()));
|
||||
}
|
||||
|
||||
public static WSPushTypeEnum of(Integer type) {
|
||||
return cache.get(type);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.abin.mallchat.common.user.domain.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Description: ws前端请求类型枚举
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-19
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum WSReqTypeEnum {
|
||||
LOGIN(1, "请求登录二维码"),
|
||||
HEARTBEAT(2, "心跳包"),
|
||||
AUTHORIZE(3, "登录认证"),
|
||||
;
|
||||
|
||||
private final Integer type;
|
||||
private final String desc;
|
||||
|
||||
private static Map<Integer, WSReqTypeEnum> cache;
|
||||
|
||||
static {
|
||||
cache = Arrays.stream(WSReqTypeEnum.values()).collect(Collectors.toMap(WSReqTypeEnum::getType, Function.identity()));
|
||||
}
|
||||
|
||||
public static WSReqTypeEnum of(Integer type) {
|
||||
return cache.get(type);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.abin.mallchat.common.user.domain.enums;
|
||||
|
||||
import com.abin.mallchat.common.user.domain.vo.response.ws.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Description: ws前端请求类型枚举
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-19
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum WSRespTypeEnum {
|
||||
LOGIN_URL(1, "登录二维码返回", WSLoginUrl.class),
|
||||
LOGIN_SCAN_SUCCESS(2, "用户扫描成功等待授权", null),
|
||||
LOGIN_SUCCESS(3, "用户登录成功返回用户信息", WSLoginSuccess.class),
|
||||
MESSAGE(4, "新消息", WSMessage.class),
|
||||
ONLINE_OFFLINE_NOTIFY(5, "上下线通知", WSOnlineOfflineNotify.class),
|
||||
INVALIDATE_TOKEN(6, "使前端的token失效,意味着前端需要重新登录", null),
|
||||
BLACK(7, "拉黑用户", WSBlack.class),
|
||||
MARK(8, "消息标记", WSMsgMark.class),
|
||||
RECALL(9, "消息撤回", WSMsgRecall.class),
|
||||
APPLY(10, "好友申请", WSFriendApply.class),
|
||||
MEMBER_CHANGE(11, "成员变动", WSMemberChange.class),
|
||||
;
|
||||
|
||||
private final Integer type;
|
||||
private final String desc;
|
||||
private final Class dataClass;
|
||||
|
||||
private static Map<Integer, WSRespTypeEnum> cache;
|
||||
|
||||
static {
|
||||
cache = Arrays.stream(WSRespTypeEnum.values()).collect(Collectors.toMap(WSRespTypeEnum::getType, Function.identity()));
|
||||
}
|
||||
|
||||
public static WSRespTypeEnum of(Integer type) {
|
||||
return cache.get(type);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.abin.mallchat.common.user.domain.vo.request.ws;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-19
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class WSAuthorize {
|
||||
private String token;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.abin.mallchat.common.user.domain.vo.request.ws;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Description: websocket前端请求体
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-19
|
||||
*/
|
||||
@Data
|
||||
public class WSBaseReq {
|
||||
/**
|
||||
* 请求类型 1.请求登录二维码,2心跳检测
|
||||
*
|
||||
* @see com.abin.mallchat.common.user.domain.enums.WSReqTypeEnum
|
||||
*/
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 每个请求包具体的数据,类型不同结果不同
|
||||
*/
|
||||
private String data;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.abin.mallchat.common.user.domain.vo.response.ws;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Description: 群成员列表的成员信息
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-23
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ChatMemberResp {
|
||||
@ApiModelProperty("uid")
|
||||
private Long uid;
|
||||
/**
|
||||
* @see com.abin.mallchat.common.user.domain.enums.ChatActiveStatusEnum
|
||||
*/
|
||||
@ApiModelProperty("在线状态 1在线 2离线")
|
||||
private Integer activeStatus;
|
||||
@ApiModelProperty("最后一次上下线时间")
|
||||
private Date lastOptTime;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.abin.mallchat.common.user.domain.vo.response.ws;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-19
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class WSBlack {
|
||||
private Long uid;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.abin.mallchat.common.user.domain.vo.response.ws;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-19
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class WSFriendApply {
|
||||
@ApiModelProperty("申请人")
|
||||
private Long uid;
|
||||
@ApiModelProperty("申请未读数")
|
||||
private Integer unreadCount;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.abin.mallchat.common.user.domain.vo.response.ws;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-19
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class WSLoginSuccess {
|
||||
private Long uid;
|
||||
private String avatar;
|
||||
private String token;
|
||||
private String name;
|
||||
//用户权限 0普通用户 1超管
|
||||
private Integer power;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.abin.mallchat.common.user.domain.vo.response.ws;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-19
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class WSLoginUrl {
|
||||
private String loginUrl;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.abin.mallchat.common.user.domain.vo.response.ws;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-19
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class WSMemberChange {
|
||||
public static final Integer CHANGE_TYPE_ADD = 1;
|
||||
public static final Integer CHANGE_TYPE_REMOVE = 2;
|
||||
@ApiModelProperty("群组id")
|
||||
private Long roomId;
|
||||
@ApiModelProperty("变动uid集合")
|
||||
private Long uid;
|
||||
@ApiModelProperty("变动类型 1加入群组 2移除群组")
|
||||
private Integer changeType;
|
||||
/**
|
||||
* @see com.abin.mallchat.common.user.domain.enums.ChatActiveStatusEnum
|
||||
*/
|
||||
@ApiModelProperty("在线状态 1在线 2离线")
|
||||
private Integer activeStatus;
|
||||
@ApiModelProperty("最后一次上下线时间")
|
||||
private Date lastOptTime;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.abin.mallchat.common.user.domain.vo.response.ws;
|
||||
|
||||
import com.abin.mallchat.common.chat.domain.vo.response.ChatMessageResp;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Description: 用户消息推送
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-19
|
||||
*/
|
||||
@Data
|
||||
public class WSMessage extends ChatMessageResp {
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.abin.mallchat.common.user.domain.vo.response.ws;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-19
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class WSMessageRead {
|
||||
@ApiModelProperty("消息")
|
||||
private Long msgId;
|
||||
@ApiModelProperty("阅读人数(可能为0)")
|
||||
private Integer readCount;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.abin.mallchat.common.user.domain.vo.response.ws;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-19
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class WSMsgMark {
|
||||
private List<WSMsgMarkItem> markList;
|
||||
|
||||
@Data
|
||||
public static class WSMsgMarkItem {
|
||||
@ApiModelProperty("操作者")
|
||||
private Long uid;
|
||||
@ApiModelProperty("消息id")
|
||||
private Long msgId;
|
||||
/**
|
||||
* @see com.abin.mallchat.common.chat.domain.enums.MessageMarkTypeEnum
|
||||
*/
|
||||
@ApiModelProperty("标记类型 1点赞 2举报")
|
||||
private Integer markType;
|
||||
@ApiModelProperty("被标记的数量")
|
||||
private Integer markCount;
|
||||
/**
|
||||
* @see com.abin.mallchat.common.chat.domain.enums.MessageMarkActTypeEnum
|
||||
*/
|
||||
@ApiModelProperty("动作类型 1确认 2取消")
|
||||
private Integer actType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.abin.mallchat.common.user.domain.vo.response.ws;
|
||||
|
||||
import com.abin.mallchat.common.chat.domain.dto.ChatMsgRecallDTO;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Description:消息撤回的推送类
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-19
|
||||
*/
|
||||
@Data
|
||||
public class WSMsgRecall extends ChatMsgRecallDTO {
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.abin.mallchat.common.user.domain.vo.response.ws;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Description:用户上下线变动的推送类
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-19
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class WSOnlineOfflineNotify {
|
||||
private List<ChatMemberResp> changeList = new ArrayList<>();//新的上下线用户
|
||||
private Long onlineNum;//在线人数
|
||||
}
|
||||
@@ -70,6 +70,13 @@ public class UserCache {
|
||||
RedisUtils.zAdd(onlineKey, uid, optTime.getTime());
|
||||
}
|
||||
|
||||
//获取用户上线列表
|
||||
public List<Long> getOnlineUidList() {
|
||||
String onlineKey = RedisKey.getKey(RedisKey.ONLINE_UID_ZET);
|
||||
Set<String> strings = RedisUtils.zAll(onlineKey);
|
||||
return strings.stream().map(Long::parseLong).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public boolean isOnline(Long uid) {
|
||||
String onlineKey = RedisKey.getKey(RedisKey.ONLINE_UID_ZET);
|
||||
return RedisUtils.zIsMember(onlineKey, uid);
|
||||
|
||||
Reference in New Issue
Block a user