瀏覽代碼

perf(base-卡1): OnlyOffice api.js 改按需加载——index.html 移除首屏注入,新增 loadDocsApi 单例,3 个 DocEditor 弹窗 await 后初始化并带 loading/失败提示

86132 1 周之前
父節點
當前提交
0e54a39eb6

+ 1 - 6
index.html

@@ -13,7 +13,7 @@
     <script defer src="/js/liveplayer-lib.min.js"></script>
     <script src="/js/libs/adapter.min.js"></script>
     <script src="/js/webrtcstreamer.js"></script>
-    <!-- <script type="text/javascript" src="http://182.92.126.35:9050/web-apps/apps/api/documents/api.js"></script> -->
+    <!-- [perf-base-v1] 卡1: OnlyOffice api.js 改为打开文档编辑器时按需加载(见 src/utils/onlyOffice.ts),此处不再静态/动态注入 -->
   </head>
   <body>
     <script>
@@ -24,11 +24,6 @@
           htmlRoot.setAttribute('data-theme', theme);
           theme = htmlRoot = null;
         }
-        const remoteUrl = window.location.hostname === 'localhost' ? '182.92.126.35' : window.location.hostname;
-        var script = document.createElement('script');
-        script.type = 'text/javascript';
-        script.src = 'http://' + remoteUrl + ':9050/web-apps/apps/api/documents/api.js';
-        document.head.appendChild(script);
       })();
     </script>
     <div id="app">

+ 2 - 1
public/js/config.js

