| | |
| | | <!--onlyoffice 编辑器--> |
| | | <template> |
| | | <div id="vabOnlyOffice"></div> |
| | | <div class="document-preview"> |
| | | <iframe |
| | | v-if="isPdf" |
| | | :key="option.url" |
| | | :src="option.url" |
| | | class="native-pdf-preview" |
| | | title="PDF预览" |
| | | ></iframe> |
| | | <div v-else id="vabOnlyOffice"></div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | // OnlyOffice 文档服务地址,按环境配置;脚本在真正需要预览时才加载 |
| | | const OFFICE_API_BASE = process.env.VUE_APP_ONLYOFFICE_API || "http://192.168.21.53:9001"; |
| | | |
| | | // 多个页面共用编辑器,api.js 只加载一次 |
| | | let docsApiPromise = null; |
| | | function loadDocsApi() { |
| | | if (window.DocsAPI) { |
| | | return Promise.resolve(window.DocsAPI); |
| | | } |
| | | if (!docsApiPromise) { |
| | | docsApiPromise = new Promise((resolve, reject) => { |
| | | const script = document.createElement("script"); |
| | | script.src = OFFICE_API_BASE.replace(/\/$/, "") + "/web-apps/apps/api/documents/api.js"; |
| | | script.onload = () => { |
| | | if (window.DocsAPI) { |
| | | resolve(window.DocsAPI); |
| | | } else { |
| | | reject(new Error("api.js 加载完成但未注册 DocsAPI")); |
| | | } |
| | | }; |
| | | script.onerror = () => reject(new Error("OnlyOffice 文档服务脚本加载失败:" + script.src)); |
| | | document.head.appendChild(script); |
| | | }); |
| | | // 加载失败后允许下次重试 |
| | | docsApiPromise.catch(() => { |
| | | docsApiPromise = null; |
| | | }); |
| | | } |
| | | return docsApiPromise; |
| | | } |
| | | |
| | | export default { |
| | | name: "VabOnlyOffice", |
| | | props: ['options'], |
| | |
| | | editUrl: "" |
| | | } |
| | | }; |
| | | }, |
| | | computed: { |
| | | isPdf() { |
| | | return this.isPdfFile(this.option); |
| | | } |
| | | }, |
| | | created() { |
| | | if(this.options){ |
| | |
| | | } |
| | | }, |
| | | beforeDestroy() { |
| | | if (this.docEditor !== null) { |
| | | this.docEditor.destroyEditor(); |
| | | this.docEditor = null; |
| | | } |
| | | this.destroyEditor(); |
| | | }, |
| | | watch: { |
| | | option: { |
| | |
| | | } |
| | | }, |
| | | methods: { |
| | | async setEditor(option) { |
| | | destroyEditor() { |
| | | if (this.docEditor !== null) { |
| | | this.docEditor.destroyEditor(); |
| | | this.docEditor = null; |
| | | } |
| | | }, |
| | | async setEditor(option) { |
| | | this.destroyEditor(); |
| | | // PDF 使用浏览器原生预览;其他文档才初始化 OnlyOffice。 |
| | | if (!option || !option.url || this.isPdfFile(option)) { |
| | | return; |
| | | } |
| | | // 等待 v-else 中的 OnlyOffice 容器完成渲染。 |
| | | await this.$nextTick(); |
| | | this.doctype = this.getFileType(option.fileType); |
| | | let config = { |
| | | document: { |
| | |
| | | token: option.token || "" |
| | | }; |
| | | |
| | | // eslint-disable-next-line no-undef,no-unused-vars |
| | | this.docEditor = new DocsAPI.DocEditor("vabOnlyOffice", config); |
| | | try { |
| | | await loadDocsApi(); |
| | | } catch (error) { |
| | | console.error(error); |
| | | this.$message.error("文档服务暂时不可用,无法预览"); |
| | | return; |
| | | } |
| | | if (this._isDestroyed) { |
| | | return; |
| | | } |
| | | this.docEditor = new window.DocsAPI.DocEditor("vabOnlyOffice", config); |
| | | }, |
| | | isPdfFile(option) { |
| | | if (!option) { |
| | | return false; |
| | | } |
| | | const fileType = String(option.fileType || "").toLowerCase(); |
| | | const url = String(option.url || "").split(/[?#]/)[0].toLowerCase(); |
| | | return fileType === "pdf" || url.endsWith(".pdf"); |
| | | }, |
| | | getFileType(fileType) { |
| | | let docType = ""; |
| | |
| | | }; |
| | | </script> |
| | | |
| | | <style> |
| | | <style scoped> |
| | | .document-preview, |
| | | .native-pdf-preview, |
| | | #vabOnlyOffice { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | .native-pdf-preview { |
| | | display: block; |
| | | border: 0; |
| | | } |
| | | html, |
| | | body { |
| | | height: 100%; |