package com.ruoyi.app.pay; import com.ruoyi.app.order.dto.OrderPushBodyDto; import com.ruoyi.app.order.DeliveryOrderNotificationService; import com.ruoyi.app.order.MerchantNotificationRouter; import com.ruoyi.app.utils.PayPush; 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.PosOrder; import com.ruoyi.system.service.IInfoUserService; import com.ruoyi.system.utils.OrderLogHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.transaction.support.TransactionSynchronization; import java.util.Locale; import org.springframework.transaction.support.TransactionSynchronizationManager; /** Executes the existing one-time order log and push side effects after LINE payment capture. */ @Service public class LinePayOrderNotificationService { private static final Logger log = LoggerFactory.getLogger(LinePayOrderNotificationService.class); private final IInfoUserService infoUserService; private final PushEventService pushEventService; private final OrderLogHelper orderLogHelper; private final DeliveryOrderNotificationService deliveryOrderNotificationService; private final MerchantNotificationRouter merchantNotificationRouter; public LinePayOrderNotificationService(IInfoUserService infoUserService, PushEventService pushEventService, OrderLogHelper orderLogHelper, DeliveryOrderNotificationService deliveryOrderNotificationService, MerchantNotificationRouter merchantNotificationRouter) { this.infoUserService = infoUserService; this.pushEventService = pushEventService; this.orderLogHelper = orderLogHelper; this.deliveryOrderNotificationService = deliveryOrderNotificationService; this.merchantNotificationRouter = merchantNotificationRouter; } public void paymentCaptured(PosOrder order) { orderLogHelper.logSync(String.valueOf(order.getDdId()), 0, null, "system", "LINE Pay payment captured"); runAfterCommit(() -> pushPaymentSuccess(order)); } private void pushPaymentSuccess(PosOrder order) { try { String ddId = String.valueOf(order.getDdId()); String body = OrderPushBodyDto.getJson(ddId, String.valueOf(order.getState()), 0); InfoUser user = order.getUserId() == null ? null : infoUserService.getById(order.getUserId()); if (user != null) { // 推送常在异步线程执行(confirm 回调投递 linePayTaskExecutor),无请求级 locale, // 必须按收件人用户语言解析,否则回落 JVM 默认语言(线上为英文) Locale userLocale = LocaleUtils.getUserLocale(user.getUserId()); String title = MessageUtils.message("no.message.push.message", userLocale); String content = MessageUtils.message("no.message.push.payment.success", userLocale); new PayPush().apppush(user.getCid(), title, content, body); pushEventService.PublisherEvent(user.getUserId(), title, content, body); } if (Long.valueOf(0L).equals(order.getType())) { deliveryOrderNotificationService.notifyOrderAvailable(order); } else { merchantNotificationRouter.sendStoreNotification(order.getMdId(), order.getShId(), "no.message.push.message", "no.message.push.new.order", body, ddId); } } catch (Exception exception) { log.error("LINE Pay payment success push failed, ddId={}", order.getDdId(), exception); } } private static void runAfterCommit(Runnable action) { if (!TransactionSynchronizationManager.isSynchronizationActive()) { action.run(); return; } TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { @Override public void afterCommit() { action.run(); } }); } }