From b871888a4ee32d15adfd52fdfabc44c7c674db0e Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期四, 17 九月 2026 16:36:45 +0800
Subject: [PATCH] 新疆——新聚lims 1.标准维护预览附件问题

---
 .env.staging                                 |    3 +
 .env.development                             |    3 +
 src/views/standard/standardLibrary/index.vue |    8 ++
 vue.config.js                                |    2 
 public/index.html                            |    4 -
 .env.production                              |    3 +
 src/components/Onlyoffice/onlyoffice.vue     |   58 +++++++++++++++++--
 src/components/Preview/filePreview.vue       |   52 +++++++++++++++--
 8 files changed, 113 insertions(+), 20 deletions(-)

diff --git a/.env.development b/.env.development
index 8d38372..8215534 100644
--- a/.env.development
+++ b/.env.development
@@ -10,5 +10,8 @@
 # 鏈湴鐜ip+绔彛
 VUE_APP_BASE_URL = 'http://127.0.0.1:8001/lims'
 
+# OnlyOffice 鏂囨。鏈嶅姟鍦板潃锛堥瑙� pdf 鐢紝娌℃湁 http:// 鍓嶇紑浼氬綋鎴愮浉瀵硅矾寰勶級
+VUE_APP_ONLYOFFICE_API = 'http://192.168.21.53:9001'
+
 # 璺敱鎳掑姞杞�
 VUE_CLI_BABEL_TRANSPILE_MODULES = true
diff --git a/.env.production b/.env.production
index b287d88..30d7bf4 100644
--- a/.env.production
+++ b/.env.production
@@ -9,3 +9,6 @@
 
 # 鐢熶骇鐜ip+绔彛
 VUE_APP_BASE_URL = 'http://192.168.21.53:8001/lims'
+
+# OnlyOffice 鏂囨。鏈嶅姟鍦板潃锛堥瑙� pdf 鐢紝娌℃湁 http:// 鍓嶇紑浼氬綋鎴愮浉瀵硅矾寰勶級
+VUE_APP_ONLYOFFICE_API = 'http://192.168.21.53:9001'
diff --git a/.env.staging b/.env.staging
index b1ee379..0c13d82 100644
--- a/.env.staging
+++ b/.env.staging
@@ -14,5 +14,8 @@
 # 娴嬭瘯鐜ip+绔彛
 VUE_APP_BASE_URL = http://127.0.0.1:8001/lims
 
+# OnlyOffice 鏂囨。鏈嶅姟鍦板潃锛堥瑙� pdf 鐢紝娌℃湁 http:// 鍓嶇紑浼氬綋鎴愮浉瀵硅矾寰勶級
+VUE_APP_ONLYOFFICE_API = 'http://192.168.21.53:9001'
+
 # 杩愯绔彛
 PORT= '80'
diff --git a/public/index.html b/public/index.html
index 79f9cb1..ab1f709 100644
--- a/public/index.html
+++ b/public/index.html
@@ -234,9 +234,5 @@
     <script src="<%= BASE_URL %>luckysheet/plugins/js/plugin.js"></script>
     <script src="<%= BASE_URL %>luckysheet/luckysheet.umd.js"></script>
   </body>
-  <script
-    type="text/javascript"
-    src="http://192.168.21.53:9001/web-apps/apps/api/documents/api.js"
-  ></script>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.min.js"></script>
 </html>
diff --git a/src/components/Onlyoffice/onlyoffice.vue b/src/components/Onlyoffice/onlyoffice.vue
index a903641..1c1e261 100644
--- a/src/components/Onlyoffice/onlyoffice.vue
+++ b/src/components/Onlyoffice/onlyoffice.vue
@@ -4,6 +4,37 @@
 </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'],
