356 lines
9.5 KiB
Vue
356 lines
9.5 KiB
Vue
<template>
|
|
<div>
|
|
<message-dialog
|
|
title="确认信息"
|
|
content="是否在关闭前保存修改?"
|
|
:show.sync="isSaveDialogVisible"
|
|
operatButtonText="放弃修改"
|
|
confirmButtonText="保存"
|
|
@operating="closeDialog"
|
|
@confirm="saveAndClose"
|
|
>
|
|
</message-dialog>
|
|
<div class="office-preview" v-if="show" v-loading="!readyShow">
|
|
<div class="preview-block" v-show="readyShow">
|
|
<div class="close-bar" @click="beforeClose">
|
|
<svg-icon class="preview-close" icon-class="close"/>
|
|
</div>
|
|
<div class="wrapper">
|
|
<CADPreview v-if="fileType === 'cad'" :file="file" :shareId="shareId" :file-url="fileUrl" @onReady="onReady" @loadFileFailed="loadFileFailed"></CADPreview>
|
|
<pdf-preview v-else-if="fileType === 'pdf'" :file="file" :shareId="shareId" :file-url="fileUrl" @onReady="onReady"></pdf-preview>
|
|
<drawio v-else-if="fileType === 'drawio'" v-show="fileReday" :file="file" :shareId="shareId" :read-only="readOnly" @onEdit="onEdit" @onReady="onReady" @onClose="close"></drawio>
|
|
<excalidraw-editor v-else-if="fileType === 'excalidraw'" v-show="fileReday" :file="file" :shareId="shareId" :read-only="readOnly" @onEdit="onEdit" @onReady="onReady" @onClose="close"></excalidraw-editor>
|
|
<my-mind-editor v-else-if="fileType === 'mind'" :file="file" :shareId="shareId" :read-only="readOnly" @onEdit="onEdit" @onReady="onReady" @onClose="close"></my-mind-editor>
|
|
<model-preview v-else-if="fileType === 'glTF/GLB'" :file="file" :file-url="fileUrl" :shareId="shareId" @onReady="onReady"></model-preview>
|
|
<only-office-editor ref="officeEditor" v-else-if="fileType === 'office'" :file="file" :file-url="fileUrl" :shareId="shareId" :sharer="sharer" :read-only="readOnly" @onEdit="onEdit" @manualSave="manualSave" @onClose="close" @onReady="onReady"></only-office-editor>
|
|
<iframe-content-preview v-else :file="file" :fileHandler="fileHandler" :file-url="fileUrl" @onReady="onReady" @loadFileFailed="loadFileFailed"></iframe-content-preview>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
|
|
import ExcalidrawEditor from '@/components/office/ExcalidrawEditor.vue'
|
|
import ModelPreview from '@/components/office/ModelPreview.vue'
|
|
import OnlyOfficeEditor from "@/components/office/OnlyOfficeEditor";
|
|
import MessageDialog from "@/components/message/MessageDialog";
|
|
import IframeContentPreview from '@/components/preview/IframeContentPreview.vue'
|
|
import fileConfig from "@/utils/file-config";
|
|
import PdfPreview from "@/components/office/PdfPreview";
|
|
import Drawio from "@/components/office/Drawio";
|
|
|
|
export default {
|
|
name: 'IframePreview',
|
|
components: {
|
|
ExcalidrawEditor, IframeContentPreview, ModelPreview, Drawio, PdfPreview, MessageDialog, OnlyOfficeEditor,
|
|
MyMindEditor: () => import('@/components/Minder/minder'),
|
|
CADPreview: () => import('@/components/preview/CADPreview.vue')
|
|
},
|
|
props: {
|
|
id: {
|
|
type: String,
|
|
default: () => {
|
|
return "office_" + Math.round(Math.random() * 10000)
|
|
}
|
|
},
|
|
file: {
|
|
type: Object,
|
|
default: function () {
|
|
return {}
|
|
}
|
|
},
|
|
fileHandler: {
|
|
type: Object,
|
|
default: {}
|
|
},
|
|
shareId: {
|
|
type: String,
|
|
default: undefined
|
|
},
|
|
sharer: {
|
|
type: String,
|
|
default: undefined
|
|
},
|
|
status: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
specifyPreviewer: {
|
|
type: String,
|
|
default: ''
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
fileUrl: '',
|
|
pc: this.$pc,
|
|
show: this.status,
|
|
readyShow: false,
|
|
readOnly: true,
|
|
isSaveDialogVisible: false,
|
|
saved: true,
|
|
previewDocument: {},
|
|
delayClosing: {},
|
|
fileReday: false,
|
|
}
|
|
},
|
|
computed: {
|
|
fileType() {
|
|
if (this.specifyPreviewer === 'office') {
|
|
return 'office'
|
|
}
|
|
return this.getType(this.file.suffix)
|
|
},
|
|
},
|
|
mounted() {
|
|
document.addEventListener('keyup', this.escape)
|
|
},
|
|
destroyed() {
|
|
document.removeEventListener('keyup', this.escape)
|
|
},
|
|
watch: {
|
|
status: function(visible){
|
|
if(visible){
|
|
this.show = true
|
|
this.$nextTick(() => {
|
|
this.previewDocument = document.querySelector('.preview-block')
|
|
})
|
|
this.checkReadOnly(this.file)
|
|
// 12秒后还没加载出来视为加载失败
|
|
let that = this
|
|
this.delayClosing = setTimeout(function () {
|
|
if (!that.readyShow) {
|
|
that.loadFileFailed()
|
|
}
|
|
},12000)
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
/**
|
|
* 按esc键
|
|
*/
|
|
escape(event) {
|
|
// 监听ESC键
|
|
if (event.code === 'Escape') {
|
|
this.beforeClose()
|
|
}
|
|
},
|
|
getType(suffix) {
|
|
if (Object.keys(this.fileHandler).length > 0) {
|
|
return 'other'
|
|
}
|
|
if (this.file.contentType.indexOf('office') > -1) {
|
|
return 'office'
|
|
}
|
|
switch (suffix) {
|
|
case 'drawio':
|
|
return 'drawio'
|
|
case 'excalidraw':
|
|
return 'excalidraw'
|
|
case 'pdf':
|
|
return 'pdf'
|
|
case 'mind':
|
|
return 'mind'
|
|
case 'gltf':
|
|
case 'glb':
|
|
return 'glTF/GLB'
|
|
case 'office':
|
|
case 'csv':
|
|
return 'office'
|
|
case 'dwg':
|
|
return 'cad'
|
|
default:
|
|
return 'other'
|
|
}
|
|
},
|
|
/**
|
|
* 加载失败
|
|
*/
|
|
loadFileFailed(msg) {
|
|
this.close()
|
|
this.$store.dispatch('updateMessage', { event: 'loadFileFailed', msg: msg})
|
|
this.readyShow = true
|
|
},
|
|
/**
|
|
* 点击关闭按钮
|
|
*/
|
|
beforeClose() {
|
|
if (!this.saved) {
|
|
this.isSaveDialogVisible = true
|
|
} else {
|
|
this.close()
|
|
}
|
|
},
|
|
/**
|
|
* 执行关闭预览窗口
|
|
*/
|
|
close() {
|
|
clearTimeout(this.delayClosing)
|
|
this.show = false
|
|
this.readyShow = false
|
|
this.$emit('update:status', false)
|
|
},
|
|
/**
|
|
* 文件内容已经加载好了
|
|
*/
|
|
onReady() {
|
|
this.saved = true
|
|
this.readyShow = true
|
|
this.fileReday = true
|
|
if (['drawio', 'office'].includes(this.fileType)) {
|
|
this.previewDocument.style.zIndex = 9999
|
|
this.$nextTick(() => {
|
|
let that = this
|
|
setTimeout(function () {
|
|
that.previewDocument.style.zIndex = 2001
|
|
},200)
|
|
})
|
|
}
|
|
},
|
|
/**
|
|
* 编辑回调
|
|
* @param saved 是否已经保存
|
|
*/
|
|
onEdit(saved) {
|
|
this.saved = saved
|
|
if(saved){
|
|
window.addEventListener('onbeforeunload', this.onbeforeunload)
|
|
} else {
|
|
window.removeEventListener('onbeforeunload', this.onbeforeunload)
|
|
}
|
|
},
|
|
onbeforeunload(event) {
|
|
event.returnValue=("文件未保存, 确定退出吗?");
|
|
},
|
|
/**
|
|
* 放弃修改
|
|
*/
|
|
closeDialog() {
|
|
this.isSaveDialogVisible = false
|
|
this.close()
|
|
},
|
|
/**
|
|
* 保存并退出
|
|
*/
|
|
saveAndClose() {
|
|
// 通知插件保存
|
|
this.$store.dispatch('updateMessage', { event: 'previewSaveAndClose'})
|
|
this.isSaveDialogVisible = false
|
|
},
|
|
/**
|
|
* 手动保存提醒,有些组件没有自动保存
|
|
*/
|
|
manualSave() {
|
|
this.$message.info('请手动保存')
|
|
},
|
|
/**
|
|
* 检查要预览的文件是否为只读
|
|
* @param file userId
|
|
*/
|
|
checkReadOnly(file){
|
|
if(this.$store.state.user.token && this.$store.state.user.userId === file.userId){
|
|
this.readOnly = false
|
|
}
|
|
if (this.$store.state.user.token && file.operationPermissionList && file.operationPermissionList.indexOf('PUT') > -1) {
|
|
this.readOnly = false
|
|
}
|
|
if (!this.$pc && this.fileType === 'office') {
|
|
this.readOnly = true
|
|
this.$nextTick(() => {
|
|
const closeBar = document.querySelector('.office-preview .close-bar');
|
|
closeBar.style.right = '2.5rem'
|
|
closeBar.style.float = 'left'
|
|
closeBar.style.transform = 'rotate(225deg)'
|
|
})
|
|
}
|
|
this.fileUrl = window.location.origin + fileConfig.previewUrl(this.$store.state.user.name, this.file, this.$store.getters.token)
|
|
if(this.readOnly && window.shareId){
|
|
this.fileUrl = window.location.origin + fileConfig.publicPreviewUrl(this.file, window.shareId, this.$store.getters.shareToken)
|
|
}
|
|
},
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
.office-preview {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
z-index: 1002;
|
|
width: 100%;
|
|
height: 100%;
|
|
|
|
}
|
|
|
|
.van-overlay {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
z-index: 1003;
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: rgba(0,0,0,.7);
|
|
}
|
|
|
|
.preview-block {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: rgba(0,0,0,.7);
|
|
z-index: 2001;
|
|
|
|
.close-bar {
|
|
z-index: 2000;
|
|
background-color: rgba(0,0,0,.5);
|
|
position: relative;
|
|
top: -2.5rem;
|
|
right: -2.5rem;
|
|
float: right;
|
|
width: 0;
|
|
height: 0;
|
|
border-radius: 2.5rem;
|
|
border-width: 2.5rem;
|
|
border-style: solid;
|
|
border-color: transparent transparent transparent #d4d4d475;
|
|
line-height: 2.5rem;
|
|
opacity: 1;
|
|
transform: rotate(-45deg);
|
|
}
|
|
|
|
.close-bar:hover {
|
|
cursor: pointer;
|
|
border-color: transparent transparent transparent #69696975;
|
|
}
|
|
|
|
.preview-close {
|
|
transform: rotate(-45deg);
|
|
position: absolute;
|
|
font-size: 1.25rem;
|
|
top: -8px;
|
|
right: 13px;
|
|
}
|
|
}
|
|
|
|
.wrapper {
|
|
|
|
>>> .component-only-office {
|
|
position: absolute;
|
|
top: 2.5rem;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
}
|
|
|
|
</style>
|