Helius
2021-06-29 5252d1396e21a16774be699a5ba1c8d39c14a22e
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
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;
    }
 
 
    /**
     * 生成小程序码
     * @param scene 参数
     * @param path  跳转路径
     * @param imgName  图片唯一名称
     * @return
     */
    public  String generateAcode(String scene,String path,String imgName,String width){
        String urlPrefix=businessUtil.getViewUrl();
        String imgPath=Constants.IMG_UPLOAD_PATH+imgName;
        if(!FileUtil.exist(imgPath)){
            //调用二维码接口
            String url = StrFormatter.format("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={}", getAccessToken());
            cn.hutool.json.JSONObject obj = JSONUtil.createObj();
            //最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,
            // 其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)
            obj.put("scene", scene);
            //必须是已经发布的小程序存在的页面(否则报错),例如 pages/index/index,
            // 根路径前不要填加 /,不能携带参数(参数请放在scene字段里),如果不填写这个字段,默认跳主页面
            obj.put("path", path);
            //最小 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();
            }
        }
    }
 
 
}