| | |
| | | # 本地环境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 |
| | |
| | | |
| | | # 生产环境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' |
| | |
| | | # 测试环境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' |
| | |
| | | <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> |
| | |
| | | </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'], |
| | |
| | | } |
| | | }, |
| | | 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(); |
| | | // 没有文档地址就不初始化编辑器,避免访问尚未加载的 DocsAPI |
| | | if (!option || !option.url) { |
| | | return; |
| | | } |
| | | this.doctype = this.getFileType(option.fileType); |
| | | let config = { |
| | |
| | | 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 = ""; |
| | |
| | | <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>正在加载 PDF…</p> |
| | | </div> |
| | | <div v-if="isDoc"> |
| | | <p v-if="!isDocShow">文档无法直接预览,请下载查看。</p> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import axios from 'axios' |
| | | import VueOfficeDocx from '@vue-office/docx' |
| | | //引入相关样式 |
| | | import '@vue-office/docx/lib/index.css' |
| | |
| | | transformData: (workbookData) => { return workbookData }, //将获取到的excel数据进行处理之后且渲染到页面之前,可通过transformData对即将渲染的数据及样式进行修改,此时每个单元格的text值就是即将渲染到页面上的内容 |
| | | }, |
| | | csvList: [],//csv文件数据 |
| | | imgUrl: '' |
| | | imgUrl: '', |
| | | pdfUrl: '', //pdf本地预览地址 |
| | | pdfError: false, |
| | | } |
| | | }, |
| | | computed: { |
| | |
| | | }, |
| | | isSupported() { |
| | | return this.isImage || this.isPdf || this.isDoc || this.isZipOrRar || this.isCsv || this.isXls; |
| | | } |
| | | }, |
| | | // 调用方传了 OnlyOffice 的配置才走文档服务,否则用浏览器内置阅读器 |
| | | 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 |
| | |
| | | <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" |
| | |
| | | <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> |
| | |
| | | // 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]: "", |