DeliveryOrderNotificationService.java 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. package com.ruoyi.app.order;
  2. import com.ruoyi.app.order.dto.OrderPushBodyDto;
  3. import com.ruoyi.app.push.BusinessPushProperties;
  4. import com.ruoyi.app.push.NativeRiderBatchPushService;
  5. import com.ruoyi.app.utils.PayPush;
  6. import com.ruoyi.app.utils.event.PushEventService;
  7. import com.ruoyi.framework.manager.AsyncManager;
  8. import com.ruoyi.system.domain.InfoUser;
  9. import com.ruoyi.system.domain.PosOrder;
  10. import com.ruoyi.system.domain.RiderPosition;
  11. import com.ruoyi.system.mapper.RiderPositionMapper;
  12. import com.ruoyi.system.service.IInfoUserService;
  13. import org.springframework.beans.factory.annotation.Autowired;
  14. import org.springframework.stereotype.Service;
  15. import org.springframework.transaction.support.TransactionSynchronization;
  16. import org.springframework.transaction.support.TransactionSynchronizationManager;
  17. import java.util.LinkedHashSet;
  18. import java.util.List;
  19. import java.util.Set;
  20. import java.util.TimerTask;
  21. /** 外送订单开放接单及取消后的推送。 */
  22. @Service
  23. public class DeliveryOrderNotificationService {
  24. private static final int RIDER_NOTIFICATION_LIMIT = 20;
  25. private final RiderPositionMapper riderPositionMapper;
  26. private final PushEventService pushEventService;
  27. private final IInfoUserService infoUserService;
  28. private final MerchantNotificationRouter merchantNotificationRouter;
  29. private final BusinessPushProperties pushProperties;
  30. private final NativeRiderBatchPushService nativeRiderBatch;
  31. public DeliveryOrderNotificationService(RiderPositionMapper riderPositionMapper,
  32. PushEventService pushEventService) {
  33. this(riderPositionMapper, pushEventService, null, null);
  34. }
  35. public DeliveryOrderNotificationService(RiderPositionMapper riderPositionMapper,
  36. PushEventService pushEventService,
  37. IInfoUserService infoUserService) {
  38. this(riderPositionMapper, pushEventService, infoUserService, null);
  39. }
  40. public DeliveryOrderNotificationService(RiderPositionMapper riderPositionMapper,
  41. PushEventService pushEventService,
  42. IInfoUserService infoUserService,
  43. MerchantNotificationRouter merchantNotificationRouter) {
  44. this(riderPositionMapper, pushEventService, infoUserService, merchantNotificationRouter, null, null);
  45. }
  46. @Autowired
  47. public DeliveryOrderNotificationService(RiderPositionMapper riderPositionMapper,
  48. PushEventService pushEventService,
  49. IInfoUserService infoUserService,
  50. MerchantNotificationRouter merchantNotificationRouter,
  51. BusinessPushProperties pushProperties,
  52. NativeRiderBatchPushService nativeRiderBatch) {
  53. this.riderPositionMapper = riderPositionMapper;
  54. this.pushEventService = pushEventService;
  55. this.infoUserService = infoUserService;
  56. this.merchantNotificationRouter = merchantNotificationRouter;
  57. this.pushProperties = pushProperties;
  58. this.nativeRiderBatch = nativeRiderBatch;
  59. }
  60. /**
  61. * 支付完成后的新外送订单通知:自配送订单通知商家,其余订单通知附近可接单骑手。
  62. * 所有下单、支付回调与线下转账确认入口复用这里,避免遗漏自配送分流。
  63. */
  64. public void notifyOrderAvailable(PosOrder order) {
  65. if (isAvailableForSelfDeliveryMerchant(order)) {
  66. notifySelfDeliveryOrderToMerchant(order);
  67. return;
  68. }
  69. if (!isAvailableForRider(order)) {
  70. return;
  71. }
  72. runAfterCommit(() -> {
  73. List<RiderPosition> riders = riderPositionMapper.getAcceptRiderList(
  74. order.getLongitude(), order.getLatitude(), RIDER_NOTIFICATION_LIMIT);
  75. if (riders != null) {
  76. if (pushProperties != null && pushProperties.getMode() == BusinessPushProperties.Mode.NATIVE
  77. && nativeRiderBatch != null) {
  78. String ddId = String.valueOf(order.getDdId());
  79. String body = OrderPushBodyDto.getJson(ddId, String.valueOf(order.getState()), 0);
  80. nativeRiderBatch.sendNewOrder(riders, "no.message.push.message",
  81. "no.message.push.new.food.order", body, ddId,
  82. rider -> sendAvailableOrderToRider(rider, order));
  83. } else {
  84. riders.forEach(rider -> sendAvailableOrderToRider(rider, order));
  85. }
  86. }
  87. });
  88. }
  89. /** 已分配骑手的外送订单取消后,通知除取消人外的相关方。 */
  90. public void notifyOrderCancelled(PosOrder order, Long operatorId) {
  91. if (order == null || !Long.valueOf(0L).equals(order.getType())
  92. || order.getQsId() == null || infoUserService == null) {
  93. return;
  94. }
  95. runAfterCommit(() -> {
  96. Set<Long> recipientIds = new LinkedHashSet<>();
  97. recipientIds.add(order.getUserId());
  98. recipientIds.add(order.getQsId());
  99. if (merchantNotificationRouter == null) {
  100. recipientIds.add(order.getShId());
  101. }
  102. recipientIds.remove(null);
  103. recipientIds.remove(operatorId);
  104. if (recipientIds.isEmpty()) {
  105. return;
  106. }
  107. List<InfoUser> recipients = infoUserService.listByIds(recipientIds);
  108. if (recipients != null) {
  109. recipients.forEach(recipient -> sendCancelledOrder(recipient, order));
  110. }
  111. if (merchantNotificationRouter != null && shouldNotifyMerchant(operatorId)) {
  112. String ddId = String.valueOf(order.getDdId());
  113. String body = OrderPushBodyDto.getJson(ddId, "4", 0);
  114. merchantNotificationRouter.sendStoreNotification(order.getMdId(), order.getShId(),
  115. "no.message.push.message", "no.message.push.order.cancelled", body, ddId);
  116. }
  117. });
  118. }
  119. private boolean shouldNotifyMerchant(Long operatorId) {
  120. if (operatorId == null || infoUserService == null) {
  121. return true;
  122. }
  123. InfoUser operator = infoUserService.getById(operatorId);
  124. return operator == null || "0".equals(operator.getUserType()) || "2".equals(operator.getUserType());
  125. }
  126. void sendAvailableOrderToRider(RiderPosition rider, PosOrder order) {
  127. if (rider == null || rider.getRiderId() == null) {
  128. return;
  129. }
  130. String ddId = String.valueOf(order.getDdId());
  131. String body = OrderPushBodyDto.getJson(ddId, String.valueOf(order.getState()), 0);
  132. AsyncManager.me().execute(new TimerTask() {
  133. @Override
  134. public void run() {
  135. PayPush.qsPushHandleLocal(new PayPush(), pushEventService, rider.getRiderId(), rider.getCid(),
  136. "no.message.push.message", "no.message.push.new.food.order", body, "", ddId);
  137. }
  138. });
  139. }
  140. void sendCancelledOrder(InfoUser recipient, PosOrder order) {
  141. if (recipient == null || recipient.getUserId() == null) {
  142. return;
  143. }
  144. String ddId = String.valueOf(order.getDdId());
  145. String body = OrderPushBodyDto.getJson(ddId, "4", 0);
  146. AsyncManager.me().execute(new TimerTask() {
  147. @Override
  148. public void run() {
  149. PayPush push = new PayPush();
  150. if (recipient.getUserId().equals(order.getQsId())) {
  151. PayPush.qsPushHandleLocal(push, pushEventService, recipient.getUserId(), recipient.getCid(),
  152. "no.message.push.message", "no.message.push.order.cancelled", body, "", ddId);
  153. } else if (recipient.getUserId().equals(order.getShId())) {
  154. PayPush.shPushHandleLocal(push, pushEventService, recipient.getUserId(), recipient.getCid(),
  155. "no.message.push.message", "no.message.push.order.cancelled", body, "", ddId);
  156. } else {
  157. PayPush.userPushHandleLocal(push, pushEventService, recipient.getUserId(), recipient.getCid(),
  158. "no.message.push.message", "no.message.push.order.cancelled", body, "", ddId);
  159. }
  160. }
  161. });
  162. }
  163. /** 自配送新单只允许通知实际门店及其归属商家,绝不进入骑手通知链路。 */
  164. private void notifySelfDeliveryOrderToMerchant(PosOrder order) {
  165. if (merchantNotificationRouter == null) {
  166. return;
  167. }
  168. runAfterCommit(() -> {
  169. String ddId = String.valueOf(order.getDdId());
  170. String body = OrderPushBodyDto.getJson(ddId, String.valueOf(order.getState()), 0);
  171. merchantNotificationRouter.sendStoreNotification(order.getMdId(), order.getShId(),
  172. "no.message.push.message", "no.message.push.new.order", body, ddId);
  173. });
  174. }
  175. private boolean isAvailableForSelfDeliveryMerchant(PosOrder order) {
  176. return isPaidUnassignedDeliveryOrder(order) && Integer.valueOf(1).equals(order.getSelfDelivery());
  177. }
  178. private boolean isAvailableForRider(PosOrder order) {
  179. return isPaidUnassignedDeliveryOrder(order) && !Integer.valueOf(1).equals(order.getSelfDelivery());
  180. }
  181. private boolean isPaidUnassignedDeliveryOrder(PosOrder order) {
  182. return order != null
  183. && Long.valueOf(0L).equals(order.getType())
  184. && Long.valueOf(0L).equals(order.getState())
  185. && Long.valueOf(0L).equals(order.getDeliveryStatus())
  186. && Long.valueOf(1L).equals(order.getPayStatus())
  187. && Long.valueOf(0L).equals(order.getAfterSaleStatus())
  188. && order.getQsId() == null;
  189. }
  190. private static void runAfterCommit(Runnable action) {
  191. if (!TransactionSynchronizationManager.isSynchronizationActive()) {
  192. action.run();
  193. return;
  194. }
  195. TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
  196. @Override
  197. public void afterCommit() {
  198. action.run();
  199. }
  200. });
  201. }
  202. }