From 62481b9f314823dce021d3a8d11c1f55acdf2fa6 Mon Sep 17 00:00:00 2001 From: xuwenbo <717567226@qq.com> Date: Thu, 13 Aug 2020 18:52:47 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=B0=8F=E7=A8=8B=E5=BA=8F?= =?UTF-8?q?=E8=AE=A2=E9=98=85=E6=B6=88=E6=81=AF=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rest/controller/WechatController.java | 13 +- .../src/main/resources/config/application.yml | 15 +- .../yixiang/config/SubscribeProperties.java | 14 ++ .../modules/wechat/domain/YxWechatLive.java | 5 +- .../tools/config/WxMaConfiguration.java | 23 ++- .../yixiang/mp/listener/TemplateListener.java | 7 +- .../mp/service/WeiXinSubscribeService.java | 181 ++++++++++++++++++ 7 files changed, 244 insertions(+), 14 deletions(-) create mode 100644 yshop-common/src/main/java/co/yixiang/config/SubscribeProperties.java create mode 100644 yshop-weixin/src/main/java/co/yixiang/mp/service/WeiXinSubscribeService.java diff --git a/yshop-app/src/main/java/co/yixiang/modules/wechat/rest/controller/WechatController.java b/yshop-app/src/main/java/co/yixiang/modules/wechat/rest/controller/WechatController.java index 8fcacb02..8ec3556d 100644 --- a/yshop-app/src/main/java/co/yixiang/modules/wechat/rest/controller/WechatController.java +++ b/yshop-app/src/main/java/co/yixiang/modules/wechat/rest/controller/WechatController.java @@ -117,12 +117,17 @@ public class WechatController { * 微信小程序接口能力配置 */ @GetMapping("/wxapp/config") - @ApiOperation(value = "微信小程序接口能力配置",notes = "微信小程序接口能力配置") - public boolean wxAppConfig(@RequestParam(value = "signature") String signature, + @ApiOperation(value = "微信小程序接口能力配置",notes = "微信小程序接口能力配置",produces = "text/plain;charset=utf-8") + public String wxAppConfig(@RequestParam(value = "signature") String signature, @RequestParam(value = "timestamp") String timestamp, - @RequestParam(value = "nonce") String nonce) throws WxErrorException { + @RequestParam(value = "nonce") String nonce, + @RequestParam(name = "echostr", required = false) String echostr) throws WxErrorException { WxMaService wxService = WxMaConfiguration.getWxMaService(); - return wxService.checkSignature(timestamp,nonce,signature); + + if( wxService.checkSignature(timestamp,nonce,signature)){ + return echostr; + } + return "false"; } /** diff --git a/yshop-app/src/main/resources/config/application.yml b/yshop-app/src/main/resources/config/application.yml index 985d8b1a..13e2081a 100644 --- a/yshop-app/src/main/resources/config/application.yml +++ b/yshop-app/src/main/resources/config/application.yml @@ -75,8 +75,17 @@ logging: yshop: #相关配置 version: 3.0 - - + #小程序订阅消息配置 + subscribe: + subscribeMaps: + #付款成功 + pay_success: W5r2c2kzhbq8uxStkPAVx_sk-5aapMFCqe7b7KU5jXI + #发货成功 + delivery-success: 2CB_1UyQrbnlyjJa5syraqJ3cfztPPDOAHe3DEXpMjg + #退款成功 + refund_success: + #充值成功 + recharge_success: # 防止XSS攻击 xss: @@ -96,4 +105,4 @@ jwt: # sm.ms 图床的 token smms: - token: 1oOP3ykFDI0K6ifmtvU7c8Y1eTWZSlyl \ No newline at end of file + token: 1oOP3ykFDI0K6ifmtvU7c8Y1eTWZSlyl diff --git a/yshop-common/src/main/java/co/yixiang/config/SubscribeProperties.java b/yshop-common/src/main/java/co/yixiang/config/SubscribeProperties.java new file mode 100644 index 00000000..ee00467e --- /dev/null +++ b/yshop-common/src/main/java/co/yixiang/config/SubscribeProperties.java @@ -0,0 +1,14 @@ +package co.yixiang.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import java.util.Map; + +@Data +@Configuration +@ConfigurationProperties(prefix = "yshop.subscribe") +public class SubscribeProperties { + private Map subscribeMaps; +} diff --git a/yshop-mall/src/main/java/co/yixiang/modules/wechat/domain/YxWechatLive.java b/yshop-mall/src/main/java/co/yixiang/modules/wechat/domain/YxWechatLive.java index 72012025..2bc131d2 100644 --- a/yshop-mall/src/main/java/co/yixiang/modules/wechat/domain/YxWechatLive.java +++ b/yshop-mall/src/main/java/co/yixiang/modules/wechat/domain/YxWechatLive.java @@ -57,8 +57,9 @@ public class YxWechatLive implements Serializable { /** 主播头像 */ private String anchorImge; - - + /** + * 101:直播中,102:未开始,103已结束,104禁播,105:暂停,106:异常,107:已过期 + */ /** 直播间状态 */ private Integer liveStatus; diff --git a/yshop-tools/src/main/java/co/yixiang/tools/config/WxMaConfiguration.java b/yshop-tools/src/main/java/co/yixiang/tools/config/WxMaConfiguration.java index 06017930..c678fc1e 100644 --- a/yshop-tools/src/main/java/co/yixiang/tools/config/WxMaConfiguration.java +++ b/yshop-tools/src/main/java/co/yixiang/tools/config/WxMaConfiguration.java @@ -2,13 +2,18 @@ package co.yixiang.tools.config; import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; +import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage; +import cn.binarywang.wx.miniapp.bean.WxMaTemplateData; +import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl; import cn.binarywang.wx.miniapp.message.WxMaMessageHandler; import cn.binarywang.wx.miniapp.message.WxMaMessageRouter; import co.yixiang.utils.RedisUtil; import co.yixiang.utils.RedisUtils; import co.yixiang.utils.ShopKeyUtils; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import me.chanjar.weixin.common.api.WxConsts; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; @@ -24,6 +29,7 @@ public class WxMaConfiguration { private static Map routers = Maps.newHashMap(); private static RedisUtils redisUtils; private static WxMaMessageHandler wxMaMessageHandler; + public static WxMaMessageRouter getRouter(String appid) { return routers.get(appid); } @@ -63,11 +69,20 @@ public class WxMaConfiguration { } private static WxMaMessageRouter newRouter(WxMaService service) { final WxMaMessageRouter router = new WxMaMessageRouter(service); - router.rule().handler(wxMaMessageHandler).next(); + router + .rule().handler(wxMaMessageHandler).next() + .rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.SUBSCRIBE).handler(templateMsgHandler).end(); return router; } - - - + private static final WxMaMessageHandler templateMsgHandler = (wxMessage, context, service, sessionManager) -> { + service.getMsgService().sendSubscribeMsg(WxMaSubscribeMessage.builder() + .templateId("此处更换为自己的模板id") + .page("") + .data(Lists.newArrayList( + new WxMaSubscribeMessage.Data("keyword1", "339208499"))) + .toUser(wxMessage.getFromUser()) + .build()); + return null; + }; } diff --git a/yshop-weixin/src/main/java/co/yixiang/mp/listener/TemplateListener.java b/yshop-weixin/src/main/java/co/yixiang/mp/listener/TemplateListener.java index 02386e84..0b636c3f 100644 --- a/yshop-weixin/src/main/java/co/yixiang/mp/listener/TemplateListener.java +++ b/yshop-weixin/src/main/java/co/yixiang/mp/listener/TemplateListener.java @@ -13,6 +13,7 @@ import co.yixiang.enums.PayTypeEnum; import co.yixiang.event.TemplateBean; import co.yixiang.event.TemplateEvent; import co.yixiang.event.TemplateListenEnum; +import co.yixiang.mp.service.WeiXinSubscribeService; import co.yixiang.mp.service.WeixinPayService; import co.yixiang.mp.service.WeixinTemplateService; import lombok.extern.slf4j.Slf4j; @@ -36,6 +37,8 @@ public class TemplateListener implements SmartApplicationListener { private WeixinTemplateService weixinTemplateService; @Autowired private WeixinPayService weixinPayService; + @Autowired + private WeiXinSubscribeService weiXinSubscribeService; @Override public boolean supportsEventType(Class aClass) { @@ -49,11 +52,13 @@ public class TemplateListener implements SmartApplicationListener { TemplateEvent templateEvent = (TemplateEvent) applicationEvent; //获取注册用户对象信息 TemplateBean templateBean = templateEvent.getTemplateBean(); - log.info("模板事件类型:{}"+templateBean.getTemplateType()); + log.info("模板事件类型:{}",templateBean.getTemplateType()); switch (TemplateListenEnum.toType(templateBean.getTemplateType())){ case TYPE_1: weixinTemplateService.paySuccessNotice(templateBean.getOrderId() ,templateBean.getPrice(),templateBean.getUid()); + weiXinSubscribeService.paySuccessNotice(templateBean.getOrderId() + ,templateBean.getPrice(),templateBean.getUid()); break; case TYPE_2: //处理退款与消息 diff --git a/yshop-weixin/src/main/java/co/yixiang/mp/service/WeiXinSubscribeService.java b/yshop-weixin/src/main/java/co/yixiang/mp/service/WeiXinSubscribeService.java new file mode 100644 index 00000000..8a49d84e --- /dev/null +++ b/yshop-weixin/src/main/java/co/yixiang/mp/service/WeiXinSubscribeService.java @@ -0,0 +1,181 @@ +package co.yixiang.mp.service; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage; +import cn.hutool.core.util.StrUtil; +import co.yixiang.config.SubscribeProperties; +import co.yixiang.modules.user.domain.YxUser; +import co.yixiang.modules.user.service.YxUserService; +import co.yixiang.modules.user.service.dto.WechatUserDto; +import co.yixiang.mp.enums.WechatTempateEnum; +import co.yixiang.tools.config.WxMaConfiguration; +import me.chanjar.weixin.common.error.WxErrorException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; + +/** + * 小程序订阅消息通知 + */ +@Service +public class WeiXinSubscribeService { + + @Autowired + private YxUserService userService; + @Autowired + private SubscribeProperties subscribeProperties; + + + + + /** + * 充值成功通知 + * @param time 时间 + * @param price 金额 + * @param uid uid + */ + public void rechargeSuccessNotice(String time,String price,Long uid){ + String openid = this.getUserOpenid(uid); + + if(StrUtil.isBlank(openid)) return; + + Map map = new HashMap<>(); + map.put("first","您的账户金币发生变动,详情如下:"); + map.put("keyword1","充值"); + map.put("keyword2",time); + map.put("keyword3",price); + map.put("remark","yshop为你服务!"); + String tempId = this.getTempId(WechatTempateEnum.RECHARGE_SUCCESS.getValue()); + this.sendSubscribeMsg( openid, tempId, "/user/account",map); + } + + + /** + * 支付成功通知 + * @param orderId 订单号 + * @param price 金额 + * @param uid uid + */ + public void paySuccessNotice(String orderId,String price,Long uid){ + + String openid = this.getUserOpenid(uid); + if(StrUtil.isBlank(openid)) return; + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); + Map map = new HashMap<>(); + map.put("amount1",price); + map.put("date2", simpleDateFormat.format(new Date())); + map.put("character_string3",orderId); + map.put("time4",simpleDateFormat.format(new Date())); + map.put("thing5","yshop购买商品"); + String tempId = this.getTempId(WechatTempateEnum.PAY_SUCCESS.getValue()); + this.sendSubscribeMsg( openid,tempId, "/order/detail/"+orderId,map); + } + + /** + * 退款成功通知 + * @param orderId 订单号 + * @param price 金额 + * @param uid uid + * @param time 时间 + */ + public void refundSuccessNotice(String orderId,String price,Long uid,String time){ + + String openid = this.getUserOpenid(uid); + + if(StrUtil.isBlank(openid)) return; + + Map map = new HashMap<>(); + map.put("first","您的订单退款申请被通过,钱款将很快还至您的支付账户。"); + map.put("keyword1",orderId);//订单号 + map.put("keyword2",price); + map.put("keyword3", time); + map.put("remark","yshop为你服务!"); + String tempId = this.getTempId(WechatTempateEnum.REFUND_SUCCESS.getValue()); + this.sendSubscribeMsg( openid,tempId, "/order/detail/"+orderId,map); + } + + /** + * 发货成功通知 + * @param orderId 单号 + * @param deliveryName 快递公司 + * @param deliveryId 快递单号 + * @param uid uid + */ + public void deliverySuccessNotice(String orderId,String deliveryName, + String deliveryId,Long uid){ + + String openid = this.getUserOpenid(uid); + + if(StrUtil.isEmpty(openid)) return; + + Map map = new HashMap<>(); + map.put("first","亲,宝贝已经启程了,好想快点来到你身边。"); + map.put("keyword2",deliveryName); + map.put("keyword1",orderId); + map.put("keyword3",deliveryId); + map.put("remark","yshop为你服务!"); + String tempId = this.getTempId(WechatTempateEnum.DELIVERY_SUCCESS.getValue()); + this.sendSubscribeMsg( openid,tempId, "/order/detail/"+orderId,map); + } + + + /** + * 构建小程序一次性订阅消息 + * @param openId 单号 + * @param templateId 模板id + * @param page 跳转页面 + * @param map map内容 + * @return String + */ + private void sendSubscribeMsg(String openId, String templateId, String page, Map map){ + WxMaSubscribeMessage wxMaSubscribeMessage = WxMaSubscribeMessage.builder() + .toUser(openId) + .templateId(templateId) + .page(page) + .build(); + map.forEach( (k,v)-> { wxMaSubscribeMessage.addData(new WxMaSubscribeMessage.Data(k, v));} ); + WxMaService wxMaService = WxMaConfiguration.getWxMaService(); + try { + wxMaService.getMsgService().sendSubscribeMsg(wxMaSubscribeMessage); + } catch (WxErrorException e) { + e.printStackTrace(); + } + } + + /** + * 获取模板消息id + * @param key 模板key + * @return string + */ + private String getTempId(String key){ + AtomicReference tempId = new AtomicReference<>(); + subscribeProperties.getSubscribeMaps().forEach((k,v)->{ + if(key.equals(k)){ + tempId.set(v); + } + }); + return tempId.get(); + } + + + /** + * 获取openid + * @param uid uid + * @return String + */ + private String getUserOpenid(Long uid){ + YxUser yxUser = userService.getById(uid); + if(yxUser == null) return ""; + + WechatUserDto wechatUserDto = yxUser.getWxProfile(); + if(wechatUserDto == null) return ""; + if(StrUtil.isBlank(wechatUserDto.getRoutineOpenid())) return ""; + return wechatUserDto.getRoutineOpenid(); + + } +}