这两天在别人的小程序逛的时候发现,有一个生成小程序二维码的功能;想着可以在自己的个人小程序中加一个生成海报和二维码的功分享功能,然后通过某些参数进入;可以做一些有趣的小功能。
参考一下博客:https://www.jianshu.com/p/266545660eef
参考官网:https://developers.weixin.qq.com/miniprogram/dev/api/qrcode.html?search-key=%E4%BA%8C%E7%BB%B4%E7%A0%81
通过后台接口可以获取小程序任意页面的二维码,扫描该二维码可以直接进入小程序对应的页面。目前微信支持两种二维码,小程序码(左),小程序二维码(右),如下所
接口A: 适用于需要的码数量较少的业务场景 接口地址:
https://api.weixin.qq.com/wxa/getwxacode?access_token=ACCESS_TOKEN
接口B:适用于需要的码数量极多的业务场景
https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN
接口C:适用于需要的码数量较少的业务场景
https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=ACCESS_TOKEN
45009:B接口调用分钟频率受限(目前5000次/分钟,会调整),如需大量小程序码,建议预生成。 45029:A接口和C接口生成码个数总和到达最大个数限制。 41030:B接口所传page页面不存在,或者小程序没有发布,请注意B接口没有path参数,传path参数虽然可以生成小程序码,但是只能跳主页面。
我选择的是B接口,由于生成的二维码没有地方存放如七牛等云存储,平穷限制了我只能另找出路 想着将二进制转为base64字符串返回;
public String getQrCodeBase64Str(@RequestBody QrCodeBInterfaceDTO qrCodeBInterfaceDTO) throws IOException {
//验证当前token是否过期
QrCodeCache qrCodeCache = QrCodeCache.getQrCodeCache();
if (qrCodeCache.isExpire()) {
Map<String, Object> accessTokenMap = restTemplate.postForObject(notepadProperties.getWeiXin().getAccessToken(), null, Map.class);
log.info("qrCode方法获取accessToken结果:{}", accessTokenMap);
qrCodeCache.setAccessToken(String.valueOf(accessTokenMap.get("access_token")));
qrCodeCache.setCreateTime(new Date());
if (!Objects.isNull(accessTokenMap.get("expires_in"))) {
qrCodeCache.setExpire((Integer) accessTokenMap.get("expires_in"));
} else {
qrCodeCache.setExpire(MathConstant.ZERO);
}
log.info("QrCodeCache结果:{}", qrCodeCache);
}
boolean isExpire = qrCodeCache.isExpire();
log.info("isExpire:{}", isExpire);
StringBuilder stringBuilder = new StringBuilder();
if (!isExpire) {
String url = notepadProperties.getWeiXin().getQrCodeB() + "?access_token=" + qrCodeCache.getAccessToken();
log.info("qrCode请求URL:{}", url);
Map<String, Object> param = new HashMap<>();
param.put("scene", qrCodeBInterfaceDTO.getScene());
param.put("page", qrCodeBInterfaceDTO.getPage());
param.put("width", qrCodeBInterfaceDTO.getWidth());
param.put("auto_color", qrCodeBInterfaceDTO.isAutoColor());
param.put("is_hyaline", qrCodeBInterfaceDTO.isHyaline());
if (!Objects.isNull(qrCodeBInterfaceDTO.getLineColor())) {
param.put("line_color", qrCodeBInterfaceDTO.getLineColor());
}
ResponseEntity<byte[]> entity = restTemplate.exchange(url, HttpMethod.POST, new HttpEntity(param), byte[].class);
byte[] result = entity.getBody();
if (Objects.isNull(result) || result.length == 0) {
return stringBuilder.toString();
}
BASE64Encoder encoder = new BASE64Encoder();
return stringBuilder.append("data:image/png;base64,").append(encoder.encode(result).replaceAll("\r\n|\r|\n", "")).toString();
}
return stringBuilder.toString();
}
结果返回的base64字符串死活显示不出来,使用在线转换http://imgbase64.duoshitong.com/ 显示错误;
然后将base64进行解密写入磁盘也可以正常显示没有问题;我也很无赖开始怀疑是不是微信小程序不支持base64编码格式的图片展示;
然后通过http://imgbase64.duoshitong.com/ 在线将图片转换成base64编码贴到小程序发现没有问题,瞬间凌乱了 不科学啊!!!
吃了个饭回来看到服务器返回的base64编码中包含显示的\r\n的回车元素,猜想就是它了;
修改返回结果:
return stringBuilder.append("data:image/png;base64,").append(encoder.encode(result).replaceAll("\r\n|\r|\n", "")).toString();