package com.ruoyi.system.utils.wx.tools; import com.ruoyi.common.redis.service.RedisService; import com.ruoyi.system.utils.wx.body.resp.AccessTokenRespBody; import com.ruoyi.system.utils.wx.body.resp.Code2SessionRespBody; import com.ruoyi.system.utils.wx.body.resq.Code2SessionResqBody; import com.ruoyi.system.utils.wx.model.WeixinProperties; import lombok.extern.slf4j.Slf4j; import org.springframework.util.StringUtils; import org.springframework.web.client.RestTemplate; import java.text.MessageFormat; import java.util.concurrent.TimeUnit; /** * @author xiaochen * @ClassName WxAppletTools * @Description * @date 2024-8-04 13:55 */ @Slf4j public class WxAppletTools { private final static String ACCESSTOKEN_CACHE_KEY = "accessToken"; /** * 请求参数 * 属性 类型 默认值 必填 说明 * appid string 是 小程序 appId * secret string 是 小程序 appSecret * js_code string 是 登录时获取的 code * grant_type string 是 授权类型,此处只需填写 authorization_cod *
* 返回值: *
* 属性 类型 说明 * openid string 用户唯一标识 * session_key string 会话密钥 * unionid string 用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台帐号下会返回,详见 UnionID 机制说明。 * errcode number 错误码 * errmsg string 错误信息 */ private static final String JSCODE_2_SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code"; /** * 请求参数 * 属性 类型 默认值 必填 说明 * grant_type string 是 填写 client_credential * appid string 是 小程序唯一凭证,即 AppID,可在「微信公众平台 - 设置 - 开发设置」页中获得。(需要已经成为开发者,且帐号没有异常状态) * secret string 是 小程序唯一凭证密钥,即 AppSecret,获取方式同 appid * 返回值 * Object * 返回的 JSON 数据包 *
* 属性 类型 说明 * access_token string 获取到的凭证 * expires_in number 凭证有效时间,单位:秒。目前是7200秒之内的值。 * errcode number 错误码 * errmsg string 错误信息 */ public static String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}"; private WeixinProperties wxConfig; private RestTemplate wxRestTemplate; private RedisService redisService; public WxAppletTools(RestTemplate wxRestTemplate, WeixinProperties wxConfig, RedisService redisService) { this.wxRestTemplate = wxRestTemplate; this.wxConfig = wxConfig; this.redisService = redisService; } /** * 自定义部分数据 * * @param wxConfig * @return */ public WxAppletTools build(WeixinProperties wxConfig) { this.wxConfig = wxConfig; return this; } /** * @param resqBody * @return */ public Code2SessionRespBody getOpenIdByJscode2session(Code2SessionResqBody resqBody) { long start = System.currentTimeMillis(); String requestUrl = MessageFormat.format(JSCODE_2_SESSION_URL, wxConfig.getAppId(), wxConfig.getSecretId(), resqBody.getJsCode()); long end = System.currentTimeMillis(); log.info("code换取sessionKey时间:{}", (end - start)); String respBody = wxRestTemplate.getForEntity(requestUrl, String.class).getBody(); end = System.currentTimeMillis(); log.info("code换取sessionKey时间:{}", (end - start)); log.info("Jscode2session:{}", respBody); Code2SessionRespBody code2SessionRespBody = WxJsonUtils.parseObject(respBody, Code2SessionRespBody.class); // 判断有误异常 if (StringUtils.hasLength(code2SessionRespBody.getErrorMsg())) { // 抛出错误 throw new WxException(code2SessionRespBody.getErrorCode() + ":" + code2SessionRespBody.getErrorMsg()); } return code2SessionRespBody; } /** * @return */ public String getAccessToken(String version) { String accessToken = redisService.getCacheObject(ACCESSTOKEN_CACHE_KEY + version); if (StringUtils.hasLength(accessToken)) { return accessToken; } String requestUrl = MessageFormat.format(ACCESS_TOKEN_URL, wxConfig.getAppId(), wxConfig.getSecretId()); String respBody = wxRestTemplate.getForEntity(requestUrl, String.class).getBody(); AccessTokenRespBody accessTokenRespBody = WxJsonUtils.parseObject(respBody, AccessTokenRespBody.class); // 判断有误异常 if (StringUtils.hasLength(accessTokenRespBody.getErrorMsg())) { // 抛出错误 throw new WxException(accessTokenRespBody.getErrorCode() + ":" + accessTokenRespBody.getErrorMsg()); } redisService.setCacheObject(ACCESSTOKEN_CACHE_KEY + version, accessTokenRespBody.getAccessToken(), 7200L, TimeUnit.SECONDS); return accessTokenRespBody.getAccessToken(); } }