Эх сурвалжийг харах

!1023 【优化】SYSTEM: 根据代码评审优化订阅消息
Merge pull request !1023 from puhui999/develop

芋道源码 9 сар өмнө
parent
commit
3be6ee271b
12 өөрчлөгдсөн 126 нэмэгдсэн , 252 устгасан
  1. 0 15
      yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/MessageTemplateConstants.java
  2. 0 1
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/message/package-info.java
  3. 0 56
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/message/subscribe/SubscribeMessageClient.java
  4. 30 17
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java
  5. 1 16
      yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApi.java
  6. 28 33
      yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialWxSubscribeMessageSendReqDTO.java
  7. 23 67
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApiImpl.java
  8. 6 5
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/SocialClientController.http
  9. 4 2
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/SocialClientController.java
  10. 0 33
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/social/SocialUserConvert.java
  11. 4 2
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientService.java
  12. 30 5
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java

+ 0 - 15
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/MessageTemplateConstants.java

@@ -11,19 +11,4 @@ public interface MessageTemplateConstants {
 
     String PAY_WALLET_CHANGE = "充值成功通知";
 
-    // TODO @puhui999:这种建议不枚举,直接写~嘿嘿。
-    /**
-     * 充值成功通知模版参数
-     *
-     * @author HUIHUI
-     */
-    class PayWalletChangeTemplateParams {
-
-        public static final String NO = "character_string1"; // 流水编号
-        public static final String PRICE = "amount2"; // 充值金额
-        public static final String PAY_TIME = "time3"; // 充值时间
-        public static final String STATUS = "phrase4"; // 充值状态
-
-    }
-
 }

+ 0 - 1
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/message/package-info.java

@@ -1 +0,0 @@
-package cn.iocoder.yudao.module.pay.message;

+ 0 - 56
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/message/subscribe/SubscribeMessageClient.java

@@ -1,56 +0,0 @@
-package cn.iocoder.yudao.module.pay.message.subscribe;
-
-import cn.iocoder.yudao.module.system.api.social.SocialClientApi;
-import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.scheduling.annotation.Async;
-import org.springframework.stereotype.Component;
-
-import java.util.Map;
-
-import static cn.iocoder.yudao.module.pay.enums.MessageTemplateConstants.PAY_WALLET_CHANGE;
-
-// TODO @puhui999:建议可以先直接调用,不要新建一个 client。
-/**
- * 订阅消息
- *
- * @author HUIHUI
- */
-@Component
-@Slf4j
-public class SubscribeMessageClient {
-
-    public static final String WALLET_MONEY_PATH = "pages/user/wallet/money"; // 钱包详情页
-
-    @Resource
-    public SocialClientApi socialClientApi;
-
-    /**
-     * 发送钱包充值通知
-     *
-     * @param messages 消息
-     * @param userType 用户类型
-     * @param userId   用户编号
-     */
-    @Async
-    public void sendPayWalletChangeMessage(Map<String, String> messages, Integer userType, Long userId) {
-        sendWxMessage(PAY_WALLET_CHANGE, messages, userType, userId, WALLET_MONEY_PATH);
-    }
-
-
-    /**
-     * 发送微信订阅消息
-     *
-     * @param templateTitle 模版标题
-     * @param messages      消息
-     * @param userType      用户类型
-     * @param userId        用户编号
-     * @param path          点击模板卡片后的跳转页面,仅限本小程序内的页面
-     */
-    private void sendWxMessage(String templateTitle, Map<String, String> messages, Integer userType, Long userId,
-                               String path) {
-        socialClientApi.sendSubscribeMessage(templateTitle, messages, userType, userId, SocialTypeEnum.WECHAT_MINI_APP.getType(), path);
-    }
-
-}

+ 30 - 17
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java

@@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.pay.service.wallet;
 
 import cn.hutool.core.date.LocalDateTimeUtil;
 import cn.hutool.core.lang.Assert;
