vue+pdfh5.js+微信小程序的结合使用

公司有一个想要实现的功能就是在小程序中要实时预览pdf文件,小程序只支持wx.downloadFile和wx.openDocument,所以不符合我的期望。然后就使用了pdfh5.js(版本号1.3.20),用webview嵌套网页做的。

<template>
  <div class="pdf-container">
    <div class="pdf-big-box">
      <div ref="menuTab" id="menuTab"></div>
      <div ref="pdfBox" id="pdfBox"></div>
    </div>


    <div class="btn-box">
      <van-button class="refuse-btn" round type="primary" @click="conBackFun">返回</van-button>
      <van-button class="immedite-btn" round type="primary" @click="immeditSigned">提交签署</van-button>
    </div>


    <!--签署方式-->
    <van-popup
        v-model="show"
        closeable
        round
        position="bottom"
        :style="{height:'5.1rem'}"
    >
      <div>
        <div class="signed-hand-types">签署意愿验证</div>
        <div class="ipt-box" style="padding-bottom:.48rem;">
          <div class="phone-box">
            <span>当前手机号:</span>
            <span>{{ startSuPhone }}</span>
          </div>

          <div class="code-input">
            <div>
              <input class="sms-input" type="number" placeholder="请输入验证码" v-model="smsCode"/>
            </div>
            <div class="verify-code">
              <button class="verify-btn" @click='getCode' :disabled='btnDisabled'>{{ btnValue }}</button>
            </div>
          </div>
        </div>

        <div class="sms-code-btn">
          <button @click="smsConfirm">确定</button>
        </div>
      </div>
    </van-popup>
  </div>
