|
@@ -1,32 +1,139 @@
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, watch } from "vue";
|
|
|
+import { nextTick, reactive, ref, watch, computed } from "vue";
|
|
|
+import VuePdfEmbed, { useVuePdfEmbed } from "vue-pdf-embed";
|
|
|
import { useRoute } from "vue-router";
|
|
|
-// @ts-ignore
|
|
|
-import Pdfh5 from "pdfh5";
|
|
|
-import "pdfh5/css/pdfh5.css";
|
|
|
+import { ElMessage } from "element-plus";
|
|
|
+import "vue-pdf-embed/dist/style/index.css";
|
|
|
+import "element-plus/theme-chalk/el-message.css";
|
|
|
+
|
|
|
+const getQueryParam = (param: string, url: string = window.location.href) => {
|
|
|
+ const urlObj = new URL(url);
|
|
|
+ return urlObj.searchParams.get(param);
|
|
|
+};
|
|
|
|
|
|
const route = useRoute();
|
|
|
-const pdfh5 = ref();
|
|
|
+const loaded = ref(false);
|
|
|
+const progress = ref(0);
|
|
|
+const state = reactive({
|
|
|
+ pageNum: 1,
|
|
|
+ scale: 1, // 缩放比例
|
|
|
+ numPages: 0, // 总页数
|
|
|
+});
|
|
|
+const { doc } = useVuePdfEmbed({
|
|
|
+ source: getQueryParam("url"),
|
|
|
+});
|
|
|
+const showAll = computed(() => route.query.showAll === "1");
|
|
|
|
|
|
watch(route, () => {
|
|
|
- if (!route || !route.query.url) return;
|
|
|
+ if (!route || !route.query.url) {
|
|
|
+ ElMessage({
|
|
|
+ message: "url参数不能为空",
|
|
|
+ type: "error",
|
|
|
+ duration: 4000,
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+});
|
|
|
|
|
|
- pdfh5.value = new Pdfh5("#pdf-view", {
|
|
|
- pdfurl: decodeURIComponent(route.query.url as string),
|
|
|
+const handleLoaded = (e: any) => {
|
|
|
+ state.numPages = e.numPages;
|
|
|
+ nextTick(() => {
|
|
|
+ loaded.value = true;
|
|
|
});
|
|
|
-});
|
|
|
+};
|
|
|
+
|
|
|
+const handleProgress = (e: { loaded: number; total: number }) => {
|
|
|
+ progress.value = Math.round((100 / e.total) * e.loaded);
|
|
|
+};
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
- <div id="pdf-view" />
|
|
|
+ <div id="vue-pdf-view" :class="{ all: showAll }">
|
|
|
+ <VuePdfEmbed
|
|
|
+ :source="doc"
|
|
|
+ :page="state.pageNum"
|
|
|
+ @loaded="handleLoaded"
|
|
|
+ @progress="handleProgress"
|
|
|
+ />
|
|
|
+
|
|
|
+ <template v-if="showAll && state.numPages > 1">
|
|
|
+ <VuePdfEmbed
|
|
|
+ v-for="page in state.numPages - 1"
|
|
|
+ :key="page"
|
|
|
+ :source="doc"
|
|
|
+ :page="page + 1"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-if="loaded && !showAll" class="toolbar">
|
|
|
+ <el-pagination
|
|
|
+ v-model:current-page="state.pageNum"
|
|
|
+ background
|
|
|
+ layout="prev, pager, next"
|
|
|
+ :total="state.numPages"
|
|
|
+ :page-size="1"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-if="!loaded" class="loading">
|
|
|
+ <el-progress
|
|
|
+ :percentage="progress"
|
|
|
+ :indeterminate="true"
|
|
|
+ :stroke-width="12"
|
|
|
+ style="width: 80%"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
</template>
|
|
|
|
|
|
-<style scoped lang="scss">
|
|
|
-#pdf-view {
|
|
|
+<style lang="scss" scoped>
|
|
|
+.toolbar {
|
|
|
+ position: fixed;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ bottom: 0;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ height: 50px;
|
|
|
+ border-top: 1px solid var(--el-border-color);
|
|
|
+ background: white;
|
|
|
+ box-sizing: border-box;
|
|
|
+ z-index: 2;
|
|
|
+}
|
|
|
+
|
|
|
+.loading {
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ bottom: 0;
|
|
|
display: flex;
|
|
|
- flex-direction: column;
|
|
|
align-items: center;
|
|
|
- height: 100vh;
|
|
|
+ justify-content: center;
|
|
|
+ background: rgba($color: #ffffff, $alpha: 0.7);
|
|
|
+ z-index: 2;
|
|
|
+}
|
|
|
+
|
|
|
+#vue-pdf-view {
|
|
|
+ width: 100vw;
|
|
|
+ height: calc(100vh - 50px);
|
|
|
overflow: hidden;
|
|
|
+ overflow-y: auto;
|
|
|
+
|
|
|
+ &.all {
|
|
|
+ height: 100vh;
|
|
|
+ }
|
|
|
+ &::-webkit-scrollbar {
|
|
|
+ width: 8px;
|
|
|
+ height: 8px;
|
|
|
+ }
|
|
|
+ &::-webkit-scrollbar-thumb {
|
|
|
+ border-radius: 15px;
|
|
|
+ background-color: #eee;
|
|
|
+ }
|
|
|
+ &::-webkit-scrollbar-thumb:hover {
|
|
|
+ background-color: #cbcbff;
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|