1.记录微信消息

2.重复上线问题解决
This commit is contained in:
zhongzb
2023-05-20 12:56:56 +08:00
parent a35e72ad46
commit fe1bd80082
19 changed files with 194 additions and 23 deletions

View File

@@ -85,7 +85,7 @@ public class ChatMessageResp {
private Integer userDislike;
}
@Data
private static class Badge {
public static class Badge {
@ApiModelProperty("徽章图像")
private String img;
@ApiModelProperty("徽章说明")

View File

@@ -7,6 +7,7 @@ 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.user.domain.entity.ItemConfig;
import com.abin.mallchat.common.user.domain.entity.User;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageReq;
import com.abin.mallchat.custom.chat.domain.vo.response.ChatMessageResp;
@@ -35,11 +36,11 @@ public class MessageAdapter {
}
public static List<ChatMessageResp> buildMsgResp(List<Message> messages, Map<Long, Message> replyMap, Map<Long, User> userMap, List<MessageMark> msgMark, Long receiveUid) {
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())));
resp.setFromUser(buildFromUser(userMap.get(a.getFromUid()),itemMap));
resp.setMessage(buildMessage(a, replyMap, userMap, markMap.getOrDefault(a.getId(), new ArrayList<>()), receiveUid));
return resp;
})
@@ -80,11 +81,18 @@ public class MessageAdapter {
return mark;
}
private static ChatMessageResp.UserInfo buildFromUser(User fromUser) {
private static ChatMessageResp.UserInfo buildFromUser(User fromUser, Map<Long, ItemConfig> itemMap) {
ChatMessageResp.UserInfo userInfo = new ChatMessageResp.UserInfo();
userInfo.setUsername(fromUser.getName());
userInfo.setAvatar(fromUser.getAvatar());
userInfo.setUid(fromUser.getId());
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());
userInfo.setBadge(badge);
}
return userInfo;
}

View File