</template>
<script>
import 'pdfh5/css/pdfh5.css';
import Pdfh5 from 'pdfh5';
import {Button, Popup} from 'vant';
import wx from 'weixin-js-sdk';
export default {
  name: 'signedPdf',
  data() {
    return {
      pdfh5: null,
      contractId: '',
      token: null,
      signType: '',
      signImgKey: '',
      phone: '',
      startSuPhone:'',
      show: false,
      handSignedList: [
        {
          id: 0,
          name: '手写签名',
          img: require('../../assets/img/handwrittenImg.png'),
          checked: true,
        },
        {
          id: 1,
          name: '默认签章',
          img: require('../../assets/img/defaultSignature.png'),
          checked: false,
        },
      ],
      btnValue: '获取验证码',
      btnDisabled: false,
      second: 60,
      smsCode: '',//验证码
    }
  },
  components: {Button, Popup},
  methods: {
    getPdfList() {
      this.$http.post('/contract/contractService/signaturePreviewForApp', {
        contractId: this.contractId,
        signType: this.signType,
        signImgKey: this.signImgKey
      }, {headers: {token: this.token}}).then(res => {
        let data = res.data;
        if (data.success) {
          this.drawData(data.data);
        }
      })
    },
    drawData(arr) {
      let that = this;
      arr.forEach((item, index) => {
        var pdfId = 'pdf-'
        var pdfTabs = document.createElement('a');//按钮菜单
        var pdfTabsDiv = document.createElement('div');
        var pdfTabsBorder = document.createElement('div');
        var pdfCanvas = document.createElement('div');//存放pdf的div
        pdfTabsDiv.className = 'pdf-a-divs';
        pdfTabsBorder.className = 'border-div'
        pdfTabsDiv.appendChild(pdfTabs);
        pdfTabsDiv.appendChild(pdfTabsBorder);
        pdfCanvas.id = pdfId + item.id;//添加id
        // pdfTabs.href = '#' + pdfId + item.id;//给a链接添加href功能
        // pdfTabs.setAttribute('new-id', pdfId + item.id)
        pdfTabs.className = 'pdf-tabs';
        pdfTabsDiv.setAttribute('new-id', pdfId + item.id)
        pdfTabs.innerText = item.filesName;
        this.$refs.pdfBox.appendChild(pdfCanvas);
        this.$refs.menuTab.appendChild(pdfTabsDiv);


        this.pdfh5 = new Pdfh5("#" + pdfId + item.id, {
          pdfurl: item.filesUrl,
          // lazy:true,
          backTop: false,
          maxZoom:1,
        })

        this.pdfh5.on("zoom", function (scale) {
          // console.log(scale)
        })

        //pdf准备开始渲染,此时可以拿到pdf总页数
        this.pdfh5.on("ready", function () {
          // console.log("pdf准备开始渲染,总页数:" + this.totalNum)
        })
        //监听pdf渲染成功
        this.pdfh5.on("success", function (time) {
          // time = time / 1000
          // console.log("pdf渲染完成,总耗时" + time + "秒");
          //滚动到第3页
          // pdfh5.goto(2);
        })
        //监听pdf渲染失败
        this.pdfh5.on("error", function (time) {
          // console.log("渲染失败,总耗时" + time + "毫秒")
        })
        //监听完成事件,加载失败、渲染成功都会触发
        this.pdfh5.on("complete", function (status, msg, time) {
          // console.log("状态:" + status + ",总耗时:" + time + "毫秒,总页数:" + this.totalNum, msg)
        })

        //监听渲染中事件
        this.pdfh5.on("render", function (currentNum, time, currentPageDom) {
          // currentPageDom.append("")
          // console.log("当前页码:" + currentNum)
        })

      })


      // $("#menuTab .pdf-tabs").eq(0).addClass('tabMenu-active');
      $("#menuTab .pdf-a-divs").eq(0).children('.border-div').addClass('border-div-active');

      $("#menuTab .pdf-a-divs").eq(0).children('.pdf-tabs').addClass('tabMenu-active')
      $(".pdf-a-divs").click(function () {
        var hrefIId = $(this).attr('new-id');
        $("html,body").animate({scrollTop:$("#" + hrefIId).offset().top + 10}, 100);
      });
    },
    //获取微信小程序传递过来的数据,进行解析
    getUrlParam(name) {
      if (!name) return null;
      var after = window.location.search;
      after = after.substr(1) || window.location.hash.split('?')[1];
      if (!after) return null;
      if (after.indexOf(name) === -1) return null;
      var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)');
      var r = decodeURIComponent(after).match(reg);
      if (!r) return null;
      return r[2];
    },
    //  打开面板
    immeditSigned() {
      this.show = true;
    },
    //返回
    conBackFun() {
      //因为是在H5里面所有要这么跳转
      this.$router.replace({
        name: 'pdf',
        query: {
          isIdent: 'formSignedPdf',
          id: this.contractId,
          token: this.token,
          phone: this.phone,
          btnShow: 1,
        }
      })

    },
    //选择签名方式
    targetHand(child, index) {
      let that = this;
      let checked = child.id
      this.handSignedList.forEach(item => {
        if (item.id == checked) {
          item.checked = true
        } else {
          item.checked = false;
        }
      })
    },
    //确认签章
    confirmSigned() {
      let id = ''
      this.handSignedList.forEach(item => {
        if (item.checked) {
          id = item.id
        }
      })
      if (id == 0) {
        wx.miniProgram.redirectTo({
          url: `/pages/signPanel/signPanel?id=${this.contractId}&signType=1` //signType 1-手绘签名 2-默认签名
        })
        // wx.miniProgram.postMessage({
        //   data:{
        //     id: this.contractId,
        //     signType: 1
        //   }
        // })
        this.show = false;
      } else {
        wx.miniProgram.redirectTo({
          url: `/pages/contractShallSigned/contractShallSigned?id=${this.contractId}&signType=2` //signType 1-手绘签名 2-默认签名
        })
        // wx.miniProgram.postMessage({
        //   data:{
        //     id: this.contractId,
        //     signType: 2
        //   }
        // })
        this.show = false;
      }
    },
    //验证码
    getCode() {
      var that = this;
      //  发送验证码
      this.$http.post('/login/loginService/sendVerifyCode', {
        phone: this.phone,
        type: 11
      }, {headers: {token: this.token}}).then(res => {
        let data = res.data;
        if (data.success) {
          this.$toast(data.msg);
          that.timer();
        } else {
          this.$toast(data.msg);
        }
      })
    },
    //倒计时
    timer() {
      let promise = new Promise((resolve, reject) => {
        let setTimer = setInterval(
            () => {
              var second = this.second - 1;
              this.second = second;
              this.btnValue = second + '秒'
              this.btnDisabled = true
              if (this.second <= 0) {
                this.second = 60;
                this.btnValue = '获取验证码';
                this.btnDisabled = false;
                resolve(setTimer)
              }
            }
            , 1000)
      })
      promise.then((setTimer) => {
        clearInterval(setTimer)
      })
    },
    //确认
    smsConfirm() {
      let that = this;
      let params = {
        contractId: this.contractId,
        code: this.smsCode
      }
      if (this.signType == 1) {//手签章
        params.signType = 1;
        params.signImgKey = this.signImgKey
      } else {
        params.signType = 2;
      }
      if (this.smsCode) {
        this.$http.post('xxxx你的url地址', params, {headers: {token: this.token}}).then(res => {
          let data = res.data;
          if (data.success) {
            wx.miniProgram.redirectTo({
              url: `/pages/signedStatus/signedStatus?status=1&id=${that.contractId}`
            })
          } else {
            this.$toast(data.msg);
          }
        })
      }
    },
  },
  mounted() {
  //这些是我结合微信小程序传递的数据,可根据自己的数据进行替换
    if (this.$route.query.signType == 2) {//2是默认签署
      this.contractId = this.$route.query.id
      this.signType = this.$route.query.signType
      this.token = this.$route.query.token;
      this.phone = this.$route.query.phone;
      let startPhone = '' + this.$route.query.phone;
      this.startSuPhone = startPhone.substr(0,3) + '****' + startPhone.substr(7);
      this.getPdfList();
    } else {
      this.contractId = this.getUrlParam('id');
      this.token = this.getUrlParam('token');
      this.phone = this.getUrlParam('phone');
      let startPhone = '' + this.getUrlParam('phone');
      this.startSuPhone = startPhone.substr(0,3) + '****' + startPhone.substr(7);
      this.signImgKey = this.getUrlParam('signImgKey');
      this.signType = this.getUrlParam('signType');
      this.getPdfList();
    }
   //监听页面滚动,实时改变tab栏的切换
    window.addEventListener('scroll',()=>{
      let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
      var listss = document.getElementById('pdfBox');
      var navList = $("#menuTab>div");
      let BoxList = $("#pdfBox .pdfjs");
      Array.from(BoxList).forEach((item,index) =>{
        if(scrollTop > item.offsetTop && scrollTop < (item.clientHeight + item.offsetTop)){
          navList[index].childNodes[0].className = 'pdf-tabs tabMenu-active'
          navList[index].childNodes[1].className = 'border-div border-div-active'
        }else{
          navList[index].childNodes[0].className = 'pdf-tabs'
          navList[index].childNodes[1].className = 'border-div'
        }

        if(scrollTop >= 0 && scrollTop <= BoxList[0].clientHeight){
          navList[0].childNodes[0].className = 'pdf-tabs tabMenu-active'
          navList[0].childNodes[1].className = 'border-div border-div-active'
        }
      })

    })
  }
}
</script>
<style lang="scss" scoped>
.pdf-container {
  .pdf-big-box {
    padding-bottom: 1.56rem;
    background-color: #f5f5f5;
  }

  font-size: .32rem;
  height: 100%;

  ::v-deep .pdf-tabs {
    text-decoration: none;
    padding:0rem .24rem;
    color: #81878E;
    font-size: .28rem;
    margin-bottom: .1rem;
  }

  ::v-deep .tabMenu-active {
    color: #007BFF;
    //border-bottom: 1px solid #007BFF;
    font-size: .32rem;
    font-weight: 700;
  }

  ::v-deep .pinch-zoom-container {
    height: auto !important;
  }

  .btn-box {
    position: fixed;
    width: 100%;
    box-sizing: border-box;
    padding: .32rem;
    background: rgba(255,255,255,1);
    box-shadow: 0px -4px 12px 0px rgba(0,0,0,0.09);
    display: flex;
    justify-content: space-between;
    bottom: 0px;

    .refuse-btn {
      border-color: #007BFF;
      background-color: #fff;
      color: #007BFF;
      padding: .26rem 1.34rem;
      font-size: .32rem;
    }

    .immedite-btn {
      color: #fff;
      background-color: #007BFF;
      padding: .26rem 1.02rem;
      font-size: .32rem;
      border-color: transparent;
    }
  }
}
::v-deep .pdfjs .loadingBar .progress .glimmer{
  background: #007BFF!important;
}

