diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/handler/GlobalUncaughtExceptionHandler.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/handler/GlobalUncaughtExceptionHandler.java index b3229e6..4dc9775 100644 --- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/handler/GlobalUncaughtExceptionHandler.java +++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/handler/GlobalUncaughtExceptionHandler.java @@ -9,7 +9,6 @@ public class GlobalUncaughtExceptionHandler implements Thread.UncaughtException @Override public void uncaughtException(Thread t, Throwable e) { log.error("Exception in thread {} ", t.getName(), e); - e.printStackTrace(); } } diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/WeChatMsgOperationService.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/WeChatMsgOperationService.java new file mode 100644 index 0000000..1e08b4a --- /dev/null +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/WeChatMsgOperationService.java @@ -0,0 +1,14 @@ +package com.abin.mallchat.custom.chat.service; + +import java.util.List; + +public interface WeChatMsgOperationService { + /** + * 向被at的用户微信推送群聊消息 + * + * @param senderUid senderUid + * @param receiverUidList receiverUidList + * @param msg msg + */ + void publishChatMsgToWeChatUser(long senderUid, List receiverUidList, String msg); +} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/WeChatMsgOperationServiceImpl.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/WeChatMsgOperationServiceImpl.java new file mode 100644 index 0000000..10347a6 --- /dev/null +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/WeChatMsgOperationServiceImpl.java @@ -0,0 +1,102 @@ +package com.abin.mallchat.custom.chat.service.impl; + +import cn.hutool.core.thread.NamedThreadFactory; +import com.abin.mallchat.common.common.handler.GlobalUncaughtExceptionHandler; +import com.abin.mallchat.common.common.utils.JsonUtils; +import com.abin.mallchat.common.user.domain.entity.User; +import com.abin.mallchat.common.user.service.cache.UserCache; +import com.abin.mallchat.custom.chat.service.WeChatMsgOperationService; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.WxMpTemplateMsgService; +import me.chanjar.weixin.mp.bean.template.WxMpTemplateData; +import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +@Slf4j +@Component +public class WeChatMsgOperationServiceImpl implements WeChatMsgOperationService { + + private static final ExecutorService executor = new ThreadPoolExecutor(1, 10, 3000L, + TimeUnit.MILLISECONDS, + new LinkedBlockingQueue(20), + new NamedThreadFactory("wechat-operation-thread", null, false, + new GlobalUncaughtExceptionHandler())); + + // at消息的微信推送模板id + private final String atMsgPublishTemplateId = ""; + + private final String WE_CHAT_MSG_COLOR = "#A349A4"; + + @Autowired + private UserCache userCache; + + @Autowired + WxMpService wxMpService; + + @Override + public void publishChatMsgToWeChatUser(long senderUid, List receiverUidList, String msg) { + User sender = userCache.getUserInfo(senderUid); + Set uidSet = new HashSet(); + uidSet.addAll(receiverUidList); + Map userMap = userCache.getUserInfoBatch(uidSet); + userMap.values().forEach(user -> { + if (Objects.nonNull(user.getOpenId()) && user.isPublishChatToWechatSwitch()) { + executor.execute(() -> { + WxMpTemplateMessage msgTemplate = getAtMsgTemplate(sender, user.getOpenId(), msg); + publishTemplateMsg(msgTemplate); + }); + } + }); + } + + /* + * 构造微信模板消息 + */ + private WxMpTemplateMessage getAtMsgTemplate(User sender, String openId, String msg) { + return WxMpTemplateMessage.builder() + .toUser(openId) + .templateId(atMsgPublishTemplateId) + .data(generateAtMsgData(sender, msg)) + .build(); + } + + /* + * 构造微信消息模板的数据 + */ + private List generateAtMsgData(User sender, String msg) { + List dataList = new ArrayList(); +// todo: 没有消息模板,暂不实现 +// dataList.add(new WxMpTemplateData("senderName", sender.getName() , WE_CHAT_MSG_COLOR)); +// dataList.add(new WxMpTemplateData("content", msg , WE_CHAT_MSG_COLOR)); + return dataList; + } + + /** + * 推送微信模板消息 + * + * @param templateMsg 微信模板消息 + */ + protected void publishTemplateMsg(WxMpTemplateMessage templateMsg) { + WxMpTemplateMsgService wxMpTemplateMsgService = wxMpService.getTemplateMsgService(); + try { + wxMpTemplateMsgService.sendTemplateMsg(templateMsg); + } catch (WxErrorException e) { + log.error("publish we chat msg failed! open id is {}, msg is {}.", + templateMsg.getToUser(), JsonUtils.toStr(templateMsg.getData())); + } + } +} diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/common/event/listener/MessageSendListener.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/common/event/listener/MessageSendListener.java index ba8bcf0..e87bc0a 100644 --- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/common/event/listener/MessageSendListener.java +++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/common/event/listener/MessageSendListener.java @@ -5,6 +5,8 @@ import com.abin.mallchat.common.chat.domain.entity.Message; import com.abin.mallchat.common.common.event.MessageSendEvent; import com.abin.mallchat.custom.chat.domain.vo.response.ChatMessageResp; import com.abin.mallchat.custom.chat.service.ChatService; +import com.abin.mallchat.custom.chat.service.WeChatMsgOperationService; +import com.abin.mallchat.custom.chat.service.impl.WeChatMsgOperationServiceImpl; import com.abin.mallchat.custom.chatai.service.IChatAIService; import com.abin.mallchat.custom.user.service.WebSocketService; import com.abin.mallchat.custom.user.service.adapter.WSAdapter; @@ -15,6 +17,8 @@ import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import org.springframework.transaction.event.TransactionalEventListener; +import java.util.Objects; + /** * 消息发送监听器 * @@ -32,6 +36,9 @@ public class MessageSendListener { @Autowired private IChatAIService openAIService; + @Autowired + WeChatMsgOperationService weChatMsgOperationService; + @Async @TransactionalEventListener(classes = MessageSendEvent.class, fallbackExecution = true) public void notifyAllOnline(MessageSendEvent event) { @@ -46,4 +53,12 @@ public class MessageSendListener { openAIService.chat(message); } + @TransactionalEventListener(classes = MessageSendEvent.class, fallbackExecution = true) + public void publishChatToWechat(@NotNull MessageSendEvent event) { + Message message = messageDao.getById(event.getMsgId()); + if (Objects.nonNull(message.getExtra().getAtUidList())) { + weChatMsgOperationService.publishChatMsgToWeChatUser(message.getFromUid(), message.getExtra().getAtUidList(), + message.getContent()); + } + } }