From fb65a3883a50f58e2a92d96c60ba750f0a8e26b3 Mon Sep 17 00:00:00 2001 From: zy_Java <654600784@qq.com> Date: Wed, 15 Sep 2021 15:09:10 +0800 Subject: [PATCH] =?UTF-8?q?20210915=E7=94=9F=E6=88=90=E5=B0=8F=E7=A8=8B?= =?UTF-8?q?=E5=BA=8F=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/ccsens/util/HttpsUtil.java | 1 - .../ccsens/wechatutil/Service/IWxService.java | 66 ----- .../ccsens/wechatutil/Service/WxService.java | 145 --------- .../ccsens/wechatutil/api/WxController.java | 22 +- .../ccsens/wechatutil/bean/vo/WechatCode.java | 42 ++- .../ccsens/wechatutil/service/IWxService.java | 105 +++++++ .../ccsens/wechatutil/service/WxService.java | 274 ++++++++++++++++++ .../{Util => util}/WxCodeError.java | 2 +- .../wechatutil/{Util => util}/WxConstant.java | 23 +- .../src/main/resources/application-dev.yml | 4 +- 10 files changed, 443 insertions(+), 241 deletions(-) delete mode 100644 wechatutil/src/main/java/com/ccsens/wechatutil/Service/IWxService.java delete mode 100644 wechatutil/src/main/java/com/ccsens/wechatutil/Service/WxService.java create mode 100644 wechatutil/src/main/java/com/ccsens/wechatutil/service/IWxService.java create mode 100644 wechatutil/src/main/java/com/ccsens/wechatutil/service/WxService.java rename wechatutil/src/main/java/com/ccsens/wechatutil/{Util => util}/WxCodeError.java (88%) rename wechatutil/src/main/java/com/ccsens/wechatutil/{Util => util}/WxConstant.java (58%) diff --git a/util/src/main/java/com/ccsens/util/HttpsUtil.java b/util/src/main/java/com/ccsens/util/HttpsUtil.java index 16233cf3..52787435 100644 --- a/util/src/main/java/com/ccsens/util/HttpsUtil.java +++ b/util/src/main/java/com/ccsens/util/HttpsUtil.java @@ -209,7 +209,6 @@ public class HttpsUtil { * @param keyStorepass 密钥库密码 * @return */ - public static SSLContext custom(String keyStorePath, String keyStorepass) { SSLContext sc = null; FileInputStream instream = null; diff --git a/wechatutil/src/main/java/com/ccsens/wechatutil/Service/IWxService.java b/wechatutil/src/main/java/com/ccsens/wechatutil/Service/IWxService.java deleted file mode 100644 index 2333dfb0..00000000 --- a/wechatutil/src/main/java/com/ccsens/wechatutil/Service/IWxService.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.ccsens.wechatutil.Service; - -import com.ccsens.wechatutil.bean.po.MiniProgramUser; -import com.ccsens.wechatutil.bean.po.WxOauth2UserInfo; -import com.ccsens.wechatutil.bean.vo.WechatCode; - -/** - * @author 逗 - */ -public interface IWxService { - - /** - * 小程序登录 - * -- 从配置文件中获取默认appId - * 配置文件内的名称 h5.appId: 和 h5.secret: - * @param code code - * @return 返回当前用户的openId等 - */ - MiniProgramUser signinByMini(String code); - - /** - * 小程序登录 -- 传入appId - * @param code code - * @param appId appId - * @param secret secret - * @return 返回当前用户的openId等 - */ - MiniProgramUser signinByMini(String code, String appId, String secret); - - /** - * H5扫码登录,公众号登录 - * -- 从配置文件中获取默认appId - * 配置文件内的名称 h5.appId: 和 h5.secret: - * @param code code - * @return 返回微信用户信息 - */ - WxOauth2UserInfo signinByH5(String code); - - /** - * H5扫码登录,公众号登录 -- 传入appId - * @param code code - * @param appId appId - * @param secret secret - * @return 返回微信用户信息 - */ - WxOauth2UserInfo signinByH5(String code, String appId, String secret); - - - /** - * 生成小程序码,使用方案B - * @param page - * @param scene - * @param color - * @param path - * @param code - */ - void getWxCodeB(String page, String scene, WechatCode.LineColor color, String path, String code); - - /** - * 生成小程序码,使用方案B - * @param page - * @param path - * @param code - */ - void getWxCodeC(String page, String path, String code); -} diff --git a/wechatutil/src/main/java/com/ccsens/wechatutil/Service/WxService.java b/wechatutil/src/main/java/com/ccsens/wechatutil/Service/WxService.java deleted file mode 100644 index 44aef706..00000000 --- a/wechatutil/src/main/java/com/ccsens/wechatutil/Service/WxService.java +++ /dev/null @@ -1,145 +0,0 @@ -package com.ccsens.wechatutil.Service; - -import cn.hutool.core.util.StrUtil; -import cn.hutool.http.HttpRequest; -import com.ccsens.util.DateUtil; -import com.ccsens.util.JacksonUtil; -import com.ccsens.util.exception.BaseException; -import com.ccsens.wechatutil.Util.WxCodeError; -import com.ccsens.wechatutil.Util.WxConstant; -import com.ccsens.wechatutil.bean.po.MiniProgramUser; -import com.ccsens.wechatutil.bean.po.WxOauth2AccessToken; -import com.ccsens.wechatutil.bean.po.WxOauth2UserInfo; -import com.ccsens.wechatutil.bean.vo.WechatCode; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; - -import java.io.IOException; - -/** - * @author 逗 - */ -@Slf4j -@Service -@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class) -public class WxService implements IWxService { - - @Value("${mini.appId:}") - private String miniAppId; - @Value("${mini.secret:}") - private String miniSecret; - @Value("${h5.appId:}") - private String appIdH5; - @Value("${h5.secret:}") - private String secretH5; - - @Override - public MiniProgramUser signinByMini(String code) { - return signinByMini(code,miniAppId,miniSecret); - } - - @Override - public MiniProgramUser signinByMini(String code, String appId, String secret) { - MiniProgramUser wxUser; - //拼接wx的访问的路径 - String url = String.format(WxConstant.MINI_PROGRAM_LOGIN, appId, secret, code, WxConstant.GRANT_TYPE); - //调用微信的接口 - String response = HttpRequest.get(url).execute().body(); - log.info("url: {}\nresponse: {}",url,response); - try { - if(StrUtil.isEmpty(response) || null == (wxUser = JacksonUtil.jsonToBean(response, MiniProgramUser.class))) { - throw new BaseException(WxCodeError.WX_HTTP_ERROR); - } - } catch (IOException e) { - throw new BaseException(-1,e.getMessage()); - } - if(null != wxUser.errcode){ - throw new BaseException(wxUser.errcode, wxUser.errmsg); - } - return wxUser; - } - - @Override - public WxOauth2UserInfo signinByH5(String code) { - return signinByH5(code, appIdH5, secretH5); - } - - @Override - public WxOauth2UserInfo signinByH5(String code, String appId, String secret) { - //获取accessToken - WxOauth2AccessToken wxOauth2AccessToken = getOauth2AccessToken(code, appId, secret); - //获取用户信息 - return getOauth2UserInfo(wxOauth2AccessToken.getAccessToken(),wxOauth2AccessToken.getOpenId()); - } - - /** - * 获取网页授权凭证 - * @param code OAuth2授权码 - * @return WxOauth2AccessToken - */ - private static WxOauth2AccessToken getOauth2AccessToken(String code, String appId, String secret) { - WxOauth2AccessToken wxOauth2AccessToken; - //拼接访问路径 - String url = String.format(WxConstant.URL_GET_OAUTH2_ACCESS_TOKEN,appId,secret,code); - //调用微信接口 - String response = HttpRequest.get(url).execute().body(); - log.info("url: {}\nresponse: {}",url,response); - try { - if(StrUtil.isEmpty(response) || null == (wxOauth2AccessToken = JacksonUtil.jsonToBean(response,WxOauth2AccessToken.class))) { - throw new BaseException(WxCodeError.WX_HTTP_ERROR); - } - } catch (IOException e) { - throw new BaseException(-1,e.getMessage()); - } - if(null != wxOauth2AccessToken.getErrcode()){ - throw new BaseException(wxOauth2AccessToken.getErrcode(),wxOauth2AccessToken.getErrmsg()); - } - if (StrUtil.isEmpty(wxOauth2AccessToken.getAccessToken())) { - throw new BaseException(WxCodeError.ACCESS_TOKEN_ERROR); - } - wxOauth2AccessToken.setCreatedAt(DateUtil.currentSeconds()); - return wxOauth2AccessToken; - } - - /** - * 通过网页授权accessToken获取用户信息 - * @param accessToken 网页授权接口调用凭证 - * @param openId 用户标识 - * @return SNSUserInfo - */ - public static WxOauth2UserInfo getOauth2UserInfo(String accessToken, String openId){ - WxOauth2UserInfo wxOauth2UserInfo; - //拼接访问路径 - String url = String.format(WxConstant.URL_GET_OAUTH2_USER_INFO,accessToken,openId); - //调用微信接口 - String response = HttpRequest.get(url).execute().body(); - log.info("url: {}\nresponse: {}",url,response); - try { - if(StrUtil.isEmpty(response) || null == (wxOauth2UserInfo = JacksonUtil.jsonToBean(response, WxOauth2UserInfo.class))) { - throw new BaseException(WxCodeError.WX_HTTP_ERROR); - } - } catch (IOException e) { - throw new BaseException(-1,e.getMessage()); - } - if(null != wxOauth2UserInfo.getErrcode()){ - throw new BaseException(wxOauth2UserInfo.getErrcode(),wxOauth2UserInfo.getErrmsg()); - } - if (StrUtil.isEmpty(wxOauth2UserInfo.getOpenId())) { - throw new BaseException(WxCodeError.OPENID_ERROR); - } - return wxOauth2UserInfo; - } - - @Override - public void getWxCodeB(String page, String scene, WechatCode.LineColor color, String path, String code) { - - } - - @Override - public void getWxCodeC(String page, String path, String code) { - - } -} diff --git a/wechatutil/src/main/java/com/ccsens/wechatutil/api/WxController.java b/wechatutil/src/main/java/com/ccsens/wechatutil/api/WxController.java index 450bb671..9a27a422 100644 --- a/wechatutil/src/main/java/com/ccsens/wechatutil/api/WxController.java +++ b/wechatutil/src/main/java/com/ccsens/wechatutil/api/WxController.java @@ -1,7 +1,7 @@ package com.ccsens.wechatutil.api; import com.ccsens.util.JsonResponse; -import com.ccsens.wechatutil.Service.IWxService; +import com.ccsens.wechatutil.service.IWxService; import com.ccsens.wechatutil.bean.po.MiniProgramUser; import com.ccsens.wechatutil.bean.po.WxOauth2UserInfo; import com.ccsens.wechatutil.bean.vo.WechatCode; @@ -42,25 +42,25 @@ public class WxController { return JsonResponse.newInstance().ok(); } -// @ApiOperation(value = "生成小程序码-方案A", notes = "公众号/网页二维码") -// @RequestMapping(value = "/getWxCodeA", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) -// public JsonResponse getWxCodeA(@ApiParam @Validated String code) throws Exception{ -// WxOauth2UserInfo wxUser = miniProgramService.getWxCodeA(code); -// return JsonResponse.newInstance().ok(); -// } + @ApiOperation(value = "生成小程序码-方案A", notes = "公众号/网页二维码") + @RequestMapping(value = "/getWxCodeA", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) + public JsonResponse getWxCodeA(@ApiParam @Validated WechatCode.WechatCodeA wechatCodeA, String path) throws Exception{ + miniProgramService.getWxCodeA(wechatCodeA, path); + return JsonResponse.newInstance().ok(); + } @ApiOperation(value = "生成小程序码-方案B", notes = "公众号/网页二维码") @RequestMapping(value = "/getWxCodeB", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) - public JsonResponse getWxCodeB(@ApiParam @Validated String page, String scene, WechatCode.LineColor color, String path, String code) throws Exception{ - miniProgramService.getWxCodeB(page,scene,color,path,code); + public JsonResponse getWxCodeB(@ApiParam @Validated WechatCode.WechatCodeB wechatCodeB,String path) throws Exception{ + miniProgramService.getWxCodeB(wechatCodeB,path); return JsonResponse.newInstance().ok(); } @ApiOperation(value = "生成小程序码-方案B", notes = "公众号/网页二维码") @RequestMapping(value = "/getWxCodeC", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) - public JsonResponse getWxCodeC(@ApiParam @Validated String page,String path,String code) throws Exception{ - miniProgramService.getWxCodeC(page,path,code); + public JsonResponse getWxCodeC(@ApiParam @Validated WechatCode.WechatCodeC wechatCodeC,String path) throws Exception{ + miniProgramService.getWxCodeC(wechatCodeC,path); return JsonResponse.newInstance().ok(); } } diff --git a/wechatutil/src/main/java/com/ccsens/wechatutil/bean/vo/WechatCode.java b/wechatutil/src/main/java/com/ccsens/wechatutil/bean/vo/WechatCode.java index cab540a7..96dead29 100644 --- a/wechatutil/src/main/java/com/ccsens/wechatutil/bean/vo/WechatCode.java +++ b/wechatutil/src/main/java/com/ccsens/wechatutil/bean/vo/WechatCode.java @@ -1,6 +1,5 @@ package com.ccsens.wechatutil.bean.vo; -import com.ccsens.util.wx.WxXcxUtil; import lombok.Data; /** @@ -9,27 +8,56 @@ import lombok.Data; @Data public class WechatCode { /** - * Get wx code + * 获取小程序码--方案A + */ + public static class WechatCodeA{ + // 扫码进入的小程序页面路径,最大长度 128 字节,不能为空; + public String path; + //二维码的宽度,单位 px,最小 280px,最大 1280px 默认430 + public Integer width; + //默认false 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调,默认 false + public Boolean auto_color; + //auto_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} 十进制表示 + public LineColor line_color; + //默认false 是否需要透明底色,为 true 时,生成透明底色的小程序 + public Boolean is_hyaline; + } + + /** + * 获取小程序码--方案B */ public static class WechatCodeB{ + //参数 --最大32个可见字符 public String scene; + //小程序主页地址 public String page; + //二维码的宽度,单位 px,最小 280px,最大 1280px 默认430 public Integer width; + //默认false 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调,默认 false public Boolean auto_color; - public WxXcxUtil.LineColor line_color; + //auto_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} 十进制表示 + public LineColor line_color; + //默认false 是否需要透明底色,为 true 时,生成透明底色的小程序 public Boolean is_hyaline; } + + /** + * rgb颜色 + */ public static class LineColor{ public String r; public String g; public String b; } - public static class WechatCodeA{ + /** + * 获取小程序码--方案C + */ + public static class WechatCodeC{ + // 扫码进入的小程序页面路径,最大长度 128 字节,不能为空; public String path; + //二维码的宽度,单位 px,最小 280px,最大 1280px 默认430 public Integer width; - public Boolean auto_color; - public WxXcxUtil.LineColor line_color; - public Boolean is_hyaline; } + } diff --git a/wechatutil/src/main/java/com/ccsens/wechatutil/service/IWxService.java b/wechatutil/src/main/java/com/ccsens/wechatutil/service/IWxService.java new file mode 100644 index 00000000..6f38822f --- /dev/null +++ b/wechatutil/src/main/java/com/ccsens/wechatutil/service/IWxService.java @@ -0,0 +1,105 @@ +package com.ccsens.wechatutil.service; + +import com.ccsens.wechatutil.bean.po.MiniProgramUser; +import com.ccsens.wechatutil.bean.po.WxOauth2UserInfo; +import com.ccsens.wechatutil.bean.vo.WechatCode; +import com.fasterxml.jackson.core.JsonProcessingException; + +/** + * @author 逗 + */ +public interface IWxService { + + /** + * 小程序登录 + * -- 从配置文件中获取默认appId + * 配置文件内的名称 h5.appId: 和 h5.secret: + * @param code code + * @return 返回当前用户的openId等 + */ + MiniProgramUser signinByMini(String code); + + /** + * 小程序登录 -- 传入appId + * @param code code + * @param appId appId + * @param secret secret + * @return 返回当前用户的openId等 + */ + MiniProgramUser signinByMini(String code, String appId, String secret); + + /** + * H5扫码登录,公众号登录 + * -- 从配置文件中获取默认appId + * 配置文件内的名称 h5.appId: 和 h5.secret: + * @param code code + * @return 返回微信用户信息 + */ + WxOauth2UserInfo signinByH5(String code); + + /** + * H5扫码登录,公众号登录 -- 传入appId + * @param code code + * @param appId appId + * @param secret secret + * @return 返回微信用户信息 + */ + WxOauth2UserInfo signinByH5(String code, String appId, String secret); + + /** + * 获取小程序码--方案A,可接受 path 参数较长,生成个数受限 + * 接口 A 加上接口 C,总共生成的码数量限制为 100,000,请谨慎调用。 + * 使用默认appId + * @param wechatCodeA 传入参数 + * @param path 小程序码存储位置 + */ + void getWxCodeA(WechatCode.WechatCodeA wechatCodeA,String path) throws Exception; + + /** + * 获取小程序码--方案A,可接受 path 参数较长,生成个数受限 + * 接口 A 加上接口 C,总共生成的码数量限制为 100,000,请谨慎调用。 + * @param wechatCodeA 传入参数 + * @param path 小程序码存储位置 + * @param appId appId + * @param secret secret + */ + void getWxCodeA(WechatCode.WechatCodeA wechatCodeA,String path, String appId, String secret) throws Exception; + + /** + * 获取小程序码--方案B,可接受页面参数较短,生成个数不受限。 + * 接口 B 调用分钟频率受限(5000次/分钟),如需大量小程序码,建议预生成 + * 使用默认appId + * @param wechatCodeB 传入参数 + * @param path 小程序码存储位置 + */ + void getWxCodeB(WechatCode.WechatCodeB wechatCodeB,String path) throws Exception; + + /** + * 获取小程序码--方案B,可接受页面参数较短,生成个数不受限。 + * 接口 B 调用分钟频率受限(5000次/分钟),如需大量小程序码,建议预生成 + * @param wechatCodeB 传入参数 + * @param path 小程序码存储位置 + * @param appId appId + * @param secret secret + */ + void getWxCodeB(WechatCode.WechatCodeB wechatCodeB,String path, String appId, String secret) throws Exception; + + /** + * 方案C-生成小程序码(二维码),可接受 path 参数较长,生成个数受限,数量限制见 + * 接口 A 加上接口 C,总共生成的码数量限制为 100,000,请谨慎调用。 + * 使用默认appId + * @param wechatCodeC 传入参数 + * @param path 小程序码存储位置 + */ + void getWxCodeC(WechatCode.WechatCodeC wechatCodeC,String path) throws Exception; + + /** + * 方案C-生成小程序码(二维码),可接受 path 参数较长,生成个数受限,数量限制见 + * 接口 A 加上接口 C,总共生成的码数量限制为 100,000,请谨慎调用。 + * @param wechatCodeC 传入参数 + * @param path 小程序码存储位置 + * @param appId appId + * @param secret secret + */ + void getWxCodeC(WechatCode.WechatCodeC wechatCodeC,String path, String appId, String secret) throws Exception; +} diff --git a/wechatutil/src/main/java/com/ccsens/wechatutil/service/WxService.java b/wechatutil/src/main/java/com/ccsens/wechatutil/service/WxService.java new file mode 100644 index 00000000..931a1b9e --- /dev/null +++ b/wechatutil/src/main/java/com/ccsens/wechatutil/service/WxService.java @@ -0,0 +1,274 @@ +package com.ccsens.wechatutil.service; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpRequest; +import com.ccsens.util.*; +import com.ccsens.util.bean.wx.po.WxAccessToken; +import com.ccsens.util.exception.BaseException; +import com.ccsens.util.exception.BusinessException; +import com.ccsens.util.exception.WxException; +import com.ccsens.util.wx.WxGzhUtil; +import com.ccsens.util.wx.WxXcxUtil; +import com.ccsens.wechatutil.bean.po.WxBaseEntity; +import com.ccsens.wechatutil.util.WxCodeError; +import com.ccsens.wechatutil.util.WxConstant; +import com.ccsens.wechatutil.bean.po.MiniProgramUser; +import com.ccsens.wechatutil.bean.po.WxOauth2AccessToken; +import com.ccsens.wechatutil.bean.po.WxOauth2UserInfo; +import com.ccsens.wechatutil.bean.vo.WechatCode; +import com.fasterxml.jackson.core.JsonProcessingException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import java.io.*; +import java.net.URL; + +/** + * @author 逗 + */ +@Slf4j +@Service +@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class) +public class WxService implements IWxService { + + @Resource + private RedisUtil redisUtil; + + @Value("${mini.appId:}") + private String miniAppId; + @Value("${mini.secret:}") + private String miniSecret; + @Value("${h5.appId:}") + private String appIdH5; + @Value("${h5.secret:}") + private String secretH5; + + @Override + public MiniProgramUser signinByMini(String code) { + return signinByMini(code, miniAppId, miniSecret); + } + + @Override + public MiniProgramUser signinByMini(String code, String appId, String secret) { + MiniProgramUser wxUser; + //拼接wx的访问的路径 + String url = String.format(WxConstant.MINI_PROGRAM_LOGIN, appId, secret, code, WxConstant.GRANT_TYPE); + //调用微信的接口 + String response = HttpRequest.get(url).execute().body(); + log.info("url: {}\nresponse: {}", url, response); + try { + if (StrUtil.isEmpty(response) || null == (wxUser = JacksonUtil.jsonToBean(response, MiniProgramUser.class))) { + throw new BaseException(WxCodeError.WX_HTTP_ERROR); + } + } catch (IOException e) { + throw new BaseException(e.getMessage()); + } + if (null != wxUser.errcode) { + throw new BaseException(wxUser.errcode, wxUser.errmsg); + } + return wxUser; + } + + @Override + public WxOauth2UserInfo signinByH5(String code) { + return signinByH5(code, appIdH5, secretH5); + } + + @Override + public WxOauth2UserInfo signinByH5(String code, String appId, String secret) { + //获取accessToken + WxOauth2AccessToken wxOauth2AccessToken = getOauth2AccessToken(code, appId, secret); + //获取用户信息 + return getOauth2UserInfo(wxOauth2AccessToken.getAccessToken(), wxOauth2AccessToken.getOpenId()); + } + + + + @Override + public void getWxCodeA(WechatCode.WechatCodeA wechatCodeA, String path)throws Exception { + getWxCodeA(wechatCodeA,path,miniAppId,miniSecret); + } + + @Override + public void getWxCodeA(WechatCode.WechatCodeA wechatCodeA, String path, String appId, String secret) throws Exception { + String url = String.format(WxConstant.URL_GET_WX_CODE_A, getAccessToken(appId, secret)); + log.info("调用生成二维码路径和accessToken:{}", url); + String postStr = JacksonUtil.beanToJson(wechatCodeA); + log.info("二维码的参数:{}", postStr); + //调用微信接口在指定位置生成图片 + httpWxCode(path, url, postStr); + } + + @Override + public void getWxCodeB(WechatCode.WechatCodeB wechatCodeB, String path)throws Exception { + getWxCodeB(wechatCodeB,path,miniAppId, miniSecret); + } + + @Override + public void getWxCodeB(WechatCode.WechatCodeB wechatCodeB, String path, String appId, String secret) throws Exception { + String url = String.format(WxConstant.URL_GET_WX_CODE_B, getAccessToken(appId, secret)); + log.info("调用生成二维码路径和accessToken:{}", url); + String postStr = JacksonUtil.beanToJson(wechatCodeB); + log.info("二维码的参数:{}", postStr); + //调用微信接口在指定位置生成图片 + httpWxCode(path, url, postStr); + } + + @Override + public void getWxCodeC(WechatCode.WechatCodeC wechatCodeC, String path) throws Exception { + getWxCodeC(wechatCodeC,path,miniAppId, miniSecret); + } + + @Override + public void getWxCodeC(WechatCode.WechatCodeC wechatCodeC, String path, String appId, String secret) throws Exception { + String url = String.format(WxConstant.URL_GET_WX_CODE_C, getAccessToken(appId, secret)); + log.info("调用生成二维码路径和accessToken:{}", url); + String postStr = JacksonUtil.beanToJson(wechatCodeC); + log.info("二维码的参数:{}", postStr); + //调用微信接口在指定位置生成图片 + httpWxCode(path, url, postStr); + } + + /** + * 获取网页授权凭证 + * + * @param code OAuth2授权码 + * @return WxOauth2AccessToken + */ + private WxOauth2AccessToken getOauth2AccessToken(String code, String appId, String secret) { + WxOauth2AccessToken wxOauth2AccessToken; + //拼接访问路径 + String url = String.format(WxConstant.URL_GET_OAUTH2_ACCESS_TOKEN, appId, secret, code); + //调用微信接口 + String response = HttpRequest.get(url).execute().body(); + log.info("url: {}\nresponse: {}", url, response); + try { + if (StrUtil.isEmpty(response) || null == (wxOauth2AccessToken = JacksonUtil.jsonToBean(response, WxOauth2AccessToken.class))) { + throw new BaseException(WxCodeError.WX_HTTP_ERROR); + } + } catch (IOException e) { + throw new BaseException(e.getMessage()); + } + if (null != wxOauth2AccessToken.getErrcode()) { + throw new BaseException(wxOauth2AccessToken.getErrcode(), wxOauth2AccessToken.getErrmsg()); + } + if (StrUtil.isEmpty(wxOauth2AccessToken.getAccessToken())) { + throw new BaseException(WxCodeError.ACCESS_TOKEN_ERROR); + } + wxOauth2AccessToken.setCreatedAt(DateUtil.currentSeconds()); + return wxOauth2AccessToken; + } + + /** + * 通过网页授权accessToken获取用户信息 + * + * @param accessToken 网页授权接口调用凭证 + * @param openId 用户标识 + * @return SNSUserInfo + */ + private WxOauth2UserInfo getOauth2UserInfo(String accessToken, String openId) { + WxOauth2UserInfo wxOauth2UserInfo; + //拼接访问路径 + String url = String.format(WxConstant.URL_GET_OAUTH2_USER_INFO, accessToken, openId); + //调用微信接口 + String response = HttpRequest.get(url).execute().body(); + log.info("url: {}\nresponse: {}", url, response); + try { + if (StrUtil.isEmpty(response) || null == (wxOauth2UserInfo = JacksonUtil.jsonToBean(response, WxOauth2UserInfo.class))) { + throw new BaseException(WxCodeError.WX_HTTP_ERROR); + } + } catch (IOException e) { + throw new BaseException(e.getMessage()); + } + if (null != wxOauth2UserInfo.getErrcode()) { + throw new BaseException(wxOauth2UserInfo.getErrcode(), wxOauth2UserInfo.getErrmsg()); + } + if (StrUtil.isEmpty(wxOauth2UserInfo.getOpenId())) { + throw new BaseException(WxCodeError.OPENID_ERROR); + } + return wxOauth2UserInfo; + } + + /** + * 调用微信的接口在指定位置生成二维码 + * @param path 图片储存位置 + * @param url 微信接口路径 + * @param postStr 传入参数 + * @throws Exception 异常 + */ + public void httpWxCode(String path, String url, String postStr) throws Exception { + WxBaseEntity wxBaseEntity; + String response = HttpsUtil.httpsRequest(url, "POST", postStr); + if(StrUtil.isEmpty(response)){ + throw new BaseException(WxCodeError.WX_HTTP_ERROR); + } + try { + if (null == (wxBaseEntity = JacksonUtil.jsonToBean(response, WxBaseEntity.class))) { + throw new BaseException(WxCodeError.WX_HTTP_ERROR); + } + if (null != wxBaseEntity.getErrcode()) { + throw new BaseException(wxBaseEntity.getErrcode(), wxBaseEntity.getErrmsg()); + } + } catch (IOException e) { + // 从输入流读取返回内容 + File file = new File(path); + if (!file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + } + InputStream inputStream = new ByteArrayInputStream(response.getBytes()); + BufferedInputStream bis = new BufferedInputStream(inputStream); + OutputStream os = new FileOutputStream(file); + int len; + byte[] arr = new byte[1024]; + while ((len = bis.read(arr)) != -1) + { + os.write(arr, 0, len); + os.flush(); + } + os.close(); + } + } + + /** + * 小程序获取Access_token + */ + private String getAccessToken(String appId, String secret) throws BaseException { + log.info("获取accessToken,appid:{}", appId.substring(appId.length() - 4)); + Object obj = redisUtil.get(WxConstant.ACCESS_TOKEN + appId); + if (obj == null || StrUtil.isBlank((String) obj)) { + WxAccessToken wxAccessToken; + String url = String.format(WxConstant.URL_GET_ACCESS_TOKEN, "client_credential", appId, secret); + String response = HttpRequest.get(url).execute().body(); + log.info("getAccessToken: {}", response); + try { + if (StrUtil.isEmpty(response) || null == (wxAccessToken = JacksonUtil.jsonToBean(response, WxAccessToken.class))) { + throw new BaseException(WxCodeError.WX_HTTP_ERROR); + } + } catch (IOException e) { + throw new BaseException(e.getMessage()); + } + + if (null != wxAccessToken.getErrcode()) { + throw new BaseException(wxAccessToken.getErrcode(), wxAccessToken.getErrmsg()); + } + if (StrUtil.isEmpty(wxAccessToken.getAccessToken())) { + throw new BaseException(WxCodeError.ACCESS_TOKEN_ERROR); + } + redisUtil.set(WebConstant.Wx.ACCESS_TOKEN + appId, wxAccessToken.getAccessToken(), WebConstant.Wx.EXPIRE_TIME); + log.info("存储access_token:{}", wxAccessToken.getAccessToken()); + return wxAccessToken.getAccessToken(); + } + log.info("读取reids的token:{}", obj); + return (String) obj; + } + + +} diff --git a/wechatutil/src/main/java/com/ccsens/wechatutil/Util/WxCodeError.java b/wechatutil/src/main/java/com/ccsens/wechatutil/util/WxCodeError.java similarity index 88% rename from wechatutil/src/main/java/com/ccsens/wechatutil/Util/WxCodeError.java rename to wechatutil/src/main/java/com/ccsens/wechatutil/util/WxCodeError.java index de1ca987..0f2a505a 100644 --- a/wechatutil/src/main/java/com/ccsens/wechatutil/Util/WxCodeError.java +++ b/wechatutil/src/main/java/com/ccsens/wechatutil/util/WxCodeError.java @@ -1,4 +1,4 @@ -package com.ccsens.wechatutil.Util; +package com.ccsens.wechatutil.util; import com.ccsens.util.CodeError; diff --git a/wechatutil/src/main/java/com/ccsens/wechatutil/Util/WxConstant.java b/wechatutil/src/main/java/com/ccsens/wechatutil/util/WxConstant.java similarity index 58% rename from wechatutil/src/main/java/com/ccsens/wechatutil/Util/WxConstant.java rename to wechatutil/src/main/java/com/ccsens/wechatutil/util/WxConstant.java index 23e0f590..600c7942 100644 --- a/wechatutil/src/main/java/com/ccsens/wechatutil/Util/WxConstant.java +++ b/wechatutil/src/main/java/com/ccsens/wechatutil/util/WxConstant.java @@ -1,4 +1,4 @@ -package com.ccsens.wechatutil.Util; +package com.ccsens.wechatutil.util; import java.util.HashMap; import java.util.Map; @@ -12,19 +12,26 @@ public class WxConstant { public static final String ANYRING = "anyring"; /*** 小程序登录路径 */ - public static final String MINI_PROGRAM_LOGIN - = "https://api.weixin.qq.com/sns/jscode2session?appid=%1$s&secret=%2$s&js_code=%3$s&grant_type=%4$s"; + public static final String MINI_PROGRAM_LOGIN = "https://api.weixin.qq.com/sns/jscode2session?appid=%1$s&secret=%2$s&js_code=%3$s&grant_type=%4$s"; /*** 公众号获取accessToken */ - public static final String URL_GET_OAUTH2_ACCESS_TOKEN - = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%1$s&secret=%2$s&code=%3$s&grant_type=authorization_code"; + public static final String URL_GET_OAUTH2_ACCESS_TOKEN = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%1$s&secret=%2$s&code=%3$s&grant_type=authorization_code"; /*** 通过网页授权和openId获取用户信息 */ - public static final String URL_GET_OAUTH2_USER_INFO - = "https://api.weixin.qq.com/sns/userinfo?access_token=%1$s&openid=%2$s"; - + public static final String URL_GET_OAUTH2_USER_INFO = "https://api.weixin.qq.com/sns/userinfo?access_token=%1$s&openid=%2$s"; + /*** 获取小程序码A */ + public static final String URL_GET_WX_CODE_A = "https://api.weixin.qq.com/wxa/getwxacode?access_token=%1$s"; + /*** 获取小程序码B */ + public static final String URL_GET_WX_CODE_B = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%1$s"; + /*** 获取小程序码C */ + public static final String URL_GET_WX_CODE_C = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=%1$s"; + /*** 小程序获取accessToken */ + public static final String URL_GET_ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=%1$s&appid=%2$s&secret=%3$s"; /*** 小程序登录路径内的type */ public static final String GRANT_TYPE = "authorization_code"; + /*** redis内存储AccessToken的Key */ + public static final String ACCESS_TOKEN = "tall_wx_access_token_"; + /*** 小程序appId */ public static final Map APP_ID = new HashMap<>(); static { diff --git a/wechatutil/src/main/resources/application-dev.yml b/wechatutil/src/main/resources/application-dev.yml index 29f18eab..780e9bfb 100644 --- a/wechatutil/src/main/resources/application-dev.yml +++ b/wechatutil/src/main/resources/application-dev.yml @@ -60,8 +60,8 @@ file: queryPowerAddress: /power/query mini: - appId: 1 - secret: 1 + appId: wx356e01c7eb01d55d + secret: 353033db85d4b5a35f05d1c0176a0cc6 h5: appId: 1 secret: 1 \ No newline at end of file