【Vue】二维码生成
按组长提供的样例,功能比较相符合的是这个博客:
https://www.jianshu.com/p/8d59107e1992
这个博客引用的是这篇文章:
https://blog.csdn.net/wwqqqq123/article/details/90261994
如何使用和参数说明很清楚,这里我就直接贴我写的DEMO
东西还没要求要弄上去,但是我自己先弄出来,怕后面需求变动又说需要了
首先主界面会放一个对话框:
<el-dialog v-if="qrCodeVisible" title="二维码生成" :append-to-body="true" :visible.sync="qrCodeVisible" width="450px" class="roll-dialog" > <qr-code-page :rooms="changedList" /> </el-dialog>
会传递选中的房间列表数据
二维码对话框页面:
logo随便引用一个小图标
大小200像素
text属性就是存储的参数,因为不确定传什么,先放上场所编号和房间号
因为是房间列表,所以传递若干个房间,用div包裹组件再遍历
<template> <div> <div class="qrCode-border" v-for="(room, idx) in rooms" :key="idx" align="center" > <h3>房号:{{room.roomNo}}</h3> <vue-qr :logo-src="logoSrc" :size="200" :auto-color="true" :dot-scale="1" :text="room.placeCode + '-' + room.roomNo" /> </div> </div> </template> <script> import VueQr from 'vue-qr' export default { name: 'QrCodePage', components: { VueQr }, props: { rooms: { type: Array, default() { return [] } } }, data() { return { logoSrc: '/favicon.ico' } } } </script> <style scoped> .qrCode-border { margin: 20px 0px; } </style>
解决对话框过长的问题,设置对话框的滚动条
https://blog.csdn.net/qq_32837111/article/details/121248211
效果:
在确定这个功能之后,发现是一个小程序的二维码生成
则这样vue-qr组件没啥用了,二维码的生成是在后台完成的
拿到微信接口的Token之后再请求二维码接口获取图片
/** * 获取小程序码,数量暂无限制 */ public final static String APPLET_QRCORE_UNLIMIT = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN"; /** * 获取小程序码,数量限制 */ public final static String APPLET_QRCORE_GET = "https://api.weixin.qq.com/wxa/getwxacode?access_token=ACCESS_TOKEN"; /** * 封装小程序二维码相关信息 * * @param placeCode 场所编号 * @param roomNo 房间号 * @param dataMap 返回结果map信息 * @param redisTemplate redis工具类 * @return * @author wangkun * @createTime 2022/3/14 16:15 */ public final static void packageAppletQrcodeInfo(String placeCode, String roomNo, Map<String, Object> dataMap, RedisTemplate<String, Object> redisTemplate) { //step1 获取小程序token信息 String accessToken = redisTemplate.opsForValue().get(ApiConstants.CACHE_KEY_AISW_WX_APPLET_TOKEN_PREFIX).toString(); String requestUrl = APPLET_QRCORE_GET.replace("ACCESS_TOKEN", accessToken); //封装小程序二维码参数值 JSONObject paramJson = new JSONObject(); paramJson.put("width", "280"); StringBuffer sceneData = new StringBuffer(); //sceneData.append(placeCode).append("##").append(roomNo); sceneData.append("pages/index/index").append("?c=").append(placeCode).append("&r=").append(roomNo); paramJson.put("path", sceneData.toString()); RSClient rsClient = new RSClient(requestUrl); AppletDataQueryApi qrCodeQueryApi = rsClient.createObject(AppletDataQueryApi.class, 60000, 60000); byte[] qrCodeByte = qrCodeQueryApi.sendQrcodeData(paramJson.toString()); if (!ChkUtil.isEmpty(qrCodeByte)) { String qrCodeBaseImg64 = "data:image/png;base64," + Base64.getEncoder().encodeToString(qrCodeByte).replaceAll("\r\n", ""); dataMap.put("imagBase", qrCodeBaseImg64); } }
接口响应结果:
返回Base64图片编码,直接传给img的src属性上面
前端接口获取数据:
created() { this.getRoomQrcodePics() }, methods: { async getRoomQrcodePics() { const rooms = this.rooms.map(room => room.roomNo).toString() const { data: res } = await getRoomQrCodes({ placeCode: this.rooms[0].placeCode, rooms: rooms }) console.log(res) this.qrCodeInfoList = res this.loadingFlag = false },
}
标签渲染:
<div v-if="!loadingFlag" ref="qrCodeZone" class="container"> <div v-for="(qrCode, idx) in qrCodeInfoList" :key="idx" class="qrCode-border" align="center" > <!--<img :src="qrCode.imagBase">--> <!--<img src="./../../../assets/images/test-qrCode.png" alt="">--> <div class="qrCode-info"> <img :src="qrCode.imagBase"> <div class="room">房间号:{{ qrCode.roomNo }}</div> <div class="placeName">{{ qrCode.placeName }}</div> </div> </div> </div>
设置样式渲染,因为这个二维码需要被打印出来贴在房间里面直接用:
所以对div元素嵌套了一个背景图,然后再把二维码摆在上面
.qrCode-border { width: 500px; height: 1000px; margin: 10px 0px; background-image: url('./../../../assets/images/qrCode-bg.png'); background-size: 100%; position: relative; float: left; border-radius: 15px; } .qrCode-border:nth-child(odd) { margin-right: 20px; } .qrCode-info { position: absolute; left: 50%; top: 21%; transform: translate(-50%, -21%); height: 285px; } .qrCode-info .room { font-size: 30px; font-weight: bolder; color: black; margin: 5px; } .qrCode-info .placeName { font-size: 20px; font-weight: bolder; color: black; }
上面只能让二维码直接浏览,为了方便用户打印,还需要让预览界面生成图片下载下来
这里参考了两篇博客来实现:
把元素转换成图片参考博客 https://blog.csdn.net/Mr__proto__/article/details/124481187 https://www.jianshu.com/p/eb963fc867b8
抓取选中的元素,然后转成BASE64编码来下载
生成逻辑和下载逻辑:
spawnPicture() { html2canvas(this.$refs.qrCodeZone).then((canvas) => { const dataURL = canvas.toDataURL('image/png') // 这里是转换成base64格式的 this.picData = dataURL console.log(dataURL) // 生成下载资源 const link = document.createElement('a') // 去掉此标签的所有样式避免展示出a标签 link.style.display = 'none' // 把获取到的流文件放到href属性里 link.href = dataURL // 调用download属性,并添加名字 link.setAttribute('download', '二维码.png') // 添加这个a标签到body上 document.body.appendChild(link) // 触发click事件 link.click() }) }