|
@@ -141,6 +141,9 @@ import com.fs.wxwork.dto.WxWorkResponseDTO;
|
|
|
import com.fs.wxwork.dto.WxWorkSendTextMsgDTO;
|
|
import com.fs.wxwork.dto.WxWorkSendTextMsgDTO;
|
|
|
import com.fs.wxwork.dto.WxWorkUserId2VidDTO;
|
|
import com.fs.wxwork.dto.WxWorkUserId2VidDTO;
|
|
|
import com.fs.wxwork.dto.WxWorkVid2UserIdRespDTO;
|
|
import com.fs.wxwork.dto.WxWorkVid2UserIdRespDTO;
|
|
|
|
|
+import com.fs.wxwork.dto.WxwSendCDNImgMsgDTO;
|
|
|
|
|
+import com.fs.wxwork.dto.WxwUploadCdnLinkImgDTO;
|
|
|
|
|
+import com.fs.wxwork.dto.WxwUploadCdnLinkImgRespDTO;
|
|
|
import com.fs.wxwork.service.WxWorkService;
|
|
import com.fs.wxwork.service.WxWorkService;
|
|
|
import com.fs.ybPay.domain.OrderResult;
|
|
import com.fs.ybPay.domain.OrderResult;
|
|
|
import com.fs.ybPay.domain.RefundResult;
|
|
import com.fs.ybPay.domain.RefundResult;
|
|
@@ -498,6 +501,11 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
|
|
|
|
|
|
|
|
@Value("${cloud_host.company_name}")
|
|
@Value("${cloud_host.company_name}")
|
|
|
private String companyName;
|
|
private String companyName;
|
|
|
|
|
+
|
|
|
|
|
+ private static final String PAY_SUCCESS_MSG =
|
|
|
|
|
+ "尊敬的VIP,感谢您的信任与购买~若后续遇到任何售后相关问题,欢迎您第一时间联系专属销售对接处理或拨打客服电话400-0909-575。我们将竭诚为您高效解决问题,保障您的权益。";
|
|
|
|
|
+
|
|
|
|
|
+ private static final String PAY_SUCCESS_MSG_REDIS_KEY = "fs:pay:success:msg:send:";
|
|
|
@PostConstruct
|
|
@PostConstruct
|
|
|
public void initErpServiceMap() {
|
|
public void initErpServiceMap() {
|
|
|
erpServiceMap = new HashMap<>();
|
|
erpServiceMap = new HashMap<>();
|
|
@@ -3015,6 +3023,11 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
|
|
|
log.error("团购订单支付后处理失败,orderId={}", order.getId(), e);
|
|
log.error("团购订单支付后处理失败,orderId={}", order.getId(), e);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ if ("北京卓美".equals(companyName)) {
|
|
|
|
|
+ // 支付确认完成后异步推送企微感谢消息,与支付事务/回调线程分离
|
|
|
|
|
+ final Long paySuccessOrderId = order.getId();
|
|
|
|
|
+ CompletableFuture.runAsync(() -> safeSendPaySuccessMsgToWx(paySuccessOrderId));
|
|
|
|
|
+ }
|
|
|
return "SUCCESS";
|
|
return "SUCCESS";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -7473,6 +7486,93 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 支付成功后异步推送企微感谢消息;异常仅记录日志,不影响支付主流程。
|
|
|
|
|
+ */
|
|
|
|
|
+ private void safeSendPaySuccessMsgToWx(Long orderId) {
|
|
|
|
|
+ if (orderId == null) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ sendPaySuccessMsgToWx(orderId);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("推送支付成功企微消息失败,orderId:{}", orderId, e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 支付成功后向用户发送感谢文案及配图(Redis 去重,防止支付回调重试重复发送)。
|
|
|
|
|
+ */
|
|
|
|
|
+ private void sendPaySuccessMsgToWx(Long orderId) {
|
|
|
|
|
+ boolean isSend = redisCache.setIfAbsent(PAY_SUCCESS_MSG_REDIS_KEY + orderId, "1", 24, TimeUnit.HOURS);
|
|
|
|
|
+ if (!isSend) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderById(orderId);
|
|
|
|
|
+ if (order == null || order.getUserId() == null) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ List<QwExternalContact> qwExternalContact = qwExternalContactMapper.selectQwExternalContactByFsUserIdAndCompany(order.getUserId(), order.getCompanyUserId());
|
|
|
|
|
+ if (qwExternalContact == null || qwExternalContact.isEmpty()) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ for (QwExternalContact externalContact : qwExternalContact) {
|
|
|
|
|
+ Long qwUserId = externalContact.getQwUserId();
|
|
|
|
|
+ if (qwUserId == null) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ QwUser qwUser = qwUserMapper.selectQwUserById(qwUserId);
|
|
|
|
|
+ if (qwUser == null || qwUser.getUid() == null || qwUser.getServerId() == null
|
|
|
|
|
+ || qwUser.getServerStatus() != 1 || qwUser.getIpadStatus() != 1) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ WxWorkUserId2VidDTO wxWorkUserId2VidDTO = new WxWorkUserId2VidDTO();
|
|
|
|
|
+ wxWorkUserId2VidDTO.setOpenid(Collections.singletonList(externalContact.getExternalUserId()));
|
|
|
|
|
+ wxWorkUserId2VidDTO.setUuid(qwUser.getUid());
|
|
|
|
|
+ WxWorkResponseDTO<List<WxWorkVid2UserIdRespDTO>> vidResp = wxWorkService.UserId2Vid(wxWorkUserId2VidDTO, qwUser.getServerId());
|
|
|
|
|
+ List<WxWorkVid2UserIdRespDTO> data = vidResp.getData();
|
|
|
|
|
+ if (data == null || data.isEmpty()) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ Long sendId = data.get(0).getUser_id();
|
|
|
|
|
+ WxWorkSendTextMsgDTO textMsgDto = new WxWorkSendTextMsgDTO();
|
|
|
|
|
+ textMsgDto.setSend_userid(sendId);
|
|
|
|
|
+ textMsgDto.setUuid(qwUser.getUid());
|
|
|
|
|
+ textMsgDto.setContent(PAY_SUCCESS_MSG);
|
|
|
|
|
+ textMsgDto.setIsRoom(false);
|
|
|
|
|
+ wxWorkService.SendTextMsg(textMsgDto, qwUser.getServerId());
|
|
|
|
|
+ /** 支付成功企微消息配图,在配置文件中设置 store.pay-success.image-url */
|
|
|
|
|
+ String paySuccessImageUrl = "https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/vip-ele.jpg";
|
|
|
|
|
+ if (StringUtils.isNotEmpty(paySuccessImageUrl)) {
|
|
|
|
|
+ sendWxImageMsg(sendId, qwUser.getUid(), qwUser.getServerId(), paySuccessImageUrl);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ log.warn("支付成功企微配图未配置,跳过图片发送,orderId:{}", orderId);
|
|
|
|
|
+ }
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void sendWxImageMsg(Long sendId, String uuid, Long serverId, String imageUrl) {
|
|
|
|
|
+ WxwUploadCdnLinkImgDTO uploadDto = new WxwUploadCdnLinkImgDTO();
|
|
|
|
|
+ uploadDto.setUuid(uuid);
|
|
|
|
|
+ uploadDto.setUrl(imageUrl);
|
|
|
|
|
+ WxWorkResponseDTO<WxwUploadCdnLinkImgRespDTO> uploadResp = wxWorkService.uploadCdnLinkImg(uploadDto, serverId);
|
|
|
|
|
+ if (uploadResp == null || !"成功".equals(uploadResp.getErrmsg()) || uploadResp.getData() == null) {
|
|
|
|
|
+ log.warn("支付成功消息图片上传CDN失败,sendId:{},imageUrl:{}", sendId, imageUrl);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ WxwUploadCdnLinkImgRespDTO imgData = uploadResp.getData();
|
|
|
|
|
+ WxwSendCDNImgMsgDTO imgMsgDto = new WxwSendCDNImgMsgDTO();
|
|
|
|
|
+ imgMsgDto.setSend_userid(sendId);
|
|
|
|
|
+ imgMsgDto.setUuid(uuid);
|
|
|
|
|
+ imgMsgDto.setIsRoom(false);
|
|
|
|
|
+ imgMsgDto.setCdnkey(imgData.getCdn_key());
|
|
|
|
|
+ imgMsgDto.setAeskey(imgData.getAes_key());
|
|
|
|
|
+ imgMsgDto.setMd5(imgData.getMd5());
|
|
|
|
|
+ imgMsgDto.setFileSize(imgData.getSize());
|
|
|
|
|
+ wxWorkService.SendCDNImgMsg(imgMsgDto, serverId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
@Override
|
|
@Override
|
|
|
public R sendExpressInfoToWx(@PathVariable Long orderId) {
|
|
public R sendExpressInfoToWx(@PathVariable Long orderId) {
|
|
|
boolean isSend = redisCache.setIfAbsent("fs:express:info:send:" + orderId, "1", 2, TimeUnit.MINUTES);
|
|
boolean isSend = redisCache.setIfAbsent("fs:express:info:send:" + orderId, "1", 2, TimeUnit.MINUTES);
|