@@ -17,8 +17,10 @@ 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.user.dao.UserDao;
import com.abin.mallchat.common.user.domain.entity.ItemConfig;
import com.abin.mallchat.common.user.domain.entity.User;
import com.abin.mallchat.common.user.domain.enums.ChatActiveStatusEnum;
import com.abin.mallchat.common.user.service.cache.ItemCache;
import com.abin.mallchat.common.user.service.cache.UserCache;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageMarkReq;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessagePageReq;
@@ -69,6 +71,8 @@ public class ChatServiceImpl implements ChatService {
private RoomDao roomDao;
@Autowired
private MessageMarkDao messageMarkDao;
@Autowired
private ItemCache itemCache;
/**
* 发送消息
@@ -209,7 +213,8 @@ public class ChatServiceImpl implements ChatService {
return new ArrayList<>();
}
Map<Long, Message> replyMap = new HashMap<>();
Map<Long, User> userMap = new HashMap<>();
Map<Long, User> userMap;
Map<Long, ItemConfig> itemMap;
//批量查出回复的消息
List<Long> replyIds = messages.stream().map(Message::getReplyMsgId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
if (CollectionUtil.isNotEmpty(replyIds)) {
@@ -218,9 +223,11 @@ 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()));
//查询消息标志
List<MessageMark> msgMark = messageMarkDao.getValidMarkByMsgIdBatch(messages.stream().map(Message::getId).collect(Collectors.toList()));
return MessageAdapter.buildMsgResp(messages, replyMap, userMap, msgMark, receiveUid);
return MessageAdapter.buildMsgResp(messages, replyMap, userMap, msgMark, receiveUid,itemMap);
}
}

View File

@@ -38,7 +38,7 @@ public class UserOnlineListener {
User user = event.getUser();
userCache.online(user.getId(), user.getLastOptTime());
//推送给所有在线用户,该用户登录成功
webSocketService.sendToAllOnline(wsAdapter.buildOnlineNotifyResp(event.getUser()), event.getUser().getId());
webSocketService.sendToAllOnline(wsAdapter.buildOnlineNotifyResp(event.getUser()), null);
}
@Async

View File

@@ -59,7 +59,7 @@ public class WxPortalController {
log.error("callBack error",e);
}
RedirectView redirectView = new RedirectView();
redirectView.setUrl("https://mp.weixin.qq.com/s/MKCWzoCIzvh5G_1sK5sLoA");
redirectView.setUrl("https://mp.weixin.qq.com/s/m1SRsBG96kLJW5mPe4AVGA");
return redirectView;
}

View File

@@ -17,7 +17,7 @@ public class BadgeResp {
private Long id;
@ApiModelProperty(value = "徽章图标")
private String image;
private String img;
@ApiModelProperty(value = "徽章描述")
private String describe;

View File

@@ -91,7 +91,9 @@ public class WxMsgService {
public void authorize(WxOAuth2UserInfo userInfo) {
User user = userDao.getByOpenId(userInfo.getOpenid());
//更新用户信息
fillUserInfo(user.getId(), userInfo);
if(Objects.isNull(user.getName())){
fillUserInfo(user.getId(), userInfo);
}
//触发用户登录成功操作
Integer eventKey = OPENID_EVENT_CODE_MAP.get(userInfo.getOpenid());
login(user.getId(), eventKey);

View File

@@ -1,6 +1,8 @@
package com.abin.mallchat.custom.user.service.handler;
import cn.hutool.json.JSONUtil;
import com.abin.mallchat.common.chat.dao.WxMsgDao;
import com.abin.mallchat.common.chat.domain.entity.WxMsg;
import com.abin.mallchat.custom.user.service.adapter.TextBuilder;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
@@ -9,6 +11,7 @@ import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutTextMessage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
@@ -21,12 +24,18 @@ import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType;
@Component
public class MsgHandler extends AbstractHandler {
@Autowired
private WxMsgDao wxMsgDao;
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map<String, Object> context, WxMpService weixinService,
WxSessionManager sessionManager) {
if (true) {
return WxMpXmlOutMessage.TEXT().build();
WxMsg msg =new WxMsg();
msg.setOpenId(wxMessage.getFromUser());
msg.setMsg(wxMessage.getContent());
wxMsgDao.save(msg);
return null;
}
if (!wxMessage.getMsgType().equals(XmlMsgType.EVENT)) {
//可以选择将消息保存到本地

View File

@@ -7,6 +7,7 @@ import com.abin.mallchat.common.common.config.ThreadPoolConfig;
import com.abin.mallchat.common.user.dao.UserDao;
import com.abin.mallchat.common.user.domain.entity.User;
import com.abin.mallchat.common.common.event.UserOfflineEvent;
import com.abin.mallchat.common.user.service.cache.UserCache;
import com.abin.mallchat.custom.user.domain.dto.ws.WSChannelExtraDTO;
import com.abin.mallchat.custom.user.domain.vo.request.ws.WSAuthorize;
import com.abin.mallchat.custom.user.domain.vo.response.ws.WSBaseResp;
@@ -51,7 +52,8 @@ public class WebSocketServiceImpl implements WebSocketService {
* 所有已连接的websocket连接列表和一些额外参数
*/
private static final ConcurrentHashMap<Channel, WSChannelExtraDTO> ONLINE_WS_MAP = new ConcurrentHashMap<>();
public static ConcurrentHashMap<Channel, WSChannelExtraDTO> getOnlineMap(){
public static ConcurrentHashMap<Channel, WSChannelExtraDTO> getOnlineMap() {
return ONLINE_WS_MAP;
}
@@ -67,6 +69,8 @@ public class WebSocketServiceImpl implements WebSocketService {
@Autowired
@Qualifier(ThreadPoolConfig.WS_EXECUTOR)
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Autowired
private UserCache userCache;
/**
* 处理用户登录请求需要返回一张带code的二维码
@@ -144,12 +148,14 @@ public class WebSocketServiceImpl implements WebSocketService {
//返回给用户登录成功
sendMsg(channel, WSAdapter.buildLoginSuccessResp(user, token));
//发送用户上线事件
user.setLastOptTime(new Date());
user.getIpInfo().refreshIp(NettyUtil.getAttr(channel, NettyUtil.IP));
applicationEventPublisher.publishEvent(new UserOnlineEvent(this, user));
boolean online = userCache.isOnline(user.getId());
if (!online) {
user.setLastOptTime(new Date());
user.getIpInfo().refreshIp(NettyUtil.getAttr(channel, NettyUtil.IP));
applicationEventPublisher.publishEvent(new UserOnlineEvent(this, user));
}
}
/**
* 用户上线
*/

View File

@@ -86,17 +86,18 @@ public class NettyWebSocketServerHandler extends SimpleChannelInboundHandler<Tex
// 读取客户端发送的请求报文
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
log.info("服务器端收到消息 = " + msg.text());
WSBaseReq wsBaseReq = JSONUtil.toBean(msg.text(), WSBaseReq.class);
WSReqTypeEnum wsReqTypeEnum = WSReqTypeEnum.of(wsBaseReq.getType());
switch (wsReqTypeEnum) {
case LOGIN:
getService().handleLoginReq(ctx.channel());
log.info("请求二维码 = " + msg.text());
break;
case HEARTBEAT:
break;
case AUTHORIZE:
getService().authorize(ctx.channel(), JSONUtil.toBean(wsBaseReq.getData(), WSAuthorize.class));
log.info("主动认证 = " + msg.text());
default:
log.info("未知类型");
}