|
@@ -1,144 +1,110 @@
|
|
|
<template>
|
|
|
- <el-scrollbar style="height: calc(100vh - 120px)">
|
|
|
+ <el-scrollbar>
|
|
|
<div class="grid-container">
|
|
|
- <div v-for="(box, index) in drawingData" :key="index" class="suit-box" :data-index="index">
|
|
|
- <div class="pdf-box">
|
|
|
- <PDFView
|
|
|
- v-if="box.pdfPath && visiblePdfs[index]"
|
|
|
- :need-to-show-pdf="true"
|
|
|
- :pdf-source="baseUrl + box.pdfPath"
|
|
|
- :key="'pdf-' + index + '-' + visiblePdfs[index]"
|
|
|
- />
|
|
|
- <div v-else class="pdf-placeholder">
|
|
|
- <!-- 可以添加一个简单的PDF图标或提示文字 -->
|
|
|
- <el-icon :size="40"><Document /></el-icon>
|
|
|
- </div>
|
|
|
+ <div v-for="(box, index) in drawingData" :key="index" class="suit-box">
|
|
|
+ <div class="pdf-box" @click="toShowPDF(box)">
|
|
|
+ <el-image class="pdf-box" :src="baseUrl + box.pdfPath + '.jpg'">
|
|
|
+ <template #error>
|
|
|
+ <el-image class="pdf-box" :src="DefaultPDF" fit="cover" />
|
|
|
+ </template>
|
|
|
+ </el-image>
|
|
|
+ <!-- <PDFView :need-to-show-pdf="true" :pdf-source="baseUrl + box.pdfPath" />-->
|
|
|
</div>
|
|
|
<div class="suit-title">{{ box?.drawingTitle }}</div>
|
|
|
<div class="suit-desc">{{ box?.created }}</div>
|
|
|
+ <el-button
|
|
|
+ class="download-btn"
|
|
|
+ type="primary"
|
|
|
+ @click="download(box)"
|
|
|
+ :key="box.drawingPath"
|
|
|
+ >下载</el-button
|
|
|
+ >
|
|
|
</div>
|
|
|
</div>
|
|
|
</el-scrollbar>
|
|
|
+ <PDFDrawerView ref="PDFDrawerViewRef"></PDFDrawerView>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
import { drawingList } from "@/api/process/reportBreak";
|
|
|
import { useProcessStore } from "@/store/modules/processView";
|
|
|
import PDFView from "@/components/PDFView/index.vue";
|
|
|
-import { onMounted, ref, onBeforeUnmount } from "vue";
|
|
|
-import { Document } from '@element-plus/icons-vue';
|
|
|
+import DefaultPDF from "@/assets/images/401.gif";
|
|
|
|
|
|
const processStore = useProcessStore();
|
|
|
const drawingData = ref<any>([]);
|
|
|
-const visiblePdfs = ref<boolean[]>([]);
|
|
|
-const observer = ref<IntersectionObserver | null>(null);
|
|
|
-const lastVisibleIndex = ref<number>(-1);
|
|
|
|
|
|
const baseUrl = import.meta.env.VITE_APP_UPLOAD_URL;
|
|
|
|
|
|
onMounted(() => {
|
|
|
- drawingList({ materialCode: processStore.scanInfo.materialCode }).then((res) => {
|
|
|
- drawingData.value = res.data;
|
|
|
- visiblePdfs.value = new Array(res.data.length).fill(false);
|
|
|
- initIntersectionObserver();
|
|
|
- });
|
|
|
-});
|
|
|
-
|
|
|
-onBeforeUnmount(() => {
|
|
|
- cleanupObserver();
|
|
|
+ drawingList({ materialCode: processStore.scanInfo.materialCode }).then(
|
|
|
+ (res) => {
|
|
|
+ drawingData.value = res.data;
|
|
|
+ }
|
|
|
+ );
|
|
|
});
|
|
|
|
|
|
-const initIntersectionObserver = () => {
|
|
|
- cleanupObserver();
|
|
|
-
|
|
|
- observer.value = new IntersectionObserver((entries) => {
|
|
|
- entries.forEach(entry => {
|
|
|
- const index = parseInt(entry.target.getAttribute('data-index') || '0', 10);
|
|
|
-
|
|
|
- if (entry.isIntersecting) {
|
|
|
- // 显示当前PDF
|
|
|
- visiblePdfs.value[index] = true;
|
|
|
- lastVisibleIndex.value = index;
|
|
|
-
|
|
|
- // 可以在这里添加预加载相邻PDF的逻辑
|
|
|
- preloadAdjacentPdfs(index);
|
|
|
- } else {
|
|
|
- // 当元素离开视口时,根据策略决定是否卸载
|
|
|
- if (shouldUnloadPdf(index, lastVisibleIndex.value)) {
|
|
|
- visiblePdfs.value[index] = false;
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- }, {
|
|
|
- rootMargin: '200px 0px', // 提前200px加载
|
|
|
- threshold: 0.01
|
|
|
- });
|
|
|
-
|
|
|
- // 使用nextTick确保DOM已更新
|
|
|
- setTimeout(() => {
|
|
|
- document.querySelectorAll('.suit-box').forEach((box) => {
|
|
|
- observer.value?.observe(box);
|
|
|
- });
|
|
|
- }, 0);
|
|
|
-};
|
|
|
-
|
|
|
-const preloadAdjacentPdfs = (currentIndex: number) => {
|
|
|
- // 预加载前后各1个PDF
|
|
|
- const preloadIndices = [currentIndex - 1, currentIndex + 1];
|
|
|
- preloadIndices.forEach(i => {
|
|
|
- if (i >= 0 && i < visiblePdfs.value.length && !visiblePdfs.value[i]) {
|
|
|
- visiblePdfs.value[i] = true;
|
|
|
- }
|
|
|
- });
|
|
|
+const downloadBtnLoading = ref(false);
|
|
|
+const download = async (row: any) => {
|
|
|
+ downloadBtnLoading.value = true;
|
|
|
+ let url = import.meta.env.VITE_APP_UPLOAD_URL + row.drawingPath;
|
|
|
+
|
|
|
+ // 1. 获取资源并转为Blob
|
|
|
+ const response = await fetch(url);
|
|
|
+ const blob = await response.blob();
|
|
|
+
|
|
|
+ // 2. 创建临时对象URL
|
|
|
+ const tempUrl = URL.createObjectURL(blob);
|
|
|
+
|
|
|
+ // 3. 创建隐藏a标签触发下载
|
|
|
+ const link = document.createElement("a");
|
|
|
+ link.href = tempUrl;
|
|
|
+ link.download = row.fileName;
|
|
|
+ link.style.display = "none";
|
|
|
+ document.body.appendChild(link);
|
|
|
+ link.click();
|
|
|
+
|
|
|
+ // 4. 清理内存
|
|
|
+ URL.revokeObjectURL(tempUrl);
|
|
|
+ document.body.removeChild(link);
|
|
|
+ downloadBtnLoading.value = false;
|
|
|
};
|
|
|
|
|
|
-const shouldUnloadPdf = (index: number, lastVisibleIndex: number) => {
|
|
|
- // 只保留当前可见项和相邻项的PDF加载
|
|
|
- return Math.abs(index - lastVisibleIndex) > 2;
|
|
|
-};
|
|
|
-
|
|
|
-const cleanupObserver = () => {
|
|
|
- if (observer.value) {
|
|
|
- observer.value.disconnect();
|
|
|
- observer.value = null;
|
|
|
- }
|
|
|
+const PDFDrawerViewRef = ref(null);
|
|
|
+const toShowPDF = (row) => {
|
|
|
+ let url = import.meta.env.VITE_APP_UPLOAD_URL + row.pdfPath;
|
|
|
+ PDFDrawerViewRef.value && PDFDrawerViewRef.value.showPdf(url);
|
|
|
};
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
.grid-container {
|
|
|
display: grid;
|
|
|
+ /*行间距*/
|
|
|
grid-row-gap: 24px;
|
|
|
+ /*列间距*/
|
|
|
grid-column-gap: 24px;
|
|
|
+
|
|
|
overflow-y: auto;
|
|
|
padding: 24px;
|
|
|
width: calc(100% - 48px);
|
|
|
grid-template-columns: 1fr 1fr 1fr;
|
|
|
+ height: calc(100vh - 100px);
|
|
|
|
|
|
.suit-box {
|
|
|
height: 343px;
|
|
|
background-color: white;
|
|
|
- border-radius: 16px;
|
|
|
+ border-radius: 16px 16px 16px 16px;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
align-items: start;
|
|
|
justify-content: center;
|
|
|
+ position: relative;
|
|
|
|
|
|
.pdf-box {
|
|
|
height: 263px;
|
|
|
width: 100%;
|
|
|
overflow: hidden;
|
|
|
- position: relative;
|
|
|
- }
|
|
|
-
|
|
|
- .pdf-placeholder {
|
|
|
- height: 100%;
|
|
|
- width: 100%;
|
|
|
- background-color: #f5f5f5;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- color: #999;
|
|
|
}
|
|
|
|
|
|
.suit-title {
|
|
@@ -155,6 +121,12 @@ const cleanupObserver = () => {
|
|
|
text-align: left;
|
|
|
margin-left: 24px;
|
|
|
}
|
|
|
+
|
|
|
+ .download-btn {
|
|
|
+ position: absolute;
|
|
|
+ right: 20px;
|
|
|
+ top: 20px;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
-</style>
|
|
|
+</style>
|