浏览代码

fix: 测试pdf预览页面

Signed-off-by: tangshizhe <48740614+tangshizhe@users.noreply.github.com>
tangshizhe 3 月之前
父节点
当前提交
59b25272d7
共有 3 个文件被更改,包括 167 次插入8 次删除
  1. 2 0
      apps/mobile/index.html
  2. 141 2
      apps/mobile/src/views/common/pdfViewExample.vue
  3. 24 6
      apps/mobile/vite.config.js

+ 2 - 0
apps/mobile/index.html

@@ -132,6 +132,8 @@
       defer
       src="/common-module/chart-module/js/chart-common.js?v=<%= assets.version %>"
     ></script>
+    <script src="https://cdn-common.jianyu360.com/cdn/lib/pdfjs-dist/2.1.266/build/pdf.min.js"></script>
+    <script src="https://cdn-common.jianyu360.com/cdn/lib/pdfjs-dist/2.1.266/web/pdf_viewer.js"></script>
     <% } %>
   </body>
 </html>

+ 141 - 2
apps/mobile/src/views/common/pdfViewExample.vue

@@ -1,3 +1,142 @@
 <template>
-  <div>111</div>
-</template>
+  <div class="pdf-view-example j-contanter">
+    <div id="pdf-view-container" class="j-main" />
+    <div v-if="!getUserId" class="j-footer">
+      <a href="/jyapp/free/login?url=/jy_mobile/order/create/creditreport&activity=bidCreditReportPreview" class="adsense-container">
+        <AdSingle
+          ad="app-credit-report-sample"
+          :show-tag="false"
+          :show-close-icon="false"
+          class="adsense-container"
+        />
+      </a>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+import AdSingle from '@/components/ad/Ad'
+import { getAssetsFile } from '@/utils'
+
+export default {
+  name: 'PdfViewExample',
+  components: {
+    AdSingle
+  },
+  data() {
+    return {
+      pdfUrl: '',
+      pdf: null,
+      totalPages: 0,
+      currentPage: 1, // 新增
+      batchSize: 5, // 新增
+      config: {
+        PAGE_TO_VIEW: 0,
+        SCALE: 1.0,
+        CMAP_URL:
+          'https://cdn-common.jianyu360.com/cdn/lib/pdfjs-dist/2.1.266/cmaps/',
+        CMAP_PACKED: true,
+        workerSrc:
+          'https://cdn-common.jianyu360.com/cdn/lib/pdfjs-dist/2.1.266/build/pdf.worker.min.js'
+      }
+    }
+  },
+  computed: {
+    ...mapGetters('user', ['getUserId'])
+  },
+  created() {
+    this.$toast.loading('加载中...')
+
+    const { pdfUrl } = this.$route.query
+    if (pdfUrl) {
+      this.pdfUrl = decodeURIComponent(pdfUrl)
+    }
+    else {
+      const pdfAssets = getAssetsFile('example-min.pdf')
+      // this.pdfUrl = 'https://cdn-common.jianyu360.cn/cdn/assets/file/example.pdf'
+      this.pdfUrl = pdfAssets
+    }
+  },
+  mounted() {
+    const container = document.getElementById('pdf-view-container')
+
+    this.loadPdf(this.pdfUrl, container)
+    // 监听窗口的 resize 事件,实现自适应效果
+    window.addEventListener('resize', () => {
+      container.innerHTML = ''
+      this.loadPdf(this.pdfUrl, container)
+    })
+  },
+  methods: {
+    async loadPdf(pdfUrl, container) {
+      console.log('pdfUrl', pdfUrl)
+      try {
+        pdfjsLib.GlobalWorkerOptions.workerSrc = this.config.workerSrc
+        const loadingTask = pdfjsLib.getDocument({
+          url: pdfUrl,
+          cMapUrl: this.config.CMAP_URL,
+          cMapPacked: this.config.CMAP_PACKED,
+          disableRange: true,
+          disableAutoFetch: false, // 启动自动分块加载
+          // 添加缓存头
+          httpHeaders: {
+            'Cache-Control': 'max-age=3600' // 缓存 1 小时
+          },
+          // 增加网络请求超时时间,避免因网络问题导致加载失败
+          timeout: 30000,
+          // 减少初始加载的字节数,提高初始加载速度
+          initialDataSize: 1024 * 1024
+        })
+        this.pdf = await loadingTask.promise
+        this.totalPages = this.pdf.numPages
+        this.currentPage = 1
+        this.batchSize = 5 // 新增
+
+        await this.loadBatchPages(container) // 新增
+        this.$toast.clear()
+        // 监听滚动事件
+        container.addEventListener('scroll', () => this.handleScroll(container))
+      }
+      catch (error) {
+        console.error('Error loading PDF:', error)
+      }
+    },
+    async loadBatchPages(container) {
+      // 加载当前页码开始的连续多页,这里以5页为例
+      // 分批加载,从当前页码开始,最多加载5页
+      const endPage = Math.min(this.currentPage + this.batchSize - 1, this.totalPages)
+      for (let pageNum = this.currentPage; pageNum <= endPage; pageNum++) {
+        const page = await this.pdf.getPage(pageNum)
+        const viewport = page.getViewport({ scale: this.calculateScale(page) })
+        const canvas = document.createElement('canvas')
+        const ctx = canvas.getContext('2d')
+        canvas.height = viewport.height
+        canvas.width = viewport.width
+        container.appendChild(canvas)
+
+        await page.render({
+          canvasContext: ctx,
+          viewport,
+        }).promise
+      }
+      this.currentPage = endPage + 1 // 更新当前页码
+    },
+    handleScroll(container) {
+      const { scrollTop, scrollHeight, clientHeight } = container
+      if (scrollTop + clientHeight >= scrollHeight - 100) { // 当滚动到底部附近时
+        if (this.currentPage <= this.totalPages) {
+          this.loadBatchPages(container)
+        }
+      }
+    },
+    // 计算缩放比例以适应容器宽度
+    calculateScale(page) {
+      const containerWidth = document.getElementById('pdf-view-container').clientWidth
+      const viewport = page.getViewport({ scale: 1 })
+      // 增加一个倍数来提高清晰度,例如 1.5
+      return (containerWidth / viewport.width) * 3
+    }
+  }
+}
+</script>

