소스 검색

公众号模版消息:充值成功,订单结算

skyline 10 달 전
부모
커밋
ec98740d26

+ 28 - 0
car-wash-common/src/main/java/com/kym/common/enums/MsgTemplateType.java

@@ -0,0 +1,28 @@
+package com.kym.common.enums;
+
+/**
+ * 业务类型枚举
+ */
+public enum MsgTemplateType {
+    PAYMENT_SUCCESS("PAYMENT_SUCCESS"),       // 支付成功通知
+    ORDER_COMPLETED("ORDER_COMPLETED");       // 订单完成提醒
+
+    private final String bizType;
+
+    MsgTemplateType(String bizType) {
+        this.bizType = bizType;
+    }
+
+    public static MsgTemplateType fromBizType(String bizType) {
+        for (MsgTemplateType type : values()) {
+            if (type.getBizType().equals(bizType)) {
+                return type;
+            }
+        }
+        throw new IllegalArgumentException("未知的业务类型: " + bizType);
+    }
+
+    public String getBizType() {
+        return bizType;
+    }
+}

+ 5 - 0
car-wash-entity/src/main/java/com/kym/entity/MpMsgTemplate.java

@@ -25,6 +25,11 @@ public class MpMsgTemplate extends BaseEntity {
      */
     private String templateId;
 
+    /**
+     * 业务类型
+     */
+    private String bizType;
+
     /**
      * 模板标题
      */

+ 11 - 1
car-wash-service/src/main/java/com/kym/service/MpMsgTemplateService.java

@@ -1,7 +1,10 @@
 package com.kym.service;
 
-import com.kym.entity.MpMsgTemplate;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.kym.common.enums.MsgTemplateType;
+import com.kym.entity.MpMsgTemplate;
+import com.kym.entity.PayLog;
+import com.kym.entity.WashOrder;
 
 /**
  * <p>
@@ -13,4 +16,11 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface MpMsgTemplateService extends IService<MpMsgTemplate> {
 
+    // 发送支付成功消息
+    void sendPaymentSuccessMsg(PayLog payLog, Integer balance);
+
+    // 发送订单完成提醒
+    void sendOrderCompletedMsg(WashOrder washOrder, Integer balance);
+
+    void sendTemplateMessage(MsgTemplateType templateType, Long userId, Object... args);
 }

+ 11 - 5
car-wash-service/src/main/java/com/kym/service/awoara/event/handle/OrderCloseEventHandler.java

@@ -29,16 +29,20 @@ public class OrderCloseEventHandler implements AwoaraEventHandler<OrderInfoObjec
     private final StationAccountService stationAccountService;
     private final SplitRecordService splitRecordService;
 
+    private final MpMsgTemplateService mpMsgTemplateService;
+
     private final StationAccountRecordService stationAccountRecordService;
 
     public OrderCloseEventHandler(WashOrderService washOrderService, WalletDetailService walletDetailService,
                                   AccountService accountService, StationAccountService stationAccountService,
-                                  SplitRecordService splitRecordService, StationAccountRecordService stationAccountRecordService) {
+                                  SplitRecordService splitRecordService,
+                                  StationAccountRecordService stationAccountRecordService, MpMsgTemplateService mpMsgTemplateService) {
         this.washOrderService = washOrderService;
         this.walletDetailService = walletDetailService;
         this.accountService = accountService;
         this.stationAccountService = stationAccountService;
         this.splitRecordService = splitRecordService;
+        this.mpMsgTemplateService = mpMsgTemplateService;
         this.stationAccountRecordService = stationAccountRecordService;
     }
 
@@ -132,7 +136,8 @@ public class OrderCloseEventHandler implements AwoaraEventHandler<OrderInfoObjec
         // 扣费等资金操作
         deductions(washOrder, account);
 
-
+        // 发送公众号消息
+        mpMsgTemplateService.sendOrderCompletedMsg(washOrder, account.getBalance());
     }
 
     /**
@@ -171,9 +176,9 @@ public class OrderCloseEventHandler implements AwoaraEventHandler<OrderInfoObjec
         BigDecimal consumeRate = BigDecimal.valueOf(0.3);
 
         // 平台技术服务费10%
-        var platformAmount = amount * platformRate.intValueExact();
+        var platformAmount = platformRate.multiply(BigDecimal.valueOf(amount)).intValue();
         // 解冻金额
-        var unfreezeAmount = amount * consumeRate.intValueExact();
+        var unfreezeAmount = consumeRate.multiply(BigDecimal.valueOf(amount)).intValue();
 
         int localAmount = unfreezeAmount - platformAmount;
 
@@ -261,7 +266,8 @@ public class OrderCloseEventHandler implements AwoaraEventHandler<OrderInfoObjec
         BigDecimal crossRate = BigDecimal.valueOf(0.7);
 
         // 平台技术服务费10%
-        var platformAmount = amount * platformRate.intValueExact();;
+        var platformAmount = amount * platformRate.intValueExact();
+        ;
 
         // 解冻金额 = 订单金额
         var unfreezeAmount = amount;

+ 5 - 2
car-wash-service/src/main/java/com/kym/service/awoara/factory/AwoaraEventHandlerFactory.java

@@ -23,9 +23,11 @@ public class AwoaraEventHandlerFactory {
 
     private static StationAccountRecordService stationAccountRecordService;
 
+    private static MpMsgTemplateService mpMsgTemplateService;
+
     public AwoaraEventHandlerFactory(WashDeviceService washDeviceService, WashOrderService washOrderService, WalletDetailService walletDetailService,
                                      AccountService accountService, StationAccountService stationAccountService, SplitRecordService splitRecordService,
-                                     StationAccountRecordService stationAccountRecordService) {
+                                     StationAccountRecordService stationAccountRecordService, MpMsgTemplateService mpMsgTemplateService) {
         AwoaraEventHandlerFactory.washDeviceService = washDeviceService;
         AwoaraEventHandlerFactory.washOrderService = washOrderService;
         AwoaraEventHandlerFactory.walletDetailService = walletDetailService;
@@ -33,6 +35,7 @@ public class AwoaraEventHandlerFactory {
         AwoaraEventHandlerFactory.stationAccountService = stationAccountService;
         AwoaraEventHandlerFactory.splitRecordService = splitRecordService;
         AwoaraEventHandlerFactory.stationAccountRecordService = stationAccountRecordService;
+        AwoaraEventHandlerFactory.mpMsgTemplateService = mpMsgTemplateService;
     }
 
     public static AwoaraEventHandler getEventHandler(String eventName) {
@@ -44,7 +47,7 @@ public class AwoaraEventHandlerFactory {
                 case order_create -> new OrderCreateEventHandler(washOrderService);
                 case order_update -> new OrderUpdateEventHandler(washOrderService);
                 case order_close ->
-                        new OrderCloseEventHandler(washOrderService, walletDetailService, accountService, stationAccountService, splitRecordService, stationAccountRecordService);
+                        new OrderCloseEventHandler(washOrderService, walletDetailService, accountService, stationAccountService, splitRecordService, stationAccountRecordService, mpMsgTemplateService);
                 case user_login -> new UserLoginEventHandler();
                 case card_event -> new CardEventHandler();
             };

+ 11 - 3
car-wash-service/src/main/java/com/kym/service/cache/KymCache.java

@@ -25,7 +25,6 @@ public enum KymCache {
     private static ConcurrentHashMap<String, String> SHORT_ID_TO_PRODUCT_KEY_AND_DEVICE_NAME_MAPPING = new ConcurrentHashMap<>();
 
 
-
     /**
      * 用户id与归属站点id映射
      *
@@ -41,7 +40,16 @@ public enum KymCache {
      * @param userId
      */
     public String getUserStationId(Long userId) {
-        return  KymCacheInjector.redisTemplate.opsForValue().get(RedisKeys.USER_ID_TO_STATION_ID + userId);
+        return KymCacheInjector.redisTemplate.opsForValue().get(RedisKeys.USER_ID_TO_STATION_ID + userId);
+    }
+
+    /**
+     * 通过消费用户id获取归属站点Id
+     *
+     * @param userId
+     */
+    public String getUserStationName(Long userId) {
+        return getStationNameById(getUserStationId(userId));
     }
 
     /**
@@ -116,7 +124,6 @@ public enum KymCache {
     }
 
 
-
     /**
      * 缓存短编号和设备信息
      *
@@ -175,6 +182,7 @@ public enum KymCache {
     public void putShortId2SeqName(Map<String, String> map) {
         map.forEach((k, v) -> KymCacheInjector.redisTemplate.opsForValue().set(RedisKeys.SHORT_ID_TO_SEQ_NAME + k, v));
     }
+
     public String getSeqNameByShortId(String shortId) {
         return KymCacheInjector.redisTemplate.opsForValue().get(RedisKeys.SHORT_ID_TO_SEQ_NAME + shortId);
     }

+ 49 - 1
car-wash-service/src/main/java/com/kym/service/impl/MpMsgTemplateServiceImpl.java

@@ -1,11 +1,20 @@
 package com.kym.service.impl;
 
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.kym.common.enums.MsgTemplateType;
+import com.kym.common.utils.wx.WxPbUtil;
 import com.kym.entity.MpMsgTemplate;
+import com.kym.entity.MpRelation;
+import com.kym.entity.PayLog;
+import com.kym.entity.WashOrder;
 import com.kym.mapper.MpMsgTemplateMapper;
 import com.kym.service.MpMsgTemplateService;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.kym.service.MpRelationService;
+import com.kym.service.wechat.TemplateParamBuilder;
 import org.springframework.stereotype.Service;
 
+import java.util.Map;
+
 /**
  * <p>
  * 微信公众号消息模版表 服务实现类
@@ -16,5 +25,44 @@ import org.springframework.stereotype.Service;
  */
 @Service
 public class MpMsgTemplateServiceImpl extends ServiceImpl<MpMsgTemplateMapper, MpMsgTemplate> implements MpMsgTemplateService {
+    private final Map<MsgTemplateType, TemplateParamBuilder> paramBuilders;
+
+    private final MpRelationService mpRelationService;
+
+    public MpMsgTemplateServiceImpl(Map<MsgTemplateType, TemplateParamBuilder> paramBuilders, MpRelationService mpRelationService) {
+        this.paramBuilders = paramBuilders;
+        this.mpRelationService = mpRelationService;
+    }
+
+
+    // 发送支付成功消息
+    @Override
+    public void sendPaymentSuccessMsg(PayLog payLog, Integer balance) {
+        sendTemplateMessage(MsgTemplateType.PAYMENT_SUCCESS, payLog.getUserId(), payLog, balance);
+    }
+
+    // 发送订单完成提醒
+    @Override
+    public void sendOrderCompletedMsg(WashOrder washOrder, Integer balance) {
+        sendTemplateMessage(MsgTemplateType.ORDER_COMPLETED, washOrder.getUserId(), washOrder, balance);
+    }
+
+
+    @Override
+    public void sendTemplateMessage(MsgTemplateType templateType, Long userId, Object... args) {
+        var mpMsgTemplate = lambdaQuery().eq(MpMsgTemplate::getBizType, templateType.getBizType()).one();
+        if (mpMsgTemplate == null) return;
 
+        mpRelationService.lambdaQuery().eq(MpRelation::getUserId, userId).oneOpt().ifPresent(mpRelation -> {
+            TemplateParamBuilder builder = paramBuilders.get(templateType);
+            Map<String, String> params = builder.buildParams(args);
+            WxPbUtil.sendPublicTemplateMessage(
+                    mpRelation.getMpOpenid(),
+                    mpMsgTemplate.getTemplateId(),
+                    params,
+                    "",
+                    ""
+            );
+        });
+    }
 }

+ 12 - 0
car-wash-service/src/main/java/com/kym/service/wechat/TemplateParamBuilder.java

@@ -0,0 +1,12 @@
+package com.kym.service.wechat;
+
+import java.time.format.DateTimeFormatter;
+import java.util.Map;
+
+/**
+ * 公众号模板消息参数构建
+ */
+public interface TemplateParamBuilder {
+    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+    Map<String, String> buildParams(Object... args);
+}

+ 22 - 0
car-wash-service/src/main/java/com/kym/service/wechat/TemplateParamBuilderConfig.java

@@ -0,0 +1,22 @@
+package com.kym.service.wechat;
+
+import com.kym.common.enums.MsgTemplateType;
+import com.kym.service.wechat.impl.OrderCompletedParamBuilder;
+import com.kym.service.wechat.impl.PaymentSuccessParamBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Configuration
+public class TemplateParamBuilderConfig {
+
+    @Bean
+    public Map<MsgTemplateType, TemplateParamBuilder> templateParamBuilders() {
+        Map<MsgTemplateType, TemplateParamBuilder> builders = new HashMap<>();
+        builders.put(MsgTemplateType.PAYMENT_SUCCESS, new PaymentSuccessParamBuilder());
+        builders.put(MsgTemplateType.ORDER_COMPLETED, new OrderCompletedParamBuilder());
+        return builders;
+    }
+}

+ 31 - 0
car-wash-service/src/main/java/com/kym/service/wechat/impl/OrderCompletedParamBuilder.java

@@ -0,0 +1,31 @@
+package com.kym.service.wechat.impl;
+
+
+import com.kym.entity.WashOrder;
+import com.kym.service.cache.KymCache;
+import com.kym.service.wechat.TemplateParamBuilder;
+
+import java.time.format.DateTimeFormatter;
+import java.util.Map;
+
+/**
+ * 订单完成提醒消息模板参数构建器
+ */
+public class OrderCompletedParamBuilder implements TemplateParamBuilder {
+
+    @Override
+    public Map<String, String> buildParams(Object... args) {
+        if (args.length == 0 || !(args[0] instanceof WashOrder washOrder)) {
+            throw new IllegalArgumentException("需要传入有效的参数");
+        }
+        return Map.of(
+                "character_string2", washOrder.getOrderId(),
+                "thing4", KymCache.INSTANCE.getStationNameById(washOrder.getStationId()), // 站点名称
+                "amount11", String.valueOf(washOrder.getAmountReceived() * 0.01) + "元", // 消费金额
+                "amount12", String.valueOf(Integer.valueOf(args[1].toString()) * 0.01) + "元",  // 账户余额
+                "time5", washOrder.getEndTime().format(formatter)
+        );
+        // LocalDateTime格式化
+
+    }
+}

+ 27 - 0
car-wash-service/src/main/java/com/kym/service/wechat/impl/PaymentSuccessParamBuilder.java

@@ -0,0 +1,27 @@
+package com.kym.service.wechat.impl;
+
+import com.kym.entity.PayLog;
+import com.kym.service.cache.KymCache;
+import com.kym.service.wechat.TemplateParamBuilder;
+
+import java.util.Map;
+
+/**
+ * 充值支付成功消息模板参数构建器
+ */
+public class PaymentSuccessParamBuilder implements TemplateParamBuilder {
+    @Override
+    public Map<String, String> buildParams(Object... args) {
+        if (args.length == 0 || !(args[0] instanceof PayLog)) {
+            throw new IllegalArgumentException("需要传入有效的参数");
+        }
+        PayLog payLog = (PayLog) args[0];
+        return Map.of(
+                "character_string4", payLog.getOutTradeNo(),
+                "thing9", KymCache.INSTANCE.getUserStationName(payLog.getUserId()),
+                "amount1", payLog.getTotal() / 100 + "元",
+                "amount2", "当前金额",
+                "time5", payLog.getSuccessTime().format(formatter)
+        );
+    }
+}

+ 6 - 1
car-wash-service/src/main/java/com/kym/service/wechat/impl/WxPayServiceImpl.java

@@ -92,6 +92,7 @@ public class WxPayServiceImpl implements WxPayService {
     private final SplitRecordService splitRecordService;
     private final StationAccountRecordService stationAccountRecordService;
     private final WashOrderService washOrderService;
+    private final MpMsgTemplateService mpMsgTemplateService;
 
 
     /**
@@ -104,7 +105,7 @@ public class WxPayServiceImpl implements WxPayService {
                             PayLogService payLogService, AccountService accountService,
                             RefundLogService refundLogService,
                             ActivityService activityService, UserRechargeRightsService userRechargeRightsService,
-                            RechargeConfigService rechargeConfigService, StationAccountService stationAccountService, SplitRecordService splitRecordService, StationAccountRecordService stationAccountRecordService, WashOrderService washOrderService) {
+                            RechargeConfigService rechargeConfigService, StationAccountService stationAccountService, SplitRecordService splitRecordService, StationAccountRecordService stationAccountRecordService, WashOrderService washOrderService, MpMsgTemplateService mpMsgTemplateService) {
         this.conf = conf;
         this.walletDetailService = walletDetailService;
         this.payLogService = payLogService;
@@ -117,6 +118,7 @@ public class WxPayServiceImpl implements WxPayService {
         this.splitRecordService = splitRecordService;
         this.stationAccountRecordService = stationAccountRecordService;
         this.washOrderService = washOrderService;
+        this.mpMsgTemplateService = mpMsgTemplateService;
     }
 
     /**
@@ -381,6 +383,9 @@ public class WxPayServiceImpl implements WxPayService {
                         .setBeforeFrozenAmount(stationAccount.getFrozenAmount() + stationFreezeAmount);
                 stationAccountRecordService.save(stationAccountRecord);
 
+                // 发送公众号消息
+                mpMsgTemplateService.sendPaymentSuccessMsg(payLog, account.getBalance());
+
                 LOGGER.info("微信支付回调{}:业务处理结束", notifyRes[2]);
                 return ResponseEntity.status(HttpStatus.OK).build();