@@ -1,7 +1,8 @@
 const VUE_APP_URL = {
   baseUrl: "/modelreq", // 后台地址
   webRtcUrl: '/webRtc', // rtsp服务器IP地址
-  wsUrl: 'http://182.92.126.35:9999' // WebSocket 地址
+  wsUrl: 'http://182.92.126.35:9999', // WebSocket 地址
+  onlyOfficeUrl: '/documents' // [perf-base-v1] 卡1: OnlyOffice Document Server 反向代理前缀(api.js 按需加载时拼接)
 }
 const History_Type = {
   // type: 'remote', // remote、vent  (remote 代表的是历史查询走的装备院的接口,vent是走的咱们的,目前神东的项目都用remote, 其他矿用vent)

+ 35 - 0
src/utils/onlyOffice.ts

@@ -0,0 +1,35 @@
+// [perf-base-v1] 卡1: OnlyOffice DocsAPI 按需加载单例
+// 原实现:index.html 首屏即动态注入 http://<host>:9050/web-apps/apps/api/documents/api.js
+// (阻塞首屏、硬编码端口)。现实现:首次打开文档编辑器弹窗时才插入 <script>,
+// 后续调用复用同一 Promise;地址由 public/js/config.js 的 VUE_APP_URL.onlyOfficeUrl 配置。
+
+let docsApiPromise: Promise<void> | null = null;
+
+/**
+ * 加载 OnlyOffice Documents API(web-apps/apps/api/documents/api.js)
+ * - 已加载(全局 DocsAPI 存在)直接 resolve
+ * - 并发调用共享同一 Promise
+ * - 加载失败后重置缓存,允许下次重试
+ */
+export function loadDocsApi(): Promise<void> {
+  if (typeof (window as any).DocsAPI !== 'undefined') {
+    return Promise.resolve();
+  }
+  if (docsApiPromise) return docsApiPromise;
+
+  const base = (typeof VUE_APP_URL !== 'undefined' && VUE_APP_URL.onlyOfficeUrl) || '/documents';
+  const src = `${base}/web-apps/apps/api/documents/api.js`;
+
+  docsApiPromise = new Promise<void>((resolve, reject) => {
+    const script = document.createElement('script');
+    script.type = 'text/javascript';
+    script.src = src;
+    script.onload = () => resolve();
+    script.onerror = () => {
+      docsApiPromise = null; // [perf-base-v1] 失败后允许重试
+      reject(new Error(`OnlyOffice api.js 加载失败: ${src}`));
+    };
+    document.head.appendChild(script);
+  });
+  return docsApiPromise;
+}

+ 15 - 1
src/views/vent/monitorManager/comment/components/reportInfo.vue

@@ -17,8 +17,11 @@
 
 <script lang="ts" setup>
   import { computed, unref, inject, reactive, ref, watch } from 'vue';
+  import { message } from 'ant-design-vue';
   import { BasicModal, useModalInner } from '/@/components/Modal';
   import { useUserStore } from '/@/store/modules/user';
+  // [perf-base-v1] 卡1: OnlyOffice api.js 改为打开编辑器时按需加载
+  import { loadDocsApi } from '/@/utils/onlyOffice';
 
   let props = defineProps({
     editID: {
@@ -49,8 +52,19 @@
 
   watch(
     () => props.editID,
-    (newV, oldV) => {
+    async (newV, oldV) => {
       console.log(newV, 'newV----------');
+      // [perf-base-v1] 卡1: 先按需加载 OnlyOffice api.js,成功后再初始化编辑器
+      setModalProps({ loading: true, loadingTip: '文档编辑器加载中...' });
+      try {
+        await loadDocsApi();
+      } catch (e) {
+        console.error(e);
+        message.error('文档编辑器加载失败,请检查 OnlyOffice 服务后重试');
+        return;
+      } finally {
+        setModalProps({ loading: false });
+      }
       new DocsAPI.DocEditor(
         'fileEdit', // 元素id
         {

+ 14 - 0
src/views/vent/performance/comment/DeviceModal.vue

@@ -15,9 +15,12 @@
 </template>
 <script lang="ts" setup>
   import { unref, reactive } from 'vue';
+  import { message } from 'ant-design-vue';
   import { BasicModal, useModalInner } from '/@/components/Modal';
   import { onMounted } from 'vue';
   import { useUserStore } from '/@/store/modules/user';
+  // [perf-base-v1] 卡1: OnlyOffice api.js 改为打开编辑器时按需加载
+  import { loadDocsApi } from '/@/utils/onlyOffice';
 
   let props = defineProps({
     fileType: {
@@ -44,6 +47,17 @@
     setModalProps({ confirmLoading: false });
     Object.assign(record, data.record);
 
+    // [perf-base-v1] 卡1: 先按需加载 OnlyOffice api.js,成功后再初始化编辑器
+    setModalProps({ loading: true, loadingTip: '文档编辑器加载中...' });
+    try {
+      await loadDocsApi();
+    } catch (e) {
+      console.error(e);
+      message.error('文档编辑器加载失败,请检查 OnlyOffice 服务后重试');
+      return;
+    } finally {
+      setModalProps({ loading: false });
+    }
     new DocsAPI.DocEditor(
       'fileEdit', // 元素id
       {

+ 14 - 0
src/views/vent/reportManager/comment/DeviceModal.vue

@@ -89,12 +89,15 @@
 </template>
 <script lang="ts" setup>
   import { computed, unref, inject, reactive, ref, watch, onMounted } from 'vue';
+  import { message } from 'ant-design-vue';
   import NormalHisTable from '../comment/NormalHisTable.vue';
   import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
   import { BasicModal, useModalInner } from '/@/components/Modal';
   import { useUserStore } from '/@/store/modules/user';
   import { reportList, hisList, hisdownload } from '../reportManager.api';
   import { columnsHis } from '../reportManager.data';
+  // [perf-base-v1] 卡1: OnlyOffice api.js 改为打开编辑器时按需加载
+  import { loadDocsApi } from '/@/utils/onlyOffice';
 
   let props = defineProps({
     addOredit: {
@@ -172,6 +175,17 @@
     //重置表单
     setModalProps({ confirmLoading: false });
     // Object.assign(deviceData, data.record);
+    // [perf-base-v1] 卡1: 先按需加载 OnlyOffice api.js,成功后再初始化编辑器
+    setModalProps({ loading: true, loadingTip: '文档编辑器加载中...' });
+    try {
+      await loadDocsApi();
+    } catch (e) {
+      console.error(e);
+      message.error('文档编辑器加载失败,请检查 OnlyOffice 服务后重试');
+      return;
+    } finally {
+      setModalProps({ loading: false });
+    }
     new DocsAPI.DocEditor(
       'fileEdit', // 元素id
       {

+ 13 - 0
types/global.d.ts

@@ -1,6 +1,19 @@
 import type { ComponentRenderProxy, VNode, VNodeChild, ComponentPublicInstance, FunctionalComponent, PropType as VuePropType } from 'vue';
 
 declare global {
+  // [perf-base-v1] 卡1/卡7: public/js/config.js 注入的全局配置(经典脚本顶层 const,为全局词法绑定,不在 window 上)
+  const VUE_APP_URL: {
+    baseUrl: string; // 后台地址
+    webRtcUrl: string; // rtsp 服务器地址前缀
+    wsUrl: string; // WebSocket 地址
+    onlyOfficeUrl?: string; // OnlyOffice Document Server 反向代理前缀
+  };
+
+  // [perf-base-v1] 卡1: OnlyOffice Documents API 全局(由 src/utils/onlyOffice.ts loadDocsApi 按需注入)
+  const DocsAPI: {
+    DocEditor: new (placeholderId: string, config?: Recordable<any>) => any;
+  };
+
   const VENT_PARAM: {
     simulatedPassword: string;
     showReport: boolean;