微信小程序生成二维码、程序码、海报

文章目录

  • 前言
  • 一、二维码
    • 1 选用getUnlimited
    • 2 后端java
    • 3 前端(小程序页面)
  • 二、普通二维码使用
  • 总结:


前言

微信二维码,方便传播和列表,可以用于签到扫码,分销二维码,团长二维码,分享海报等一系列二维码


效果如图:
微信小程序生成二维码、程序码、海报_第1张图片

一、二维码

1 选用getUnlimited

wxacode.getUnlimited
因为它:永久有效,数量暂无限制。
使用 后端生成,返回到前端显示

2 后端java

service写好的服务
第一步:获取access_token,我这里把它做一个一下处理,把他存在redis中,时间设置2个小时,哪个redisUtil是我封装的一个的,可以换成你们自己的。

第二步:填一下你需要参数
微信小程序生成二维码、程序码、海报_第2张图片
我这边写的是的,方便我传入,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;

@Service
public class WeChatService {

    @Resource
    private RedisUtil redisUtil;

    private final String appid = "xxxxxxxxxxxxxxxxx";//小程序id
    private final String secret = "xxxxxxxxxxxxxxxx";//小程序秘钥

    public String getAccessToken() {
        String keyStr="Access_Token";
        Object o = redisUtil.get(keyStr);
        if (o == null) {
            String url = "https://api.weixin.qq.com/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_token
        String accessToken=getAccessToken();
        String result = null;

        // 获取小程序二维码
        String url = "https://api.weixin.qq.com/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);
        // 二维码图片转base64
        if (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 //获取accessToken
class 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()
        //返回一个对象实例,通过实例可获取canvas
        query.select('#shareCard').fields({
            node: true,
            size: true
        }).exec((res) => { //绘制canvas
            console.log('width', that.data.width)
            console.log('piR', that.data.pixelRatio)
            console.log(res)
            var width = res[0].width
            var height = res[0].height

            const canvas = res[0].node
            const ctx = canvas.getContext('2d')

            //使canvas适应各种屏幕不至于大小不同
            let piR = that.data.pixelRatio; //比例
            canvas.width = width * piR
            canvas.height = height * piR
            ctx.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>

二、普通二维码使用

是把你内容,变成二维码形式,方便扫描获取,上面可以说是程序码,非常适合小程序。先看一下结果
微信小程序生成二维码、程序码、海报_第3张图片
大家扫描会获取到 abc 12345。这是固定的

这里使用 weapp-qrcode 是一个开源的
在github 地址是:https://github.com/MrITzhongzi/small_routine_components/tree/master/6.create_qr_code

把下来,把 weapp-qrcode.js存在你小程序中

微信小程序生成二维码、程序码、海报_第4张图片
在这里插入图片描述
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, // 生成二维码四周自动留边宽度,不传入默认为0
                correctLevel: 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种,可以弄来看一下。大家觉得呢

你可能感兴趣的:(小程序,小程序)