WechatCustomerServiceImpl.java 11 KB

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