-import cn.hutool.core.map.MapUtil;
+import cn.hutool.extra.spring.SpringUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum;
@@ -15,21 +15,22 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargeDO;
 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargePackageDO;
 import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletRechargeMapper;
-import cn.iocoder.yudao.module.pay.enums.MessageTemplateConstants;
 import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
 import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum;
 import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum;
-import cn.iocoder.yudao.module.pay.message.subscribe.SubscribeMessageClient;
 import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
 import cn.iocoder.yudao.module.pay.service.refund.PayRefundService;
+import cn.iocoder.yudao.module.system.api.social.SocialClientApi;
+import cn.iocoder.yudao.module.system.api.social.dto.SocialWxSubscribeMessageSendReqDTO;
+import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.time.Duration;
 import java.time.LocalDateTime;
-import java.util.Map;
 import java.util.Objects;
 
 import static cn.hutool.core.util.ObjectUtil.notEqual;
@@ -39,6 +40,7 @@ import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString
 import static cn.iocoder.yudao.framework.common.util.number.MoneyUtils.fenToYuanStr;
 import static cn.iocoder.yudao.module.pay.convert.wallet.PayWalletRechargeConvert.INSTANCE;
 import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*;
+import static cn.iocoder.yudao.module.pay.enums.MessageTemplateConstants.PAY_WALLET_CHANGE;
 import static cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum.*;
 
 /**
@@ -57,6 +59,8 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
 
     private static final String WALLET_RECHARGE_ORDER_SUBJECT = "钱包余额充值";
 
+    public static final String WALLET_MONEY_PATH = "pages/user/wallet/money"; // 钱包详情页
+
     @Resource
     private PayWalletRechargeMapper walletRechargeMapper;
     @Resource
@@ -68,7 +72,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
     @Resource
     private PayWalletRechargePackageService payWalletRechargePackageService;
     @Resource
-    private SubscribeMessageClient subscribeMessageClient;
+    public SocialClientApi socialClientApi;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -136,21 +140,21 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
                 PayWalletBizTypeEnum.RECHARGE, walletRecharge.getTotalPrice());
 
         // 4. 发送订阅消息
-        sendPayWalletChangeMessage(payOrderId, walletRecharge);
+        getSelf().sendPayWalletChangeMessage(payOrderId, walletRecharge);
     }
 
-    // TODO @puhui999:发送,使用异步发送;@Async
-    private void sendPayWalletChangeMessage(Long payOrderId, PayWalletRechargeDO walletRecharge) {
+    @Async
+    public void sendPayWalletChangeMessage(Long payOrderId, PayWalletRechargeDO walletRecharge) {
+        // 1.1 获得会员钱包信息
         PayWalletDO wallet = payWalletService.getWallet(walletRecharge.getWalletId());
-        // TODO @puhui999:可以使用 MapUtil.builder();另外,不应该是并发 hashmap 哈
-        Map<String, String> messages = MapUtil.newConcurrentHashMap(4);
-        messages.put(MessageTemplateConstants.PayWalletChangeTemplateParams.NO, String.valueOf(payOrderId));
-        messages.put(MessageTemplateConstants.PayWalletChangeTemplateParams.PRICE,
-                fenToYuanStr(walletRecharge.getTotalPrice()));
-        messages.put(MessageTemplateConstants.PayWalletChangeTemplateParams.STATUS, "充值成功");
-        messages.put(MessageTemplateConstants.PayWalletChangeTemplateParams.PAY_TIME,
-                LocalDateTimeUtil.formatNormal(LocalDateTime.now()));
-        subscribeMessageClient.sendPayWalletChangeMessage(messages, wallet.getUserType(), wallet.getUserId());
+        // 1.2 构建并发送模版消息
+        socialClientApi.sendSubscribeMessage(new SocialWxSubscribeMessageSendReqDTO().setPage(WALLET_MONEY_PATH)
+                .setUserId(wallet.getUserId()).setUserType(wallet.getUserType()).setTemplateTitle(PAY_WALLET_CHANGE)
+                .setSocialType(SocialTypeEnum.WECHAT_MINI_APP.getType())
+                // 添加模版消息
+                .addMessage("phrase4", "充值成功").addMessage("character_string1", String.valueOf(payOrderId))
+                .addMessage("amount2", fenToYuanStr(walletRecharge.getTotalPrice()))
+                .addMessage("time3", LocalDateTimeUtil.formatNormal(LocalDateTime.now())));
     }
 
     @Override
@@ -307,4 +311,13 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
         return payOrder;
     }
 
+    /**
+     * 获得自身的代理对象,解决 AOP 生效问题
+     *
+     * @return 自己
+     */
+    private PayWalletRechargeServiceImpl getSelf() {
+        return SpringUtil.getBean(getClass());
+    }
+
 }

