ZaiZai 1 年之前
父節點
當前提交
d3f7384884
共有 2 個文件被更改,包括 116 次插入21 次删除
  1. 95 17
      src/plugins/HcPdfSign.js
  2. 21 4
      src/test/index.vue

+ 95 - 17
src/plugins/HcPdfSign.js

@@ -12,6 +12,8 @@ export default class HcPdfSign {
     static curSignDom = null
     static signList = []
     static signChange = null
+    static pdfLoadFunc = null
+    static batchSign = false
 
     /**
      * 初始化创建PDF预览
@@ -20,7 +22,7 @@ export default class HcPdfSign {
      * @param img   签章图片url
      * @param func  回调函数
      */
-    static createPdf(ele, url, img, func) {
+    static createPdf({ ele, url, img, change, load }) {
         //初始化为空
         this.disX = 0
         this.disY = 0
@@ -84,8 +86,12 @@ export default class HcPdfSign {
         }
         this.signImage(img)
         //设置回调事件
-        if (!isNullES(func)) {
-            this.addEventFunc(func)
+        if (!isNullES(change)) {
+            this.addEventFunc(change)
+        }
+        //设置回调事件
+        if (!isNullES(load)) {
+            this.addPdfLoadFunc(load)
         }
     }
 
@@ -108,13 +114,32 @@ export default class HcPdfSign {
         }
     }
 
+    //设置加载完成的回调事件
+    static addPdfLoadFunc(func) {
+        if (typeof func !== 'function') {
+            console.warn('请传入函数')
+            return false
+        } else {
+            this.pdfLoadFunc = func
+        }
+    }
+
+    //加载完成
+    static setPdfLoadFunc(val) {
+        if (typeof this.pdfLoadFunc !== 'function') {
+            return false
+        } else {
+            this.pdfLoadFunc(val)
+        }
+    }
+
     //设置签章图片
     static signImage(url) {
         this.signImgCss = { url: url, width: 100, height: 26 }
     }
 
     //创建签章图片
-    static createSignImage(event) {
+    static async createSignImage(event) {
         //创建图片元素
         const { url, width, height } = this.signImgCss
         const uuid = 'pdf-sign-img-' + getRandom(6)
@@ -131,12 +156,43 @@ export default class HcPdfSign {
         return signImg
     }
 
+    /**
+     * 是否批量签章
+     * @param val   true/false
+     */
+    static setBatchSign(val = false) {
+        this.batchSign = val
+    }
+
+    //让PDF页面全部渲染一下
+    static async setPageScrolling() {
+        const pageDom = this.pdfViewer?.children ?? []
+        await this.toPdfPage('firstPage')
+        for (let i = 0; i < pageDom.length; i++) {
+            await this.toPdfPage('next')
+        }
+        await this.toPdfPage('firstPage')
+    }
+
+    /**
+     * 跳转pdf的页面
+     * @param pageId 最后一页:lastPage,第一页:firstPage,上一页:previous,下一页:next
+     */
+    static async toPdfPage(pageId) {
+        return new Promise((resolve) => {
+            this.iframeDom?.contentDocument?.getElementById(pageId)?.click()
+            setTimeout(() => {
+                resolve(true)
+            }, 100)
+        })
+    }
+
     //PDF加载完成
     static iframeLoad() {
-        const viewer = this.iframeDom.contentDocument.getElementById('viewer')
+        const viewer = this.iframeDom?.contentDocument?.getElementById('viewer')
         //页面被点击
         viewer.addEventListener('click', (event) => {
-            this.viewerClick(event)
+            this.viewerClick(event).then()
         })
         //鼠标移动
         viewer.addEventListener('mousemove', (event) => {
@@ -155,10 +211,15 @@ export default class HcPdfSign {
             this.curSignDom.style.cursor = 'default'
         })
         this.pdfViewer = viewer
+        //处理pdf渲染
+        setTimeout(async () => {
+            await this.setPageScrolling()
+            this.setPdfLoadFunc(true)
+        }, 500)
     }
 
     //页面被点击
-    static viewerClick(event) {
+    static async viewerClick(event) {
         const target = event.target
         //当前为移动模式
         if (this.signType === '移动') {
@@ -168,14 +229,30 @@ export default class HcPdfSign {
         if (target.className !== 'textLayer') {
             return
         }
-        //获取PDF的点击页面
-        const parentNode = target.parentNode
-        if (parentNode.children.length < 3) {
-            parentNode.prepend('<div class="signLayer" style="position: absolute;height: 100%;width: 100%;z-index: 999;pointer-events: none;overflow: hidden"></div>')
+        //批量签章
+        if (this.batchSign) {
+            const parent = target?.parentNode?.parentNode?.children ?? []
+            for (let i = 0; i < parent.length; i++) {
+                const textLayer = parent[i]?.children[1]
+                if (textLayer) {
+                    await this.setPdfNodeSign(parent[i], textLayer, event)
+                }
+            }
+            this.signChangeFunc()
+        } else {
+            await this.setPdfNodeSign(target?.parentNode, target, event)
+            this.signChangeFunc()
+        }
+    }
+
+    //设置PDF节点签章
+    static async setPdfNodeSign(node, textLayer, event) {
+        if (node.children.length < 3) {
+            node.prepend('<div class="signLayer" style="position: absolute;height: 100%;width: 100%;z-index: 999;pointer-events: none;overflow: hidden"></div>')
         }
         //插入图片
-        const signImgDom = this.createSignImage(event)
-        parentNode.children[0].append(signImgDom)
+        const signImgDom = await this.createSignImage(event)
+        node.children[0].append(signImgDom)
         //鼠标按下
         signImgDom.addEventListener('mousedown', (e) => {
             this.curSignDom = e.target
@@ -187,12 +264,13 @@ export default class HcPdfSign {
         })
         //保存签章信息
         this.signList.push({
-            x: ((event.layerX * 100) / target.clientWidth).toFixed(4),
-            y: ((event.layerY * 100) / target.clientHeight).toFixed(4),
-            page: parentNode.getAttribute('data-page-number'),
+            x: ((event.layerX * 100) / textLayer.clientWidth).toFixed(4),
+            y: ((event.layerY * 100) / textLayer.clientHeight).toFixed(4),
+            page: node.getAttribute('data-page-number'),
             id: signImgDom.getAttribute('id'),
             dom: signImgDom,
         })
-        this.signChangeFunc()
+        return signImgDom
     }
+
 }

+ 21 - 4
src/test/index.vue

@@ -1,22 +1,39 @@
 <template>
     <div class="hc-page-box">
         <HcCard title="测试">
-            <div id="pdfView" class="h-full" />
+            <div v-loading="loading" element-loading-text="加载文件并初始渲染中..." class="h-full">
+                <div id="pdfView" class="h-full" />
+            </div>
         </HcCard>
     </div>
 </template>
 
 <script setup>
-import { onMounted } from 'vue'
+import { onMounted, ref } from 'vue'
 import logoName from '~src/assets/logo/name.png'
 import HcPdfSign from '~src/plugins/HcPdfSign'
 
+const loading = ref(true)
+
 onMounted(()=> {
     const pdf = 'https://bladex-chongqing-info.oss-cn-hangzhou.aliyuncs.com//upload/20230908/2878b0b7a59c1ce9b5779381a1fb82ef.pdf'
 
     //创建PDF签章控件以及相关功能
-    HcPdfSign.createPdf('pdfView', pdf, logoName, (data) => {
-        console.log(data)
+    HcPdfSign.createPdf({
+        ele: 'pdfView', //挂载元素的id
+        url: pdf, //pdf的url地址
+        img: logoName, //签章图片的url地址
+        //加载完成
+        load: () => {
+            loading.value = false
+        },
+        //签章数据改变
+        change: (data) => {
+            console.log(data)
+        },
     })
+
+    //批量签章
+    HcPdfSign.setBatchSign(true)
 })
 </script>