扫描pc端页面二维码,在手机上签名

npm install qrcodejs2
npm install signature_pad

在移动端需要安装 vant和jquery
npm install vant
npm install jquery

<template>
  <div v-loading="loading" class="dashboard-container">
    <div v-if="imgState" class="autograph-wrapper">
      <img :src="src" alt>
      <el-button size="small" type="primary" @click="resetClick">修改签名</el-button>
    </div>
    <div v-else class="qrcode-wrapper">
      <div id="qrcode" ref="qrCode" class="qrcode" />
      <p class="qrcode-wrapper-codeText">{{ qrcodeText }}</p>
    </div>
  </div>
</template>

<script>
import QRCode from 'qrcodejs2'
import { getSignature } from '@/api/audit'
import { getToken } from '@/utils/auth'

export default {
  data() {
    return {
      src: '',
      token: getToken(),
      // 在服务上页面的地址路径 
      qrcodeUrl:process.env.VUE_APP_URL + '*******/audit/signature',
      qrcodeText: '您尚未进行签名,请手机扫描以下二维码,完善个人签名信息。',
      imgState: false,
      code: null,
      loading: false
    }
  },
  mounted() {
    // 查询个人签名
    this.getAtograph()
  },
  methods: {
    // 查询个人签名
    async getAtograph() {
      this.imgState = false
      this.crateQrcode()
      this.loading = true
      const res = await getSignature()
      if (res.code == '-1') {
        this.imgState = false
        this.code ? '' : this.crateQrcode()
      } else {
        this.imgState = true
        this.src = res.response.image
      }
      this.loading = false
    },
    // 二维码
    crateQrcode() {
      this.$nextTick(() => {
        this.code = new QRCode(this.$refs.qrCode, {
          width: 160,
          height: 160, // 高度
          text: this.qrcodeUrl, // 二维码内容
          background: '#f0f',
          foreground: '#ff0'
        })
      })
    },
    // 修改签名
    resetClick() {
      this.imgState = false
      this.qrcodeText = '请手机扫描以下二维码,修改个人签名信息。'
      this.crateQrcode()
    }
  }
}
</script>

<style scoped lang="scss">
.dashboard-container {
  font-size: 14px;
  padding: 20px 0;
  margin: 0 20px;
  .autograph-wrapper {
    position: relative;
    width: 234px;
    height: 260px;
    margin: 40px auto;
    border: 1px solid #dddd;
    border-radius: 5px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
    img {
      width: 100%;
      height: 100%;
      // width: 700px;
      margin: 0 auto;
      display: block;
    }
    .el-button {
      position: absolute;
      bottom: -50px;
      left: 50%;
      transform: translateX(-50%);
    }
  }
  .qrcode-wrapper {
    position: relative;
    width: 234px;
    height: 280px;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
    padding: 40px;
    margin-top: 80px;
    box-sizing: border-box;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    #qrcode {
      margin: 0 auto 10px;
      width: 160px;
    }
    .qrcode-wrapper-codeText {
      text-align: center;
      color: #2d61ad;
    }
  }
}
</style>


移动端页面

<template>
  <div id="signature-pad" class="signature-pad" :style="{'max-height':maxHeight}">
    <div>
      <div class="signature-pad--body">
        <canvas id="signature-canvas" :width="width" :height="height" />
        <i class="leftup lefta" />
        <i class="leftup rightup" />
        <i class="leftup leftdown" />
        <i class="leftup rightdown" />
      </div>
      <div class="signature-pad--footer">
        <p @click="saveButton">
          <span>确定</span>
        </p>
        <p @click="cancelButton">
          <span>重签</span>
        </p>
      </div>
    </div>
  </div>
</template>
<script>
import $ from 'jquery'
import SignaturePad from 'signature_pad'
import { autograph } from '@/api/audit'
import Vue from 'vue'
import 'vant/lib/index.css'
import { Dialog } from 'vant'