+ 1 - 16
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApi.java

@@ -5,7 +5,6 @@ import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
 import jakarta.validation.Valid;
 
 import java.util.List;
-import java.util.Map;
 
 /**
  * 社交应用的 API 接口
@@ -57,25 +56,11 @@ public interface SocialClientApi {
      */
     List<SocialWxSubscribeTemplateRespDTO> getSubscribeTemplateList(Integer userType);
 
-    // TODO @puhui999:sendSubscribeMessage 两个方法,可以融合成一个么?
     /**
      * 发送微信小程序订阅消息
      *
      * @param reqDTO 请求
      */
-    void sendSubscribeMessage(SocialWxSubscribeMessageSendReqDTO reqDTO, Integer userType);
-
-    /**
-     * 发送微信小程序订阅消息
-     *
-     * @param templateTitle 模版标题
-     * @param messages      消息
-     * @param userType      用户类型
-     * @param userId        用户编号
-     * @param socialType    社交客服端类型
-     * @param path          点击模板卡片后的跳转页面,仅限本小程序内的页面
-     */
-    void sendSubscribeMessage(String templateTitle, Map<String, String> messages, Integer userType, Long userId,
-                              Integer socialType, String path);
+    void sendSubscribeMessage(SocialWxSubscribeMessageSendReqDTO reqDTO);
 
 }

+ 28 - 33
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialWxSubscribeMessageSendReqDTO.java

@@ -1,69 +1,64 @@
 package cn.iocoder.yudao.module.system.api.social.dto;
 
-import jakarta.validation.constraints.NotNull;
+import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
+import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
 import lombok.Data;
 
+import java.util.HashMap;
 import java.util.Map;
 
 /**
  * 微信小程序订阅消息发送 Request DTO
  *
- * @see <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html">接口文档</a>
  * @author HUIHUI
  */
 @Data
 public class SocialWxSubscribeMessageSendReqDTO {
 
-    // TODO @puhui999:貌似使用 userId + userType 会不会更合理哈。这样,后端进行查询三方用户的绑定表~
     /**
-     * 接收者(用户)的 openid.
-     * <pre>
-     * 参数:touser
-     * 是否必填: 是
-     * 描述: 接收者(用户)的 openid
-     * </pre>
+     * 用户 id
+     *
+     * 关联 MemberUserDO 的 id 编号
+     * 关联 AdminUserDO 的 id 编号
      */
-    @NotNull(message = "接收者(用户)的 openid不能为空")
-    private String toUser;
-
+    private Long userId;
     /**
-     * 模版消息编号
+     * 用户类型, 预留 多商户转帐可能需要用到
+     *
+     * 关联 {@link UserTypeEnum}
      */
-    @NotNull(message = "模版消息编号不能为空")
-    private String templateId;
+    private Integer userType;
 
     /**
-     * 点击模板卡片后的跳转页面,仅限本小程序内的页面
+     * 社交类型
      *
-     * 支持带参数,(示例 index?foo=bar )。该字段不填则模板无跳转。
+     * 枚举 {@link SocialTypeEnum}
      */
-    private String page;
+    private Integer socialType;
 
     /**
-     * 跳转小程序类型
-     *
-     * developer 为开发版;trial 为体验版;formal 为正式版【默认】
-     *
-     * 枚举 WxMaConstants.MiniProgramState
+     * 消息模版标题
      */
-    // TODO @puhui999:这个非必填。如果没有,代码里去默认下;
-    @NotNull(message = "跳转小程序类型不能为空")
-    private String miniprogramState;
+    private String templateTitle;
 
     /**
-     * 进入小程序查看的语言类型
-     *
-     * zh_CN(简体中文)【默认】、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文)
+     * 点击模板卡片后的跳转页面,仅限本小程序内的页面
      *
-     * 枚举 WxMaConstants.MiniProgramLang
+     * 支持带参数,(示例 index?foo=bar )。该字段不填则模板无跳转。
      */
-    // TODO @puhui999:这个非必填。如果没有,代码里去默认下;
-    @NotNull(message = "进入小程序查看的语言类型不能为空")
-    private String lang;
+    private String page;
 
     /**
      * 模板内容的参数
      */
     private Map<String, String> messages;
 
+    public SocialWxSubscribeMessageSendReqDTO addMessage(String key, String value) {
+        if (messages == null) {
+            messages = new HashMap<>();
+        }
+        messages.put(key, value);
+        return this;
+    }
+
 }

