WechatCustomerServiceImpl.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. package com.ydtech.modules.admin.service.impl;
  2. import com.fasterxml.jackson.core.JsonProcessingException;
  3. import com.fasterxml.jackson.dataformat.xml.XmlMapper;
  4. import com.ydtech.modules.admin.components.WechatCustomerComponents;
  5. import com.ydtech.modules.admin.components.wechat.customer.request.CustomerAddContactWayRequest;
  6. import com.ydtech.modules.admin.components.wechat.customer.request.CustomerListRequest;
  7. import com.ydtech.modules.admin.components.wechat.customer.request.CustomerSendMsgOnEventRequest;
  8. import com.ydtech.modules.admin.components.wechat.customer.response.CustomerAddContactWayResponse;
  9. import com.ydtech.modules.admin.components.wechat.customer.response.CustomerListResponse;
  10. import com.ydtech.modules.admin.model.SysUser;
  11. import com.ydtech.modules.admin.model.po.SysWechatCustomer;
  12. import com.ydtech.modules.admin.model.po.SysWechatCustomerDuty;
  13. import com.ydtech.modules.admin.model.vo.wechat.WechatCustomerCallbackVo;
  14. import com.ydtech.modules.admin.model.vo.wechat.WechatEncryptVo;
  15. import com.ydtech.modules.admin.service.*;
  16. import com.ydtech.utils.StringUtils;
  17. import lombok.RequiredArgsConstructor;
  18. import lombok.extern.slf4j.Slf4j;
  19. import me.chanjar.weixin.common.error.WxErrorException;
  20. import me.chanjar.weixin.common.util.crypto.WxCryptUtil;
  21. import me.chanjar.weixin.cp.api.WxCpKfService;
  22. import me.chanjar.weixin.cp.bean.kf.WxCpKfMsgListResp;
  23. import me.chanjar.weixin.cp.bean.kf.WxCpKfMsgSendRequest;
  24. import me.chanjar.weixin.cp.bean.kf.WxCpKfServiceStateResp;
  25. import me.chanjar.weixin.cp.bean.kf.msg.WxCpKfEventMsg;
  26. import me.chanjar.weixin.cp.bean.kf.msg.WxCpKfTextMsg;
  27. import org.springframework.data.redis.core.StringRedisTemplate;
  28. import org.springframework.stereotype.Service;
  29. import org.springframework.util.ObjectUtils;
  30. import java.time.LocalDateTime;
  31. import java.util.List;
  32. import java.util.concurrent.TimeUnit;
  33. import java.util.stream.Collectors;
  34. @Slf4j
  35. @Service
  36. @RequiredArgsConstructor
  37. public class WechatCustomerServiceImpl implements WechatCustomerService {
  38. private final WechatCustomerComponents wechatCustomerComponents;
  39. private final SysUserService sysUserService;
  40. private final XmlMapper xmlMapper = new XmlMapper();
  41. private final WxCpKfService wxCpKfService;
  42. private final SysWechatCustomerService sysWechatCustomerService;
  43. private final IWorkScheduleConfigService workScheduleConfigService;
  44. private final SysWechatCustomerDutyService sysWechatCustomerDutyService;
  45. private final StringRedisTemplate redisTemplate;
  46. @Override
  47. public String customerCallback(String msgSignature, String timestamp, String nonce, String echoStr) {
  48. WxCryptUtil wxCryptUtil = wechatCustomerComponents.getWxCryptUtil();
  49. return wxCryptUtil.decrypt(echoStr);
  50. }
  51. @Override
  52. public void callbackSendMsgOnEvent(String wechatEncrypt) throws JsonProcessingException, WxErrorException {
  53. log.info("回调参数为{}", wechatEncrypt);
  54. WechatEncryptVo wechatEncryptVo = xmlMapper.readValue(wechatEncrypt, WechatEncryptVo.class);
  55. WxCryptUtil wxCryptUtil = wechatCustomerComponents.getWxCryptUtil();
  56. log.info("解密参数为{}", wechatEncryptVo.getEncrypt());
  57. String encrypt = wxCryptUtil.decrypt(wechatEncryptVo.getEncrypt());
  58. log.info("解密后的参数为{}", encrypt);
  59. WechatCustomerCallbackVo wechatCustomerCallbackVo = xmlMapper.readValue(encrypt, WechatCustomerCallbackVo.class);
  60. // 获取消息
  61. WxCpKfMsgListResp wxCpKfMsgListResp = wxCpKfService.syncMsg(null, wechatCustomerCallbackVo.getToken(), null, null, wechatCustomerCallbackVo.getOpenKfId());
  62. while (wxCpKfMsgListResp.getHasMore() == 1) {
  63. String nextCursor = wxCpKfMsgListResp.getNextCursor();
  64. wxCpKfMsgListResp = wxCpKfService.syncMsg(nextCursor, wechatCustomerCallbackVo.getToken(), null, null, wechatCustomerCallbackVo.getOpenKfId());
  65. }
  66. List<WxCpKfMsgListResp.WxCpKfMsgItem> msgList = wxCpKfMsgListResp.getMsgList();
  67. WxCpKfMsgListResp.WxCpKfMsgItem wxCpKfMsgItem = wxCpKfMsgListResp.getMsgList().get(msgList.size() - 1);
  68. SysWechatCustomer sysWechatCustomer = sysWechatCustomerService.lambdaQuery().eq(SysWechatCustomer::getOpenKfId, wechatCustomerCallbackVo.getOpenKfId()).one();
  69. boolean workingHours = workScheduleConfigService.isWorkingHours();
  70. List<SysWechatCustomerDuty> sysWechatCustomerDuties = sysWechatCustomerDutyService.lambdaQuery()
  71. .eq(SysWechatCustomerDuty::getCustomerId, sysWechatCustomer.getId())
  72. .le(SysWechatCustomerDuty::getStartTime, LocalDateTime.now())
  73. .ge(SysWechatCustomerDuty::getEndTime, LocalDateTime.now())
  74. .list();
  75. // 改变会话状态
  76. if (wxCpKfMsgItem.getOrigin() == 3) {
  77. // 1 管理人是否一致
  78. // 2 休息日
  79. // 3 工作时间内 安排了值班客服
  80. if (!sysWechatCustomerService.whetherTheManagersAreConsistent(wxCpKfMsgItem.getExternalUserId(), sysWechatCustomer) || !workingHours || !sysWechatCustomerDuties.isEmpty()) {
  81. WxCpKfServiceStateResp serviceState = wxCpKfService.getServiceState(wxCpKfMsgItem.getOpenKfid(), wxCpKfMsgItem.getExternalUserId());
  82. Integer state1 = serviceState.getServiceState();
  83. if (state1 == 0) {
  84. state1 = 1;
  85. wxCpKfService.transServiceState(wxCpKfMsgItem.getOpenKfid(), wxCpKfMsgItem.getExternalUserId(), state1, sysWechatCustomer.getReceptionistId());
  86. restTimeSendMsg(wxCpKfMsgItem.getExternalUserId(), wxCpKfMsgItem.getOpenKfid());
  87. } else if (state1 == 1) {
  88. String s = redisTemplate.opsForValue().get(wxCpKfMsgItem.getMsgId());
  89. if (!ObjectUtils.isEmpty(s)) {
  90. return;
  91. }
  92. restTimeSendMsg(wxCpKfMsgItem.getExternalUserId(), wxCpKfMsgItem.getOpenKfid());
  93. redisTemplate.opsForValue().set(wxCpKfMsgItem.getMsgId(), wxCpKfMsgItem.getMsgId(), 1, TimeUnit.MINUTES);
  94. } else if (state1 == 3) {
  95. state1 = 4;
  96. wxCpKfService.transServiceState(wxCpKfMsgItem.getOpenKfid(), wxCpKfMsgItem.getExternalUserId(), state1, sysWechatCustomer.getReceptionistId());
  97. }
  98. } else {
  99. WxCpKfServiceStateResp serviceState = wxCpKfService.getServiceState(wxCpKfMsgItem.getOpenKfid(), wxCpKfMsgItem.getExternalUserId());
  100. Integer state1 = serviceState.getServiceState();
  101. if (state1 == 0 || state1 == 1) {
  102. state1 = 3;
  103. wxCpKfService.transServiceState(wxCpKfMsgItem.getOpenKfid(), wxCpKfMsgItem.getExternalUserId(), state1, sysWechatCustomer.getReceptionistId());
  104. }
  105. }
  106. } else if (wxCpKfMsgItem.getOrigin() == 4) {
  107. // 发送欢迎语
  108. WxCpKfEventMsg event = wxCpKfMsgItem.getEvent();
  109. if (ObjectUtils.isEmpty(event)) {
  110. return;
  111. }
  112. String scene = event.getScene();
  113. if (!StringUtils.isEmpty(scene)) {
  114. SysUser sysUser = sysUserService.getById(scene);
  115. sysUser.setExternalUserId(event.getExternalUserId());
  116. sysUserService.updateById(sysUser);
  117. CustomerSendMsgOnEventRequest customerSendMsgOnEventRequest = CustomerSendMsgOnEventRequest.sendMsgOnEvent(sysUser, event.getWelcomeCode(), workingHours);
  118. wechatCustomerComponents.sendMsgOnEvent(customerSendMsgOnEventRequest);
  119. }
  120. WxCpKfServiceStateResp serviceState = wxCpKfService.getServiceState(event.getOpenKfid(), event.getExternalUserId());
  121. Integer state = serviceState.getServiceState();
  122. if (workingHours && (state == 0 || state == 1)) {
  123. state = 3;
  124. List<SysWechatCustomer> list = sysWechatCustomerService.lambdaQuery().eq(SysWechatCustomer::getOpenKfId, wxCpKfMsgItem.getEvent().getOpenKfid()).list();
  125. String receptionistId = list.get(0).getReceptionistId();
  126. wxCpKfService.transServiceState(wxCpKfMsgItem.getEvent().getOpenKfid(), wxCpKfMsgItem.getEvent().getExternalUserId(), state, receptionistId);
  127. }
  128. }
  129. List<WxCpKfMsgListResp.WxCpKfMsgItem> msgListDTOList = msgList.stream().filter(x -> "event".equals(x.getMsgType())).collect(Collectors.toList());
  130. msgListDTOList.forEach(x -> {
  131. try {
  132. WxCpKfEventMsg xEvent = x.getEvent();
  133. WxCpKfServiceStateResp wxCpKfServiceStateResp = wxCpKfService.getServiceState(xEvent.getOpenKfid(), xEvent.getExternalUserId());
  134. Integer state = wxCpKfServiceStateResp.getServiceState();
  135. if (workingHours && (state == 0 || state == 1)) {
  136. state = 3;
  137. // 休息时间
  138. List<SysWechatCustomer> list = sysWechatCustomerService.lambdaQuery().eq(SysWechatCustomer::getOpenKfId, xEvent.getOpenKfid()).list();
  139. String receptionistId = list.get(0).getReceptionistId();
  140. wxCpKfService.transServiceState(xEvent.getOpenKfid(), xEvent.getExternalUserId(), state, receptionistId);
  141. }
  142. } catch (WxErrorException e) {
  143. throw new RuntimeException(e);
  144. }
  145. });
  146. }
  147. private void restTimeSendMsg(String externalUserId, String openKfId) throws WxErrorException {
  148. String message = "您咨询的客服目前暂时不在服务时间,请您前往“晋掌柜App”点击“微信客服”,将为您安排新的客服为您提供服务~(客服服务时间:周一至周五 8:30-18:30,周六至周日 9:00-18:00,午间 12:00-14:00 休息)";
  149. WxCpKfMsgSendRequest wxCpKfMsgSendRequest = new WxCpKfMsgSendRequest();
  150. wxCpKfMsgSendRequest.setToUser(externalUserId);
  151. wxCpKfMsgSendRequest.setOpenKfid(openKfId);
  152. wxCpKfMsgSendRequest.setMsgType("text");
  153. WxCpKfTextMsg wxCpKfTextMsg = new WxCpKfTextMsg();
  154. wxCpKfTextMsg.setContent(message);
  155. wxCpKfMsgSendRequest.setText(wxCpKfTextMsg);
  156. wxCpKfService.sendMsg(wxCpKfMsgSendRequest);
  157. }
  158. @Override
  159. public List<CustomerListResponse.AccountListDTO> list() {
  160. CustomerListRequest customerListResponse = new CustomerListRequest(0, 100);
  161. return wechatCustomerComponents.list(customerListResponse).getAccountList();
  162. }
  163. @Override
  164. public String addContactWay(String openKfId) {
  165. CustomerAddContactWayRequest customerAddContactWayRequest = new CustomerAddContactWayRequest(openKfId, "WELCOME_MESSAGE");
  166. CustomerAddContactWayResponse customerAddContactWayResponse = wechatCustomerComponents.addContactWay(customerAddContactWayRequest);
  167. return customerAddContactWayResponse.getUrl();
  168. }
  169. }