zhongshujie
6 天以前 bb584963c6abe77c5577cbcad3c9956b69444ae9
src/components/pdfview/index.vue
@@ -1,26 +1,25 @@
<!-- @format -->
<template>
  <div class="preview" v-if="this.preViewMd5">
    <div id="imageParent" class="imageBox"></div>
    <div class="bottom_tool">
      <svg
        @click="downloadPdf"
        t="1718251204993"
        class="icon"
        viewBox="0 0 1024 1024"
        version="1.1"
        xmlns="http://www.w3.org/2000/svg"
        p-id="4418"
        xmlns:xlink="http://www.w3.org/1999/xlink"
        width="25"
        height="25"
      >
        <path
          d="M557 564.974l153.188-181.04c16.054-18.972 44.448-21.34 63.42-5.286 18.972 16.054 21.338 44.448 5.284 63.42L550.56 711.92a44.982 44.982 0 0 1-8.95 10.254 44.872 44.872 0 0 1-15.082 8.432A44.944 44.944 0 0 1 512 733c-16.264 0-30.512-8.628-38.42-21.556L245.65 442.068c-16.052-18.972-13.686-47.366 5.286-63.42 18.972-16.052 47.366-13.686 63.42 5.286l152.646 180.4V157c0-24.852 20.148-45 45-45s45 20.148 45 45v407.974zM823 630c0-24.852 20.148-45 45-45s45 20.148 45 45v238c0 24.87-20.176 45.026-45.046 45l-710-0.726c-24.834-0.026-44.954-20.166-44.954-45V630c0-24.852 20.148-45 45-45s45 20.148 45 45v192.32l620 0.634V630z"
          p-id="4419"
        ></path>
      </svg>
  <el-dialog :visible.sync="localDialogVisible" @open="hadleOpenDialog" width="60vw" top="2vh" append-to-body
    lock-scroll :show-close="false" class="custom-dialog">
    <div slot="title" class="header_title">
      <span>{{ pdfTitle }}</span>
      <span @click="closeDialog"> x </span>
    </div>
  </div>
    <div class="pdfModal" v-if="localDialogVisible">
      <!-- 原有的内容 -->
      <div class="pdfBox-component">
        <div class="preview" v-if="this.preViewMd5">
          <div id="imageParent" class="imageBox"></div>
          <div class="bottom_tool"></div>
        </div>
        <div class="notBox" v-if="totalPage == 0 && !loading">
          <el-empty description="暂无数据"></el-empty>
        </div>
        <div class="notBox" v-if="loading" v-loading="loading"></div>
      </div>
    </div>
  </el-dialog>
