This commit is contained in:
oneao committed 2025-12-30 22:25:54 +08:00
1 parent a6dbe24dd4
commit 52b16ed2b0
21 files changed
+444 -107

No files matched your search

@@ -89,4 +89,18 @@ public class ImController {
return Result.success();
}
@GetMapping("/friend/{friendId}")
public Result<FriendProfileVO> getFriendProfile(@PathVariable("friendId") Long friendId){
FriendProfileVO friendProfileVO = imFriendService.getFriendProfile(friendId);
return Result.success(friendProfileVO);
}
@GetMapping("/group/{groupId}")
public Result<GroupProfileVO> getGroupProfile(@PathVariable("groupId") Long groupId){
GroupProfileVO groupProfileVO = imGroupService.getGroupProfile(groupId);
return Result.success(groupProfileVO);
}
}
@@ -13,8 +13,7 @@ public enum MessageTypeEnums {
OFFLINE(6),
GROUP_OFFLINE(7),
PRIVATE(8),
GROUP(9),
FRIEND_UPDATE(10);
GROUP(9);
private final int code;
@@ -12,12 +12,12 @@ import cn.link56.im.message.MessageResponse;
import cn.link56.im.model.dto.GroupDTO;
import cn.link56.im.model.dto.LoginDTO;
import cn.link56.im.model.dto.PrivateDTO;
import cn.link56.im.model.po.ImGroupMessage;
import cn.link56.im.model.po.ImPrivateMessage;
import cn.link56.im.model.vo.GroupMessageVO;
import cn.link56.im.model.vo.PrivateMessageVO;
import cn.link56.im.model.vo.QueryFriendVO;
import cn.link56.im.service.ImFriendService;
import cn.link56.im.service.ImGroupUserService;
import cn.link56.im.service.ImPrivateMessageService;
import cn.link56.im.service.*;
import cn.link56.im.storage.SessionManager;
import cn.link56.im.utils.MessageDataConverter;
import cn.link56.im.utils.MessageWriter;
@@ -40,6 +40,10 @@ public class MessageHandler {
private ImPrivateMessageService imPrivateMessageService;
@Resource
private CompanyUserService companyUserService;
@Resource
private ImGroupMessageService imGroupMessageService;
@Resource
private ImGroupService imGroupService;
// 处理消息
public void handleMessage(Channel channel, MessageRequest request) {
@@ -104,7 +108,7 @@ public class MessageHandler {
MessageWriter.broadcastToUsers(onlineFriends,MessageResponse.success(MessageTypeEnums.ONLINE).setFrom(from));
// 通知群组
List<Long> onlineGroupUsers = imGroupUserService.getOnlineGroupUsers(from);
List<Long> onlineGroupUsers = imGroupUserService.getAllOnlineGroupUsers(from);
MessageWriter.broadcastToUsers(onlineGroupUsers,MessageResponse.success(MessageTypeEnums.GROUP_ONLINE).setFrom(from));
}
@@ -115,7 +119,7 @@ public class MessageHandler {
MessageWriter.broadcastToUsers(onlineFriends,MessageResponse.success(MessageTypeEnums.OFFLINE).setFrom(from));
// 通知群组
List<Long> onlineGroupUsers = imGroupUserService.getOnlineGroupUsers(from);
List<Long> onlineGroupUsers = imGroupUserService.getAllOnlineGroupUsers(from);
MessageWriter.broadcastToUsers(onlineGroupUsers,MessageResponse.success(MessageTypeEnums.GROUP_OFFLINE).setFrom(from));
}
@@ -132,22 +136,6 @@ public class MessageHandler {
// 好友关系建立
imFriendService.createFriend(to,from);
// 通知建立了好友关系
if (SessionManager.isOnline(to)) {
CompanyUser companyUser = companyUserService.getById(from);
if (ObjectUtils.isNotEmpty(companyUser)){
QueryFriendVO queryFriendVO = new QueryFriendVO();
queryFriendVO.setFriendId(from);
queryFriendVO.setFriendName(companyUser.getName());
queryFriendVO.setFriendAvatar(companyUser.getAvatar());
queryFriendVO.setIsOnline(true);
queryFriendVO.setUnreadCount(0);
MessageWriter.writeToUser(to,MessageResponse.success(MessageTypeEnums.FRIEND_UPDATE,from).setData(queryFriendVO));
}
}
// 保存
Long privateMessageID = IdGenerator.nextId();
Long sendTime = TimeUtils.getCurrentTimestampMillis();
@@ -188,11 +176,51 @@ public class MessageHandler {
// 群聊逻辑
private void handleGroup(Channel channel, MessageRequest request) {
Long from = request.getFrom();
Long to = request.getTo();
Long groupId = request.getTo();
GroupDTO dto = MessageDataConverter.convert(request.getData(), GroupDTO.class);
String content = dto.getContent();
Integer type = dto.getType();
String tempId = dto.getTempId();
String senderName = dto.getSenderName();
String senderAvatar = dto.getSenderAvatar();
// 将消息插入到数据库中
long nextId = IdGenerator.nextId();
long timestampMillis = TimeUtils.getCurrentTimestampMillis();
ImGroupMessage imGroupMessage = new ImGroupMessage();
imGroupMessage.setId(nextId);
imGroupMessage.setContent(content);
imGroupMessage.setType(type);
imGroupMessage.setSenderId(from);
imGroupMessage.setSendTime(timestampMillis);
imGroupMessage.setGroupId(groupId);
imGroupMessageService.save(imGroupMessage);
// 更新未读状态
imGroupUserService.updateGroupUnreadCount(groupId,from);
// 更新lastMessageId
imGroupService.updateLaseMessageId(groupId,nextId);
// 构建回复消息
GroupMessageVO groupMessageVO = new GroupMessageVO();
groupMessageVO.setTempId(tempId);
groupMessageVO.setId(nextId);
groupMessageVO.setSenderId(from);
groupMessageVO.setContent(content);
groupMessageVO.setType(type);
groupMessageVO.setSendTime(timestampMillis);
groupMessageVO.setGroupId(groupId);
groupMessageVO.setSenderName(senderName);
groupMessageVO.setSenderAvatar(senderAvatar);
// 通知建立群组关系
// 查询该群在线的用户
List<Long> onlineGroupUsers = imGroupUserService.getGroupOnlineUserIds(groupId);
MessageWriter.broadcastToUsers(onlineGroupUsers,MessageResponse.success(MessageTypeEnums.GROUP,groupId).setData(groupMessageVO));
}
}
@@ -1,6 +1,7 @@
package cn.link56.im.mapper;
import cn.link56.im.model.po.ImFriend;
import cn.link56.im.model.vo.FriendProfileVO;
import cn.link56.im.model.vo.QueryFriendVO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@@ -34,4 +35,10 @@ public interface ImFriendMapper extends BaseMapper<ImFriend> {
@Param("userId") Long userId,
@Param("friendId") Long friendId
);
FriendProfileVO selectFriendProfile(
@Param("userId") Long userId,
@Param("friendId") Long friendId
);
}
@@ -1,7 +1,7 @@
package cn.link56.im.mapper;
import cn.link56.im.model.po.ImGroup;
import cn.link56.im.model.vo.QueryFriendVO;
import cn.link56.im.model.vo.GroupProfileVO;
import cn.link56.im.model.vo.QueryGroupVO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@@ -21,4 +21,8 @@ public interface ImGroupMapper extends BaseMapper<ImGroup> {
Long selectGroupTotal(@Param("userId") Long userId,
@Param("name") String name);
GroupProfileVO selectGroupProfile(
@Param("groupId") Long groupId,
@Param("userId") Long userId);
}
@@ -11,4 +11,7 @@ public class GroupDTO {
private String content;
private Integer type;
private String tempId;
private String senderAvatar;
private String senderName;
}
@@ -0,0 +1,15 @@
package cn.link56.im.model.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class FriendProfileVO {
private Long friendId;
private String friendName;
private String friendAvatar;
private Integer unreadCount;
}
@@ -0,0 +1,14 @@
package cn.link56.im.model.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class GroupMessageVO extends QueryGroupMessageVO {
private String tempId;
}
@@ -0,0 +1,16 @@
package cn.link56.im.model.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class GroupProfileVO {
private Long groupId;
private String groupName;
private String groupAvatar;
private Integer unreadCount;
}
@@ -16,7 +16,6 @@ public class QueryFriendVO {
private Integer unreadCount;
private Long lastMessageId;
private Long lastMessageTime;
private Integer lastMessageType;
private String lastMessageContent;
@@ -14,8 +14,9 @@ public class QueryGroupVO {
private Integer unreadCount;
private Long lastMessageId;
private Long lastMessageTime;
private Integer lastMessageType;
private String lastMessageContent;
private String lastMessageSenderName;
}
@@ -6,6 +6,7 @@ import cn.link56.common.utils.snowflake.idgen.IdGenerator;
import cn.link56.im.mapper.ImFriendMapper;
import cn.link56.im.model.dto.QueryFriendDTO;
import cn.link56.im.model.po.ImFriend;
import cn.link56.im.model.vo.FriendProfileVO;
import cn.link56.im.model.vo.QueryFriendVO;
import cn.link56.im.storage.SessionManager;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -103,4 +104,10 @@ public class ImFriendService extends ServiceImpl<ImFriendMapper, ImFriend> {
public void decreaseUnreadCount(Long userId,Long friendId){
imFriendMapper.decreaseUnreadCount(userId, friendId);
}
public FriendProfileVO getFriendProfile(Long friendId) {
Long userId = UserContext.getUserId();
return imFriendMapper.selectFriendProfile(userId, friendId);
}
}
@@ -5,13 +5,17 @@ import cn.link56.common.context.UserContext;
import cn.link56.im.mapper.ImGroupMapper;
import cn.link56.im.model.dto.QueryGroupDTO;
import cn.link56.im.model.po.ImGroup;
import cn.link56.im.model.vo.GroupProfileVO;
import cn.link56.im.model.vo.QueryFriendVO;
import cn.link56.im.model.vo.QueryGroupVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
@Service
public class ImGroupService extends ServiceImpl<ImGroupMapper, ImGroup>{
@@ -32,4 +36,18 @@ public class ImGroupService extends ServiceImpl<ImGroupMapper, ImGroup>{
return new BasePageVO<>(total,queryFriendVOS);
}
public void updateLaseMessageId(Long groupId,Long lastMessageId){
LambdaUpdateWrapper<ImGroup> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(ImGroup::getId,groupId)
.set(ImGroup::getLastMessageId,lastMessageId);
imGroupMapper.update(updateWrapper);
}
public GroupProfileVO getGroupProfile(Long groupId) {
Long userId = UserContext.getUserId();
return imGroupMapper.selectGroupProfile(groupId,userId);
}
}
@@ -21,7 +21,7 @@ public class ImGroupUserService extends ServiceImpl<ImGroupUserMapper, ImGroupUs
private ImGroupUserMapper imGroupUserMapper;
// 获取群组在线用户列表
public List<Long> getOnlineGroupUsers(Long userId) {
public List<Long> getAllOnlineGroupUsers(Long userId) {
// 1️⃣ 查询用户所在的群组ID列表
LambdaQueryWrapper<ImGroupUser> groupWrapper = new LambdaQueryWrapper<>();
groupWrapper.eq(ImGroupUser::getUserId, userId)
@@ -48,6 +48,19 @@ public class ImGroupUserService extends ServiceImpl<ImGroupUserMapper, ImGroupUs
.collect(Collectors.toList());
}
public List<Long> getGroupOnlineUserIds(Long groupId) {
LambdaQueryWrapper<ImGroupUser> groupWrapper = new LambdaQueryWrapper<>();
groupWrapper.eq(ImGroupUser::getGroupId, groupId)
.select(ImGroupUser::getUserId);
List<ImGroupUser> groupMembers = imGroupUserMapper.selectList(groupWrapper);
return groupMembers.stream()
.map(ImGroupUser::getUserId)
.filter(SessionManager::isOnline)
.distinct() // 去重
.collect(Collectors.toList());
}
public void decreaseUnreadCount(Long groupId,Long userId){
LambdaUpdateWrapper<ImGroupUser> updateWrapper = new LambdaUpdateWrapper<>();
@@ -70,4 +83,15 @@ public class ImGroupUserService extends ServiceImpl<ImGroupUserMapper, ImGroupUs
return queryGroupUserVOS;
}
public void updateGroupUnreadCount(Long groupId, Long excludeUserId) {
LambdaUpdateWrapper<ImGroupUser> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper
.eq(ImGroupUser::getGroupId, groupId)
.ne(ImGroupUser::getUserId, excludeUserId)
.setSql("b_unread_count = b_unread_count + 1");
imGroupUserMapper.update(updateWrapper);
}
}
@@ -9,13 +9,11 @@
SELECT *
FROM (
SELECT
f.b_id AS id,
f.b_friend_id AS friendId,
u.b_name AS friendName,
u.b_avatar AS friendAvatar,
f.b_unread_count AS unreadCount,
m.b_id AS lastMessageId,
m.b_send_time AS lastMessageTime,
m.b_send_time AS lastMessageTime,
m.b_type AS lastMessageType,
m.b_content AS lastMessageContent,
ROW_NUMBER() OVER (
@@ -63,4 +61,15 @@
WHERE b_user_id = #{userId} and b_friend_id = #{friendId}
</update>
<select id="selectFriendProfile" resultType="cn.link56.im.model.vo.FriendProfileVO">
SELECT
f.b_friend_id AS friendId,
u.b_name AS friendName,
u.b_avatar AS friendAvatar,
f.b_unread_count AS unreadCount
FROM b_im_friend f
INNER JOIN b_company_user u ON f.b_friend_id = u.b_id
WHERE f.b_user_id = #{userId} AND f.b_friend_id = #{friendId}
</select>
</mapper>
@@ -14,12 +14,10 @@
g.b_avatar AS groupAvatar,
gu.b_unread_count AS unreadCount,
m.b_id AS lastMessageId,
m.b_send_time AS lastMessageTime,
m.b_type AS lastMessageType,
m.b_content AS lastMessageContent,
u.b_id AS lastMessageSenderId,
u.b_name AS lastMessageSenderName,
ROW_NUMBER() OVER (
@@ -29,7 +27,7 @@
) AS rn
FROM b_im_group g
INNER JOIN b_im_group_user gu ON g.b_id = gu.b_group_id
LEFT JOIN b_im_group_message m ON gu.b_last_message_id = m.b_id
LEFT JOIN b_im_group_message m ON g.b_last_message_id = m.b_id
LEFT JOIN b_company_user u ON m.b_sender_id = u.b_id
WHERE gu.b_user_id = #{userId}
<if test="name != null and name != ''">
@@ -51,4 +49,18 @@
</if>
</select>
<select id="selectGroupProfile"
resultType="cn.link56.im.model.vo.GroupProfileVO">
SELECT
g.b_id AS groupId,
g.b_name AS groupName,
g.b_avatar AS groupAvatar,
gu.b_unread_count AS unreadCount
FROM b_im_group g
INNER JOIN b_im_group_user gu ON g.b_id = gu.b_group_id
WHERE gu.b_user_id = #{userId}
AND g.b_id = #{groupId}
</select>
</mapper>