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

  

 

posted @ 2022-06-06 11:50  emdzz  阅读(848)  评论(0编辑  收藏  举报