// 全局注册
Vue.use(Dialog)
export default {
  name: 'Signature',
  data() {
    return {
      signaturePad: '',
      canvas: '',
      width: '',
      height: '',
      maxHeight: '',
      buttonState: false
    }
  },
  watch: {},
  mounted() {
    this.canvas = document.querySelector('canvas')
    const signaturePad = new SignaturePad(this.canvas)
    this.signaturePad = signaturePad
    /* */
    this.height = $(window).height()
    this.width = $(window).width()
    this.maxHeight = this.height
    signaturePad.penColor = 'rgb(0, 0, 0)'
    signaturePad.backgroundColor = 'rgb(255, 255, 255)'
    this.resizeCanvas()
    window.onresize = () => {
      this.resizeCanvas()
    }
  },
  methods: {
    // 保存个人签名
    async postAutograph(val) {
      this.tableLoading = true
      const params = {
        file: val
      }
      /* eslint-disable no-undef */
      var res = await autograph(params)
      if (res.code == 0) {
        Dialog.alert({
          title: '提示',
          message: '个人签名提交成功,点击确定关闭页面。'
        }).then(() => {
          this.buttonState = true
          WeixinJSBridge.call('closeWindow')
          window.AlipayJSBridge.call('closeWebview')
        })
      }
    },
    saveButton() {
      if (this.buttonState == true) {
        // 重复提交签名
        Dialog.alert({
          title: '提示',
          message: '个人签名不能重复提交。'
        })
      } else {
        // 未提交签名
        // 签名为空的判断
        if (this.signaturePad.isEmpty()) {
          Dialog.alert({
            title: '提示',
            message: '个人签名不能为空'
          })
        } else {
          const ctx = this.canvas.getContext('2d')
          const imageData = ctx.getImageData(
            0,
            0,
            this.canvas.width,
            this.canvas.height
          )
          for (var i = 0; i < imageData.data.length; i += 4) {
            // 当该像素是透明的,则设置成白色
            if (imageData.data[i + 3] == 0) {
              imageData.data[i] = 255
              imageData.data[i + 1] = 255
              imageData.data[i + 2] = 255
              imageData.data[i + 3] = 255
            }
          }
          ctx.putImageData(imageData, 0, 0)
          // 使用canvas的toDataURL方法返回一个包含图片展示的 data URI
          const data = this.signaturePad.toDataURL('image/jpeg')
          this.postAutograph(data)
        }
      }
    },
    cancelButton() {
      this.signaturePad.clear()
    },
    resizeCanvas() {
      const ratio = Math.max(window.devicePixelRatio || 1, 1)
      this.canvas.width = this.canvas.offsetWidth * ratio
      this.canvas.height = this.canvas.offsetWidth * ratio
      this.canvas.getContext('2d').scale(ratio, ratio)
      this.signaturePad.clear() // otherwise isEmpty() might return incorrect value
    }
  }
}
</script>

<style scoped lang="scss">
.signature-pad,
.signature-pad--body {
  height: 90%;
}

.signature-pad {
  position: relative;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  width: 100%;
  height: 100%;
  background: #fff;
  font-size: 10px;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -ms-flex-direction: column;
  flex-direction: column;
}
.signature-pad--body {
  position: absolute;
  right: 0;
  width: 85%;
  height: 100%;
}
.signature-pad--body canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  // border-radius: 4px;
  // box-shadow: 0 0 5px rgba(0, 0, 0, 0.02) inset;
}
.signature-pad--footer {
  width: 15%;
  position: absolute;
  left: 0;
  height: 100%;
  p {
    left: 10px;
    padding: 26px 2px;
    position: absolute;
    bottom: 220px;
    color: #fff;
    background-color: #2d61ad;
    border-color: #2d61ad;
    border-radius: 7px;
    span {
      font-size: 15px;
      transform: rotate(90deg);
      display: block;
      color: #fff;
    }
    &:last-child {
      bottom: 100px;
      background-color: #fff;
      border: 1px solid #ccc;
      span {
        color: #828282;
      }
    }
  }
}
</style>

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值