|
@@ -0,0 +1,194 @@
|
|
|
+package com.zhongshu.reward.server.core.util.wx;
|
|
|
+
|
|
|
+import cn.hutool.core.bean.BeanUtil;
|
|
|
+import cn.hutool.json.JSONUtil;
|
|
|
+import com.github.microservice.core.util.net.HttpClient;
|
|
|
+import com.github.microservice.core.util.net.apache.HttpClientUtil;
|
|
|
+import com.github.microservice.core.util.net.apache.HttpModel;
|
|
|
+import com.github.microservice.core.util.net.apache.MethodType;
|
|
|
+import com.github.microservice.core.util.net.apache.ResponseModel;
|
|
|
+import com.zhongshu.reward.client.model.wechat.AccessTokenVo;
|
|
|
+import com.zhongshu.reward.client.model.wechat.GenerateSchemeVo;
|
|
|
+import com.zhongshu.reward.client.model.wechat.MiniAppUserInfoVo;
|
|
|
+import com.zhongshu.reward.client.model.wechat.WechatPhoneNumber;
|
|
|
+import com.zhongshu.reward.client.ret.ResultContent;
|
|
|
+import com.zhongshu.reward.client.ret.ResultState;
|
|
|
+import com.zhongshu.reward.server.core.service.RedisService;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.io.IOException;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.LinkedHashMap;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Objects;
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ */
|
|
|
+@Component
|
|
|
+@Slf4j
|
|
|
+public class WechatCUtil {
|
|
|
+
|
|
|
+ private final static String ACCESS_TOKEN_KEY = "com:zswl:cloud:bdb:wechat:accessToken:";
|
|
|
+
|
|
|
+ private final static String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/stable_token?grant_type=client_credential&appid=%s&secret=%s";
|
|
|
+
|
|
|
+ private final static String WECHAT_MINI_APP_AUTH_URL = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=%s";
|
|
|
+
|
|
|
+ private final static String PHONE_NUMBER_URL = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=%s";
|
|
|
+
|
|
|
+ private final static String GENERATE_SCHEME = "https://api.weixin.qq.com/wxa/generatescheme?access_token=%s";
|
|
|
+
|
|
|
+ private final static String UNLIMITED_QRCODE_URL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s";
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private WechatCAuthConfig wechatAuthConfig;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private RedisService redisService;
|
|
|
+
|
|
|
+ // @PostConstruct
|
|
|
+ public void init() throws Exception {
|
|
|
+ log.info("init微信Token... ");
|
|
|
+ AccessTokenVo accessTokenVo = getAccess_token();
|
|
|
+ if (Objects.nonNull(accessTokenVo) && StringUtils.isNotEmpty(accessTokenVo.getAccessToken())) {
|
|
|
+ log.info("accessTokenVo: {}", accessTokenVo);
|
|
|
+ redisService.setValueSecond(ACCESS_TOKEN_KEY, accessTokenVo.getAccessToken(), 300);
|
|
|
+ log.info("微信登录初始化成功");
|
|
|
+ } else {
|
|
|
+ log.error("*******fail *********");
|
|
|
+ log.error("WechatUtil init fail");
|
|
|
+ log.error("*******fail *********");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public AccessTokenVo genAccessToken() throws Exception {
|
|
|
+ String url = String.format(ACCESS_TOKEN_URL, wechatAuthConfig.getAppid().trim(), wechatAuthConfig.getSecret().trim());
|
|
|
+ ResponseModel request = HttpClientUtil.request(HttpModel.builder().method(MethodType.Get).url(url).build());
|
|
|
+ if (200 == request.getCode()) {
|
|
|
+ return BeanUtil.copyProperties(request.getBody(), AccessTokenVo.class);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public synchronized AccessTokenVo getAccess_token() throws IOException {
|
|
|
+ String url = String.format(ACCESS_TOKEN_URL, wechatAuthConfig.getAppid(), wechatAuthConfig.getSecret());
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("grant_type", "client_credential");
|
|
|
+ map.put("appid", wechatAuthConfig.getAppid().trim());
|
|
|
+ map.put("secret", wechatAuthConfig.getSecret().trim());
|
|
|
+ String json = JSONUtil.toJsonStr(map);
|
|
|
+ ResponseModel request = HttpClientUtil.request(HttpModel.builder()
|
|
|
+ .url(url).method(MethodType.Post).body(json).build());
|
|
|
+ if (200 == request.getCode()) {
|
|
|
+ return BeanUtil.copyProperties(request.getBody(), AccessTokenVo.class);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getAccessToken() throws Exception {
|
|
|
+ String value = redisService.getValue(ACCESS_TOKEN_KEY);
|
|
|
+ if (Objects.isNull(value)) {
|
|
|
+ init();
|
|
|
+ value = redisService.getValue(ACCESS_TOKEN_KEY);
|
|
|
+ }
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+
|
|
|
+ public WechatPhoneNumber getPhoneNumber(String code) throws Exception {
|
|
|
+ String url = String.format(PHONE_NUMBER_URL, getAccessToken());
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("code", code);
|
|
|
+ String json = JSONUtil.toJsonStr(map);
|
|
|
+ ResponseModel request = HttpClientUtil.request(HttpModel.builder().method(MethodType.Post)
|
|
|
+ .url(url).body(json).build());
|
|
|
+ if (200 == request.getCode()) {
|
|
|
+ try {
|
|
|
+ LinkedHashMap map1 = (LinkedHashMap) request.getBody();
|
|
|
+ if (map1.containsKey("errcode")) {
|
|
|
+ log.error("getPhoneNumber error: {} {} {}", map1.get("errcode"), map1.get("errmsg"), code);
|
|
|
+ String errcode = map1.get("errcode").toString();
|
|
|
+ if (errcode.equals("40001")) {
|
|
|
+ clear();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ WechatPhoneNumber wechatPhoneNumber = BeanUtil.copyProperties(((LinkedHashMap) request.getBody()).get("phone_info"), WechatPhoneNumber.class);
|
|
|
+ log.info("wechatPhoneNumber: {}", wechatPhoneNumber);
|
|
|
+ return wechatPhoneNumber;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public MiniAppUserInfoVo getMiniAppUserInfo(String jsCode) throws Exception {
|
|
|
+ String url = String.format(WECHAT_MINI_APP_AUTH_URL, "wx92ae04fb0f325887", "09c789bfa6d6b66362c0794468a4470a", jsCode, "authorization_code");
|
|
|
+ ResponseModel request = HttpClientUtil.request(HttpModel.builder().url(url).build());
|
|
|
+ if (200 == request.getCode()) {
|
|
|
+ MiniAppUserInfoVo miniAppUserInfoVo = BeanUtil.copyProperties(
|
|
|
+ JSONUtil.parseObj(request.getBody().toString()),
|
|
|
+ MiniAppUserInfoVo.class);
|
|
|
+ if (Objects.nonNull(miniAppUserInfoVo.getOpenid())) {
|
|
|
+ return miniAppUserInfoVo;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ MiniAppUserInfoVo vo = new MiniAppUserInfoVo();
|
|
|
+ vo.setMsg(request.toString());
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ResultContent generateScheme() throws Exception {
|
|
|
+ String accessToken = getAccessToken();
|
|
|
+ String url = String.format(GENERATE_SCHEME, accessToken);
|
|
|
+ ResponseModel request = HttpClientUtil.request(HttpModel.builder().method(MethodType.Post).url(url).build());
|
|
|
+ String msg = "";
|
|
|
+ if (200 == request.getCode()) {
|
|
|
+ LinkedHashMap body = (LinkedHashMap) request.getBody();
|
|
|
+ Integer errcode = (Integer) body.get("errcode");
|
|
|
+ msg = body.get("errmsg").toString();
|
|
|
+ String openlink = (String) body.get("openlink");
|
|
|
+ GenerateSchemeVo vo = new GenerateSchemeVo(errcode, msg, openlink);
|
|
|
+ if (Objects.nonNull(vo.getOpenLink()))
|
|
|
+ return ResultContent.buildContent(vo.getOpenLink());
|
|
|
+ msg = vo.getErrMsg();
|
|
|
+ }
|
|
|
+ return ResultContent.build(ResultState.Exception, msg);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成微信小程序 页面二维码
|
|
|
+ *
|
|
|
+ * @param scene
|
|
|
+ * @param page
|
|
|
+ * @return
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public byte[] getUnlimitedQRCodeToByte(String scene, String page) throws Exception {
|
|
|
+ String url = String.format(UNLIMITED_QRCODE_URL, getAccessToken());
|
|
|
+ Map<String, String> header = new HashMap<>();
|
|
|
+ header.put("Content-Type", "image/jpeg");
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("scene", scene);
|
|
|
+ if (StringUtils.isNotEmpty(page)) {
|
|
|
+ map.put("page", page);
|
|
|
+ }
|
|
|
+ map.put("env_version", "trial");
|
|
|
+ HttpClient.ResultBean resultBean = new HttpClient().ReadDocuments(url, true,
|
|
|
+ JSONUtil.toJsonStr(map).getBytes(), header);
|
|
|
+ if (200 == resultBean.getStat()) {
|
|
|
+ return resultBean.getData();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void clear() {
|
|
|
+ redisService.removeValue(ACCESS_TOKEN_KEY);
|
|
|
+ }
|
|
|
+}
|