lanan-system-vue/src/components/FilePreviewDialog/FilePreviewDialog.vue
2025-08-04 14:28:21 +08:00

200 lines
4.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<el-dialog :title="'文件预览(' + file.fileName + ''" :visible.sync="visible" width="70%" append-to-body>
<div class="preview-container">
<audio v-if="isAudioType" class="preview-iframe" controls>
<source :src="getFileUrl()"/>
</audio>
<!-- 左侧预览区域 -->
<iframe
:src="fileUrl"
frameborder="0"
class="preview-iframe"
v-if="!isImage && fileExtension != 'txt' && !isAudioType && fileExtension != 'pdf'"
>
</iframe>
<image-preview
class="preview-iframe"
:src="getFileUrl()"
v-if="isImage">
</image-preview>
<iframe
:src="getFileUrl()"
frameborder="0"
class="preview-iframe"
v-if="fileExtension == 'txt' || fileExtension == 'pdf'"
>
</iframe>
<!-- 右侧文件列表 -->
<div class="file-list">
<el-table
:data="fileList.filter(file => file.type !== '1')"
height="100%"
@row-click="handleFileClick"
:row-class-name="getRowClassName">
<el-table-column
prop="fileName"
label="文件列表"
min-width="180">
<template #default="{ row }">
<div class="file-item">
<i :class="row.type === '1' ? 'el-icon-folder' : 'el-icon-document'"></i>
{{ row.fileName }}
</div>
</template>
</el-table-column>
</el-table>
</div>
</div>
</el-dialog>
</template>
<script>
import ImagePreview from '@/components/ImagePreview/ImagePreview.vue'
export default {
name: 'FilePreviewDialog',
components: { imagePreview },
props: {
visible: {
type: Boolean,
required: true,
default: false
},
file: {
type: Object,
required: true,
default: () => ({})
},
fileList: {
type: Array,
required: true,
default: () => []
},
previewUrl: {
type: String,
required: false,
default: process.env.VUE_APP_PREVIEW_URL
},
inspectionFileUrl: {
type: String,
required: false,
default: process.env.VUE_APP_INSPECTION_FILE_URL
},
imageUrl: {
type: String,
required: false,
default: process.env.VUE_APP_FILE_API
}
},
data() {
return {
fileUrl: ''
}
},
computed: {
fileExtension() {
if (!this.file.filePath) return '';
const lastDotIndex = this.file.filePath.lastIndexOf('.');
return lastDotIndex > -1 ? this.file.filePath.slice(lastDotIndex + 1).toLowerCase() : '';
},
isImage() {
const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
return imageExtensions.includes(this.fileExtension);
},
isAudioType() {
const audioExtensions = ['mp3', 'wav', 'ogg', 'aac', 'm4a', 'flac'];
return audioExtensions.includes(this.fileExtension);
}
},
watch: {
visible(val) {
if (val) {
this.initFileUrl();
}
},
file(val) {
if (this.visible) {
this.initFileUrl();
}
}
},
methods: {
close() {
this.$emit('update:visible', false);
},
initFileUrl() {
const ext = this.fileExtension;
if (ext === 'pdf' || ext === 'txt') {
this.fileUrl = this.getFileUrl();
} else if (!this.isImage && !this.isAudioType) {
this.fileUrl = `https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(this.getFileUrl())}`;
}
},
getFileUrl() {
if (this.file.filePath.includes('http')) {
return this.inspectionFileUrl + this.file.filePath.replace(/^.*?uploads\//, 'uploads/');
} else {
return this.previewUrl ? this.previewUrl + this.file.filePath : this.imageUrl + this.file.filePath;
}
},
handleFileClick(row) {
if (row.type === '2') {
this.$emit('file-click', row);
}
},
getRowClassName({ row }) {
return row.id === this.file.id ? 'highlight-row' : '';
},
downloadFile(item) {
this.$emit('download', item);
}
}
}
</script>
<style scoped>
.preview-container {
display: flex;
height: 80vh;
}
.preview-iframe {
flex: 6;
width: 100%;
height: 100%;
margin-right: 10px;
}
.file-list {
flex: 1;
border-left: 1px solid #ebeef5;
padding-left: 10px;
}
.file-item {
cursor: pointer;
padding: 8px;
transition: background 0.3s;
}
.file-item:hover {
background: #f5f7fa;
}
/* 调整表格高度 */
::v-deep .el-table {
height: calc(100% - 2px) !important;
}
/* 隐藏表格头 */
::v-deep .el-table__header-wrapper {
display: none;
}
highlight-row {
background-color: #f0f7ff; /* 高亮背景色 */
color: #409eff; /* 高亮文字颜色 */
}
</style>