2022-02-23 09:41:19 +08:00

181 lines
5.9 KiB
Vue

<template>
<div class="file-preview">
<iframe v-if="isPreview" ref="myPreview" class="preview-iframe" :src="previewUrl"></iframe>
<template v-else>
<div v-show="!['word', 'excel', 'ppt'].includes(file.type)" class="edit-header">
<div class="header-title">
{{formatName(file)}}
<Tag color="default">{{$L('只读')}}</Tag>
<div class="refresh">
<Loading v-if="contentLoad"/>
<Icon v-else type="ios-refresh" @click="getContent" />
</div>
</div>
<Dropdown v-if="file.type=='mind'"
trigger="click"
class="header-hint"
@on-click="exportMenu">
<a href="javascript:void(0)">{{$L('导出')}}<Icon type="ios-arrow-down"></Icon></a>
<DropdownMenu slot="list">
<DropdownItem name="png">{{$L('导出PNG图片')}}</DropdownItem>
<DropdownItem name="pdf">{{$L('导出PDF文件')}}</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
<div v-if="contentDetail" class="content-body">
<template v-if="file.type=='document'">
<MDPreview v-if="contentDetail.type=='md'" :initialValue="contentDetail.content"/>
<TEditor v-else v-model="contentDetail.content" height="100%" readOnly/>
</template>
<Drawio v-else-if="file.type=='drawio'" ref="myFlow" v-model="contentDetail" :title="file.name" readOnly/>
<Minder v-else-if="file.type=='mind'" ref="myMind" v-model="contentDetail" readOnly/>
<OnlyOffice v-else-if="['word', 'excel', 'ppt'].includes(file.type)" v-model="contentDetail" :code="code" :documentKey="documentKey" readOnly/>
<AceEditor v-else-if="['code', 'txt'].includes(file.type)" v-model="contentDetail.content" :ext="file.ext" readOnly/>
</div>
</template>
<div v-if="contentLoad" class="content-load"><Loading/></div>
</div>
</template>
<script>
import Vue from 'vue'
import Minder from '../../../components/minder'
Vue.use(Minder)
const MDPreview = () => import('../../../components/MDEditor/preview');
const TEditor = () => import('../../../components/TEditor');
const AceEditor = () => import('../../../components/AceEditor');
const OnlyOffice = () => import('../../../components/OnlyOffice');
const Drawio = () => import('../../../components/Drawio');
export default {
name: "FilePreview",
components: {AceEditor, TEditor, MDPreview, OnlyOffice, Drawio},
props: {
code: {
type: String,
default: ''
},
file: {
type: Object,
default: () => {
return {};
}
},
},
data() {
return {
loadContent: 0,
contentDetail: null,
loadPreview: true,
}
},
mounted() {
window.addEventListener('message', this.handleMessage)
},
beforeDestroy() {
window.removeEventListener('message', this.handleMessage)
},
watch: {
'file.id': {
handler(id) {
if (id) {
this.contentDetail = null;
this.getContent();
}
},
immediate: true,
deep: true,
},
},
computed: {
contentLoad() {
return this.loadContent > 0 || this.previewLoad;
},
isPreview() {
return this.contentDetail && this.contentDetail.preview === true;
},
previewLoad() {
return this.isPreview && this.loadPreview === true;
},
previewUrl() {
if (this.isPreview) {
return $A.apiUrl("../fileview/onlinePreview?url=" + encodeURIComponent(this.contentDetail.url))
} else {
return '';
}
},
},
methods: {
handleMessage (event) {
const data = event.data;
switch (data.act) {
case 'ready':
this.loadPreview = false;
break
}
},
getContent() {
if (['word', 'excel', 'ppt'].includes(this.file.type)) {
this.contentDetail = $A.cloneJSON(this.file);
return;
}
this.loadContent++;
this.$store.dispatch("call", {
url: 'file/content',
data: {
id: this.code || this.file.id,
},
}).then(({data}) => {
this.loadContent--;
this.contentDetail = data.content;
}).catch(({msg}) => {
$A.modalError(msg);
this.loadContent--;
})
},
documentKey() {
return new Promise(resolve => {
this.$store.dispatch("call", {
url: 'file/content',
data: {
id: this.code || this.file.id,
only_update_at: 'yes'
},
}).then(({data}) => {
resolve($A.Date(data.update_at, true))
}).catch(() => {
resolve(0)
});
})
},
exportMenu(act) {
switch (this.file.type) {
case 'mind':
this.$refs.myMind.exportHandle(act == 'pdf' ? 1 : 0, this.file.name);
break;
}
},
formatName(file) {
let {name, ext} = file;
if (ext != '') {
name += "." + ext;
}
return name;
},
}
}
</script>