mirror of
https://github.com/kuaifan/dootask.git
synced 2026-03-27 07:40:51 +00:00
整理iframe事件
This commit is contained in:
parent
cae7184a7e
commit
e7cb48f0b1
@ -70,8 +70,7 @@ class FileContent extends AbstractModel
|
|||||||
'fullfilename' => $fullFileName
|
'fullfilename' => $fullFileName
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
$previewType = $fileSize < 10 * 1024 * 1024 ? 'pdf' : 'image'; // 10M以下使用pdf预览模式
|
return Base::fillUrl("fileview/onlinePreview?url=" . urlencode(base64_encode($url)));
|
||||||
return Base::fillUrl("fileview/onlinePreview?url=" . urlencode(base64_encode($url)) . "&officePreviewType=" . $previewType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -102,7 +102,7 @@ services:
|
|||||||
|
|
||||||
fileview:
|
fileview:
|
||||||
container_name: "dootask-fileview-${APP_ID}"
|
container_name: "dootask-fileview-${APP_ID}"
|
||||||
image: "kuaifan/fileview:4.1.0-SNAPSHOT-RC5"
|
image: "kuaifan/fileview:4.1.0-SNAPSHOT-RC9"
|
||||||
environment:
|
environment:
|
||||||
TZ: "Asia/Shanghai"
|
TZ: "Asia/Shanghai"
|
||||||
KK_CONTEXT_PATH: "/fileview"
|
KK_CONTEXT_PATH: "/fileview"
|
||||||
|
|||||||
4
docker/office/resources/api/documents/api.js
vendored
4
docker/office/resources/api/documents/api.js
vendored
@ -11,10 +11,10 @@
|
|||||||
window.localStorage.removeItem('ui-theme-id')
|
window.localStorage.removeItem('ui-theme-id')
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
//
|
//
|
||||||
window._toolbarClick = function(el, type) {
|
window._toolbarClick = function(el, action) {
|
||||||
window.parent.postMessage({
|
window.parent.postMessage({
|
||||||
source: 'onlyoffice',
|
source: 'onlyoffice',
|
||||||
act: type,
|
action: action,
|
||||||
rect: el.getBoundingClientRect()
|
rect: el.getBoundingClientRect()
|
||||||
}, "*");
|
}, "*");
|
||||||
};
|
};
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -6,5 +6,5 @@
|
|||||||
/*# sourceMappingURL=app.css.map */
|
/*# sourceMappingURL=app.css.map */
|
||||||
|
|
||||||
|
|
||||||
body{margin-top:-26px;height:calc(100% + 26px)}
|
body .navbar.main-navbar.navbar-with-logo{height:0px}
|
||||||
body .settings-popup{margin-top:26px;height:calc(100% - 26px}
|
body .page.page-with-subnavbar.page-with-logo .page-content{--f7-page-subnavbar-offset:0px}
|
||||||
|
|||||||
@ -7,5 +7,5 @@
|
|||||||
/*# sourceMappingURL=app.css.map */
|
/*# sourceMappingURL=app.css.map */
|
||||||
|
|
||||||
|
|
||||||
body{margin-top:-26px;height:calc(100% + 26px)}
|
body .navbar.main-navbar.navbar-with-logo{height:0px}
|
||||||
body .settings-popup{margin-top:26px;height:calc(100% - 26px}
|
body .page.page-with-subnavbar.page-with-logo .page-content{--f7-page-subnavbar-offset:0px}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="drawio-content">
|
<div class="drawio-content">
|
||||||
<iframe ref="myFlow" class="drawio-iframe" :src="url"></iframe>
|
<IFrame ref="frame" class="drawio-iframe" :src="url" @on-message="onMessage"/>
|
||||||
<div v-if="loadIng" class="drawio-loading"><Loading/></div>
|
<div v-if="loadIng" class="drawio-loading"><Loading/></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -36,9 +36,11 @@
|
|||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
import {mapState} from "vuex";
|
import {mapState} from "vuex";
|
||||||
|
import IFrame from "../pages/manage/components/IFrame";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Drawio",
|
name: "Drawio",
|
||||||
|
components: {IFrame},
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@ -109,20 +111,15 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
updateContent() {
|
updateContent() {
|
||||||
this.$refs.myFlow.contentWindow.postMessage(JSON.stringify({
|
this.$refs.frame.postMessage(JSON.stringify({
|
||||||
action: "load",
|
action: "load",
|
||||||
autosave: 1,
|
autosave: 1,
|
||||||
xml: this.value.xml,
|
xml: this.value.xml,
|
||||||
}), "*");
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
handleMessage(event) {
|
onMessage(data) {
|
||||||
const editWindow = this.$refs.myFlow.contentWindow;
|
switch (data.event) {
|
||||||
if (event.source !== editWindow) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const payload = $A.jsonParse(event.data);
|
|
||||||
switch (payload.event) {
|
|
||||||
case "init":
|
case "init":
|
||||||
this.loadIng = false;
|
this.loadIng = false;
|
||||||
this.updateContent();
|
this.updateContent();
|
||||||
@ -130,15 +127,15 @@ export default {
|
|||||||
|
|
||||||
case "load":
|
case "load":
|
||||||
if (typeof this.value.xml === "undefined") {
|
if (typeof this.value.xml === "undefined") {
|
||||||
editWindow.postMessage(JSON.stringify({
|
this.$refs.frame.postMessage(JSON.stringify({
|
||||||
action: "template"
|
action: "template"
|
||||||
}), "*");
|
}));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "autosave":
|
case "autosave":
|
||||||
const content = {
|
const content = {
|
||||||
xml: payload.xml,
|
xml: data.xml,
|
||||||
}
|
}
|
||||||
this.bakData = $A.jsonStringify(content);
|
this.bakData = $A.jsonStringify(content);
|
||||||
this.$emit('input', content);
|
this.$emit('input', content);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="component-only-office">
|
<div class="component-only-office">
|
||||||
<iframe v-if="isPreviewAndMobile" ref="myPreview" class="preview-iframe" :src="mobilePreviewUrl"></iframe>
|
<IFrame v-if="isPreviewAndMobile" class="preview-iframe" :src="mobilePreviewUrl" @on-message="onMessage"/>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<Alert v-if="loadError" class="load-error" type="error" show-icon>{{$L('组件加载失败!')}}</Alert>
|
<Alert v-if="loadError" class="load-error" type="error" show-icon>{{$L('组件加载失败!')}}</Alert>
|
||||||
<div :id="id" class="placeholder"></div>
|
<div :id="id" class="placeholder"></div>
|
||||||
@ -62,9 +62,11 @@
|
|||||||
<script>
|
<script>
|
||||||
|
|
||||||
import {mapState} from "vuex";
|
import {mapState} from "vuex";
|
||||||
|
import IFrame from "../pages/manage/components/IFrame";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "OnlyOffice",
|
name: "OnlyOffice",
|
||||||
|
components: {IFrame},
|
||||||
props: {
|
props: {
|
||||||
id: {
|
id: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -106,7 +108,6 @@ export default {
|
|||||||
if (this.isPreviewAndMobile) {
|
if (this.isPreviewAndMobile) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
}
|
}
|
||||||
window.addEventListener('message', this.handleMessage)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@ -115,7 +116,6 @@ export default {
|
|||||||
this.docEditor.destroyEditor();
|
this.docEditor.destroyEditor();
|
||||||
this.docEditor = null;
|
this.docEditor = null;
|
||||||
}
|
}
|
||||||
window.removeEventListener('message', this.handleMessage)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
@ -181,9 +181,8 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
handleMessage(event) {
|
onMessage(data) {
|
||||||
const data = event.data;
|
switch (data.action) {
|
||||||
switch (data.act) {
|
|
||||||
case 'ready':
|
case 'ready':
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
break
|
break
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="ready" class="file-content">
|
<div v-if="ready" class="file-content">
|
||||||
<iframe v-if="isPreview" ref="myPreview" class="preview-iframe" :src="previewUrl"></iframe>
|
<IFrame v-if="isPreview" class="preview-iframe" :src="previewUrl" @on-message="onMessage"/>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<EPopover
|
<EPopover
|
||||||
v-if="['word', 'excel', 'ppt'].includes(file.type)"
|
v-if="['word', 'excel', 'ppt'].includes(file.type)"
|
||||||
@ -115,6 +115,7 @@ import Vue from 'vue'
|
|||||||
import Minder from '../../../components/Minder'
|
import Minder from '../../../components/Minder'
|
||||||
import {mapState} from "vuex";
|
import {mapState} from "vuex";
|
||||||
import FileHistory from "./FileHistory";
|
import FileHistory from "./FileHistory";
|
||||||
|
import IFrame from "./IFrame";
|
||||||
Vue.use(Minder)
|
Vue.use(Minder)
|
||||||
|
|
||||||
const MDEditor = () => import('../../../components/MDEditor/index');
|
const MDEditor = () => import('../../../components/MDEditor/index');
|
||||||
@ -125,7 +126,7 @@ const Drawio = () => import('../../../components/Drawio');
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "FileContent",
|
name: "FileContent",
|
||||||
components: {FileHistory, AceEditor, TEditor, MDEditor, OnlyOffice, Drawio},
|
components: {IFrame, FileHistory, AceEditor, TEditor, MDEditor, OnlyOffice, Drawio},
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@ -167,7 +168,7 @@ export default {
|
|||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
document.addEventListener('keydown', this.keySave)
|
document.addEventListener('keydown', this.keySave)
|
||||||
window.addEventListener('message', this.handleMessage)
|
window.addEventListener('message', this.handleOfficeMessage)
|
||||||
//
|
//
|
||||||
if (this.$isSubElectron) {
|
if (this.$isSubElectron) {
|
||||||
window.__onBeforeUnload = () => {
|
window.__onBeforeUnload = () => {
|
||||||
@ -188,7 +189,7 @@ export default {
|
|||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
document.removeEventListener('keydown', this.keySave)
|
document.removeEventListener('keydown', this.keySave)
|
||||||
window.removeEventListener('message', this.handleMessage)
|
window.removeEventListener('message', this.handleOfficeMessage)
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
@ -277,8 +278,7 @@ export default {
|
|||||||
|
|
||||||
previewUrl() {
|
previewUrl() {
|
||||||
if (this.isPreview) {
|
if (this.isPreview) {
|
||||||
const previewType = this.file.size < 10 * 1024 * 1024 ? 'pdf' : 'image'; // 10M以下使用pdf预览模式
|
return $A.apiUrl("../fileview/onlinePreview?url=" + encodeURIComponent(this.contentDetail.url))
|
||||||
return $A.apiUrl(`../fileview/onlinePreview?url=${encodeURIComponent(this.contentDetail.url)}&officePreviewType=${previewType}`)
|
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@ -286,10 +286,9 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
handleMessage (event) {
|
handleOfficeMessage({data}) {
|
||||||
const data = event.data;
|
|
||||||
if (data.source === 'onlyoffice') {
|
if (data.source === 'onlyoffice') {
|
||||||
switch (data.act) {
|
switch (data.action) {
|
||||||
case 'link':
|
case 'link':
|
||||||
this.handleClick('link')
|
this.handleClick('link')
|
||||||
break;
|
break;
|
||||||
@ -304,9 +303,11 @@ export default {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
switch (data.act) {
|
},
|
||||||
|
|
||||||
|
onMessage(data) {
|
||||||
|
switch (data.action) {
|
||||||
case 'ready':
|
case 'ready':
|
||||||
this.loadPreview = false;
|
this.loadPreview = false;
|
||||||
break
|
break
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="file-preview">
|
<div class="file-preview">
|
||||||
<iframe v-if="isPreview" ref="myPreview" class="preview-iframe" :src="previewUrl"></iframe>
|
<IFrame v-if="isPreview" class="preview-iframe" :src="previewUrl" @on-message="onMessage"/>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div v-show="!['word', 'excel', 'ppt'].includes(file.type)" class="edit-header">
|
<div v-show="!['word', 'excel', 'ppt'].includes(file.type)" class="edit-header">
|
||||||
<div class="header-title">
|
<div class="header-title">
|
||||||
@ -11,10 +11,11 @@
|
|||||||
<Icon v-else type="ios-refresh" @click="getContent" />
|
<Icon v-else type="ios-refresh" @click="getContent" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Dropdown v-if="file.type=='mind'"
|
<Dropdown
|
||||||
trigger="click"
|
v-if="file.type=='mind'"
|
||||||
class="header-hint"
|
trigger="click"
|
||||||
@on-click="exportMenu">
|
class="header-hint"
|
||||||
|
@on-click="exportMenu">
|
||||||
<a href="javascript:void(0)">{{$L('导出')}}<Icon type="ios-arrow-down"></Icon></a>
|
<a href="javascript:void(0)">{{$L('导出')}}<Icon type="ios-arrow-down"></Icon></a>
|
||||||
<DropdownMenu slot="list">
|
<DropdownMenu slot="list">
|
||||||
<DropdownItem name="png">{{$L('导出PNG图片')}}</DropdownItem>
|
<DropdownItem name="png">{{$L('导出PNG图片')}}</DropdownItem>
|
||||||
@ -40,6 +41,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Minder from '../../../components/Minder'
|
import Minder from '../../../components/Minder'
|
||||||
|
import IFrame from "./IFrame";
|
||||||
Vue.use(Minder)
|
Vue.use(Minder)
|
||||||
|
|
||||||
const MDPreview = () => import('../../../components/MDEditor/preview');
|
const MDPreview = () => import('../../../components/MDEditor/preview');
|
||||||
@ -50,7 +52,7 @@ const Drawio = () => import('../../../components/Drawio');
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "FilePreview",
|
name: "FilePreview",
|
||||||
components: {AceEditor, TEditor, MDPreview, OnlyOffice, Drawio},
|
components: {IFrame, AceEditor, TEditor, MDPreview, OnlyOffice, Drawio},
|
||||||
props: {
|
props: {
|
||||||
code: {
|
code: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -76,13 +78,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
|
||||||
window.addEventListener('message', this.handleMessage)
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
window.removeEventListener('message', this.handleMessage)
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
'file.id': {
|
'file.id': {
|
||||||
handler(id) {
|
handler(id) {
|
||||||
@ -111,8 +106,7 @@ export default {
|
|||||||
|
|
||||||
previewUrl() {
|
previewUrl() {
|
||||||
if (this.isPreview) {
|
if (this.isPreview) {
|
||||||
const previewType = this.file.size < 10 * 1024 * 1024 ? 'pdf' : 'image'; // 10M以下使用pdf预览模式
|
return $A.apiUrl("../fileview/onlinePreview?url=" + encodeURIComponent(this.contentDetail.url))
|
||||||
return $A.apiUrl(`../fileview/onlinePreview?url=${encodeURIComponent(this.contentDetail.url)}&officePreviewType=${previewType}`)
|
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@ -120,9 +114,8 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
handleMessage (event) {
|
onMessage(data) {
|
||||||
const data = event.data;
|
switch (data.action) {
|
||||||
switch (data.act) {
|
|
||||||
case 'ready':
|
case 'ready':
|
||||||
this.loadPreview = false;
|
this.loadPreview = false;
|
||||||
break
|
break
|
||||||
|
|||||||
43
resources/assets/js/pages/manage/components/IFrame.vue
Normal file
43
resources/assets/js/pages/manage/components/IFrame.vue
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<template>
|
||||||
|
<iframe v-if="src" ref="iframe" :src="src"></iframe>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "IFrame",
|
||||||
|
props: {
|
||||||
|
src: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
window.addEventListener('message', this.handleMessage)
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('message', this.handleMessage)
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
handleMessage({data, source}) {
|
||||||
|
if (source !== this.$refs.iframe?.contentWindow) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
data = $A.jsonParse(data);
|
||||||
|
if (data.source === 'fileView' && data.action === 'picture') {
|
||||||
|
this.$store.state.previewImageIndex = data.params.index;
|
||||||
|
this.$store.state.previewImageList = data.params.array;
|
||||||
|
}
|
||||||
|
this.$emit("on-message", data)
|
||||||
|
},
|
||||||
|
|
||||||
|
postMessage(message, targetOrigin = "*") {
|
||||||
|
if (this.$refs.iframe) {
|
||||||
|
this.$refs.iframe.contentWindow.postMessage(message, targetOrigin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -134,8 +134,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
previewUrl() {
|
previewUrl() {
|
||||||
const previewType = this.msgDetail.msg.size < 10 * 1024 * 1024 ? 'pdf' : 'image'; // 10M以下使用pdf预览模式
|
return $A.apiUrl("../fileview/onlinePreview?url=" + encodeURIComponent(this.msgDetail.content.url))
|
||||||
return $A.apiUrl(`../fileview/onlinePreview?url=${encodeURIComponent(this.msgDetail.content.url)}&officePreviewType=${previewType}`)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
@ -121,8 +121,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
previewUrl() {
|
previewUrl() {
|
||||||
const previewType = this.fileDetail.size < 10 * 1024 * 1024 ? 'pdf' : 'image'; // 10M以下使用pdf预览模式
|
return $A.apiUrl("../fileview/onlinePreview?url=" + encodeURIComponent(this.fileDetail.content.url))
|
||||||
return $A.apiUrl(`../fileview/onlinePreview?url=${encodeURIComponent(this.fileDetail.content.url)}&officePreviewType=${previewType}`)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user