| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- package com.ruoyi.app.push;
- import com.ruoyi.app.utils.event.PushEventService;
- import com.ruoyi.common.utils.LocaleUtils;
- import com.ruoyi.common.utils.MessageUtils;
- import com.ruoyi.system.domain.InfoUser;
- import com.ruoyi.system.domain.RiderPosition;
- import com.ruoyi.system.service.IInfoUserService;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.scheduling.annotation.Async;
- import org.springframework.stereotype.Service;
- import java.util.ArrayList;
- import java.util.LinkedHashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.function.Consumer;
- /** Batches identical Android rider alerts without changing the existing uni or iOS paths. */
- @Service
- public class NativeRiderBatchPushService {
- private static final Logger log = LoggerFactory.getLogger(NativeRiderBatchPushService.class);
- private final BusinessPushProperties properties;
- private final IInfoUserService users;
- private final FcmPushSender fcm;
- private final PushEventService events;
- public NativeRiderBatchPushService(BusinessPushProperties properties, IInfoUserService users,
- FcmPushSender fcm, PushEventService events) {
- this.properties = properties;
- this.users = users;
- this.fcm = fcm;
- this.events = events;
- }
- @Async("threadPoolTaskExecutor")
- public void sendNewOrder(List<RiderPosition> riders, String titleKey, String contentKey,
- String payload, String orderNo, Consumer<RiderPosition> perRiderFallback) {
- if (riders == null || riders.isEmpty()) {
- return;
- }
- Map<Content, List<RiderTarget>> groups = new LinkedHashMap<>();
- for (RiderPosition rider : riders) {
- if (rider == null || rider.getRiderId() == null) {
- continue;
- }
- InfoUser current;
- try {
- current = users.getById(rider.getRiderId());
- } catch (RuntimeException exception) {
- perRiderFallback.accept(rider);
- continue;
- }
- if (properties.getMode() != BusinessPushProperties.Mode.NATIVE || current == null
- || current.getCidType() == null || !"android".equalsIgnoreCase(current.getCidType().trim())
- || current.getDeviceToken() == null || current.getDeviceToken().isBlank()) {
- perRiderFallback.accept(rider);
- continue;
- }
- try {
- Long userId = rider.getRiderId();
- java.util.Locale locale = LocaleUtils.getUserLocale(userId);
- String title = MessageUtils.message(titleKey, locale);
- String content = MessageUtils.message(contentKey, locale) + ",NO:" + orderNo;
- events.PublisherEvent(userId, title, content, payload);
- groups.computeIfAbsent(new Content(title, content, payload), ignored -> new ArrayList<>())
- .add(new RiderTarget(userId, current.getDeviceToken()));
- } catch (RuntimeException exception) {
- log.warn("Native rider alert preparation failed, userId={}, category={}",
- rider.getRiderId(), exception.getClass().getSimpleName());
- }
- }
- for (Map.Entry<Content, List<RiderTarget>> entry : groups.entrySet()) {
- List<RiderTarget> targets = entry.getValue();
- Content content = entry.getKey();
- try {
- List<FcmPushSender.DeliveryResult> results = fcm.sendBatch(RecipientApp.RIDER,
- targets.stream().map(RiderTarget::token).toList(),
- content.title(), content.body(), content.payload());
- for (int index = 0; index < targets.size(); index++) {
- if (index >= results.size() || !results.get(index).successful()) {
- String category = index >= results.size() ? "RESULT_MISSING" : results.get(index).category();
- log.warn("Native rider alert failed, userId={}, category={}",
- targets.get(index).userId(), category);
- }
- }
- } catch (RuntimeException exception) {
- String message = exception.getMessage();
- String category = exception instanceof IllegalStateException && message != null
- && message.matches("FCM_[A-Z0-9_]{1,64}")
- ? message : exception.getClass().getSimpleName();
- for (RiderTarget target : targets) {
- log.warn("Native rider alert failed, userId={}, category={}", target.userId(), category);
- }
- }
- }
- }
- private record Content(String title, String body, String payload) { }
- private record RiderTarget(Long userId, String token) { }
- }
|