+ 23 - 67
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApiImpl.java

@@ -2,12 +2,10 @@ package cn.iocoder.yudao.module.system.api.social;
 
 import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
 import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.util.ObjUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.system.api.social.dto.*;
-import cn.iocoder.yudao.module.system.convert.social.SocialUserConvert;
 import cn.iocoder.yudao.module.system.service.social.SocialClientService;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
@@ -18,7 +16,9 @@ import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
 import java.util.List;
-import java.util.Map;
+
+import static cn.hutool.core.collection.CollUtil.findOne;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
 
 /**
  * 社交应用的 API 实现类
@@ -65,80 +65,36 @@ public class SocialClientApiImpl implements SocialClientApi {
     @Override
     public List<SocialWxSubscribeTemplateRespDTO> getSubscribeTemplateList(Integer userType) {
         List<TemplateInfo> subscribeTemplate = socialClientService.getSubscribeTemplateList(userType);
-        return SocialUserConvert.INSTANCE.convertList(subscribeTemplate);
+        return convertList(subscribeTemplate, item -> BeanUtils.toBean(item, SocialWxSubscribeTemplateRespDTO.class)
+                .setId(item.getPriTmplId()));
     }
 
     @Override
-    public void sendSubscribeMessage(SocialWxSubscribeMessageSendReqDTO reqDTO, Integer userType) {
-        socialClientService.sendSubscribeMessage(reqDTO, userType);
-    }
-
-    public void sendSubscribeMessage(String templateTitle, Map<String, String> messages, Integer userType, Long userId,
-                            Integer socialType, String path) {
-        // TODO @puhui999:建议是,先不拆小方法。因为逻辑的复杂度其实不高哈。合在一个方法里,因为咱写了 1.1 1.2 2. 这样的逻辑,也能一下子看懂。
-        // 1.1 获得订阅模版
-        SocialWxSubscribeTemplateRespDTO template = getTemplate(templateTitle, userType);
-        if (template == null) {
+    public void sendSubscribeMessage(SocialWxSubscribeMessageSendReqDTO reqDTO) {
+        // 1.1 获得订阅模版列表
+        List<SocialWxSubscribeTemplateRespDTO> templateList = getSubscribeTemplateList(reqDTO.getUserType());
+        if (CollUtil.isEmpty(templateList)) {
+            log.warn("[sendSubscribeMessage][reqDTO({}) 发送订阅消息失败,原因:没有找到订阅模板]", reqDTO);
             return;
         }
-        // 1.2 获得发送对象的 openId
-        String openId = getUserOpenId(userType, userId, socialType);
-        if (StrUtil.isBlankIfStr(openId)) {
+        // 1.2 获得需要使用的模版
+        SocialWxSubscribeTemplateRespDTO template = findOne(templateList, item ->
+                ObjUtil.equal(item.getTitle(), reqDTO.getTemplateTitle()));
+        if (template == null) {
+            log.warn("[sendSubscribeMessage][reqDTO({}) 发送订阅消息失败,原因:没有找到订阅模板]", reqDTO);
             return;
         }
 
-        // 2. 发送消息
-        sendSubscribeMessage(buildMessageSendReqDTO(openId, path, template).setMessages(messages), userType);
-    }
-
-    /**
-     * 构建发送消息请求参数
-     *
-     * @param openId   接收者(用户)的 openid
-     * @param path     点击模板卡片后的跳转页面,仅限本小程序内的页面
-     * @param template 订阅模版
-     * @return 微信小程序订阅消息发送
-     */
-    private SocialWxSubscribeMessageSendReqDTO buildMessageSendReqDTO(String openId, String path,
-                                                                      SocialWxSubscribeTemplateRespDTO template) {
-        return new SocialWxSubscribeMessageSendReqDTO().setLang("zh_CN").setMiniprogramState(envVersion)
-                .setTemplateId(template.getId()).setToUser(openId).setPage(path);
-    }
-
-    // TODO @puhui999:建议下沉到 service 实现。
-    /**
-     * 获得小程序订阅消息模版
-     *
-     * @param templateTitle 模版标题
-     * @param userType      用户类型
-     * @return 小程序订阅消息模版
-     */
-    private SocialWxSubscribeTemplateRespDTO getTemplate(String templateTitle, Integer userType) {
-        List<SocialWxSubscribeTemplateRespDTO> templateList = getSubscribeTemplateList(userType);
-        if (CollUtil.isEmpty(templateList)) {
-            log.warn("[getTemplate][templateTitle({}) userType({}) 没有找到订阅模板]", templateTitle, userType);
-            return null;
-        }
-        return CollectionUtil.findOne(templateList, item -> ObjUtil.equal(item.getTitle(), templateTitle));
-    }
-
-    // TODO @puhui999:建议下沉到 service 实现。
-    /**
-     * 获得用户 openId
-     *
-     * @param userType   用户类型
-     * @param userId     用户编号
-     * @param socialType 社交类型
-     * @return 用户 openId
-     */
-    private String getUserOpenId(Integer userType, Long userId, Integer socialType) {
-        SocialUserRespDTO socialUser = socialUserApi.getSocialUserByUserId(userType, userId, socialType);
+        // 2. 获得社交用户
+        SocialUserRespDTO socialUser = socialUserApi.getSocialUserByUserId(reqDTO.getUserType(), reqDTO.getUserId(),
+                reqDTO.getSocialType());
         if (StrUtil.isBlankIfStr(socialUser.getOpenid())) {
-            log.warn("[getUserOpenId][userType({}) userId({}) socialType({}) 会员 openid 缺失]",
-                    userType, userId, socialType);
-            return null;
+            log.warn("[sendSubscribeMessage][reqDTO({}) 发送订阅消息失败,原因:会员 openid 缺失]", reqDTO);
+            return;
         }
-        return socialUser.getOpenid();
+
+        // 3. 发送订阅消息
+        socialClientService.sendSubscribeMessage(reqDTO, template.getId(), socialUser.getOpenid());
     }
 
 }

