1.链接跳转功能
2.归属地功能
fix:
1.修复回复跳转功能
2.优化翻页工具类
3,修复下线重置ip的bug
This commit is contained in:
zhongzb
2023-05-28 15:29:50 +08:00
parent de27f7791f
commit 53201465f2
23 changed files with 400 additions and 31 deletions

View File

@@ -27,6 +27,8 @@ import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* <p>
@@ -66,7 +68,7 @@ public class ChatController {
return userCache.getBlackMap().get(BlackTypeEnum.UID.getType());
}
@GetMapping("/public/member/statistic")
@GetMapping("public/member/statistic/")
@ApiOperation("群成员人数统计")
public ApiResult<ChatMemberStatisticResp> getMemberStatistic() {
return ApiResult.success(chatService.getMemberStatistic());

View File

@@ -1,18 +1,12 @@
package com.abin.mallchat.custom.chat.domain.vo.response;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* Description: 消息
@@ -38,6 +32,8 @@ public class ChatMessageResp {
private Long uid;
@ApiModelProperty("头像")
private String avatar;
@ApiModelProperty("归属地")
private String locPlace;
@ApiModelProperty("徽章标识如果没有展示null")
private Badge badge;
}
@@ -50,6 +46,8 @@ public class ChatMessageResp {
private Date sendTime;
@ApiModelProperty("消息内容")
private String content;
@ApiModelProperty("消息链接映射")
private Map<String,String> urlTitleMap;
@ApiModelProperty("消息类型 1正常文本 2.爆赞 点赞超过103.危险发言举报超5")
private Integer type;
@ApiModelProperty("消息标记")

View File

@@ -2,11 +2,15 @@ package com.abin.mallchat.custom.chat.service.adapter;
import cn.hutool.core.bean.BeanUtil;
import com.abin.mallchat.common.chat.domain.entity.Message;
import com.abin.mallchat.common.chat.domain.entity.MessageExtra;
import com.abin.mallchat.common.chat.domain.entity.MessageMark;
import com.abin.mallchat.common.chat.domain.enums.MessageMarkTypeEnum;
import com.abin.mallchat.common.chat.domain.enums.MessageStatusEnum;
import com.abin.mallchat.common.chat.domain.enums.MessageTypeEnum;
import com.abin.mallchat.common.common.domain.enums.YesOrNoEnum;
import com.abin.mallchat.common.common.utils.discover.PrioritizedUrlTitleDiscover;
import com.abin.mallchat.common.user.domain.entity.IpDetail;
import com.abin.mallchat.common.user.domain.entity.IpInfo;
import com.abin.mallchat.common.user.domain.entity.ItemConfig;
import com.abin.mallchat.common.user.domain.entity.User;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageReq;
@@ -23,24 +27,32 @@ import java.util.stream.Collectors;
* Date: 2023-03-26
*/
public class MessageAdapter {
public static final int CAN_CALLBACK_GAP_COUNT = 100;
public static final int CAN_CALLBACK_GAP_COUNT = 50;
private static final PrioritizedUrlTitleDiscover URL_TITLE_DISCOVER = new PrioritizedUrlTitleDiscover();
public static Message buildMsgSave(ChatMessageReq request, Long uid) {
return Message.builder()
.replyMsgId(request.getReplyMsgId())
.content(request.getContent())
.fromUid(uid)
.roomId(request.getRoomId())
.status(MessageStatusEnum.NORMAL.getStatus())
.extra(buildExtra(request))
.build();
}
private static MessageExtra buildExtra(ChatMessageReq request) {
Map<String, String> contentTitleMap = URL_TITLE_DISCOVER.getContentTitleMap(request.getContent());
return MessageExtra.builder().urlTitleMap(contentTitleMap).build();
}
public static List<ChatMessageResp> buildMsgResp(List<Message> messages, Map<Long, Message> replyMap, Map<Long, User> userMap, List<MessageMark> msgMark, Long receiveUid, Map<Long, ItemConfig> itemMap) {
Map<Long, List<MessageMark>> markMap = msgMark.stream().collect(Collectors.groupingBy(MessageMark::getMsgId));
return messages.stream().map(a -> {
ChatMessageResp resp = new ChatMessageResp();
resp.setFromUser(buildFromUser(userMap.get(a.getFromUid()),itemMap));
resp.setFromUser(buildFromUser(userMap.get(a.getFromUid()), itemMap));
resp.setMessage(buildMessage(a, replyMap, userMap, markMap.getOrDefault(a.getId(), new ArrayList<>()), receiveUid));
return resp;
})
@@ -52,6 +64,7 @@ public class MessageAdapter {
ChatMessageResp.Message messageVO = new ChatMessageResp.Message();
BeanUtil.copyProperties(message, messageVO);
messageVO.setSendTime(message.getCreateTime());
messageVO.setUrlTitleMap(Optional.ofNullable(message.getExtra()).map(MessageExtra::getUrlTitleMap).orElse(null));
Message replyMessage = replyMap.get(message.getReplyMsgId());
//回复消息
if (Objects.nonNull(replyMessage)) {
@@ -85,9 +98,10 @@ public class MessageAdapter {
ChatMessageResp.UserInfo userInfo = new ChatMessageResp.UserInfo();
userInfo.setUsername(fromUser.getName());
userInfo.setAvatar(fromUser.getAvatar());
userInfo.setLocPlace(Optional.ofNullable(fromUser.getIpInfo()).map(IpInfo::getUpdateIpDetail).map(IpDetail::getCity).orElse(null));
userInfo.setUid(fromUser.getId());
if(Objects.nonNull(fromUser.getItemId())){
ChatMessageResp.Badge badge =new ChatMessageResp.Badge();
if (Objects.nonNull(fromUser.getItemId())) {
ChatMessageResp.Badge badge = new ChatMessageResp.Badge();
ItemConfig itemConfig = itemMap.get(fromUser.getItemId());
badge.setImg(itemConfig.getImg());
badge.setDescribe(itemConfig.getDescribe());

View File

@@ -16,6 +16,7 @@ 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.exception.BusinessException;
import com.abin.mallchat.common.common.utils.AssertUtil;
import com.abin.mallchat.common.common.utils.discover.PrioritizedUrlTitleDiscover;
import com.abin.mallchat.common.user.dao.UserDao;
import com.abin.mallchat.common.user.domain.entity.ItemConfig;
import com.abin.mallchat.common.user.domain.entity.User;
@@ -76,8 +77,6 @@ public class ChatServiceImpl implements ChatService {
/**
* 发送消息
*
* @param request
*/
@Override
@Transactional
@@ -90,6 +89,7 @@ public class ChatServiceImpl implements ChatService {
AssertUtil.equal(replyMsg.getRoomId(), request.getRoomId(), "只能回复相同会话内的消息");
}
//同步获取消息的跳转链接标题
Message insert = MessageAdapter.buildMsgSave(request, uid);
messageDao.save(insert);
//如果有回复消息
@@ -224,10 +224,10 @@ public class ChatServiceImpl implements ChatService {
Set<Long> uidSet = Stream.concat(replyMap.values().stream().map(Message::getFromUid), messages.stream().map(Message::getFromUid)).collect(Collectors.toSet());
userMap = userCache.getUserInfoBatch(uidSet);
//批量查询item信息
itemMap = userMap.values().stream().map(User::getItemId).distinct().filter(Objects::nonNull).map(itemCache::getById).collect(Collectors.toMap(ItemConfig::getId,Function.identity()));
itemMap = userMap.values().stream().map(User::getItemId).distinct().filter(Objects::nonNull).map(itemCache::getById).collect(Collectors.toMap(ItemConfig::getId, Function.identity()));
//查询消息标志
List<MessageMark> msgMark = messageMarkDao.getValidMarkByMsgIdBatch(messages.stream().map(Message::getId).collect(Collectors.toList()));
return MessageAdapter.buildMsgResp(messages, replyMap, userMap, msgMark, receiveUid,itemMap);
return MessageAdapter.buildMsgResp(messages, replyMap, userMap, msgMark, receiveUid, itemMap);
}
}

View File

@@ -45,7 +45,7 @@ public class LoginServiceImpl implements LoginService {
return false;
}
String key = RedisKey.getKey(RedisKey.USER_TOKEN_STRING, uid);
String realToken = redisUtils.getStr(key);
String realToken = RedisUtils.getStr(key);
return token.equals(realToken);//有可能token失效了需要校验是不是和最新token一致
}

View File

@@ -157,7 +157,7 @@ public class WebSocketServiceImpl implements WebSocketService {
boolean online = userCache.isOnline(user.getId());
if (!online) {
user.setLastOptTime(new Date());
user.getIpInfo().refreshIp(NettyUtil.getAttr(channel, NettyUtil.IP));
user.refreshIp(NettyUtil.getAttr(channel, NettyUtil.IP));
applicationEventPublisher.publishEvent(new UserOnlineEvent(this, user));
}
}

View File

@@ -67,7 +67,7 @@ public class NettyWebSocketServer {
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
//30秒客户端没有向服务器发送心跳则关闭连接
pipeline.addLast(new IdleStateHandler(30, 0, 0));
// pipeline.addLast(new IdleStateHandler(30, 0, 0));
// 因为使用http协议所以需要使用http的编码器解码器
pipeline.addLast(new HttpServerCodec());
// 以块方式写,添加 chunkedWriter 处理器