#menuTab {
  padding: .24rem;
  font-size: .32rem;
  position: fixed;
  width: 100%;
  box-sizing: border-box;
  background-color: #fff;
  z-index: 9;
  overflow-x: scroll;
  white-space: nowrap;
  display: flex;
}

::v-deep .pdf-a-divs{
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
::v-deep .border-div{
  width: .5rem;
  height: .06rem;
}
::v-deep .border-div-active{
  background-color: #007BFF;
}

.pdfjs {
  overflow: auto;
}

#pdfBox {
  padding-top: 1.12rem;
  overflow: scroll;
  height: 100%;
}

.signed-hand-types {
  font-size: .36rem;
  color: #212121;
  text-align: center;
  padding-top: .32rem;
}

/*短信验证*/
.code-input {
  display: flex;
  padding-bottom: .24rem;
  border-bottom: 1px solid #ccc;
  justify-content: space-between;
  align-items: center;
  margin-top: .64rem;
  font-size: .32rem;

  .sms-input {
    border: none;
  }

  .verify-btn {
    color: #007BFF;
    background: transparent;
    border: transparent;
    font-size: .24rem;
  }
}

.sms-code-btn {
  padding: 0rem .8rem;
}

.sms-code-btn button {
  background-color: #007BFF;
  border-radius: .46rem;
  color: #fff;
  padding: .26rem;
  width: 100%;
  border: transparent;
}

