ISxkWelcomeMsgServiceImpl.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. package com.linkwechat.service.impl;
  2. import cn.hutool.core.collection.ListUtil;
  3. import cn.hutool.core.util.ObjectUtil;
  4. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  5. import com.linkwechat.common.constant.MessageConstants;
  6. import com.linkwechat.common.constant.WeConstans;
  7. import com.linkwechat.common.core.domain.entity.SysUser;
  8. import com.linkwechat.common.enums.CustomerAddWay;
  9. import com.linkwechat.common.enums.MessageNoticeType;
  10. import com.linkwechat.common.enums.message.MessageTypeEnum;
  11. import com.linkwechat.common.utils.StringUtils;
  12. import com.linkwechat.common.utils.xml.XmlUtils;
  13. import com.linkwechat.domain.WeCorpAccount;
  14. import com.linkwechat.domain.WeCustomer;
  15. import com.linkwechat.domain.WeCustomerSeas;
  16. import com.linkwechat.domain.WeUser;
  17. import com.linkwechat.domain.wecom.callback.WeBackCustomerVo;
  18. import com.linkwechat.domain.wecom.callback.xml.*;
  19. import com.linkwechat.domain.wecom.query.customer.WeCustomerQuery;
  20. import com.linkwechat.domain.wecom.vo.customer.WeCustomerDetailVo;
  21. import com.linkwechat.fegin.QwCustomerClient;
  22. import com.linkwechat.mapper.WeCustomerMapper;
  23. import com.linkwechat.service.*;
  24. import lombok.extern.slf4j.Slf4j;
  25. import org.springframework.beans.factory.annotation.Autowired;
  26. import org.springframework.context.annotation.Lazy;
  27. import org.springframework.scheduling.annotation.Async;
  28. import org.springframework.stereotype.Service;
  29. import org.springframework.util.CollectionUtils;
  30. import javax.annotation.Resource;
  31. import java.util.Date;
  32. import java.util.List;
  33. import java.util.Map;
  34. import java.util.Objects;
  35. /**
  36. * Created with IntelliJ IDEA.
  37. *
  38. * @Author: Shixk
  39. * @Date: 2023/12/29/14:11
  40. * @Description:
  41. */
  42. @Slf4j
  43. @Service
  44. public class ISxkWelcomeMsgServiceImpl implements ISxkWelcomeMsgService {
  45. @Autowired
  46. private MyWeFissionMsgServiceImpl myWeFissionMsgService;
  47. @Autowired
  48. private MyQrCodeMsgServiceImpl myQrCodeMsgService;
  49. @Autowired
  50. private CarQrCodeServiceImpl carQrCodeService;
  51. @Autowired
  52. private RenewalServiceImpl renewalService;
  53. @Autowired
  54. protected IWeMaterialService weMaterialService;
  55. @Autowired
  56. private IWeCorpAccountService iWeCorpAccountService;
  57. @Autowired
  58. @Lazy
  59. private IWeCustomerService iWeCustomerService;
  60. @Autowired
  61. @Lazy
  62. private IWeUserService iWeUserService;
  63. @Autowired
  64. private WeCustomerMapper weCustomerMapper;
  65. @Autowired
  66. @Lazy
  67. private IWeCustomerTrajectoryService iWeCustomerTrajectoryService;
  68. @Autowired
  69. @Lazy
  70. private IWeMessagePushService iWeMessagePushService;
  71. @Resource
  72. @Lazy
  73. private IWeMessageNotificationService weMessageNotificationService;
  74. @Resource
  75. @Lazy
  76. private IWeCustomerSeasService weCustomerSeasService;
  77. @Autowired
  78. private QwCustomerClient qwCustomerClient;
  79. /**
  80. * 业务处理
  81. *
  82. * 客户删除业务员后, 业务员不能再给客户发送消息, 但是同步客户时,该客户还能同步过来。
  83. * 业务员删除客户后, 业务员可以给客户发送消息,客户也能给业务员发消息, 同步客户时,该客户将不能再同步过来。
  84. * 互删后,同步客户,不能再同步过来.
  85. *
  86. * @param msg
  87. */
  88. @Async
  89. @Override
  90. public void msgHandle(String msg) {
  91. log.info("企微回调:msg:{}", msg);
  92. try {
  93. // 解析XML回调报文
  94. PubExternalContact pubExternalContact = XmlUtils.convertToJavaBean(msg, PubExternalContact.class);
  95. if (ObjectUtil.isEmpty(pubExternalContact)) {
  96. log.error("企微回调消息-消息处理失败,解析XML报文为空!");
  97. }
  98. String changeType = pubExternalContact.getChangeType();
  99. String event = pubExternalContact.getEvent();
  100. // 根据event和ChangeType判断事件类型
  101. // 添加企业客户事件 add_external_contact
  102. // 免验证添加成员事件 add_half_external_contact
  103. if ("change_external_contact".equals(event) && ("add_external_contact".equals(changeType)
  104. || "add_half_external_contact".equals(changeType))) {
  105. log.info("回调 添加企业客户事件/免验证添加成员事件{} , 配置了客户联系功能的成员添加外部联系人时,回调该事件", changeType);
  106. // 添加企业客户事件
  107. AddExternalContact addExternalContact = XmlUtils.convertToJavaBean(msg, AddExternalContact.class);
  108. String state = addExternalContact.getState() == null ? "" : addExternalContact.getState();
  109. WeCorpAccount weCorpAccount = iWeCorpAccountService.getCorpAccountByCorpId(null);
  110. WeBackCustomerVo vo = null;
  111. if (Objects.nonNull(weCorpAccount)) {
  112. vo = new WeBackCustomerVo();
  113. vo.setToUserName(weCorpAccount.getCorpId());
  114. vo.setState(state);
  115. vo.setWelcomeCode(addExternalContact.getWelcomeCode());
  116. // 企微人员的账号号
  117. vo.setUserID(addExternalContact.getUserID());
  118. // 客户的userid
  119. vo.setExternalUserID(addExternalContact.getExternalUserID());
  120. }
  121. if (vo != null) {
  122. if (StringUtils.isNotBlank(state) && state.startsWith(WeConstans.FISSION_PREFIX_RWB)) {
  123. log.info("是 裂变-任务宝 推送消息,开始推送消息!");
  124. // 是 裂变-任务宝 推送
  125. // 推送消息
  126. // 设置模板
  127. myWeFissionMsgService.setTemplate(vo);
  128. log.info("是 裂变-任务宝 推送消息,推送消息完成!");
  129. } else if (StringUtils.isNotBlank(state) && state.contains(WeConstans.ZM)) {
  130. log.info(" 自定义活动 推送消息......");
  131. myQrCodeMsgService.setTemplate(vo);
  132. log.info(" 自定义活动 推送消息完成");
  133. } else if (StringUtils.isNotBlank(state) && state.contains(WeConstans.WE_QR_CODE_PREFIX)) {
  134. log.info(" 活码 推送消息......");
  135. myQrCodeMsgService.setTemplate(vo);
  136. log.info(" 活码 推送消息完成");
  137. } else if (StringUtils.isNotBlank(state) && state.startsWith(WeConstans.CAR)) {
  138. log.info(" 自定义渠道[车险] 推送消息......");
  139. carQrCodeService.setTemplate(vo);
  140. log.info(" 自定义活动[车险] 推送消息完成");
  141. } else if (StringUtils.isNotBlank(state) && state.startsWith(WeConstans.RENEWAL)) {
  142. log.info(" 自定义渠道[续保管理] 推送消息......");
  143. renewalService.setTemplate(vo);
  144. log.info(" 自定义活动[续保管理] 推送消息完成");
  145. } else {
  146. // 不推送消息
  147. log.info("不是 指定 推送消息,不推送!");
  148. }
  149. WeCustomerQuery weCustomerQuery = new WeCustomerQuery();
  150. weCustomerQuery.setExternal_userid(addExternalContact.getExternalUserID());
  151. weCustomerQuery.setCorpid(addExternalContact.getToUserName());
  152. WeCustomerDetailVo customerDetail = qwCustomerClient.getCustomerDetail(weCustomerQuery).getData();
  153. // 通过手机更新同步用户的状态时间
  154. List<String> mobileList = customerDetail.getFollowUser().get(0).getRemarkMobiles();
  155. Date now = new Date();
  156. if (!CollectionUtils.isEmpty(mobileList)) {
  157. LambdaQueryWrapper<WeUser> wrapper = new LambdaQueryWrapper<>();
  158. wrapper.in(WeUser::getPhone, mobileList);
  159. List<WeUser> userList = iWeUserService.list(wrapper);
  160. if (!CollectionUtils.isEmpty(userList)) {
  161. for (WeUser user : userList) {
  162. user.setDeliveredStatus(1);
  163. user.setAddTime(now);
  164. user.setLastInteractionTime(now);
  165. }
  166. iWeUserService.saveOrUpdateBatch(userList);
  167. }
  168. }
  169. }
  170. // 同步客戶
  171. log.info("回调, 拉取业务员指定客户信息开始。。。");
  172. // iWeCustomerService.asyncWeCustomerByAddIds(ListUtil.toList(pubExternalContact.getUserID()));
  173. iWeCustomerService.addCustomer(addExternalContact.getExternalUserID(), addExternalContact.getUserID(), state);
  174. } else if ("change_external_contact".equals(event) && "edit_external_contact".equals(changeType)) {
  175. log.info("回调 编辑企业客户事件, 配置了客户联系功能的成员添加外部联系人时,回调该事件(编辑企业客户事件)");
  176. // 编辑企业客户事件
  177. EditExternalContact editExternalContact = XmlUtils.convertToJavaBean(msg, EditExternalContact.class);
  178. iWeCustomerService.updateCustomer(editExternalContact.getExternalUserID(), editExternalContact.getUserID());
  179. } else if ("change_external_contact".equals(event) && "del_external_contact".equals(changeType)) {
  180. // 员工删除客户, 客户还能给员工发信息,员工还能接收到信息, 员工显示 是否添加为联系人,然后企微同步的状态为删除
  181. // 客户删除员工, 员工不能给客户发信息,员工显示 不是好友,然后企微同步的状态为删除
  182. // 如果客户先删除员工,会回调事件(删除跟进成员事件), 紧接着员工删除客户, 会调用事件(删除企业客户事件)
  183. // 如果员工先删除客户,会回调事件(删除企业客户事件), 紧接着客户删除员工, 不会调用事件(删除跟进成员事件)
  184. // 删除企业客户事件(员工删除客户)
  185. log.info("回调 删除企业客户事件, 配置了客户联系功能的成员添加外部联系人时,回调该事件(业务员删除客户)");
  186. DelExternalContact delExternalContact = XmlUtils.convertToJavaBean(msg, DelExternalContact.class);
  187. List<WeCustomer> weCustomers = weCustomerMapper.selectList1(WeCustomer.builder()
  188. .addUserId(delExternalContact.getUserID())
  189. .externalUserid(delExternalContact.getExternalUserID())
  190. .build());
  191. if (!CollectionUtils.isEmpty(weCustomers)) {
  192. iWeCustomerService.update(WeCustomer.builder()
  193. .delFlag(1)
  194. .delFlagBei(1)
  195. .tagIds(weCustomers.get(0).getTagIds())
  196. .build(), new LambdaQueryWrapper<WeCustomer>()
  197. .eq(WeCustomer::getAddUserId, delExternalContact.getUserID())
  198. .eq(WeCustomer::getExternalUserid, delExternalContact.getExternalUserID()));
  199. iWeCustomerTrajectoryService.createAddOrRemoveTrajectory(weCustomers.get(0).getExternalUserid(), weCustomers.get(0).getAddUserId(), false, false);
  200. }
  201. } else if ("change_external_contact".equals(event) && "del_follow_user".equals(changeType)) {
  202. // 删除跟进成员事件(客户删除员工)
  203. log.info("回调 删除跟进成员事件, 配置了客户联系功能的成员添加外部联系人时,回调该事件(企业成员被客户删除)");
  204. DelFollowUserContact delFollowUserContact = XmlUtils.convertToJavaBean(msg, DelFollowUserContact.class);
  205. Map<String, SysUser> currentTenantSysUser = iWeCustomerService.findCurrentTenantSysUser();
  206. SysUser sysUser = currentTenantSysUser.get(delFollowUserContact.getUserID());
  207. List<WeCustomer> weCustomers = weCustomerMapper.selectList1(WeCustomer.builder()
  208. .addUserId(delFollowUserContact.getUserID())
  209. .externalUserid(delFollowUserContact.getExternalUserID())
  210. .build());
  211. if (!CollectionUtils.isEmpty(weCustomers)) {
  212. iWeCustomerService.update(WeCustomer.builder()
  213. .delFlagBa(1)
  214. .delFlag(1)
  215. .lossTime(new Date())
  216. .tagIds(weCustomers.get(0).getTagIds())
  217. .build(), new LambdaQueryWrapper<WeCustomer>()
  218. .eq(WeCustomer::getAddUserId, delFollowUserContact.getUserID())
  219. .eq(WeCustomer::getExternalUserid, delFollowUserContact.getExternalUserID()));
  220. // 公海客户删除
  221. if (CustomerAddWay.ADD_WAY_SSSJH.getKey().equals(weCustomers.get(0).getAddMethod())) {
  222. log.info("删除公海客户.......{}", weCustomers.get(0).getCustomerName());
  223. weCustomerSeasService.getBaseMapper().delete(new LambdaQueryWrapper<>(WeCustomerSeas.class)
  224. .in(WeCustomerSeas::getPhone, ListUtil.toList(weCustomers.get(0).getPhone().split(",")))
  225. .eq(WeCustomerSeas::getAddUserId, weCustomers.get(0).getAddUserId()));
  226. }
  227. iWeCustomerTrajectoryService.createAddOrRemoveTrajectory(weCustomers.get(0).getExternalUserid(), weCustomers.get(0).getAddUserId(), false, true);
  228. //为被删除的员工发送一条消息提醒
  229. iWeMessagePushService.pushMessageSelfH5(ListUtil.toList(delFollowUserContact.getUserID()), "【客户动态】<br/><br/> 客户@" + weCustomers.get(0).getCustomerName() + "刚刚删除了您", MessageNoticeType.DELETEWEUSER.getType(), false);
  230. //添加消息通知
  231. weMessageNotificationService.save(MessageTypeEnum.CUSTOMER.getType(), delFollowUserContact.getUserID(), MessageConstants.CUSTOMER_DELETE, weCustomers.get(0).getCustomerName());
  232. }
  233. }else if ("change_external_contact".equals(event) && "transfer_fail".equals(changeType)) {
  234. log.info("回调 客户接替失败事件, 企业将客户分配给新的成员接替后,客户添加失败时回调该事件");
  235. }else if ("change_external_chat".equals(event) && "create".equals(changeType)) {
  236. log.info("回调 客户群创建事件, 有新增客户群时,回调该事件。收到该事件后,企业可以调用获取客户群详情接口获取客户群详情。");
  237. }else if ("change_external_chat".equals(event) && "update".equals(changeType)) {
  238. log.info("回调 客户群变更事件, 客户群被修改后(群名变更,群成员增加或移除,群主变更,群公告变更),回调该事件。收到该事件后,企业需要再调用获取客户群详情接口,以获取最新的群详情。");
  239. }else if ("change_external_chat".equals(event) && "dismiss".equals(changeType)) {
  240. log.info("回调 客户群解散事件\n, 当客户群被群主解散后,回调该事件。\n" +
  241. "需注意的是,如果发生群信息变动,会立即收到此事件,但是部分信息是异步处理,可能需要等一段时间(例如2秒)调用获取客户群详情接口才能得到最新结果");
  242. }else if ("change_external_tag".equals(event) && "create".equals(changeType)) {
  243. log.info("回调 企业客户标签创建事件\n, 企业/管理员创建客户标签/标签组时(包括规则组的标签),回调此事件。收到该事件后,企业需要调用获取企业标签库来获取标签/标签组的详细信息。");
  244. }else if ("change_external_tag".equals(event) && "update".equals(changeType)) {
  245. log.info("回调 企业客户标签变更事件\n, 当企业客户标签/标签组(包括规则组的标签)被修改时,回调此事件。收到该事件后,企业需要调用获取企业标签库来获取标签/标签组的详细信息");
  246. }else if ("change_external_tag".equals(event) && "delete".equals(changeType)) {
  247. log.info("回调 企业客户标签删除事件\n, 当企业客户标签/标签组被删除时,回调此事件。删除标签组时,该标签组下的所有标签将被同时删除,但不会进行回调。\n");
  248. }else if ("change_external_tag".equals(event) && "shuffle".equals(changeType)) {
  249. log.info("回调 企业客户标签重排事件\\n,当企业管理员在终端/管理端调整标签顺序时,可能导致标签顺序整体调整重排,引起大部分标签的order值发生变化,此时会回调此事件,收到此事件后企业应尽快全量同步标签的order值,防止后续调用接口排序出现非预期结果。 ");
  250. }
  251. } catch (Exception e) {
  252. e.printStackTrace();
  253. }
  254. }
  255. /**
  256. * 客户欢迎语
  257. *
  258. * @param vo
  259. */
  260. @Override
  261. public void sendSubscribe(WeBackCustomerVo vo) {
  262. /*rabbitTemplate.convertAndSend(rabbitMQSettingConfig.getWeWelcomeMsgEx(),
  263. rabbitMQSettingConfig.getWeKfWelcomeMsgRk(),
  264. JSON.toJSONString(vo));*/
  265. myWeFissionMsgService.setTemplate(vo);
  266. }
  267. }