浏览代码

refactor: --

chenlei 1 年之前
父节点
当前提交
294266479c
共有 8 个文件被更改,包括 2247 次插入941 次删除
  1. 1 1
      auto-imports.d.ts
  2. 1 5
      components.d.ts
  3. 2 0
      env.d.ts
  4. 4 1
      package.json
  5. 2097 915
      pnpm-lock.yaml
  6. 121 14
      src/App.vue
  7. 4 4
      src/router/index.ts
  8. 17 1
      vite.config.ts

+ 1 - 1
auto-imports.d.ts

@@ -5,5 +5,5 @@
 // Generated by unplugin-auto-import
 export {}
 declare global {
-
+  const ElMessage: typeof import('element-plus/es')['ElMessage']
 }

+ 1 - 5
components.d.ts

@@ -7,13 +7,9 @@ export {}
 /* prettier-ignore */
 declare module 'vue' {
   export interface GlobalComponents {
-    ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
-    ElLink: typeof import('element-plus/es')['ElLink']
     ElPagination: typeof import('element-plus/es')['ElPagination']
+    ElProgress: typeof import('element-plus/es')['ElProgress']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']
   }
-  export interface ComponentCustomProperties {
-    vLoading: typeof import('element-plus/es')['ElLoadingDirective']
-  }
 }

+ 2 - 0
env.d.ts

@@ -1 +1,3 @@
 /// <reference types="vite/client" />
+
+declare module "vue3-resize-drag";

+ 4 - 1
package.json

@@ -11,9 +11,10 @@
     "type-check": "vue-tsc --build --force"
   },
   "dependencies": {
-    "pdfh5": "^1.4.9",
+    "element-plus": "^2.7.3",
     "pinia": "^2.1.7",
     "vue": "^3.4.21",
+    "vue-pdf-embed": "^2.0.3",
     "vue-router": "^4.3.0"
   },
   "devDependencies": {
@@ -25,6 +26,8 @@
     "npm-run-all2": "^6.1.2",
     "sass": "^1.77.1",
     "typescript": "~5.4.0",
+    "unplugin-auto-import": "^0.17.6",
+    "unplugin-vue-components": "^0.27.0",
     "vite": "^5.2.8",
     "vue-tsc": "^2.0.11"
   }

文件差异内容过多而无法显示
+ 2097 - 915
pnpm-lock.yaml


+ 121 - 14
src/App.vue

@@ -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>

+ 4 - 4
src/router/index.ts

@@ -1,8 +1,8 @@
-import { createRouter, createWebHistory } from 'vue-router'
+import { createRouter, createWebHistory } from "vue-router";
 
 const router = createRouter({
   history: createWebHistory(import.meta.env.BASE_URL),
-  routes: []
-})
+  routes: [],
+});
 
-export default router
+export default router;

+ 17 - 1
vite.config.ts

@@ -4,13 +4,29 @@ import { defineConfig } from "vite";
 import vue from "@vitejs/plugin-vue";
 import vueJsx from "@vitejs/plugin-vue-jsx";
 
+import AutoImport from "unplugin-auto-import/vite";
+import Components from "unplugin-vue-components/vite";
+import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
+
 // https://vitejs.dev/config/
 export default defineConfig({
   base: "./",
-  plugins: [vue(), vueJsx()],
+  plugins: [
+    vue(),
+    vueJsx(),
+    AutoImport({
+      resolvers: [ElementPlusResolver()],
+    }),
+    Components({
+      resolvers: [ElementPlusResolver()],
+    }),
+  ],
   resolve: {
     alias: {
       "@": fileURLToPath(new URL("./src", import.meta.url)),
     },
   },
+  server: {
+    host: "0.0.0.0",
+  },
 });