| 
					
				 | 
			
			
				@@ -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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |