mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-12 03:01:12 +00:00
279 lines
7.9 KiB
Vue
279 lines
7.9 KiB
Vue
<template>
|
|
<div class="component-only-office">
|
|
<template v-if="$A.isDesktop()">
|
|
<Alert v-if="loadError" class="load-error" type="error" show-icon>{{$L('组件加载失败!')}}</Alert>
|
|
<div :id="id" class="placeholder"></div>
|
|
</template>
|
|
<IFrame v-else class="preview-iframe" :src="previewUrl" @on-load="onFrameLoad"/>
|
|
<div v-if="loading" class="office-loading"><Loading/></div>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
.component-only-office {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
|
|
.placeholder {
|
|
flex: 1;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.office-loading {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
z-index: 2;
|
|
}
|
|
}
|
|
</style>
|
|
<style lang="scss">
|
|
.component-only-office {
|
|
.load-error {
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
z-index: 1;
|
|
padding: 8px;
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
.ivu-alert-icon {
|
|
position: static;
|
|
margin-right: 8px;
|
|
margin-left: 4px;
|
|
}
|
|
}
|
|
}
|
|
</style>
|
|
<script>
|
|
// 只有桌面端才使用 OnlyOffice
|
|
|
|
import {mapState} from "vuex";
|
|
import IFrame from "../pages/manage/components/IFrame";
|
|
import {languageType} from "../language";
|
|
|
|
export default {
|
|
name: "OnlyOffice",
|
|
components: {IFrame},
|
|
props: {
|
|
id: {
|
|
type: String,
|
|
default: () => {
|
|
return "office_" + Math.round(Math.random() * 10000);
|
|
}
|
|
},
|
|
code: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
historyId: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
value: {
|
|
type: [Object, Array],
|
|
default: function () {
|
|
return {}
|
|
}
|
|
},
|
|
readOnly: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
documentKey: Function
|
|
},
|
|
|
|
data() {
|
|
return {
|
|
loading: false,
|
|
loadError: false,
|
|
|
|
docEditor: null,
|
|
}
|
|
},
|
|
|
|
beforeDestroy() {
|
|
if (this.docEditor !== null) {
|
|
this.docEditor.destroyEditor();
|
|
this.docEditor = null;
|
|
}
|
|
},
|
|
|
|
computed: {
|
|
...mapState(['userInfo', 'themeIsDark']),
|
|
|
|
fileType() {
|
|
return this.getType(this.value.type);
|
|
},
|
|
|
|
fileName() {
|
|
return this.value.name;
|
|
},
|
|
|
|
fileUrl() {
|
|
let codeId = this.code || this.value.id;
|
|
let fileUrl
|
|
if ($A.leftExists(codeId, "msgFile_")) {
|
|
fileUrl = `dialog/msg/download/?msg_id=${$A.leftDelete(codeId, "msgFile_")}&token=${this.userToken}`;
|
|
} else if ($A.leftExists(codeId, "taskFile_")) {
|
|
fileUrl = `project/task/filedown/?file_id=${$A.leftDelete(codeId, "taskFile_")}&token=${this.userToken}`;
|
|
} else {
|
|
fileUrl = `file/content/?id=${codeId}&token=${this.userToken}`;
|
|
if (this.historyId > 0) {
|
|
fileUrl += `&history_id=${this.historyId}`
|
|
}
|
|
}
|
|
return fileUrl;
|
|
},
|
|
|
|
previewUrl() {
|
|
return $A.apiUrl(this.fileUrl) + "&down=preview"
|
|
}
|
|
},
|
|
|
|
watch: {
|
|
'value.id': {
|
|
handler(id) {
|
|
if (!id) {
|
|
return;
|
|
}
|
|
if (!$A.isDesktop()) {
|
|
return;
|
|
}
|
|
this.loading = true;
|
|
this.loadError = false;
|
|
$A.loadScript($A.apiUrl("../office/web-apps/apps/api/documents/api.js")).then(_ => {
|
|
if (!this.documentKey) {
|
|
this.handleClose();
|
|
return
|
|
}
|
|
const documentKey = this.documentKey();
|
|
if (documentKey && documentKey.then) {
|
|
documentKey.then(this.loadFile);
|
|
} else {
|
|
this.loadFile();
|
|
}
|
|
}).catch(_ => {
|
|
this.loadError = true
|
|
}).finally(_ => {
|
|
this.loading = false
|
|
})
|
|
},
|
|
immediate: true,
|
|
},
|
|
|
|
previewUrl: {
|
|
handler() {
|
|
if (!$A.isDesktop()) {
|
|
this.loading = true;
|
|
}
|
|
},
|
|
immediate: true
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
onFrameLoad() {
|
|
this.loading = false;
|
|
},
|
|
|
|
getType(type) {
|
|
switch (type) {
|
|
case 'word':
|
|
return 'docx';
|
|
case 'excel':
|
|
return 'xlsx';
|
|
case 'ppt':
|
|
return 'pptx'
|
|
}
|
|
return type;
|
|
},
|
|
|
|
loadFile(keyAppend = '') {
|
|
if (this.docEditor !== null) {
|
|
this.docEditor.destroyEditor();
|
|
this.docEditor = null;
|
|
}
|
|
//
|
|
let lang = languageType;
|
|
switch (languageType) {
|
|
case 'zh-CHT':
|
|
lang = "zh-TW";
|
|
break;
|
|
}
|
|
//
|
|
let codeId = this.code || this.value.id;
|
|
let fileName = $A.strExists(this.fileName, '.') ? this.fileName : (this.fileName + '.' + this.fileType);
|
|
let fileKey = `${this.fileType}-${keyAppend||codeId}`;
|
|
if (this.historyId > 0) {
|
|
fileKey += `-${this.historyId}`
|
|
}
|
|
const config = {
|
|
"document": {
|
|
"fileType": this.fileType,
|
|
"title": fileName,
|
|
"key": fileKey,
|
|
"url": `http://nginx/api/${this.fileUrl}`,
|
|
},
|
|
"editorConfig": {
|
|
"mode": "edit",
|
|
"lang": lang,
|
|
"user": {
|
|
"id": String(this.userInfo.userid),
|
|
"name": this.userInfo.nickname
|
|
},
|
|
"customization": {
|
|
"uiTheme": this.themeIsDark ? "theme-dark" : "theme-classic-light",
|
|
"forcesave": true,
|
|
"help": false,
|
|
},
|
|
"callbackUrl": `http://nginx/api/file/content/office?id=${codeId}&token=${this.userToken}`,
|
|
},
|
|
"events": {
|
|
"onDocumentReady": this.onDocumentReady,
|
|
},
|
|
};
|
|
if (/\/hideenOfficeTitle\//.test(window.navigator.userAgent)) {
|
|
config.document.title = " ";
|
|
}
|
|
(async _ => {
|
|
if (this.readOnly || this.historyId > 0) {
|
|
config.editorConfig.mode = "view";
|
|
config.editorConfig.callbackUrl = null;
|
|
if (!config.editorConfig.user.id) {
|
|
let officeViewer = await $A.IDBInt("officeViewer")
|
|
if (!officeViewer) {
|
|
officeViewer = $A.randNum(1000, 99999);
|
|
await $A.IDBSet("officeViewer", officeViewer)
|
|
}
|
|
config.editorConfig.user.id = "viewer_" + officeViewer;
|
|
config.editorConfig.user.name = "Viewer_" + officeViewer
|
|
}
|
|
}
|
|
this.$nextTick(() => {
|
|
this.docEditor = new DocsAPI.DocEditor(this.id, config);
|
|
})
|
|
})()
|
|
},
|
|
|
|
onDocumentReady() {
|
|
this.$emit("on-document-ready", this.docEditor)
|
|
}
|
|
}
|
|
}
|
|
</script>
|