.ipt-box {
  padding: .8rem;
}

.phone-box {
  color: #56595B;
  font-size: .32rem;
}

.signed-content {
  padding: .48rem .32rem;
}

.signed-child {
  box-sizing: border-box;
  padding: .32rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border: 1px solid #AAB3BD;
  border-radius: .24rem;
  margin-bottom: .32rem;
}

.signed-han-img-box {
  display: flex;
}

.han-img {
  width: 1.66rem;
  height: 1.10rem;
}

.han-img img {
  width: 100%;
  height: 100%;
}

.signature-text {
  margin-left: .32rem;
  color: #212121;
  font-size: .32rem;
}

.check-img {
  width: .44rem;
  height: .44rem;
  border-radius: 100%;
}

.check-img-default {
  border: 2px solid #ccc;
}

.check-img img {
  width: 100%;
  height: 100%;
}

.default-active {
  color: #81878E;
}

.refuse-confirm-btn-box {
  padding: 0rem .32rem;
}

.confirm-btn-box {
  padding: 0rem .32rem;
}

.refuse-confirm-btn-box button {
  background-color: #007BFF;
  border-radius: .46rem;
  color: #fff;
  margin-top: .48rem;
}

.confirm-btn-box button {
  background-color: #007BFF;
  border-radius: 0.46rem;
  color: #fff;
  padding: .26rem 0rem;
  width: 100%;
  border-color: transparent;
}

</style>

vue+pdfh5.js+微信小程序的结合使用_第1张图片

你可能感兴趣的:(微信小程序,小程序,javascript,微信,vue.js)