mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-01 02:38:43 +08:00 
			
		
		
		
	【优化】SYSTEM: 根据代码评审优化小程序的订阅消息
This commit is contained in:
		| @@ -54,13 +54,13 @@ public interface SocialClientApi { | ||||
|      * | ||||
|      * @return 小程序订阅消息模版 | ||||
|      */ | ||||
|     List<SocialWxSubscribeTemplateRespDTO> getSubscribeTemplate(); | ||||
|     List<SocialWxSubscribeTemplateRespDTO> getSubscribeTemplateList(Integer userType); | ||||
|  | ||||
|     /** | ||||
|      * 发送微信小程序订阅消息 | ||||
|      * | ||||
|      * @param reqDTO 请求 | ||||
|      */ | ||||
|     void sendSubscribeMessage(SocialWxSubscribeMessageReqDTO reqDTO); | ||||
|     void sendSubscribeMessage(SocialWxSubscribeMessageSendReqDTO reqDTO, Integer userType); | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,21 +1,20 @@ | ||||
| package cn.iocoder.yudao.module.system.api.social.dto; | ||||
| 
 | ||||
| import cn.iocoder.yudao.framework.common.core.KeyValue; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.Data; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| // TODO @puhui99:1)参考 SocialWxQrcodeReqDTO,可以 @see 文档。这样,注释会更见见一点。2)是不是少了 Send:SocialWxSubscribeMessageSendReqDTO | ||||
| /** | ||||
|  * 微信小程序订阅消息 Request DTO | ||||
|  * 微信小程序订阅消息发送 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 SocialWxSubscribeMessageReqDTO { | ||||
| public class SocialWxSubscribeMessageSendReqDTO { | ||||
| 
 | ||||
|     // TODO @puhui999:参数校验 | ||||
|     /** | ||||
|      * 接收者(用户)的 openid. | ||||
|      * <pre> | ||||
| @@ -24,6 +23,7 @@ public class SocialWxSubscribeMessageReqDTO { | ||||
|      * 描述: 接收者(用户)的 openid | ||||
|      * </pre> | ||||
|      */ | ||||
|     @NotNull(message = "接收者(用户)的 openid不能为空") | ||||
|     private String toUser; | ||||
| 
 | ||||
|     /** | ||||
| @@ -34,6 +34,7 @@ public class SocialWxSubscribeMessageReqDTO { | ||||
|      * 描述: 所需下发的模板消息的id | ||||
|      * </pre> | ||||
|      */ | ||||
|     @NotNull(message = "模板消息的id不能为空") | ||||
|     private String templateId; | ||||
| 
 | ||||
|     /** | ||||
| @@ -51,6 +52,7 @@ public class SocialWxSubscribeMessageReqDTO { | ||||
|      * | ||||
|      * 枚举 WxMaConstants.MiniProgramState | ||||
|      */ | ||||
|     @NotNull(message = "跳转小程序类型不能为空") | ||||
|     private String miniprogramState; | ||||
| 
 | ||||
|     /** | ||||
| @@ -58,9 +60,9 @@ public class SocialWxSubscribeMessageReqDTO { | ||||
|      * | ||||
|      * 枚举 WxMaConstants.MiniProgramLang | ||||
|      */ | ||||
|     @NotNull(message = "进入小程序查看的语言类型不能为空") | ||||
|     private String lang; | ||||
| 
 | ||||
|     // TODO @puhui999:是必须 List<KeyValue<String, String>>,还是 Map<String, String 即可) | ||||
|     /** | ||||
|      * 模板内容,不填则下发空模板. | ||||
|      * <pre> | ||||
| @@ -69,13 +71,13 @@ public class SocialWxSubscribeMessageReqDTO { | ||||
|      * 描述: 模板内容,不填则下发空模板 | ||||
|      * </pre> | ||||
|      */ | ||||
|     private List<KeyValue<String, String>> messages; | ||||
|     private Map<String, String> messages; | ||||
| 
 | ||||
|     public SocialWxSubscribeMessageReqDTO addData(String key, String value) { | ||||
|     public SocialWxSubscribeMessageSendReqDTO addData(String key, String value) { | ||||
|         if (messages == null) { | ||||
|             messages = new ArrayList<>(); | ||||
|             messages = new HashMap<>(); | ||||
|         } | ||||
|         messages.add(new KeyValue<>(key, value)); | ||||
|         messages.put(key, value); | ||||
|         return this; | ||||
|     } | ||||
| 
 | ||||
| @@ -11,11 +11,10 @@ import lombok.Data; | ||||
| @Data | ||||
| public class SocialWxSubscribeTemplateRespDTO { | ||||
|  | ||||
|     // TODO @puhui999:建议搞成 id | ||||
|     /** | ||||
|      * 添加至账号下的模板 id,发送小程序订阅消息时所需 | ||||
|      */ | ||||
|     private String priTmplId; | ||||
|     private String id; | ||||
|  | ||||
|     /** | ||||
|      * 模版标题 | ||||
| @@ -32,7 +31,7 @@ public class SocialWxSubscribeTemplateRespDTO { | ||||
|      */ | ||||
|     private String example; | ||||
|  | ||||
|     // TODO @puhui999:这个在 wxjava 里面,有枚举字段么? | ||||
|     // TODO @puhui999:这个在 wxjava 里面,有枚举字段么?没得🤣 | ||||
|     /** | ||||
|      * 模版类型 | ||||
|      * | ||||
|   | ||||
| @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.api.social; | ||||
| import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; | ||||
| 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 me.chanjar.weixin.common.bean.WxJsapiSignature; | ||||
| @@ -47,14 +48,14 @@ public class SocialClientApiImpl implements SocialClientApi { | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<SocialWxSubscribeTemplateRespDTO> getSubscribeTemplate() { | ||||
|         List<TemplateInfo> subscribeTemplate = socialClientService.getSubscribeTemplate(); | ||||
|         return BeanUtils.toBean(subscribeTemplate, SocialWxSubscribeTemplateRespDTO.class); | ||||
|     public List<SocialWxSubscribeTemplateRespDTO> getSubscribeTemplateList(Integer userType) { | ||||
|         List<TemplateInfo> subscribeTemplate = socialClientService.getSubscribeTemplateList(userType); | ||||
|         return SocialUserConvert.INSTANCE.convertList(subscribeTemplate); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void sendSubscribeMessage(SocialWxSubscribeMessageReqDTO reqDTO) { | ||||
|         socialClientService.sendSubscribeMessage(reqDTO); | ||||
|     public void sendSubscribeMessage(SocialWxSubscribeMessageSendReqDTO reqDTO, Integer userType) { | ||||
|         socialClientService.sendSubscribeMessage(reqDTO, userType); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,19 @@ | ||||
| ### 请求 /system/social-client/send-subscribe-message 接口 => 发送测试订阅消息 | ||||
| POST {{baseUrl}}/system/social-client/send-subscribe-message | ||||
| Authorization: Bearer {{token}} | ||||
| Content-Type: application/json | ||||
| #Authorization: Bearer test100 | ||||
| tenant-id: {{adminTenentId}} | ||||
|  | ||||
| { | ||||
|   "toUser": "oKNkb4xxw2H135-MVPKtEMkumK08", | ||||
|   "templateId": "W4ybDTIwCfKHtMKR7fSfx83DtmVKEeXQo3Ti7GCw4_4", | ||||
|   "miniprogramState": "developer", | ||||
|   "lang": "zh_CN", | ||||
|   "messages": { | ||||
|      "character_string1":"5616122165165", | ||||
|      "amount2":"1000.00", | ||||
|      "time3":"2024-01-01 10:10:10", | ||||
|      "phrase4":"成功" | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,9 +1,10 @@ | ||||
| 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.dto.SocialWxSubscribeMessageReqDTO; | ||||
| 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; | ||||
| import cn.iocoder.yudao.module.system.controller.admin.socail.vo.client.SocialClientSaveReqVO; | ||||
| @@ -72,15 +73,9 @@ public class SocialClientController { | ||||
|  | ||||
|     //======================= TODO 测试发送订阅消息 ======================= | ||||
|  | ||||
|     // TODO @puhui999:这个接口,其实可以留着。然后把参数挪到 .http 文件。先直接用 SocialWxSubscribeMessageReqDTO 接参数 | ||||
|     @PostMapping("/send-subscribe-message") | ||||
|     public void testSendSubscribeMessage() { | ||||
|         SocialWxSubscribeMessageReqDTO reqDTO = new SocialWxSubscribeMessageReqDTO().setLang("zh_CN") | ||||
|                 .setMiniprogramState("developer").setTemplateId("W4ybDTIwCfKHtMKR7fSfx83DtmVKEeXQo3Ti7GCw4_4") | ||||
|                 .setToUser("oKNkb4xxw2H135-MVPKtEMkumK08"); | ||||
|         reqDTO.addData("character_string1", "11111111").addData("amount2", "6666").addData("time3", "2024-01-01 10:10:10") | ||||
|                 .addData("phrase4", "成功"); | ||||
|         socialClientService.sendSubscribeMessage(reqDTO); | ||||
|     public void testSendSubscribeMessage(@RequestBody SocialWxSubscribeMessageSendReqDTO reqDTO) { | ||||
|         socialClientService.sendSubscribeMessage(reqDTO, UserTypeEnum.MEMBER.getValue()); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,11 +1,23 @@ | ||||
| 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 { | ||||
|  | ||||
| @@ -14,4 +26,24 @@ public interface SocialUserConvert { | ||||
|     @Mapping(source = "reqVO.type", target = "socialType") | ||||
|     SocialUserBindReqDTO convert(Long userId, Integer userType, SocialUserBindReqVO reqVO); | ||||
|  | ||||
|     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; | ||||
|     } | ||||
|  | ||||
|     @Mapping(target = "id", source = "priTmplId") | ||||
|     SocialWxSubscribeTemplateRespDTO convert(TemplateInfo templateInfo); | ||||
|  | ||||
|     default List<SocialWxSubscribeTemplateRespDTO> convertList(List<TemplateInfo> subscribeTemplate) { | ||||
|         List<SocialWxSubscribeTemplateRespDTO> list = new ArrayList<>(); | ||||
|         subscribeTemplate.forEach(templateInfo -> list.add(convert(templateInfo))); | ||||
|         return list; | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.system.service.social; | ||||
| import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; | ||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||
| import cn.iocoder.yudao.module.system.api.social.dto.SocialWxQrcodeReqDTO; | ||||
| import cn.iocoder.yudao.module.system.api.social.dto.SocialWxSubscribeMessageReqDTO; | ||||
| 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.dal.dataobject.social.SocialClientDO; | ||||
| @@ -78,14 +78,14 @@ public interface SocialClientService { | ||||
|      * | ||||
|      * @return 微信小程订阅模板 | ||||
|      */ | ||||
|     List<TemplateInfo> getSubscribeTemplate(); | ||||
|     List<TemplateInfo> getSubscribeTemplateList(Integer userType); | ||||
|  | ||||
|     /** | ||||
|      * 发送微信小程序订阅消息 | ||||
|      * | ||||
|      * @param reqDTO 请求 | ||||
|      */ | ||||
|     void sendSubscribeMessage(SocialWxSubscribeMessageReqDTO reqDTO); | ||||
|     void sendSubscribeMessage(SocialWxSubscribeMessageSendReqDTO reqDTO, Integer userType); | ||||
|  | ||||
|     // =================== 客户端管理 =================== | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,6 @@ 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.lang.Assert; | ||||
| @@ -17,9 +16,10 @@ import cn.iocoder.yudao.framework.common.util.cache.CacheUtils; | ||||
| import cn.iocoder.yudao.framework.common.util.http.HttpUtils; | ||||
| import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||||
| import cn.iocoder.yudao.module.system.api.social.dto.SocialWxQrcodeReqDTO; | ||||
| import cn.iocoder.yudao.module.system.api.social.dto.SocialWxSubscribeMessageReqDTO; | ||||
| 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; | ||||
| @@ -236,7 +236,6 @@ public class SocialClientServiceImpl implements SocialClientService { | ||||
|         try { | ||||
|             return service.getUserService().getPhoneNoInfo(phoneCode); | ||||
|         } catch (WxErrorException e) { | ||||
|             // TODO @puhui999:这里的日志,reqDTO 要打进去 | ||||
|             log.error("[getPhoneNoInfo][userType({}) phoneCode({}) 获得手机号失败]", userType, phoneCode, e); | ||||
|             throw exception(SOCIAL_CLIENT_WEIXIN_MINI_APP_PHONE_CODE_ERROR); | ||||
|         } | ||||
| @@ -256,36 +255,31 @@ public class SocialClientServiceImpl implements SocialClientService { | ||||
|                     null, | ||||
|                     ObjUtil.defaultIfNull(reqVO.getHyaline(), SocialWxQrcodeReqDTO.HYALINE)); | ||||
|         } catch (WxErrorException e) { | ||||
|             log.error("[getWxQrcode][reqVO({})) 获得小程序码失败]", reqVO, e); | ||||
|             log.error("[getWxQrcode][reqVO({}) 获得小程序码失败]", reqVO, e); | ||||
|             throw exception(SOCIAL_CLIENT_WEIXIN_MINI_APP_QRCODE_ERROR); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<TemplateInfo> getSubscribeTemplate() { | ||||
|         // TODO @puhui999:这个 userType 最好通过参数,传递过来;然后这个方法名,貌似叫 getSubscribeTemplateList 更合适哈; | ||||
|         WxMaService service = getWxMaService(UserTypeEnum.MEMBER.getValue()); | ||||
|     public List<TemplateInfo> getSubscribeTemplateList(Integer userType) { | ||||
|         WxMaService service = getWxMaService(userType); | ||||
|         try { | ||||
|             WxMaSubscribeService subscribeService = service.getSubscribeService(); | ||||
|             return subscribeService.getTemplateList(); | ||||
|         } catch (WxErrorException e) { | ||||
|             log.error("[getSubscribeTemplate][获得小程序订阅消息模版]", e); | ||||
|             log.error("[getSubscribeTemplate][userType({}) 获得小程序订阅消息模版]", userType, e); | ||||
|             throw exception(SOCIAL_CLIENT_WEIXIN_MINI_APP_SUBSCRIBE_TEMPLATE_ERROR); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void sendSubscribeMessage(SocialWxSubscribeMessageReqDTO reqDTO) { | ||||
|         // TODO @puhui999:这个 userType 最好通过参数, | ||||
|         WxMaService service = getWxMaService(UserTypeEnum.MEMBER.getValue()); | ||||
|     public void sendSubscribeMessage(SocialWxSubscribeMessageSendReqDTO reqDTO, Integer userType) { | ||||
|         WxMaService service = getWxMaService(userType); | ||||
|         try { | ||||
|             WxMaSubscribeService subscribeService = service.getSubscribeService(); | ||||
|             WxMaSubscribeMessage message = BeanUtils.toBean(reqDTO, WxMaSubscribeMessage.class); | ||||
|             reqDTO.getMessages().forEach(item-> message.addData(new WxMaSubscribeMessage.MsgData(item.getKey(), item.getValue()))); | ||||
|             subscribeService.sendSubscribeMsg(message); | ||||
|             subscribeService.sendSubscribeMsg(SocialUserConvert.INSTANCE.convert(reqDTO)); | ||||
|         } catch (WxErrorException e) { | ||||
|             // TODO @puhui999:这里的日志,reqDTO 要打进去 | ||||
|             log.error("[sendSubscribeMessage][发送小程序订阅消息]", e); | ||||
|             log.error("[sendSubscribeMessage][reqVO({}) userType({}) 发送小程序订阅消息]", reqDTO, userType, e); | ||||
|             throw exception(SOCIAL_CLIENT_WEIXIN_MINI_APP_SUBSCRIBE_MESSAGE_ERROR); | ||||
|         } | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 puhui999
					puhui999