</template>
<script>
import Viewer from "viewerjs";
@@ -39,72 +38,104 @@
      type: Boolean,
      default: false,
    },
    pdfTitle: {
      type: String,
    },
  },
  data() {
    return {
      localDialogVisible: false,
      currentPageSrc: "",
      currentPage: 1,
      currentPage: 3,
      totalPage: 1,
      viewerCon: null,
      preViewMd5: "",
      loading: false,
    };
  },
  watch: {
    isClear: {
      immediate: true,
      handler(val) {
        if (val == true) this.preViewMd5 = "";
      },
    },
    md5: {
      immediate: true,
      handler(val) {
        if (val) {
          this.preViewMd5 = val;
          this.currentPage = 1;
          this.currentPageSrc = "";
          this.totalPage = 1;
          this.viewerCon?.destroy();
        }
      },
    },
  },
  mounted() {
    this.scrollBottom();
    this.clearDom();
    this.getFileInfo();
    // md5: {
    //   immediate: true,
    //   handler(val) {
    //     if (val) {
    //       // this.preViewMd5 = val
    //       this.currentPage = 1
    //       this.currentPageSrc = ''
    //       this.totalPage = 1
    //       this.viewerCon?.destroy()
    //     }
    //   },
    // },
    // dialogVisibleProp(newVal) {
    //   this.localDialogVisible = newVal;
    //   if (newVal) {
    //     this.currentPage = 1;
    //     this.loading = true;
    //     this.clearDom();
    //     this.getFileInfo();
    //     this.$nextTick(() => {
    //       this.scrollBottom()
    //     });
    //   } else {
    //     this.viewerCon?.destroy();
    //   }
    // },
  },
  methods: {
    hadleOpenDialog() {
      this.preViewMd5 = this.md5;
      this.currentPage = 3;
      this.currentPageSrc = "";
      this.totalPage = 1;
      this.viewerCon?.destroy();
      this.loading = true;
      this.clearDom();
      this.getFileInfo();
      this.$nextTick(() => {
        this.scrollBottom();
      });
    },
    closeDialog() {
      this.localDialogVisible = false;
    },
    openDialog() {
      this.localDialogVisible = true;
    },
    async downloadPdf() {
      console.log(await getResourcePath(this.preViewMd5), "12345");
      window.open(await getResourcePath(this.preViewMd5));
    },
    domViewer() {
      let ele = (this.container ? this.container : document).getElementById(
        "imageParent"
      );
      this.viewerCon = new Viewer(ele, {
        inline: false,
        container: this.container
          ? this.container.querySelector("#app")
          : "body",
        navbar: true, // 显示导航栏
        toolbar: true, // 显示工具栏
        title: true, // 显示标题
      });
      // let ele = (this.container ? this.container : document).getElementById(
      //   'imageParent'
      // )
      let ele = document.getElementById("imageParent");
      if (ele) {
        this.viewerCon = new Viewer(ele, {
          inline: false,
          container: this.container
            ? this.container.querySelector("#app")
            : "body",
          navbar: true, // 显示导航栏
          toolbar: true, // 显示工具栏
          title: true, // 显示标题
        });
      }
    },
    clearDom() {
      let ele = (this.container ? this.container : document).getElementById(
        "imageParent"
      );
      ele.innerHtml = "";
      let ele = document.getElementById("imageParent");
      if (ele) {
        ele.innerHTML = "";
      }
    },
    createDom(page) {
      var that = this;
      let ele = (this.container ? this.container : document).getElementById(
        "imageParent"
      );
      let ele = document.getElementById("imageParent");
      const img = document.createElement("img");
      img.src = this.getPageImage(page);
      // 手动触发滚动事件
      // ele.dispatchEvent(new Event("scroll"));
      img.alt = "";
      img.style.maxWidth = "90%";
      img.style.padding = "30px 5%";
@@ -113,39 +144,67 @@
        that.viewerCon?.destroy();
        that.domViewer();
      };
      ele.appendChild(img);
      if (ele) {
        ele.appendChild(img);
      }
    },
    scrollBottom() {
      var that = this;
      var ele = (this.container ? this.container : document).getElementById(
        "imageParent"
      );
      ele.addEventListener("scroll", function () {
        // 计算滚动条距离底部的位置
        const scrollBottom =
          ele.scrollHeight - ele.scrollTop - ele.clientHeight;
        if (scrollBottom <= 10) {
          that.currentPage++;
          if (that.currentPage <= that.totalPage) {
            that.createDom(that.currentPage, ele);
      const ele = document.getElementById("imageParent");
      if (ele) {
        let lastScrollTop = 0;
        ele.addEventListener("scroll", () => {
          const scrollTop = ele.scrollTop;
          const scrollBottom = ele.scrollHeight - scrollTop - ele.clientHeight;
          if (scrollBottom < 10 && scrollTop > lastScrollTop) {
            console.log(
              "滚动到底部,当前页:",
              this.currentPage,
              "总页数:",
              this.totalPage
            );
            if (this.currentPage < this.totalPage) {
              this.currentPage++;
              if (this.currentPage <= this.totalPage) {
                this.createDom(this.currentPage);
              }
            }
          }
        }
      });
          lastScrollTop = scrollTop;
        });
      }
    },
    getFileInfo() {
      // 获取目录
      this.loading = true;
      this.MG.file
        .getPdfInfo({ md5: this.preViewMd5 })
        .then((res) => {
          this.totalPage = res.totalPages;
          this.createDom(this.currentPage);
          try {
            if (typeof res === "string" && res !== null) {
              this.totalPage = JSON.parse(res).totalPages;
            } else if (typeof res === "object" && res !== null) {
              this.totalPage = res.totalPages;
            }
          } catch (error) {
            console.log(error, "pdf返回值类型错误");
          }
          const maxPages = Math.min(3, this.totalPage);
          for (let i = 0; i < maxPages; i++) {
            this.createDom(i + 1);
          }
          this.loading = false;
        })
        .catch((err) => {
          this.totalPage = 1;
          this.totalPage = 0;
          this.createDom(this.currentPage);
          console.error(err);
          this.loading = false;
        });
    },
    getPageImage(page) {
      const ctx = process.env.VUE_APP_API_URL;
      return (
@@ -161,37 +220,3 @@
  },
};
</script>
<style scoped lang="less">
.preview {
  width: 100%;
  height: 100%;
  .imageBox {
    height: calc(100% - 30px);
    overflow-x: hidden;
    overflow-y: auto;
    background: #ccc;
    box-sizing: border-box;
  }
  .imageBox:hover {
    cursor: zoom-in !important;
  }
  .bottom_tool {
    height: 30px;
    background-color: rgba(0, 0, 0, 0.8);
    display: flex;
    justify-content: flex-end;
    align-items: center;
    svg {
      margin-right: 10px;
      fill: #999;
    }
    svg:hover {
      fill: #fff;
      cursor: pointer;
    }
  }
}
</style>