@@ -50,10 +81,7 @@
     }
   },
   beforeDestroy() {
-    if (this.docEditor !== null) {
-      this.docEditor.destroyEditor();
-      this.docEditor = null;
-    }
+    this.destroyEditor();
   },
   watch: {
     option: {
@@ -70,10 +98,17 @@
     }
   },
   methods: {
-    async setEditor(option) {
+    destroyEditor() {
       if (this.docEditor !== null) {
         this.docEditor.destroyEditor();
         this.docEditor = null;
+      }
+    },
+    async setEditor(option) {
+      this.destroyEditor();
+      // 娌℃湁鏂囨。鍦板潃灏变笉鍒濆鍖栫紪杈戝櫒锛岄伩鍏嶈闂皻鏈姞杞界殑 DocsAPI
+      if (!option || !option.url) {
+        return;
       }
       this.doctype = this.getFileType(option.fileType);
       let config = {
@@ -116,8 +151,17 @@
         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);
     },
     getFileType(fileType) {
       let docType = "";
diff --git a/src/components/Preview/filePreview.vue b/src/components/Preview/filePreview.vue
index aedb375..5e15828 100644
--- a/src/components/Preview/filePreview.vue
+++ b/src/components/Preview/filePreview.vue
@@ -4,10 +4,10 @@
       <img :src="imgUrl" alt="Image Preview" />
     </div>
     <div v-if="isPdf" style="height: 80vh;">
-<!--      <object :data="fileUrl" type="application/pdf" width="100%" height="750px">-->
-<!--        <p>鎮ㄧ殑娴忚鍣ㄤ笉鏀寔 PDF 棰勮銆�<a :href="fileUrl" style="color: #3a7bfa;" target="_blank">涓嬭浇 PDF 鏂囦欢</a></p>-->
-<!--      </object>-->
-      <onlyoffice ref="onlyoffice" :options="option" style="width: 100%;height: 100%;" />
+      <onlyoffice v-if="useOnlyOffice" ref="onlyoffice" :options="option" style="width: 100%;height: 100%;" />
+      <iframe v-else-if="pdfUrl" :src="pdfUrl" title="PDF 棰勮" style="width: 100%;height: 100%;border: none;"></iframe>
+      <p v-else-if="pdfError">PDF 棰勮澶辫触锛�<a :href="fileUrl" style="color: #3a7bfa;" target="_blank">鐐规涓嬭浇鏌ョ湅</a></p>
+      <p v-else>姝e湪鍔犺浇 PDF鈥�</p>
     </div>
     <div v-if="isDoc">
       <p v-if="!isDocShow">鏂囨。鏃犳硶鐩存帴棰勮锛岃涓嬭浇鏌ョ湅銆�</p>
@@ -53,6 +53,7 @@
 </template>
 
 <script>
+import axios from 'axios'
 import VueOfficeDocx from '@vue-office/docx'
 //寮曞叆鐩稿叧鏍峰紡
 import '@vue-office/docx/lib/index.css'
@@ -92,7 +93,9 @@
         transformData: (workbookData) => { return workbookData }, //灏嗚幏鍙栧埌鐨別xcel鏁版嵁杩涜澶勭悊涔嬪悗涓旀覆鏌撳埌椤甸潰涔嬪墠锛屽彲閫氳繃transformData瀵瑰嵆灏嗘覆鏌撶殑鏁版嵁鍙婃牱寮忚繘琛屼慨鏀癸紝姝ゆ椂姣忎釜鍗曞厓鏍肩殑text鍊煎氨鏄嵆灏嗘覆鏌撳埌椤甸潰涓婄殑鍐呭
       },
       csvList: [],//csv鏂囦欢鏁版嵁
-      imgUrl: ''
+      imgUrl: '',
+      pdfUrl: '',       //pdf鏈湴棰勮鍦板潃
+      pdfError: false,
     }
   },
   computed: {
@@ -134,9 +137,46 @@
     },
     isSupported() {
       return this.isImage || this.isPdf || this.isDoc || this.isZipOrRar || this.isCsv || this.isXls;
-    }
+    },
+    // 璋冪敤鏂逛紶浜� OnlyOffice 鐨勯厤缃墠璧版枃妗f湇鍔★紝鍚﹀垯鐢ㄦ祻瑙堝櫒鍐呯疆闃呰鍣�
+    useOnlyOffice() {
+      return !!(this.option && this.option.url);
+    },
+  },
+  watch: {
+    fileUrl: {
+      handler() {
+        this.loadPdf();
+      },
+      immediate: true,
+    },
+  },
+  beforeDestroy() {
+    this.releasePdfUrl();
   },
   methods: {
+    releasePdfUrl() {
+      if (this.pdfUrl) {
+        URL.revokeObjectURL(this.pdfUrl);
+        this.pdfUrl = "";
+      }
+    },
+    async loadPdf() {
+      this.releasePdfUrl();
+      this.pdfError = false;
+      if (!this.isPdf || this.useOnlyOffice) {
+        return;
+      }
+      try {
+        const { data } = await axios.get(this.fileUrl, { responseType: "blob" });
+        // 鍚庣杩斿洖鐨� Content-Type 涓嶄竴瀹氬甫 application/pdf锛岃繖閲屽己鍒舵寚瀹氾紝
+        // 娴忚鍣ㄦ墠浼氱敤鍐呯疆闃呰鍣ㄦ墦寮�鑰屼笉鏄洿鎺ヤ笅杞�
+        this.pdfUrl = URL.createObjectURL(new Blob([data], { type: "application/pdf" }));
+      } catch (error) {
+        console.error(error);
+        this.pdfError = true;
+      }
+    },
     renderedHandler() {
       console.log("娓叉煋瀹屾垚")
       this.isDocShow = true
diff --git a/src/views/standard/standardLibrary/index.vue b/src/views/standard/standardLibrary/index.vue
index 4bf9c90..a800e11 100644
--- a/src/views/standard/standardLibrary/index.vue
+++ b/src/views/standard/standardLibrary/index.vue
@@ -6,8 +6,12 @@
         <pane size="12">
           <el-col>
             <div class="head-container addButton">
-              <el-input v-model="search" clearable placeholder="杈撳叆鍏抽敭瀛楄繘琛屾悳绱�" size="small" style="margin-bottom: 5px"
+              <el-input v-model="search" clearable placeholder="杈撳叆鍏抽敭瀛楄繘琛屾悳绱�" size="small"
+                        style="margin-bottom: 5px; flex: 1; min-width: 0"
                         suffix-icon="el-icon-search" @keydown.enter.native="searchFilter" @blur="searchFilter" @clear="searchFilter"></el-input>
+              <el-button icon="el-icon-refresh" size="small" title="鍒锋柊"
+                         style="margin-bottom: 5px; margin-left: 8px"
+                         @click="selectStandardTreeList"></el-button>
             </div>
             <div class="head-container">
               <el-tree ref="tree" v-loading="treeLoad" :data="list"
@@ -41,7 +45,7 @@
         <pane size="88">
           <el-card v-if="selected.isLeaf" shadow="never" class="template-binding-card">
             <div slot="header"><span>鍘熷璁板綍妯℃澘</span><el-button v-if="checkPermi(['standard:standardLibrary:upStandardProduct'])" type="primary" size="mini" style="float:right" @click="saveBindings">淇濆瓨缁戝畾</el-button></div>
-            <p v-if="!templateBindings.length" class="binding-tip">璇蜂负褰撳墠鏍囧噯缁戝畾鍘熷璁板綍妯℃澘锛涙ā鏉夸腑椤讳娇鐢ㄢ�滄楠岄」鈥濇爣璁般��</p>
+            <p v-if="!templateBindings.length" class="binding-tip">璇蜂负褰撳墠鏍囧噯缁戝畾鍘熷璁板綍妯℃澘銆�</p>
             <el-table :data="templateBindings" border size="small">
               <el-table-column type="index" label="椤哄簭" width="70" /><el-table-column label="妯℃澘缂栧彿" prop="number" width="180" /><el-table-column label="妯℃澘鍚嶇О" prop="name" /><el-table-column label="妫�娴嬩緷鎹紙妯℃澘澶囨敞锛�" prop="remark" />
               <el-table-column v-if="checkPermi(['standard:standardLibrary:upStandardProduct'])" label="鎿嶄綔" width="150"><template slot-scope="scope"><el-button type="text" :disabled="scope.$index === 0" @click="moveBinding(scope.$index, -1)">涓婄Щ</el-button><el-button type="text" :disabled="scope.$index === templateBindings.length - 1" @click="moveBinding(scope.$index, 1)">涓嬬Щ</el-button><el-button type="text" @click="removeBinding(scope.$index)">绉婚櫎</el-button></template></el-table-column>
diff --git a/vue.config.js b/vue.config.js
index 6d82cf9..e11b2a9 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -37,7 +37,7 @@
       // detail: https://cli.vuejs.org/config/#devserver-proxy
       [process.env.VUE_APP_BASE_API]: {
         // target: `http://36.213.90.123:9015/lims`,
-        target: `http://127.0.0.1:8001/lims`,
+        target: `http://192.168.21.53:9001/lims`,
         changeOrigin: true,
         pathRewrite: {
           ["^" + process.env.VUE_APP_BASE_API]: "",

--
Gitblit v1.9.3