123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- <template>
- <div class="code-container">
- <transition name="fade">
- <div v-if="isVisible" class="qrcode">
- <div class="title">{{ productInfo.productName }}</div>
- <div class="sncode"><span>仪器SN码:</span>{{ hanldeSNcode(productInfo.snCode) }}</div>
- <div class="content">
- <img :src="imgUrl" alt="">
- </div>
- <div class="btn down-btn" @click="handleDown">下载二维码</div>
- <div class="btn close-btn" @click="handleClose">关闭</div>
- </div>
- </transition>
- <canvas id="canvas" style="display:none" />
- <div v-if="isVisible" class="mask" @click="handleClose" />
- <a id="downloadLink" href="#" style="display:none" />
- </div>
- </template>
- <script>
- import QRCode from 'qrcode'
- import downImage from '@/assets/img/qrcode-bg-down.jpg'
- export default {
- name: 'Qrcode',
- filters: {
- },
- props: {
- productInfo: {
- type: Object,
- default: () => {}
- },
- isVisible: {
- type: Boolean,
- default: false
- }
- },
- data() {
- return {
- imgUrl: '',
- wwwServer: process.env.VUE_APP_BASE_API,
- qrcodePath: ''
- }
- },
- created() {
- this.qrcodePath = `${this.wwwServer}/product/auth/product-${this.productInfo?.productId}.html`
- this.initQrcode()
- },
- methods: {
- // 关闭二维码
- handleClose() {
- this.$emit('close')
- },
- // 下载二维码
- handleDown() {
- this.createDownFile((downCanvas) => {
- // 构造url
- var url = downCanvas.toDataURL('image/jpg')
- // 构造a标签并模拟点击
- var downloadLink = document.getElementById('downloadLink')
- downloadLink.setAttribute('href', url)
- downloadLink.setAttribute('download', '二维码.jpg')
- downloadLink.click()
- })
- },
- // 初始化二维码
- async initQrcode() {
- // 二维码配置
- const options = {
- width: 192,
- height: 192,
- margin: 1
- }
- try {
- this.imgUrl = await QRCode.toDataURL(this.qrcodePath, options)
- } catch (err) {
- console.error(err)
- }
- },
- // 生成下载的文件
- async createDownFile(callback) {
- const strHeader = this.productInfo.productName
- const strFooter1 = '仪器SN码:'
- const strFooter2 = this.hanldeSNcode(this.productInfo.snCode)
- // 生成二维码参数信息
- const options = {
- width: 720,
- height: 720,
- margin: 1
- }
- // 生成二维码dataURL
- const downDataURL = await QRCode.toDataURL(this.qrcodePath, options)
- // 设置下载二维码
- const downCanvas = document.getElementById('canvas')
- const downImg = new Image()
- const downBgImg = new Image()
- downImg.src = downDataURL
- downBgImg.src = downImage
- downBgImg.onload = function() {
- // 重新绘制画布
- const w = this.width
- const h = this.height
- downCanvas.width = w
- downCanvas.height = h
- const ctx = downCanvas.getContext('2d')
- // 设置画布背景
- ctx.fillStyle = '#ffffff'
- ctx.fillRect(0, 0, downCanvas.width, downCanvas.height)
- // 设置文字样式
- ctx.fillStyle = '#ffffff'
- ctx.font = 'bold 52px MicrosoftYaHei'
- ctx.textAlign = 'center'
- // 绘制背景
- ctx.drawImage(this, 0, 0)
- // 绘制二维码
- ctx.drawImage(downImg, 185, 372)
- // 绘制顶部文字描述
- const chr = strHeader.split('')
- let temp = ''
- const row = []
- for (let a = 0; a < chr.length; a++) {
- if (ctx.measureText(temp).width >= (w - 290)) {
- row.push(temp)
- temp = ''
- }
- temp += chr[a]
- }
- row.push(temp)
- if (row.length === 1) {
- ctx.fillText(row[0], w / 2, 122)
- } else {
- for (var b = 0; b < row.length; b++) {
- ctx.fillText(row[b], w / 2, 160 - (row.length - b - 1) * 65)
- }
- }
- // 绘制底部文字
- ctx.fillStyle = '#42aaff'
- ctx.font = 'bold 33px MicrosoftYaHei'
- ctx.textAlign = 'center'
- ctx.fillText(strFooter1 + strFooter2, w / 2, 238)
- // 绘制完成后的回调
- callback(downCanvas)
- }
- },
- hanldeSNcode(code) {
- const start = code.slice(0, 2)
- const end = code.slice(code.length - 5, code.length - 1)
- return start + '*'.repeat(6) + end
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .mask{
- position: fixed;
- top: 0;
- left: 0;
- z-index: 9998;
- width: 100vw;
- height: 100vh;
- background: rgba(0,0,0,.5);
- }
- .qrcode{
- z-index: 9999;
- position: fixed;
- left: 50%;
- top: 20%;
- transform: translateX(-50%);
- width: 300px;
- height: 400px;
- background: url(../../assets/img/qrcode-bg-show.png) no-repeat center;
- .content{
- width: 192px;
- height: 192px;
- position: absolute;
- left: 54px;
- bottom: 46px;
- }
- .down-btn{
- left: 0;
- }
- .close-btn{
- right: 0;
- }
- .title{
- position: absolute;
- top: 32px;
- left: 50%;
- transform: translateX(-50%);
- width:256px;
- text-align: center;
- font-size: 16px;
- color: #fff;
- font-weight: bold;
- }
- .sncode{
- position: absolute;
- top: 78px;
- left: 50%;
- transform: translateX(-50%);
- text-align: center;
- width: 192px;
- color: #0e9ef0;
- font-size: 14px;
- span{
- font-weight: bold;
- }
- }
- }
- .btn {
- position: absolute;
- bottom: -60px;
- width: 108px;
- height: 32px;
- background-image: linear-gradient(-90deg, #50c0ff 0%,#0e90dc 100%);
- border-radius: 4px;
- text-align: center;
- line-height: 32px;
- color: #fff;
- font-size: 14px;
- cursor: pointer;
- }
- </style>
|