Helius
2021-07-21 00ecb535a0d60687293d54d23de3e94e27cd2b1f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
package com.xzx.gc.common.utils.wxpay;
 
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.text.StrFormatter;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.xzx.gc.common.Result;
import com.xzx.gc.common.constant.Constants;
import com.xzx.gc.common.utils.BusinessUtil;
import com.xzx.gc.common.utils.RedisUtil;
import com.xzx.gc.common.utils.StringUtils;
import com.xzx.gc.model.user.UserInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
 
@Component
@Slf4j
public class  WxUtil {
 
 
 
    @Autowired
    private RedisUtil redisUtil;
 
    @Autowired
    private BusinessUtil businessUtil;
 
    /**
     * 获取微信token
     * @return
     */
    public String getAccessToken(){
        //获取微信accessToken
        String wxToken = redisUtil.get(Constants.REDIS_USER_KEY+Constants.WX_TOKEN);
        if(StringUtils.isBlank(wxToken)){
            String url=StrFormatter.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}",Constants.WX_APPID,Constants.WX_SECRET);
            String s = HttpUtil.get(url);
            cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(s);
            log.debug("生成微信TOKEN返回数据:{}",JSONUtil.toJsonPrettyStr(jsonObject));
            String access_token = jsonObject.getStr("access_token");
            String expires_in = jsonObject.getStr("expires_in");
            if(StrUtil.isNotBlank(expires_in)) {
                redisUtil.setex(Constants.REDIS_USER_KEY + Constants.WX_TOKEN, access_token, Integer.parseInt(expires_in) - 100);
            }
            wxToken=access_token;
        }
        return wxToken;
    }
 
 
    /**
     * 获取微信token
     * @return
     */
    public String getAppOpenId(String code){
        String url=StrFormatter.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid={}&secret={}&code={}&grant_type=authorization_code",Constants.WX_APP_APPID,Constants.WX_APP_SECRET,code);
        String s = HttpUtil.get(url);
        cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(s);
        log.info("获取微信APP登录openid返回:{}",jsonObject);
        String openid = jsonObject.getStr("openid");
        return openid;
    }
 
    public  String generateAcode(String scene,String path,String imgName,String width){
        return generateAcode(scene, path, imgName, width, null);
    }
 
    /**
     * 生成小程序码
     * @param scene 参数
     * @param path  跳转路径
     * @param imgName  图片唯一名称
     * @return
     */
    public  String generateAcode(String scene,String path,String imgName,String width, Integer type){
        String urlPrefix=businessUtil.getViewUrl();
        String imgPath=Constants.IMG_UPLOAD_PATH+imgName;
        if(!FileUtil.exist(imgPath)){
 
            cn.hutool.json.JSONObject obj = JSONUtil.createObj();
            //调用二维码接口
            String url = null;
            if (type == null) {
                // 该接口无数量限制,但是 scene 传参最大字符长度为32个字符
                url = StrFormatter.format("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={}", getAccessToken());
                obj.put("scene", scene);
                obj.put("path", path);
            } else {
                // 该接口存在数量限制, 总共可生成10w个, 但参数是接在path后面
                url = StrFormatter.format("https://api.weixin.qq.com/wxa/getwxacode?access_token={}", getAccessToken());
                obj.put("path", path + "?" + scene );
            }
 
            //最小 280px,最大 1280px
            obj.put("width", width);
            obj.put("auto_color", false);
            cn.hutool.json.JSONObject obj2 = JSONUtil.createObj();
            obj2.put("r", 0);
            obj2.put("g", 0);
            obj2.put("b", 0);
            obj.put("line_color", obj2);
            //是否需要透明底色,为 true 时,生成透明底色的小程序码
            obj.put("is_hyaline", false);
            try {
                InputStream inputStream = HttpRequest.post(url).body(obj.toString(), "application/json").execute().bodyStream();
                File file = new File(imgPath);
                FileUtil.writeFromStream(inputStream, file);
                long uploadUrl = FileUtil.size(file);
                //小于10kb重新生成
                if(uploadUrl<=Constants.MIN_FILE_SIZE){
                    log.error("生成微信小程序码失败:图片大小异常:{}",uploadUrl);
                    return null;
                }
            } catch (Exception e) {
                log.error("生成微信小程序码失败",e);
                return null;
            }
 
        }else {
            //判断文件是否正常 不正常 删除
            File file = new File(imgPath);
            long uploadUrl = FileUtil.size(file);
            if(uploadUrl<=Constants.MIN_FILE_SIZE){
                FileUtil.del(file);
                return null;
            }
        }
        log.debug("生成微信小程序码成功,路径:" + imgPath);
        return urlPrefix+"/"+imgName;
    }
 
 
 
 
    public Result<UserInfoVo> getOpenId(String code){
        String appid =Constants.WX_APPID;
        String secret = Constants.WX_SECRET;
 
        UserInfoVo userInfoVo = new UserInfoVo();
        Result result = new Result();
 
        BufferedReader in = null;
        //appid和secret是开发者分别是小程序ID和小程序密钥,开发者通过微信公众平台-》设置-》开发设置就可以直接获取,
        String url="https://api.weixin.qq.com/sns/jscode2session?appid="
                +appid+"&secret="+secret+"&js_code="+code+"&grant_type=authorization_code";
        JSONObject jsonObject=null;
        try {
            URL weChatUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection connection = weChatUrl.openConnection();
            // 设置通用的请求属性
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);
            // 建立实际的连接
            connection.connect();
 
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            StringBuffer sb = new StringBuffer();
            String line;
            while ((line = in.readLine()) != null) {
                sb.append(line);
            }
            jsonObject = JSONObject.parseObject(sb.toString());
            String openId = (String)jsonObject.get("openid");
            String session_key = (String)jsonObject.get("session_key");
            if(StringUtils.isBlank(openId)){
                result.setCode(-1);
                result.setMsg("获取用户OPENID失败");
                return result;
            }
            userInfoVo.setOpenId(openId);
            userInfoVo.setSessionKey(session_key);
            result.setData(userInfoVo);
            return result;
        } catch (Exception e) {
            result.setCode(-1);
            result.setMsg("获取用户OPENID失败");
            return result;
        }
        //使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
    }
 
 
}