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 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(); } } } }