+ 6 - 5
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/SocialClientController.http

@@ -6,14 +6,15 @@ Content-Type: application/json
 tenant-id: {{adminTenentId}}
 
 {
-  "toUser": "oKNkb4xxw2H135-MVPKtEMkumK08",
-  "templateId": "W4ybDTIwCfKHtMKR7fSfx83DtmVKEeXQo3Ti7GCw4_4",
-  "miniprogramState": "developer",
-  "lang": "zh_CN",
+  "userId": 247,
+  "userType": 1,
+  "socialType": 34,
+  "templateTitle": "充值成功通知",
+  "page": "",
   "messages": {
      "character_string1":"5616122165165",
      "amount2":"1000.00",
      "time3":"2024-01-01 10:10:10",
-     "phrase4":"成功"
+    "phrase4": "充值成功"
   }
 }

+ 4 - 2
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/SocialClientController.java

@@ -1,9 +1,9 @@
 package cn.iocoder.yudao.module.system.controller.admin.socail;
 
-import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.system.api.social.SocialClientApi;
 import cn.iocoder.yudao.module.system.api.social.dto.SocialWxSubscribeMessageSendReqDTO;
 import cn.iocoder.yudao.module.system.controller.admin.socail.vo.client.SocialClientPageReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.socail.vo.client.SocialClientRespVO;
