From 97dbcde392cddba101ad493ca7eb10435b5a4d80 Mon Sep 17 00:00:00 2001 From: hupeng Date: Mon, 20 Jan 2020 14:44:51 +0800 Subject: [PATCH] =?UTF-8?q?yshop1.9.1,WxJava=E5=8D=87=E7=BA=A7=E5=88=B03.6?= =?UTF-8?q?,=E5=BE=AE=E4=BF=A1=E5=85=AC=E4=BC=97=E5=8F=B7=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E9=85=8D=E7=BD=AE=E9=87=8D=E6=9E=84,=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E5=90=8E=E5=8F=B0=E9=85=8D=E7=BD=AE=E5=85=AC=E4=BC=97?= =?UTF-8?q?=E5=8F=B7API=E7=AB=AF=E5=BF=85=E9=A1=BB=E8=A6=81=E9=87=8D?= =?UTF-8?q?=E5=90=AF=E6=89=8D=E8=83=BD=E7=94=9F=E6=95=88=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/start.sh | 2 +- shell/stop.sh | 2 +- .../service/impl/YxStoreOrderServiceImpl.java | 4 +- .../modules/security/rest/AuthController.java | 10 +- .../web/controller/WechatController.java | 43 ++-- yshop-mp/pom.xml | 10 +- .../yixiang/mp/config/WxMpConfiguration.java | 215 ++++++++++-------- .../co/yixiang/mp/config/WxMpProperties.java | 44 ---- .../mp/controller/WxMenuController.java | 186 --------------- .../mp/controller/WxPortalController.java | 105 --------- .../mp/controller/WxRedirectController.java | 37 --- .../mp/controller/YxCacheController.java | 10 +- .../impl/WxMpTemplateMessageServiceImpl.java | 13 +- .../mp/service/impl/YxArticleServiceImpl.java | 17 +- .../wechat/rest/YxSystemConfigController.java | 5 + 15 files changed, 182 insertions(+), 521 deletions(-) delete mode 100644 yshop-mp/src/main/java/co/yixiang/mp/config/WxMpProperties.java delete mode 100644 yshop-mp/src/main/java/co/yixiang/mp/controller/WxMenuController.java delete mode 100644 yshop-mp/src/main/java/co/yixiang/mp/controller/WxPortalController.java delete mode 100644 yshop-mp/src/main/java/co/yixiang/mp/controller/WxRedirectController.java diff --git a/shell/start.sh b/shell/start.sh index f2ea1323..f3a0c92e 100644 --- a/shell/start.sh +++ b/shell/start.sh @@ -1 +1 @@ -nohup java -jar yshop-api-1.8.jar --spring.profiles.active=prod & \ No newline at end of file +nohup java -jar yshop-api-1.9.jar --spring.profiles.active=prod & \ No newline at end of file diff --git a/shell/stop.sh b/shell/stop.sh index d3095c45..9182c277 100644 --- a/shell/stop.sh +++ b/shell/stop.sh @@ -1,4 +1,4 @@ -PID=$(ps -ef | grep yshop-api-1.8.jar | grep -v grep | awk '{ print $2 }') +PID=$(ps -ef | grep yshop-api-1.9.jar | grep -v grep | awk '{ print $2 }') if [ -z "$PID" ];then echo Application is already stopped else diff --git a/yshop-api/src/main/java/co/yixiang/modules/order/service/impl/YxStoreOrderServiceImpl.java b/yshop-api/src/main/java/co/yixiang/modules/order/service/impl/YxStoreOrderServiceImpl.java index f620211f..6f00e20e 100644 --- a/yshop-api/src/main/java/co/yixiang/modules/order/service/impl/YxStoreOrderServiceImpl.java +++ b/yshop-api/src/main/java/co/yixiang/modules/order/service/impl/YxStoreOrderServiceImpl.java @@ -1425,8 +1425,8 @@ public class YxStoreOrderServiceImpl extends BaseServiceImpl jsConfig(@RequestParam(value = "url") String url) throws WxErrorException { + String appId = RedisUtil.get("wechat_appid"); + if(StrUtil.isBlank(appId)) return ApiResult.fail("请配置公众号"); + WxMpService wxService = WxMpConfiguration.getWxMpService(appId); return ApiResult.ok(wxService.createJsapiSignature(url)); } @@ -165,6 +149,9 @@ public class WechatController extends BaseController { @RequestParam(name = "nonce", required = false) String nonce, @RequestParam(name = "echostr", required = false) String echostr){ + String appId = RedisUtil.get("wechat_appid"); + if(StrUtil.isBlank(appId)) return "请配置公众号"; + WxMpService wxService = WxMpConfiguration.getWxMpService(appId); if (wxService.checkSignature(timestamp, nonce, signature)) { return echostr; } @@ -186,6 +173,12 @@ public class WechatController extends BaseController { HttpServletRequest request, HttpServletResponse response) throws IOException { + String appId = RedisUtil.get("wechat_appid"); + if(StrUtil.isBlank(appId)) { + log.error("请配置公众号!"); + return; + } + WxMpService wxService = WxMpConfiguration.getWxMpService(appId); if (!wxService.checkSignature(timestamp, nonce, signature)) { throw new IllegalArgumentException("非法请求,可能属于伪造的请求!"); @@ -195,14 +188,14 @@ public class WechatController extends BaseController { if (encType == null) { // 明文传输的消息 WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody); - WxMpXmlOutMessage outMessage = this.route(inMessage); + WxMpXmlOutMessage outMessage = this.route(inMessage,appId); if(outMessage == null) return; out = outMessage.toXml();; } else if ("aes".equalsIgnoreCase(encType)) { // aes加密的消息 WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody, wxService.getWxMpConfigStorage(), timestamp, nonce, msgSignature); - WxMpXmlOutMessage outMessage = this.route(inMessage); + WxMpXmlOutMessage outMessage = this.route(inMessage,appId); if(outMessage == null) return; out = outMessage.toEncryptedXml(wxService.getWxMpConfigStorage()); @@ -214,9 +207,9 @@ public class WechatController extends BaseController { writer.close(); } - private WxMpXmlOutMessage route(WxMpXmlMessage message) { + private WxMpXmlOutMessage route(WxMpXmlMessage message,String appId) { try { - return this.messageRouter.route(message); + return WxMpConfiguration.getWxMpMessageRouter(appId).route(message); } catch (Exception e) { log.error("路由消息时出现异常!", e); } diff --git a/yshop-mp/pom.xml b/yshop-mp/pom.xml index f128d216..09bafa49 100644 --- a/yshop-mp/pom.xml +++ b/yshop-mp/pom.xml @@ -12,21 +12,25 @@ yshop-mp 微信模块 + + 3.6.0 + + com.github.binarywang weixin-java-mp - 3.5.0 + ${weixin-java.version} com.github.binarywang wx-java-pay-spring-boot-starter - 3.5.0 + ${weixin-java.version} com.github.binarywang wx-java-miniapp-spring-boot-starter - 3.5.0 + ${weixin-java.version} co.yixiang diff --git a/yshop-mp/src/main/java/co/yixiang/mp/config/WxMpConfiguration.java b/yshop-mp/src/main/java/co/yixiang/mp/config/WxMpConfiguration.java index e3b3307f..7d8c5e74 100644 --- a/yshop-mp/src/main/java/co/yixiang/mp/config/WxMpConfiguration.java +++ b/yshop-mp/src/main/java/co/yixiang/mp/config/WxMpConfiguration.java @@ -1,141 +1,154 @@ package co.yixiang.mp.config; -import cn.hutool.core.util.StrUtil; import co.yixiang.mp.handler.*; -import co.yixiang.utils.RedisUtil; -import lombok.AllArgsConstructor; +import com.google.common.collect.Maps; +import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.mp.api.WxMpMessageRouter; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; -import org.apache.poi.util.StringUtil; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; +import me.chanjar.weixin.mp.constant.WxMpEventConstants; import org.springframework.context.annotation.Configuration; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; +import java.util.Map; import static me.chanjar.weixin.common.api.WxConsts.EventType; -import static me.chanjar.weixin.common.api.WxConsts.EventType.SUBSCRIBE; -import static me.chanjar.weixin.common.api.WxConsts.EventType.UNSUBSCRIBE; -import static me.chanjar.weixin.common.api.WxConsts.MenuButtonType.CLICK; -import static me.chanjar.weixin.common.api.WxConsts.MenuButtonType.VIEW; import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType; -import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType.EVENT; -import static me.chanjar.weixin.mp.constant.WxMpEventConstants.CustomerService.*; -import static me.chanjar.weixin.mp.constant.WxMpEventConstants.POI_CHECK_NOTIFY; /** - * wechat mp configuration + * 公众号配置 + * @author hupeng + * @date 2020/01/20 */ -@AllArgsConstructor @Configuration -@EnableConfigurationProperties(WxMpProperties.class) public class WxMpConfiguration { - private final LogHandler logHandler; - private final NullHandler nullHandler; - private final KfSessionHandler kfSessionHandler; - private final StoreCheckNotifyHandler storeCheckNotifyHandler; - private final LocationHandler locationHandler; - private final MenuHandler menuHandler; - private final MsgHandler msgHandler; - private final UnsubscribeHandler unsubscribeHandler; - private final SubscribeHandler subscribeHandler; - private final ScanHandler scanHandler; - private final WxMpProperties properties; - private final RedisHandler redisHandler; - @Bean - public WxMpService wxMpService() { + private static Map mpServices = Maps.newHashMap(); + private static Map routers = Maps.newHashMap(); - final List configs = new ArrayList<>(); - WxMpProperties.MpConfig mpConfig = new WxMpProperties.MpConfig(); - String appId = redisHandler.getVal("wechat_appid"); - String secret = redisHandler.getVal("wechat_appsecret"); - String token = redisHandler.getVal("wechat_token"); - String aesKey = redisHandler.getVal("wechat_encodingaeskey"); + private static LogHandler logHandler; + private static NullHandler nullHandler; + private static KfSessionHandler kfSessionHandler; + private static StoreCheckNotifyHandler storeCheckNotifyHandler; + private static LocationHandler locationHandler; + private static MenuHandler menuHandler; + private static MsgHandler msgHandler; + private static UnsubscribeHandler unsubscribeHandler; + private static SubscribeHandler subscribeHandler; + private static ScanHandler scanHandler; + private static RedisHandler redisHandler; - - if(StrUtil.isNotBlank(appId) && StrUtil.isNotBlank(secret) - && StrUtil.isNotBlank(token) && StrUtil.isNotBlank(aesKey)) { - mpConfig.setAppId(appId); - mpConfig.setSecret(secret); - mpConfig.setToken(token); - mpConfig.setAesKey(aesKey); - System.out.println(mpConfig); - - configs.add(mpConfig); - }else{ - mpConfig.setAppId("111111"); - mpConfig.setSecret("111111"); - mpConfig.setToken("111111"); - mpConfig.setAesKey("111111"); - - configs.add(mpConfig); - } - - //System.out.println("configs:"+configs); - - if (configs.isEmpty()) { - throw new RuntimeException("请先配置!"); - } - - WxMpService service = new WxMpServiceImpl(); - service.setMultiConfigStorages(configs - .stream().map(a -> { - WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl(); - configStorage.setAppId(a.getAppId()); - configStorage.setSecret(a.getSecret()); - configStorage.setToken(a.getToken()); - configStorage.setAesKey(a.getAesKey()); - return configStorage; - }).collect(Collectors.toMap(WxMpDefaultConfigImpl::getAppId, a -> a, (o, n) -> o))); - return service; + public WxMpConfiguration(LogHandler logHandler,NullHandler nullHandler,KfSessionHandler kfSessionHandler, + StoreCheckNotifyHandler storeCheckNotifyHandler,LocationHandler locationHandler, + MenuHandler menuHandler,MsgHandler msgHandler,UnsubscribeHandler unsubscribeHandler, + SubscribeHandler subscribeHandler,ScanHandler scanHandler, + RedisHandler redisHandler){ + this.logHandler = logHandler; + this.nullHandler = nullHandler; + this.kfSessionHandler = kfSessionHandler; + this.storeCheckNotifyHandler = storeCheckNotifyHandler; + this.locationHandler = locationHandler; + this.menuHandler = menuHandler; + this.msgHandler = msgHandler; + this.unsubscribeHandler = unsubscribeHandler; + this.subscribeHandler = subscribeHandler; + this.scanHandler = scanHandler; + this.redisHandler = redisHandler; } - @Bean - public WxMpMessageRouter messageRouter(WxMpService wxMpService) { + + /** + * 获取WxMpService + * @return + */ + public static WxMpService getWxMpService(String appId) { + + WxMpService wxMpService = mpServices.get(appId); + if(wxMpService == null) { + WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl(); + configStorage.setAppId(redisHandler.getVal("wechat_appid")); + configStorage.setSecret(redisHandler.getVal("wechat_appsecret")); + configStorage.setToken(redisHandler.getVal("wechat_token")); + configStorage.setAesKey(redisHandler.getVal("wechat_encodingaeskey")); + wxMpService = new WxMpServiceImpl(); + wxMpService.setWxMpConfigStorage(configStorage); + mpServices.put(appId, wxMpService); + routers.put(appId, newRouter(wxMpService)); + } + return wxMpService; + } + + /** + * 移除WxMpService + * @param appId + */ + public static void removeWxMpService(String appId){ + mpServices.remove(appId); + routers.remove(appId); + } + + /** + * 获取WxMpMessageRouter + * @param appId + */ + public static WxMpMessageRouter getWxMpMessageRouter(String appId) { + WxMpMessageRouter wxMpMessageRouter = routers.get(appId); + return wxMpMessageRouter; + } + + private static WxMpMessageRouter newRouter(WxMpService wxMpService) { final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService); // 记录所有事件的日志 (异步执行) - //newRouter.rule().handler(this.logHandler).next(); + newRouter.rule().handler(logHandler).next(); // 接收客服会话管理事件 -// newRouter.rule().async(false).msgType(EVENT).event(KF_CREATE_SESSION) -// .handler(this.kfSessionHandler).end(); -// newRouter.rule().async(false).msgType(EVENT).event(KF_CLOSE_SESSION) -// .handler(this.kfSessionHandler).end(); -// newRouter.rule().async(false).msgType(EVENT).event(KF_SWITCH_SESSION) -// .handler(this.kfSessionHandler).end(); + newRouter.rule().async(false).msgType(XmlMsgType.EVENT) + .event(WxMpEventConstants.CustomerService.KF_CREATE_SESSION) + .handler(kfSessionHandler).end(); + newRouter.rule().async(false).msgType(XmlMsgType.EVENT) + .event(WxMpEventConstants.CustomerService.KF_CLOSE_SESSION) + .handler(kfSessionHandler) + .end(); + newRouter.rule().async(false).msgType(XmlMsgType.EVENT) + .event(WxMpEventConstants.CustomerService.KF_SWITCH_SESSION) + .handler(kfSessionHandler).end(); // 门店审核事件 - //newRouter.rule().async(false).msgType(EVENT).event(POI_CHECK_NOTIFY).handler(this.storeCheckNotifyHandler).end(); + newRouter.rule().async(false).msgType(XmlMsgType.EVENT) + .event(WxMpEventConstants.POI_CHECK_NOTIFY) + .handler(storeCheckNotifyHandler).end(); // 自定义菜单事件 - newRouter.rule().async(false).msgType(EVENT).event(CLICK).handler(this.menuHandler).end(); + newRouter.rule().async(false).msgType(XmlMsgType.EVENT) + .event(WxConsts.MenuButtonType.CLICK).handler(menuHandler).end(); // 点击菜单连接事件 - newRouter.rule().async(false).msgType(EVENT).event(VIEW).handler(this.nullHandler).end(); - - // 关注事件 - newRouter.rule().async(false).msgType(EVENT).event(SUBSCRIBE).handler(this.subscribeHandler).end(); - - // 取消关注事件 - newRouter.rule().async(false).msgType(EVENT).event(UNSUBSCRIBE).handler(this.unsubscribeHandler).end(); - - // 上报地理位置事件 - //newRouter.rule().async(false).msgType(EVENT).event(EventType.LOCATION).handler(this.locationHandler).end(); - - // 接收地理位置消息 - //newRouter.rule().async(false).msgType(XmlMsgType.LOCATION).handler(this.locationHandler).end(); + newRouter.rule().async(false).msgType(XmlMsgType.EVENT) + .event(WxConsts.MenuButtonType.VIEW).handler(menuHandler).end(); // 扫码事件 - //newRouter.rule().async(false).msgType(EVENT).event(EventType.SCAN).handler(this.scanHandler).end(); + newRouter.rule().async(false).msgType(XmlMsgType.EVENT) + .event(EventType.SCANCODE_WAITMSG).handler(menuHandler).end(); + + // 关注事件 + newRouter.rule().async(false).msgType(XmlMsgType.EVENT) + .event(EventType.SUBSCRIBE).handler(subscribeHandler) + .end(); + + // 取消关注事件 + newRouter.rule().async(false).msgType(XmlMsgType.EVENT) + .event(EventType.UNSUBSCRIBE) + .handler(unsubscribeHandler).end(); + + // 上报地理位置事件 + newRouter.rule().async(false).msgType(XmlMsgType.EVENT) + .event(EventType.LOCATION).handler(locationHandler) + .end(); + // 默认 - newRouter.rule().async(false).handler(this.msgHandler).end(); + newRouter.rule().async(false).handler(msgHandler).end(); return newRouter; } diff --git a/yshop-mp/src/main/java/co/yixiang/mp/config/WxMpProperties.java b/yshop-mp/src/main/java/co/yixiang/mp/config/WxMpProperties.java deleted file mode 100644 index 428803fe..00000000 --- a/yshop-mp/src/main/java/co/yixiang/mp/config/WxMpProperties.java +++ /dev/null @@ -1,44 +0,0 @@ -package co.yixiang.mp.config; - -import co.yixiang.mp.utils.JsonUtils; -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; - -import java.util.List; - -/** - * wechat mp properties - */ -@Data -@ConfigurationProperties(prefix = "wx.mp") -public class WxMpProperties { - private List configs; - - @Data - public static class MpConfig { - /** - * 设置微信公众号的appid - */ - private String appId; - - /** - * 设置微信公众号的app secret - */ - private String secret; - - /** - * 设置微信公众号的token - */ - private String token; - - /** - * 设置微信公众号的EncodingAESKey - */ - private String aesKey; - } - - @Override - public String toString() { - return JsonUtils.toJson(this); - } -} diff --git a/yshop-mp/src/main/java/co/yixiang/mp/controller/WxMenuController.java b/yshop-mp/src/main/java/co/yixiang/mp/controller/WxMenuController.java deleted file mode 100644 index 5fab0b56..00000000 --- a/yshop-mp/src/main/java/co/yixiang/mp/controller/WxMenuController.java +++ /dev/null @@ -1,186 +0,0 @@ -package co.yixiang.mp.controller; - -import lombok.AllArgsConstructor; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.bean.menu.WxMenu; -import me.chanjar.weixin.common.bean.menu.WxMenuButton; -import me.chanjar.weixin.common.error.WxErrorException; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.menu.WxMpGetSelfMenuInfoResult; -import me.chanjar.weixin.mp.bean.menu.WxMpMenu; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; - -import javax.servlet.http.HttpServletRequest; -import java.net.MalformedURLException; -import java.net.URL; - -import static me.chanjar.weixin.common.api.WxConsts.MenuButtonType; - - -@AllArgsConstructor -@RestController -@RequestMapping("/wx/menu/{appid}") -public class WxMenuController { - private final WxMpService wxService; - - /** - *
-     * 自定义菜单创建接口
-     * 详情请见:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141013&token=&lang=zh_CN
-     * 如果要创建个性化菜单,请设置matchrule属性
-     * 详情请见:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1455782296&token=&lang=zh_CN
-     * 
- * - * @return 如果是个性化菜单,则返回menuid,否则返回null - */ - @PostMapping("/create") - public String menuCreate(@PathVariable String appid, @RequestBody WxMenu menu) throws WxErrorException { - return this.wxService.switchoverTo(appid).getMenuService().menuCreate(menu); - } - - @GetMapping("/create") - public String menuCreateSample(@PathVariable String appid) throws WxErrorException, MalformedURLException { - WxMenu menu = new WxMenu(); - WxMenuButton button1 = new WxMenuButton(); - button1.setType(MenuButtonType.CLICK); - button1.setName("今日歌曲"); - button1.setKey("V1001_TODAY_MUSIC"); - -// WxMenuButton button2 = new WxMenuButton(); -// button2.setType(WxConsts.BUTTON_MINIPROGRAM); -// button2.setName("小程序"); -// button2.setAppId("wx286b93c14bbf93aa"); -// button2.setPagePath("pages/lunar/index.html"); -// button2.setUrl("http://mp.weixin.qq.com"); - - WxMenuButton button3 = new WxMenuButton(); - button3.setName("菜单"); - - menu.getButtons().add(button1); -// menu.getButtons().add(button2); - menu.getButtons().add(button3); - - WxMenuButton button31 = new WxMenuButton(); - button31.setType(MenuButtonType.VIEW); - button31.setName("搜索"); - button31.setUrl("http://www.soso.com/"); - - WxMenuButton button32 = new WxMenuButton(); - button32.setType(MenuButtonType.VIEW); - button32.setName("视频"); - button32.setUrl("http://v.qq.com/"); - - WxMenuButton button33 = new WxMenuButton(); - button33.setType(MenuButtonType.CLICK); - button33.setName("赞一下我们"); - button33.setKey("V1001_GOOD"); - - WxMenuButton button34 = new WxMenuButton(); - button34.setType(MenuButtonType.VIEW); - button34.setName("获取用户信息"); - - ServletRequestAttributes servletRequestAttributes = - (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); - if (servletRequestAttributes != null) { - HttpServletRequest request = servletRequestAttributes.getRequest(); - URL requestURL = new URL(request.getRequestURL().toString()); - String url = this.wxService.switchoverTo(appid).oauth2buildAuthorizationUrl( - String.format("%s://%s/wx/redirect/%s/greet", requestURL.getProtocol(), requestURL.getHost(), appid), - WxConsts.OAuth2Scope.SNSAPI_USERINFO, null); - button34.setUrl(url); - } - - button3.getSubButtons().add(button31); - button3.getSubButtons().add(button32); - button3.getSubButtons().add(button33); - button3.getSubButtons().add(button34); - - this.wxService.switchover(appid); - return this.wxService.getMenuService().menuCreate(menu); - } - - /** - *
-     * 自定义菜单创建接口
-     * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141013&token=&lang=zh_CN
-     * 如果要创建个性化菜单,请设置matchrule属性
-     * 详情请见:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1455782296&token=&lang=zh_CN
-     * 
- * - * @return 如果是个性化菜单,则返回menuid,否则返回null - */ - @PostMapping("/createByJson") - public String menuCreate(@PathVariable String appid, @RequestBody String json) throws WxErrorException { - return this.wxService.switchoverTo(appid).getMenuService().menuCreate(json); - } - - /** - *
-     * 自定义菜单删除接口
-     * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141015&token=&lang=zh_CN
-     * 
- */ - @GetMapping("/delete") - public void menuDelete(@PathVariable String appid) throws WxErrorException { - this.wxService.switchoverTo(appid).getMenuService().menuDelete(); - } - - /** - *
-     * 删除个性化菜单接口
-     * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1455782296&token=&lang=zh_CN
-     * 
- * - * @param menuId 个性化菜单的menuid - */ - @GetMapping("/delete/{menuId}") - public void menuDelete(@PathVariable String appid, @PathVariable String menuId) throws WxErrorException { - this.wxService.switchoverTo(appid).getMenuService().menuDelete(menuId); - } - - /** - *
-     * 自定义菜单查询接口
-     * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141014&token=&lang=zh_CN
-     * 
- */ - @GetMapping("/get") - public WxMpMenu menuGet(@PathVariable String appid) throws WxErrorException { - return this.wxService.switchoverTo(appid).getMenuService().menuGet(); - } - - /** - *
-     * 测试个性化菜单匹配结果
-     * 详情请见: http://mp.weixin.qq.com/wiki/0/c48ccd12b69ae023159b4bfaa7c39c20.html
-     * 
- * - * @param userid 可以是粉丝的OpenID,也可以是粉丝的微信号。 - */ - @GetMapping("/menuTryMatch/{userid}") - public WxMenu menuTryMatch(@PathVariable String appid, @PathVariable String userid) throws WxErrorException { - return this.wxService.switchoverTo(appid).getMenuService().menuTryMatch(userid); - } - - /** - *
-     * 获取自定义菜单配置接口
-     * 本接口将会提供公众号当前使用的自定义菜单的配置,如果公众号是通过API调用设置的菜单,则返回菜单的开发配置,而如果公众号是在公众平台官网通过网站功能发布菜单,则本接口返回运营者设置的菜单配置。
-     * 请注意:
-     * 1、第三方平台开发者可以通过本接口,在旗下公众号将业务授权给你后,立即通过本接口检测公众号的自定义菜单配置,并通过接口再次给公众号设置好自动回复规则,以提升公众号运营者的业务体验。
-     * 2、本接口与自定义菜单查询接口的不同之处在于,本接口无论公众号的接口是如何设置的,都能查询到接口,而自定义菜单查询接口则仅能查询到使用API设置的菜单配置。
-     * 3、认证/未认证的服务号/订阅号,以及接口测试号,均拥有该接口权限。
-     * 4、从第三方平台的公众号登录授权机制上来说,该接口从属于消息与菜单权限集。
-     * 5、本接口中返回的图片/语音/视频为临时素材(临时素材每次获取都不同,3天内有效,通过素材管理-获取临时素材接口来获取这些素材),本接口返回的图文消息为永久素材素材(通过素材管理-获取永久素材接口来获取这些素材)。
-     *  接口调用请求说明:
-     * http请求方式: GET(请使用https协议)
-     * https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info?access_token=ACCESS_TOKEN
-     * 
- */ - @GetMapping("/getSelfMenuInfo") - public WxMpGetSelfMenuInfoResult getSelfMenuInfo(@PathVariable String appid) throws WxErrorException { - return this.wxService.switchoverTo(appid).getMenuService().getSelfMenuInfo(); - } -} diff --git a/yshop-mp/src/main/java/co/yixiang/mp/controller/WxPortalController.java b/yshop-mp/src/main/java/co/yixiang/mp/controller/WxPortalController.java deleted file mode 100644 index 79bd9c55..00000000 --- a/yshop-mp/src/main/java/co/yixiang/mp/controller/WxPortalController.java +++ /dev/null @@ -1,105 +0,0 @@ -package co.yixiang.mp.controller; - -import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import me.chanjar.weixin.mp.api.WxMpMessageRouter; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; -import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; -import org.apache.commons.lang3.StringUtils; -import org.springframework.web.bind.annotation.*; - -/** - * @author Binary Wang(https://github.com/binarywang) - */ -@Slf4j -@AllArgsConstructor -@RestController -@RequestMapping("/wx/portal/{appid}") -public class WxPortalController { - private final WxMpService wxService; - private final WxMpMessageRouter messageRouter; - - @GetMapping(produces = "text/plain;charset=utf-8") - public String authGet(@PathVariable String appid, - @RequestParam(name = "signature", required = false) String signature, - @RequestParam(name = "timestamp", required = false) String timestamp, - @RequestParam(name = "nonce", required = false) String nonce, - @RequestParam(name = "echostr", required = false) String echostr) { - - log.info("\n接收到来自微信服务器的认证消息:[{}, {}, {}, {}]", signature, - timestamp, nonce, echostr); - if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) { - throw new IllegalArgumentException("请求参数非法,请核实!"); - } - - if (!this.wxService.switchover(appid)) { - throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid)); - } - - if (wxService.checkSignature(timestamp, nonce, signature)) { - return echostr; - } - - return "非法请求"; - } - - @PostMapping(produces = "application/xml; charset=UTF-8") - public String post(@PathVariable String appid, - @RequestBody String requestBody, - @RequestParam("signature") String signature, - @RequestParam("timestamp") String timestamp, - @RequestParam("nonce") String nonce, - @RequestParam("openid") String openid, - @RequestParam(name = "encrypt_type", required = false) String encType, - @RequestParam(name = "msg_signature", required = false) String msgSignature) { - log.info("\n接收微信请求:[openid=[{}], [signature=[{}], encType=[{}], msgSignature=[{}]," - + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ", - openid, signature, encType, msgSignature, timestamp, nonce, requestBody); - - if (!this.wxService.switchover(appid)) { - throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid)); - } - - if (!wxService.checkSignature(timestamp, nonce, signature)) { - throw new IllegalArgumentException("非法请求,可能属于伪造的请求!"); - } - - String out = null; - if (encType == null) { - // 明文传输的消息 - WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody); -// WxMpXmlOutMessage outMessage = this.route(inMessage); -// if (outMessage == null) { -// return ""; -// } - - //out = outMessage.toXml(); - } else if ("aes".equalsIgnoreCase(encType)) { - // aes加密的消息 - WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody, wxService.getWxMpConfigStorage(), - timestamp, nonce, msgSignature); -// log.debug("\n消息解密后内容为:\n{} ", inMessage.toString()); -// WxMpXmlOutMessage outMessage = this.route(inMessage); -// if (outMessage == null) { -// return ""; -// } -// -// out = outMessage.toEncryptedXml(wxService.getWxMpConfigStorage()); - } - - //log.debug("\n组装回复信息:{}", out); - return out; - } - - private WxMpXmlOutMessage route(WxMpXmlMessage message) { - try { - return this.messageRouter.route(message); - } catch (Exception e) { - log.error("路由消息时出现异常!", e); - } - - return null; - } - -} diff --git a/yshop-mp/src/main/java/co/yixiang/mp/controller/WxRedirectController.java b/yshop-mp/src/main/java/co/yixiang/mp/controller/WxRedirectController.java deleted file mode 100644 index 843e20a2..00000000 --- a/yshop-mp/src/main/java/co/yixiang/mp/controller/WxRedirectController.java +++ /dev/null @@ -1,37 +0,0 @@ -package co.yixiang.mp.controller; - -import lombok.AllArgsConstructor; -import me.chanjar.weixin.common.error.WxErrorException; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; -import me.chanjar.weixin.mp.bean.result.WxMpUser; -import org.springframework.stereotype.Controller; -import org.springframework.ui.ModelMap; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; - - -@AllArgsConstructor -@Controller -@RequestMapping("/wx/redirect/{appid}") -public class WxRedirectController { - private final WxMpService wxService; - - @RequestMapping("/greet") - public String greetUser(@PathVariable String appid, @RequestParam String code, ModelMap map) { - if (!this.wxService.switchover(appid)) { - throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid)); - } - - try { - WxMpOAuth2AccessToken accessToken = wxService.oauth2getAccessToken(code); - WxMpUser user = wxService.oauth2getUserInfo(accessToken, null); - map.put("user", user); - } catch (WxErrorException e) { - e.printStackTrace(); - } - - return "greet_user"; - } -} diff --git a/yshop-mp/src/main/java/co/yixiang/mp/controller/YxCacheController.java b/yshop-mp/src/main/java/co/yixiang/mp/controller/YxCacheController.java index dad0d3be..e3f3363d 100644 --- a/yshop-mp/src/main/java/co/yixiang/mp/controller/YxCacheController.java +++ b/yshop-mp/src/main/java/co/yixiang/mp/controller/YxCacheController.java @@ -3,9 +3,11 @@ package co.yixiang.mp.controller; import cn.hutool.core.util.StrUtil; import co.yixiang.exception.BadRequestException; +import co.yixiang.mp.config.WxMpConfiguration; import co.yixiang.mp.domain.YxCache; import co.yixiang.mp.service.YxCacheService; import co.yixiang.utils.OrderUtil; +import co.yixiang.utils.RedisUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import io.swagger.annotations.Api; @@ -31,8 +33,6 @@ public class YxCacheController { @Autowired private YxCacheService yxCacheService; - @Autowired - private WxMpService wxService; @ApiOperation(value = "查询菜单") @@ -53,6 +53,12 @@ public class YxCacheController { YxCache yxCache = new YxCache(); Boolean isExist = yxCacheService.isExist("wechat_menus"); WxMenu menu = JSONObject.parseObject(jsonStr,WxMenu.class); + + String appId = RedisUtil.get("wechat_appid"); + if(StrUtil.isBlank(appId)) { + throw new BadRequestException("请配置公众号"); + } + WxMpService wxService = WxMpConfiguration.getWxMpService(appId); if(isExist){ yxCache.setKey("wechat_menus"); yxCache.setResult(jsonButton); diff --git a/yshop-mp/src/main/java/co/yixiang/mp/service/impl/WxMpTemplateMessageServiceImpl.java b/yshop-mp/src/main/java/co/yixiang/mp/service/impl/WxMpTemplateMessageServiceImpl.java index bc3a1537..d09089da 100644 --- a/yshop-mp/src/main/java/co/yixiang/mp/service/impl/WxMpTemplateMessageServiceImpl.java +++ b/yshop-mp/src/main/java/co/yixiang/mp/service/impl/WxMpTemplateMessageServiceImpl.java @@ -1,6 +1,9 @@ package co.yixiang.mp.service.impl; +import cn.hutool.core.util.StrUtil; +import co.yixiang.mp.config.WxMpConfiguration; import co.yixiang.mp.service.WxMpTemplateMessageService; +import co.yixiang.utils.RedisUtil; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.bean.template.WxMpTemplateData; @@ -13,9 +16,6 @@ import java.util.Map; @Component public class WxMpTemplateMessageServiceImpl implements WxMpTemplateMessageService { - @Autowired - private WxMpService wxMpService; - @Override public String sendWxMpTemplateMessage(String openId, String templateId, String url, Map map){ WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder() @@ -25,8 +25,13 @@ public class WxMpTemplateMessageServiceImpl implements WxMpTemplateMessageServic .build(); map.forEach( (k,v)-> { templateMessage.addData(new WxMpTemplateData(k, v, "#000000"));} ); String msgId = null; + String appId = RedisUtil.get("wechat_appid"); + if(StrUtil.isBlank(appId)) { + return "请配置公众号"; + } + WxMpService wxService = WxMpConfiguration.getWxMpService(appId); try { - msgId = wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage); + msgId = wxService.getTemplateMsgService().sendTemplateMsg(templateMessage); } catch (WxErrorException e) { e.printStackTrace(); } diff --git a/yshop-mp/src/main/java/co/yixiang/mp/service/impl/YxArticleServiceImpl.java b/yshop-mp/src/main/java/co/yixiang/mp/service/impl/YxArticleServiceImpl.java index 2aa7e821..579d19e5 100644 --- a/yshop-mp/src/main/java/co/yixiang/mp/service/impl/YxArticleServiceImpl.java +++ b/yshop-mp/src/main/java/co/yixiang/mp/service/impl/YxArticleServiceImpl.java @@ -3,9 +3,12 @@ package co.yixiang.mp.service.impl; import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.ReUtil; +import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONUtil; +import co.yixiang.exception.BadRequestException; import co.yixiang.exception.ErrorRequestException; +import co.yixiang.mp.config.WxMpConfiguration; import co.yixiang.mp.domain.YxArticle; import co.yixiang.mp.repository.YxArticleRepository; import co.yixiang.mp.service.YxArticleService; @@ -13,10 +16,7 @@ import co.yixiang.mp.service.dto.YxArticleDTO; import co.yixiang.mp.service.dto.YxArticleQueryCriteria; import co.yixiang.mp.service.mapper.YxArticleMapper; import co.yixiang.mp.utils.URLUtils; -import co.yixiang.utils.OrderUtil; -import co.yixiang.utils.PageUtil; -import co.yixiang.utils.QueryHelp; -import co.yixiang.utils.ValidationUtil; +import co.yixiang.utils.*; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.error.WxErrorException; @@ -56,8 +56,6 @@ public class YxArticleServiceImpl implements YxArticleService { @Autowired private YxArticleMapper yxArticleMapper; - @Autowired - private WxMpService wxMpService; @Value("${file.path}") private String uploadDirStr; @@ -107,6 +105,12 @@ public class YxArticleServiceImpl implements YxArticleService { @Override public void uploadNews(YxArticleDTO wxNewsArticleItem) throws Exception { + String appId = RedisUtil.get("wechat_appid"); + if(StrUtil.isBlank(appId)) { + throw new BadRequestException("请配置公众号"); + } + WxMpService wxMpService = WxMpConfiguration.getWxMpService(appId); + WxMpMaterialNews wxMpMaterialNews = new WxMpMaterialNews(); @@ -118,7 +122,6 @@ public class YxArticleServiceImpl implements YxArticleService { article.setAuthor( wxNewsArticleItem.getAuthor() ); - System.out.println(wxNewsArticleItem.getContent()); //处理content String content = processContent(wxMpService, wxNewsArticleItem.getContent()); diff --git a/yshop-shop/src/main/java/co/yixiang/modules/wechat/rest/YxSystemConfigController.java b/yshop-shop/src/main/java/co/yixiang/modules/wechat/rest/YxSystemConfigController.java index f4169676..56407de1 100644 --- a/yshop-shop/src/main/java/co/yixiang/modules/wechat/rest/YxSystemConfigController.java +++ b/yshop-shop/src/main/java/co/yixiang/modules/wechat/rest/YxSystemConfigController.java @@ -7,6 +7,7 @@ import co.yixiang.exception.BadRequestException; import co.yixiang.modules.wechat.domain.YxSystemConfig; import co.yixiang.modules.wechat.service.YxSystemConfigService; import co.yixiang.modules.wechat.service.dto.YxSystemConfigQueryCriteria; +import co.yixiang.mp.config.WxMpConfiguration; import co.yixiang.utils.RedisUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; @@ -52,6 +53,10 @@ public class YxSystemConfigController { YxSystemConfig yxSystemConfigModel = new YxSystemConfig(); yxSystemConfigModel.setMenuName(key); yxSystemConfigModel.setValue(value.toString()); + //重新配置微信相关 + if(key.equals("wechat_appid")){ + WxMpConfiguration.removeWxMpService(key); + } RedisUtil.set(key,value.toString(),0); if(ObjectUtil.isNull(yxSystemConfig)){ yxSystemConfigService.create(yxSystemConfigModel);