<template>
|
<j-modal
|
:title="title"
|
:width="800"
|
:visible="visible"
|
switchFullscreen
|
@ok="handleOk"
|
@cancel="handleCancel"
|
:footer="null"
|
cancelText="关闭">
|
<a-spin :spinning="confirmLoading">
|
<img v-if="isImage" :src="fileUrl" width="100%" height="100%" alt="图片预览" />
|
<iframe v-else-if="isPdf" :src="fileUrl" width="100%" height="600px"></iframe>
|
<video v-else-if="isVideo" controls>
|
<source :src="fileUrl" type="video/mp4">
|
您的浏览器不支持 video 标签。
|
</video>
|
<pre v-else-if="isText">{{ textContent }}</pre>
|
<h1 v-else>不支持预览,请下载后查看</h1>
|
</a-spin>
|
</j-modal>
|
</template>
|
|
<script>
|
import { getFileAccessHttpUrl } from '@/api/manage'
|
|
export default {
|
props: {
|
fileUrl: String
|
},
|
data() {
|
return {
|
title: '预览',
|
textContent: '',
|
confirmLoading: false,
|
visible: false
|
}
|
},
|
computed: {
|
isImage() {
|
return /\.(jpeg|jpg|png|gif|bmp|webp)$/i.test(this.fileUrl)
|
},
|
isPdf() {
|
return /\.pdf$/i.test(this.fileUrl)
|
},
|
isVideo() {
|
return /\.(mp4|webm|ogg)$/i.test(this.fileUrl)
|
},
|
isText() {
|
return /\.(txt|md|json|xml|yaml|yml)$/i.test(this.fileUrl)
|
}
|
},
|
watch: {
|
fileUrl: 'fetchTextContent'
|
},
|
mounted() {
|
if (this.isText) {
|
this.fetchTextContent()
|
}
|
},
|
methods: {
|
async fetchTextContent() {
|
try {
|
const response = await fetch(this.fileUrl)
|
if (!response.ok) throw new Error('网络响应不是OK')
|
const text = await response.text()
|
this.textContent = text
|
} catch (error) {
|
console.error('获取文本内容失败:', error)
|
this.textContent = '无法加载文本内容'
|
}
|
},
|
close() {
|
this.$emit('close')
|
this.visible = false
|
},
|
preview(fileUrl) {
|
let url = getFileAccessHttpUrl(fileUrl)
|
this.visible = true
|
this.fileUrl = url
|
},
|
handleOk() {
|
this.close()
|
},
|
handleCancel() {
|
this.close()
|
}
|
}
|
}
|
</script>
|
|
<style lang="less" scoped>
|
|
/deep/ .ant-modal {
|
height: 80%;
|
/* 滚动条优化 start */
|
::-webkit-scrollbar{
|
width:8px;
|
height:8px;
|
}
|
|
.ant-modal-content {
|
height: 100%;
|
display: flex;
|
flex-direction: column;
|
|
.ant-modal-body {
|
flex: 1;
|
overflow: auto;
|
}
|
}
|
}
|
|
pre {
|
overflow: visible;
|
}
|
|
|
</style>
|