文章目录
前言一、二维码1 选用getUnlimited2 后端java3 前端(小程序页面)二、普通二维码使用总结:前言
微信二维码,方便传播和列表,可以用于签到扫码,分销二维码,团长二维码,分享海报等一系列二维码
效果如图:
一、二维码
1 选用getUnlimited
wxacode.getUnlimited
因为它:永久有效,数量暂无限制。
使用 后端生成,返回到前端显示
2 后端java
service写好的服务
第一步:获取access_token,我这里把它做一个一下处理,把他存在redis中,时间设置2个小时,哪个redisUtil是我封装的一个的,可以换成你们自己的。
第二步:填一下你需要参数
我这边写的是的,方便我传入,page是页面,扫一下二维码,会进入对应页面。scene是参数,进入页面是代入参数
import lombok.Data;import org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;import org.springframework.stereotype.Service;import org.springframework.web.client.RestTemplate;import xyz.kszs.base.ResultInfo;import xyz.kszs.utils.RedisUtil;import javax.annotation.Resource;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.InputStream;import java.util.Base64;import java.util.HashMap;import java.util.Map;import java.util.concurrent.TimeUnit;@Servicepublic class WeChatService {@Resourceprivate RedisUtil redisUtil;private final String appid = "xxxxxxxxxxxxxxxxx";//小程序idprivate final String secret = "xxxxxxxxxxxxxxxx";//小程序秘钥public String getAccessToken() {String keyStr="Access_Token";Object o = redisUtil.get(keyStr);if (o == null) {String url = "https://api./cgi-bin/token?grant_type=client_credential" +"&appid=" + appid +"&secret=" + secret;RestTemplate restTemplate = new RestTemplate();AccessToken accessToken = restTemplate.getForObject(url, AccessToken.class);if (accessToken==null){return null;}else{String token=accessToken.getAccess_token();redisUtil.set(keyStr,token,(long)2, TimeUnit.HOURS);//存2个小时return token;}} else {return o.toString();}}/*** 获取小程序二维码* @param scene 携带参数* @param page 页面路径* @return base64格式的二维码*/public ResultInfo getQrImage(String scene,String page) {//获取小程序access_tokenString accessToken=getAccessToken();String result = null;// 获取小程序二维码String url = "https://api./wxa/getwxacodeunlimit?access_token=" + accessToken;Map<String, Object> params = new HashMap<>();params.put("scene", scene);params.put("page",page);params.put("check_path",false);params.put("env_version","develop");// 注意这里byte是小写RestTemplate restTemplate = new RestTemplate();ResponseEntity<byte[]> responseEntity = restTemplate.postForEntity(url, params, byte[].class);// 二维码图片转base64if (responseEntity.getStatusCode() == HttpStatus.OK) {InputStream inputStream = null;ByteArrayOutputStream swapStream = null;try {byte[] body = responseEntity.getBody();inputStream = new ByteArrayInputStream(body);// 将获取流转为base64格式byte[] data;swapStream = new ByteArrayOutputStream();byte[] buff = new byte[1024];int rc;while ((rc = inputStream.read(buff, 0, 1024)) > 0) {swapStream.write(buff, 0, rc);}data = swapStream.toByteArray();result = new String(Base64.getEncoder().encode(data));result = "data:image/jpeg;base64," + result;ResultInfo resultInfo=new ResultInfo();resultInfo.setResult(result);return resultInfo;} catch (Exception e) {} finally {try {if (inputStream != null) {inputStream.close();}if (swapStream != null) {swapStream.close();}} catch (Exception e) {}}}return null;}}@Data //获取accessTokenclass AccessToken {private String access_token;//获取到的凭证private Integer expires_in;//获取有效时间,单位:秒。目前是7200秒内值private Integer errcode;//错误码private String errmsg;//错误信息}
3 前端(小程序页面)
我们才后端获取图片,需要通过base64转成img
这个是一个方法,当然,你也可以在java后台做一些处理,把图片在服务器,或者存在ssm,返回一个链接过来,前端页面直接使用。就不需要转化了
const fsm = wx.getFileSystemManager();const FILE_BASE_NAME = 'tmp_base64src'; //自定义文件名function base64src(base64data, cb) {const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || [];if (!format) {return (new Error('ERROR_BASE64SRC_PARSE'));}const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`;const buffer = wx.base64ToArrayBuffer(bodyData);fsm.writeFile({filePath,data: buffer,encoding: 'binary',success() {cb(filePath);},fail() {return (new Error('ERROR_BASE64SRC_WRITE'));},});};module.exports = base64src;
在js
var base64src = require('../../../utils/base64src.js');
生成图片方法(请求rq做一下封装,大家可以wx.request去请求你后端写好代码)
createImg() {wx.vibrateShort({type: 'light',})wx.showLoading({title: '生成中...',})var that = this;that.setData({isCode:true})const query = wx.createSelectorQuery()//返回一个对象实例,通过实例可获取canvasquery.select('#shareCard').fields({node: true,size: true}).exec((res) => {//绘制canvasconsole.log('width', that.data.width)console.log('piR', that.data.pixelRatio)console.log(res)var width = res[0].widthvar height = res[0].heightconst canvas = res[0].nodeconst ctx = canvas.getContext('2d')//使canvas适应各种屏幕不至于大小不同let piR = that.data.pixelRatio; //比例canvas.width = width * piRcanvas.height = height * piRctx.scale(piR, piR)// 绘制图片背景const backImg = canvas.createImage();let data = {page: 'pages/system/login/login',scene: '108',//用户id}rq('WeChat/getQrImage', data, 'GET').then(res => {base64src(res, resCurrent => {console.log(resCurrent)backImg.src = resCurrent;backImg.onload = () => {ctx.drawImage(backImg, width*0.1, width*0.1, width*0.8, width*0.8);wx.hideLoading();}})})const avatarImg = canvas.createImage();let avatarUrl = wx.getStorageSync('avatarUrl');if (avatarUrl == '') avatarUrl = '/img/base/avatar.jpg'avatarImg.src = avatarUrl; //头像路径avatarImg.onload = () => {let size = width * 100 / 750; //大小ctx.drawImage(avatarImg, width * 0.1, width-15, size, size);}//文字ctx.font = 'normal bold 18px sans-serif';ctx.fillStyle = '#000000'; //背景颜色let w = width * 0.1 + 10 + width * 100 / 750;ctx.fillText('邀请你,扫码登录', w, width+10);// ctx.draw = true;})},
wxml写一个页面(页面样式这里不展示呢)
<!--遮罩--><view class="cu-modal show"></view><view class="modalDlg" style="--width:{{width*0.8}}px;--height:{{width*0.9}}px"><!--关闭按钮--><view style="text-align: center;margin-top: -100rpx;"><icon type="cancel" size="40" color="#fff" bindtap="close"></icon></view><!--显示图片用的标签--><canvas type="2d" id="shareCard" style="width: {{width*0.8}}px;height: {{width*0.9}}px;"></canvas><!--创建一个画布,将它移出屏幕外看不到的地方 不看见的--><canvas canvas-id="myQrcode" style="background:#fff;width: {{width}}px;height: {{width}}px; display:block; left:-800rpx;position:absolute;" /></view><!--按钮--><view style="position: absolute;z-index: 9999;top: {{height*4/5}}px;left:50%;margin-left: -250rpx;"><button class="cu-btn round bg-green lg" style="width: 500rpx;" bindtap="share"><text class="cuIcon-wechat text-lg margin-right-xs"></text> 转发与下载</button></view>
二、普通二维码使用
是把你内容,变成二维码形式,方便扫描获取,上面可以说是程序码,非常适合小程序。先看一下结果
大家扫描会获取到 abc 12345。这是固定的
这里使用 weapp-qrcode 是一个开源的
在github 地址是:/MrITzhongzi/small_routine_components/tree/master/6.create_qr_code
把下来,把weapp-qrcode.js存在你小程序中
js 引入:
import QRCode from '../../../utils/weapp-qrcode.js';
new QRCode('myQrcode', {text: 'abc 12345',width: that.data.width, //canvas 画布的宽height:that.data.width, //canvas 画布的高padding: 0, // 生成二维码四周自动留边宽度,不传入默认为0correctLevel: QRCode.CorrectLevel.L, // 二维码可辨识度callback: (res) => {//工具回调数据// 接下来就可以直接调用微信小程序的api保存到本地或者将这张二维码直接画在海报上面去,看各自需求wx.hideLoading()console.log("生成二维码", res)backImg.src=res.path;backImg.onload = () => {ctx.drawImage(backImg, width*0.1, width*0.1, width*0.8, width*0.8);}}})
wxml和前面一样
其中canvas
其中 这条一定要存在,不然不显示不出来二维码
<!--创建一个画布,将它移出屏幕外看不到的地方 不看见的--><canvas canvas-id="myQrcode" style="background:#fff;width: {{width}}px;height: {{width}}px; display:block; left:-800rpx;position:absolute;" />
总结:
对于这2中生成二维码方式。我还是推荐是使用第一种的,因为比较适合小程序。第2种,可以弄来看一下。大家觉得呢