采用 pdfh5 组件完成隐私协议、合同文档的 PDF 在线预览功能,提供页面滚动到底部、计时读秒双重校验规则,以此确认用户已完整查阅文件内容。
具体实现:
导入pdfh5库
npm install pdfh5
修改pdf 多页阅读时,当前页码错误问题:
pdfh5.js 文件修改如下:
javascript
//FIXME svg scroll 无效, uniapp使用 onPageScroll onReachBottom
viewerContainer.addEventListener('scroll', function () {
var scrollTop = viewerContainer.scrollTop;
console.log(`scroll event ${scrollTop}`);
if (scrollTop >= 150) {
if (self.options.backTop) {
self.backTop.show();
}
} else {
if (self.options.backTop) {
self.backTop.fadeOut(200);
}
}
if (self.viewerContainer) {
self.pages = self.viewerContainer.find('.pageContainer');
}
clearTimeout(self.timer);
if (self.options.pageNum && self.pageNum) {
self.pageNum.show();
}
var h = containerH;
if (self.pages) {
self.pages.each(function (index, obj) {
var top = obj.getBoundingClientRect().top;
var bottom = obj.getBoundingClientRect().bottom;
if (top <= height && bottom > height) {
if (self.options.pageNum) {
self.pageNow.text(index + 1);
}
self.currentNum = index + 1;
}
if (top <= h && bottom > h) {
self.cacheNum = index + 1;
}
});
}
if (scrollTop + self.container.height() >= self.viewer[0].offsetHeight) {
self.pageNow.text(self.totalNum);
//阅读到最后一页 把当前页进行赋值
self.currentNum =self.totalNum
}
if (scrollTop === 0) {
self.pageNow.text(1);
}
self.timer = setTimeout(function () {
if (self.options.pageNum && self.pageNum) {
self.pageNum.fadeOut(200);
}
}, 1500);
// console.log(`pdfh5:1309 pageNow=${self.pageNow.text()} pageNum=${self.pageNum.text()} currentNum = ${self.currentNum}`);
var arr1 = self.eventType["scroll"];
if (arr1 && arr1 instanceof Array) {
for (var i = 0; i < arr1.length; i++) {
arr1[i] && arr1[i].call(self, scrollTop, self.currentNum);
}
}
});
具体组件使用:
javascript
<template>
<view class="pdf-page">
<view class="pdf-wrap" :style="{'height':viewHeight}">
<!-- :style="{'height': pdfviewHeight}" -->
<view ref="pdfRef" id="pdfView" :style="{'height':viewHeight}"></view>
</view>
<view v-if="showBottom" class="pdf-btn-group">
<slot>
<button class="btn-readed" size="mini" @click="handleComplete" :style="btnStyle"
:disabled="btnDisabled">{{showTimer ? countTimer<=1 ? '':'('+countTimer+'s)':''}}我已阅读</button>
</slot>
</view>
</view>
</template>
<script>
import Pdfh5 from "pdfh5";
import "pdfh5/css/pdfh5.css";
export default {
name: "u-pdf",
props: {
url: {
type: String,
require: true
},
viewHeight: { // 高度设置后可能会影响到滚动条的监听,需要使用pdf总页数和当前页码对比
type: String,
default: "100%"
},
showBottom: {
type: Boolean,
default: true
},
options: {
type: Object,
default: () => ({
cMapUrl: "https://unpkg.com/pdfjs-dist@3.8.162/cmaps/",
lazy: false,
withCredentials: true,
// pdfLoaded:false,
renderType: "svg",
maxZoom: 3, //手势缩放最大倍数 默认3
scrollEnable: true, //是否允许pdf滚动
zoomEnable: true //是否允许pdf手势缩放
})
},
disabled:{
type:Boolean,
default:true
},
showTimer:Boolean,
readTimer:{
type:Number,
default:20
},
btnStyle:{
type:Object,
default:()=>{}
}
},
data() {
return {
totalPages: 0,
pdfh5: undefined,
countTimer:20,
timer:undefined,
btnDisabled:true,
}
},
computed:{
},
watch:{
disabled(n,o){
this.btnDisabled = this.disabled
},
showTimer(n,o){
console.log("showTimer ",n);
this.countTimer = this.readTimer
if(this.showTimer){
this.startCountDownTimer()
}
}
},
mounted() {
this.$nextTick(() => {
this.loadPdf()
})
// 判断是否启动阅读计时
this.countTimer = this.readTimer
if(this.showTimer){
this.startCountDownTimer()
}
},
// onPageScroll(scroll) {
// console.log(`onPageScroll ${scroll}`,scroll);
// },
// onReachBottom(scroll) {
// console.log(`onReachBottom 滚动到底部`);
// },
methods: {
handleComplete(){
this.$emit("onClickReader")
},
startCountDownTimer(){
this.timer= setInterval(()=>{
// console.log(`countTimer = ${this.countTimer}`);
if(this.countTimer<=1){
this.btnDisabled=false
clearInterval(this.timer)
}else{
--this.countTimer
}
},1000)
},
.........
}
}
}
</script>
<style scoped>
@import 'pdfh5/css/pdfh5.css';
.pdf-page {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.pdf-wrap {
width: 100%;
flex: 1;
}
.pdf-btn-group {
width: 100%;
border-top: 2rpx solid #F8F9FC;
height: 8%;
position: fixed;
bottom: -1rpx;
z-index: 999;
background: white;
display: flex;
align-items: center;
justify-content: center;
}
.btn-readed {
background: #4E70F6;
color: #ffffff;
font-size: 32rpx;
}
</style>
使用方式
主要运用在uniapp项目中
1、导入node-modules 目录中 canvas 和 pdfh5 库
2、引用组件 <u-pdf :url="pdfUrl" :show-timer="true" :disabled="disabled"></u-pdf>