+ 24 - 6
apps/mobile/vite.config.js

@@ -33,6 +33,23 @@ function getExternals(isDev) {
   }
 }
 
+const baseCDN = {
+  js: [
+    'https://cdn-common.jianyu360.com/cdn/lib/pdfjs-dist/2.1.266/build/pdf.min.js',
+    'https://cdn-common.jianyu360.com/cdn/lib/pdfjs-dist/2.1.266/web/pdf_viewer.js'
+  ]
+}
+
+function getCDN() {
+  const isDev = process.env.NODE_ENV === 'development'
+  console.log(isDev, 'isDev')
+  if (isDev) {
+    return baseCDN
+  } else {
+    return {}
+  }
+}
+
 export default defineConfig(({ mode, command }) => {
   const env = loadEnv(mode, process.cwd())
   return {
@@ -63,6 +80,7 @@ export default defineConfig(({ mode, command }) => {
       vue2(),
       UnoCSS(),
       ViteEjsPlugin({
+        cdn: getCDN(),
         assets: {
           version: Date.now()
         }
@@ -128,22 +146,22 @@ export default defineConfig(({ mode, command }) => {
       proxy: {
         // 接口解密iframe
         '^/page_decrypt': {
-          target: 'https://jybx2-webtest.jydev.jianyu360.com',
+          target: 'https://jybx-webtest.jydev.jianyu360.com',
           changeOrigin: true
         },
         '/jyapi': {
-          target: 'https://jybx2-webtest.jydev.jianyu360.com',
+          target: 'https://jybx-webtest.jydev.jianyu360.com',
           changeOrigin: true,
           rewrite: path => path.replace(/^\/jyapi/, '')
         },
         '/api': {
-          target: 'https://jybx2-webtest.jydev.jianyu360.com',
+          target: 'https://jybx-webtest.jydev.jianyu360.com',
           changeOrigin: true,
           rewrite: path => path.replace(/^\/api/, '')
         },
-        '/aiChat': 'https://jybx2-webtest.jydev.jianyu360.com',
-        '/commonFunctions': 'https://jybx2-webtest.jydev.jianyu360.com',
-        '/common-module': 'https://jybx2-webtest.jydev.jianyu360.com'
+        '/aiChat': 'https://jybx-webtest.jydev.jianyu360.com',
+        '/commonFunctions': 'https://jybx-webtest.jydev.jianyu360.com',
+        '/common-module': 'https://jybx-webtest.jydev.jianyu360.com'
       }
     }
   }