@@ -29,6 +29,8 @@ public class SocialClientController {
 
     @Resource
     private SocialClientService socialClientService;
+    @Resource
+    private SocialClientApi socialClientApi;
 
     @PostMapping("/create")
     @Operation(summary = "创建社交客户端")
@@ -75,7 +77,7 @@ public class SocialClientController {
     @Operation(summary = "发送订阅消息") // 用于测试
     @PreAuthorize("@ss.hasPermission('system:social-client:query')")
     public void sendSubscribeMessage(@RequestBody SocialWxSubscribeMessageSendReqDTO reqDTO) {
-        socialClientService.sendSubscribeMessage(reqDTO, UserTypeEnum.MEMBER.getValue());
+        socialClientApi.sendSubscribeMessage(reqDTO);
     }
 
 }

+ 0 - 33
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/social/SocialUserConvert.java

@@ -1,23 +1,11 @@
 package cn.iocoder.yudao.module.system.convert.social;
 
-import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
-import cn.hutool.core.collection.CollUtil;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
-import cn.iocoder.yudao.module.system.api.social.dto.SocialWxSubscribeMessageSendReqDTO;
-import cn.iocoder.yudao.module.system.api.social.dto.SocialWxSubscribeTemplateRespDTO;
 import cn.iocoder.yudao.module.system.controller.admin.socail.vo.user.SocialUserBindReqVO;
-import me.chanjar.weixin.common.bean.subscribemsg.TemplateInfo;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
 import org.mapstruct.factory.Mappers;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
-
 @Mapper
 public interface SocialUserConvert {
 
@@ -26,25 +14,4 @@ public interface SocialUserConvert {
     @Mapping(source = "reqVO.type", target = "socialType")
     SocialUserBindReqDTO convert(Long userId, Integer userType, SocialUserBindReqVO reqVO);
 
-    // TODO @puhui999:要不 convert 直接放到 service 里。
-    default WxMaSubscribeMessage convert(SocialWxSubscribeMessageSendReqDTO reqDTO) {
-        WxMaSubscribeMessage message = BeanUtils.toBean(reqDTO, WxMaSubscribeMessage.class);
-        Map<String, String> messages = reqDTO.getMessages();
-        if (CollUtil.isNotEmpty(messages)) {
-            messages.keySet().forEach(key -> findAndThen(messages, key, value -> message.addData(new WxMaSubscribeMessage.MsgData(key, value))));
-        }
-        return message;
-    }
-
-    // TODO @puhui999:要不 convert 直接放到 service 里。其实可以 BeanUtils.toBean(reqDTO, WxMaSubscribeMessage.class) 来搞的呀。
-    @Mapping(target = "id", source = "priTmplId")
-    SocialWxSubscribeTemplateRespDTO convert(TemplateInfo templateInfo);
-
-    // TODO @puhui999:是不是用 CollectionUtils.convertList 就 ok 啦。
-    default List<SocialWxSubscribeTemplateRespDTO> convertList(List<TemplateInfo> subscribeTemplate) {
-        List<SocialWxSubscribeTemplateRespDTO> list = new ArrayList<>();
-        subscribeTemplate.forEach(templateInfo -> list.add(convert(templateInfo)));
-        return list;
-    }
-
 }

+ 4 - 2
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientService.java

@@ -83,9 +83,11 @@ public interface SocialClientService {
     /**
      * 发送微信小程序订阅消息
      *
-     * @param reqDTO 请求
+     * @param reqDTO     请求
+     * @param templateId 模版编号
+     * @param openId     会员 openId
      */
-    void sendSubscribeMessage(SocialWxSubscribeMessageSendReqDTO reqDTO, Integer userType);
+    void sendSubscribeMessage(SocialWxSubscribeMessageSendReqDTO reqDTO, String templateId, String openId);
 
     // =================== 客户端管理 ===================
 

+ 30 - 5
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java

@@ -4,8 +4,10 @@ import cn.binarywang.wx.miniapp.api.WxMaService;
 import cn.binarywang.wx.miniapp.api.WxMaSubscribeService;
 import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
 import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
+import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
 import cn.binarywang.wx.miniapp.config.impl.WxMaRedisBetterConfigImpl;
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.ObjUtil;
 import cn.hutool.core.util.ReflectUtil;
@@ -19,7 +21,6 @@ import cn.iocoder.yudao.module.system.api.social.dto.SocialWxQrcodeReqDTO;
 import cn.iocoder.yudao.module.system.api.social.dto.SocialWxSubscribeMessageSendReqDTO;
 import cn.iocoder.yudao.module.system.controller.admin.socail.vo.client.SocialClientPageReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.socail.vo.client.SocialClientSaveReqVO;
-import cn.iocoder.yudao.module.system.convert.social.SocialUserConvert;
 import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialClientDO;
 import cn.iocoder.yudao.module.system.dal.mysql.social.SocialClientMapper;
 import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
@@ -51,9 +52,11 @@ import org.springframework.stereotype.Service;
 
 import java.time.Duration;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
 import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
 
@@ -273,17 +276,39 @@ public class SocialClientServiceImpl implements SocialClientService {
     }
 
     @Override
-    public void sendSubscribeMessage(SocialWxSubscribeMessageSendReqDTO reqDTO, Integer userType) {
-        WxMaService service = getWxMaService(userType);
+    public void sendSubscribeMessage(SocialWxSubscribeMessageSendReqDTO reqDTO, String templateId, String openId) {
+        WxMaService service = getWxMaService(reqDTO.getUserType());
         try {
             WxMaSubscribeService subscribeService = service.getSubscribeService();
-            subscribeService.sendSubscribeMsg(SocialUserConvert.INSTANCE.convert(reqDTO));
+            subscribeService.sendSubscribeMsg(buildMessageSendReqDTO(reqDTO, templateId, openId));
         } catch (WxErrorException e) {
-            log.error("[sendSubscribeMessage][reqVO({}) userType({}) 发送小程序订阅消息]", reqDTO, userType, e);
+            log.error("[sendSubscribeMessage][reqVO({}) templateId({}) openId({}) 发送小程序订阅消息失败]", reqDTO, templateId, openId, e);
             throw exception(SOCIAL_CLIENT_WEIXIN_MINI_APP_SUBSCRIBE_MESSAGE_ERROR);
         }
     }
 
+    /**
+     * 构建发送消息请求参数
+     *
+     * @param reqDTO     请求
+     * @param templateId 模版编号
+     * @param openId     会员 openId
+     * @return 微信小程序订阅消息发送
+     */
+    private WxMaSubscribeMessage buildMessageSendReqDTO(SocialWxSubscribeMessageSendReqDTO reqDTO,
+                                                        String templateId, String openId) {
+        // 1.1 设置订阅消息基本参数
+        WxMaSubscribeMessage subscribeMessage = new WxMaSubscribeMessage().setLang("zh_CN").setMiniprogramState(envVersion)
+                .setTemplateId(templateId).setToUser(openId).setPage(reqDTO.getPage());
+        // 1.2 设置具体消息参数
+        Map<String, String> messages = reqDTO.getMessages();
+        if (CollUtil.isNotEmpty(messages)) {
+            messages.keySet().forEach(key -> findAndThen(messages, key, value ->
+                    subscribeMessage.addData(new WxMaSubscribeMessage.MsgData(key, value))));
+        }
+        return subscribeMessage;
+    }
+
     /**
      * 获得 clientId + clientSecret 对应的 WxMpService 对象
      *