askbot-dragon 1.7.65-beta → 1.7.67-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/README.md +27 -27
  2. package/babel.config.js +6 -6
  3. package/dragon.iml +7 -7
  4. package/package.json +57 -57
  5. package/public/index.html +73 -73
  6. package/src/App.vue +31 -31
  7. package/src/api/index.js +1 -1
  8. package/src/api/mock.http +2 -2
  9. package/src/api/requestUrl.js +185 -185
  10. package/src/assets/js/AliyunlssUtil.js +141 -141
  11. package/src/assets/js/Base64Util.js +22 -22
  12. package/src/assets/js/common.js +252 -252
  13. package/src/assets/js/hammer.js +100 -100
  14. package/src/assets/js/script.js +36 -36
  15. package/src/assets/less/common.css +6773 -6773
  16. package/src/assets/less/converSationContainer/common.less +199 -199
  17. package/src/assets/less/converSationContainer/converSatonContainer.less +493 -493
  18. package/src/assets/less/iconfont.css +37 -37
  19. package/src/assets/less/ticketMessage.less +294 -294
  20. package/src/components/ActionAlertIframe.vue +178 -178
  21. package/src/components/AiGuide.vue +434 -434
  22. package/src/components/AnswerDocknowledge.vue +1203 -1203
  23. package/src/components/AnswerVoice.vue +285 -285
  24. package/src/components/AskIFrame.vue +15 -15
  25. package/src/components/ConversationContainer.vue +10764 -10764
  26. package/src/components/FileType.vue +86 -86
  27. package/src/components/Message.vue +27 -27
  28. package/src/components/MyEditor.vue +342 -342
  29. package/src/components/QwFeedback.vue +302 -302
  30. package/src/components/actionSatisfaction.vue +107 -107
  31. package/src/components/actionSendToBot.vue +62 -62
  32. package/src/components/answerDissatisfaction.vue +62 -62
  33. package/src/components/answerRadio.vue +259 -259
  34. package/src/components/ask-components/DissatisfactionOptions.vue +57 -57
  35. package/src/components/ask-components/Msgloading.vue +37 -37
  36. package/src/components/ask-components/SatisfactionV2.vue +15 -15
  37. package/src/components/askVideo.vue +162 -162
  38. package/src/components/assetDetails.vue +378 -378
  39. package/src/components/assetMessage.vue +229 -229
  40. package/src/components/associationIntention.vue +378 -378
  41. package/src/components/attachmentPreview.vue +90 -90
  42. package/src/components/botActionSatisfactor.vue +68 -68
  43. package/src/components/chatContent.vue +513 -513
  44. package/src/components/feedBack.vue +136 -136
  45. package/src/components/fielListView.vue +351 -351
  46. package/src/components/file/AliyunOssComponents.vue +108 -108
  47. package/src/components/formTemplate.vue +3512 -3512
  48. package/src/components/imgView.vue +31 -31
  49. package/src/components/intelligentSummary.vue +234 -234
  50. package/src/components/kkview.vue +1138 -1138
  51. package/src/components/loadingProcess.vue +164 -164
  52. package/src/components/markDownText.vue +357 -357
  53. package/src/components/message/ActionAlertIframe.vue +112 -112
  54. package/src/components/message/ShopMessage.vue +164 -164
  55. package/src/components/message/TextMessage.vue +928 -928
  56. package/src/components/message/TicketMessage.vue +201 -201
  57. package/src/components/message/swiper/index.js +4 -4
  58. package/src/components/message/swiper/ticketSwiper.vue +503 -503
  59. package/src/components/message/swiper/ticketSwiperItem.vue +61 -61
  60. package/src/components/msgLoading.vue +231 -231
  61. package/src/components/myPopup.vue +73 -73
  62. package/src/components/newPdfPosition.vue +877 -877
  63. package/src/components/pagination.vue +128 -128
  64. package/src/components/pdfPosition.vue +1523 -1523
  65. package/src/components/popup.vue +228 -228
  66. package/src/components/preview/docView.vue +113 -113
  67. package/src/components/preview/excelView.vue +190 -190
  68. package/src/components/preview/newPositionPreview.vue +384 -369
  69. package/src/components/preview/pdfView.vue +824 -824
  70. package/src/components/previewDoc.vue +252 -252
  71. package/src/components/previewPdf.vue +1087 -1087
  72. package/src/components/receiverMessagePlatform.vue +69 -69
  73. package/src/components/recommend.vue +80 -80
  74. package/src/components/selector/hOption.vue +20 -20
  75. package/src/components/selector/hSelector.vue +199 -199
  76. package/src/components/selector/hWrapper.vue +216 -216
  77. package/src/components/senderMessagePlatform.vue +58 -58
  78. package/src/components/source/BotMessage.vue +24 -24
  79. package/src/components/source/CustomMessage.vue +24 -24
  80. package/src/components/test.vue +260 -260
  81. package/src/components/tree.vue +307 -307
  82. package/src/components/utils/AliyunIssUtil.js +103 -103
  83. package/src/components/utils/ckeditor.js +185 -185
  84. package/src/components/utils/format_date.js +25 -25
  85. package/src/components/utils/index.js +6 -6
  86. package/src/components/utils/math_utils.js +29 -29
  87. package/src/components/voiceComponent.vue +119 -119
  88. package/src/components/welcomeKnowledgeFile.vue +347 -347
  89. package/src/components/welcomeLlmCard.vue +144 -144
  90. package/src/components/welcomeSuggest.vue +97 -97
  91. package/src/locales/cn.json +95 -95
  92. package/src/locales/en.json +95 -95
  93. package/src/locales/jp.json +72 -72
  94. package/src/main.js +76 -76
  95. package/vue.config.js +54 -54
@@ -1,1523 +1,1523 @@
1
- <template>
2
- <div class="pdf_view" id="pdf_view">
3
- <div class="change_scale" v-if="isPC">
4
- <section @click="changeScale('reduce')">
5
- <i class="el-icon-minus"></i>
6
- </section>
7
- <el-divider direction="vertical"></el-divider>
8
- <section @click="changeScale('zoom')">
9
- <i class="el-icon-plus"></i>
10
- </section>
11
- <el-select size="small" v-model="handScale" @change="changeScale" :placeholder="$t('dragonCommon.selectScale')">
12
- <el-option v-for="item in scaleList" :key="item.value" :label="item.label" :value="item.value">
13
- </el-option>
14
- </el-select>
15
- </div>
16
- <div class="pdf_container_view" id="pdf_container_view" @scroll="pdfScroll" ref="pdfView"></div>
17
- <div class="btn_footer" v-if="tagIds.length > 1 && !isPC">
18
- <div class="prev" @click="prev">{{ $t('dragonCommon.previous') }}</div>
19
- <div class="next" @click="next">{{ $t('dragonCommon.next') }}</div>
20
- </div>
21
- <div id="pagination" v-if="tagIds.length > 1 && isPC">
22
- <el-pagination
23
- :current-page="currentPage + 1"
24
- @current-change="currentChange"
25
- @prev-click="prev"
26
- @next-click="next"
27
- layout="slot, prev, pager, next"
28
- :page-size="1"
29
- :total="tagIds.length"
30
- >
31
- <span class="total-class">{{ $t('dragonCommon.answersGeneratedByPre') }}{{tagIds.length}}{{ $t('dragonCommon.answersGeneratedByAfter') }}</span>
32
- </el-pagination>
33
- </div>
34
- </div>
35
- </template>
36
- <script>
37
- // :style="{
38
- // marginBottom: tagIds.length > 1 ? '60px' : '0px',
39
- // height: setHeight
40
- // }"
41
- import _ from 'lodash'
42
- import { newInitWaterMark } from "../assets/js/common";
43
- // import * as pdfjsLib from 'pdfjs-dist'
44
- // pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdfjs-dist/build/pdf.worker';
45
- // import { TextLayerBuilder } from "pdfjs-dist/web/pdf_viewer";
46
- // EventBus pdf_viewer 支持绑定自定义事件,一版不做
47
- // import 'pdfjs-dist/web/pdf_viewer.css'
48
- /* eslint-disable */
49
- const pdfjsLib = window['pdfjsLib']
50
- if (pdfjsLib) {
51
- pdfjsLib.GlobalWorkerOptions.workerSrc = window['pdfjs-dist/build/pdf.worker']
52
- // 'pdfjs-dist/build/pdf.worker';
53
- }
54
- const { TextLayerBuilder } = window['pdfjs-dist/web/pdf_viewer']
55
- const CSS_UNITS = 96.0 / 72.0
56
- // import { zoomElement } from '../assets/js/hammer'
57
- export default {
58
- name: 'pdfView',
59
- props: ['tagIds', 'isMessageRecord','fileName', "knowledgeItem",'textWatermarkStr'],
60
- data () {
61
- return {
62
- url: '',
63
- pages: [],
64
- pageLoadStatus: {
65
- WAIT: 0,
66
- LOADED: 1,
67
- },
68
- scale: 1,
69
- rotation: 0,
70
- pageSize: {},
71
- PAGE_INTVERVAL: 15,
72
- SLICE_COUNT: 5,
73
- contentView: null,
74
- fisrtLoad: true,
75
- TextLayerBuilder: null,
76
- totalPageCount: 0,
77
- identifyTextPostion: {
78
- top: 0,
79
- left: 0,
80
- width: 100,
81
- height: 0,
82
- page: 1,
83
- pageHeight: 0,
84
- pageWidth: 0,
85
- extractInfo: {},
86
- currentPageAllLine: []
87
- },
88
- currentPageAllLine: [],
89
- pdfUrl: '',
90
- cachePdf: [],
91
- newViewer: null,
92
- currentPage: 0,
93
- changetoolbar: false,
94
- allTr: [],
95
- preViewType: 'pdf',
96
- displacement: {
97
- pageX: 0,
98
- pageY: 0,
99
- moveable: false,
100
- pageX2: 0,
101
- pageY2: 0,
102
- originScale: 1,
103
- },
104
- isTouchMoved: false,
105
- transformSalce: null,
106
- defaultTransform:0.8,
107
- isPC: false,
108
- handScale: 'auto',
109
- scaleList: [],
110
- scrollTop: 0,
111
- scrollLeft: 0
112
- }
113
- },
114
- methods: {
115
- getpdfResloutePage (pdfResloute) {
116
- // 根据当前页面宽度设置缩放比例
117
- // this.scale = Math.round(this.$refs.pdfView.clientWidth / pdfResloute.pageWidth * 100) / 100
118
- if (this.isMessageRecord) {
119
- this.scale = Math.round(this.$refs.pdfView.clientWidth / pdfResloute.pageWidth * 100) / 100
120
- } else {
121
- this.scale = 2
122
- }
123
- // 从后端获取到当前分片后所有的pdf页码,初始化数组,数组下{} 对应每页pdf文件
124
- this.pdfUrl = pdfResloute.publicPageFileUrl.substring(0, pdfResloute.publicPageFileUrl.lastIndexOf('/') + 1)
125
- this.initPages(pdfResloute.total)
126
- // 定位功能,加载对应页码位置
127
- this.loadPdfData(pdfResloute.page)
128
- },
129
- async loadPdfData (loadPage) {
130
- if (this.pages[loadPage - 1] && ((this.pages[loadPage - 1].dom && this.pages[loadPage - 1].dom.children.length > 0) || this.pages[loadPage - 1].loadStatus)) {
131
- return
132
- } else {
133
- if (this.changetoolbar) {
134
- this.$nextTick(() => {
135
- this.renderHighlights()
136
- })
137
- this.changetoolbar = false
138
- }
139
- }
140
- // 记录开始缓存的状态
141
- // pdfjsLib.GlobalWorkerOptions.workerSrc = require("pdfjs-dist/legacy/build/pdf.worker.entry.js");
142
- // 拿到第一个分片
143
- const { startPage, url } = await this.fetchPdfFragment(loadPage);
144
- let loadingTask = pdfjsLib.getDocument(url)
145
- loadingTask.promise.then(async (pdfDoc) => {
146
- // 将已经下载的分片保存到 pages 数组中
147
- // for (let i = 0; i < pdfDoc.numPages; i += 1) {
148
- // const pageIndex = startPage + i;
149
- // const page = this.pages[pageIndex - 1];
150
- // // // 不在缓存列表内,重新获取本页pdf
151
- // // if (page.loadStatus !== this.pageLoadStatus.LOADED) {
152
-
153
- // // } else {
154
- // // if (this.changetoolbar) {
155
- // // this.$nextTick(() => {
156
- // // this.renderHighlights()
157
- // // })
158
- // // this.changetoolbar = false
159
- // // }
160
- // // }
161
- // }
162
- const page = this.pages[loadPage - 1]
163
- await pdfDoc.getPage(1).then(async (pdfPage) => {
164
- this.pages[loadPage - 1].loadStatus = true
165
- this.pages[loadPage - 1].pdfPage = pdfPage;
166
- // 通知可以进行渲染了
167
- await this.startRenderPages(pdfPage, page, loadPage)
168
- });
169
- });
170
- },
171
- initPages (totalPage) {
172
- // const pages = [];
173
- this.totalPageCount = totalPage
174
- for (let i = 0; i < totalPage; i += 1) {
175
- this.pages.push({
176
- pageNo: i + 1,
177
- loadStatus: false,
178
- pdfPage: null,
179
- dom: null
180
- });
181
- }
182
- },
183
- async fetchPdfFragment (pageIndex) {
184
- // 置换加签后的文件地址。
185
- let obj = {}
186
- await this.$http.post(
187
- '/knowledge-api/temporary-certificate/or-origin?expired=30',
188
- this.pdfUrl + pageIndex + '.pdf',
189
- {
190
- headers: {
191
- "Content-Type": "application/json",
192
- },
193
- }).then(async res => {
194
- if (res.bodyText) {
195
- // 最后返回一个 包含这4个参数的对象
196
- obj = await {
197
- "startPage": pageIndex, // 分片的开始页码
198
- "endPage": pageIndex + 5, // 分片结束页码
199
- "totalPage": this.totalPageCount, // pdf 总页数
200
- "url": res.bodyText // 分片内容下载地址
201
- }
202
- }
203
- if (res.data) {
204
- // 最后返回一个 包含这4个参数的对象
205
- obj = await {
206
- "startPage": pageIndex, // 分片的开始页码
207
- "endPage": pageIndex + 5, // 分片结束页码
208
- "totalPage": this.totalPageCount, // pdf 总页数
209
- "url": res.data // 分片内容下载地址
210
- }
211
- }
212
- })
213
- return obj
214
- },
215
- startRenderPages (pdfPage, page, pageIndex) {
216
- if (Object.keys(this.pageSize).length == 0) {
217
- const viewport = pdfPage.getViewport({
218
- scale: this.scale, // 缩放的比例
219
- rotation: this.rotation, // 旋转的角度
220
- });
221
- // 记录pdf页面高度
222
- const pageSize = {
223
- width: viewport.width,
224
- height: viewport.height,
225
- }
226
- this.pageSize = pageSize
227
- // 创建内容绘制区,并设置大小
228
- if (this.$refs.pdfView.clientWidth / this.pageSize.width >= 1 || this.isMessageRecord) {
229
- this.contentView.style.width = `${pageSize.width - 10}px`;
230
- this.contentView.style.height = `${(this.totalPageCount * (pageSize.height + this.PAGE_INTVERVAL)) + this.PAGE_INTVERVAL}px`;
231
- } else {
232
- this.transformSalce = this.$refs.pdfView.clientWidth / this.pageSize.width
233
- this.contentView.style.width = `${pageSize.width * this.transformSalce - 10}px`;
234
- this.contentView.style.height = `${(this.totalPageCount * (pageSize.height * (this.transformSalce) + this.PAGE_INTVERVAL)) + this.PAGE_INTVERVAL}px`;
235
- }
236
- this.contentView.style.margin = '0 auto 0'
237
- this.contentView.style.position = 'relative'
238
- this.contentView.style.paddingBottom = '60px'
239
- // contentView.style.overflowY = 'auto'
240
- this.$refs.pdfView.appendChild(this.contentView);
241
- if (this.textWatermarkStr){
242
- newInitWaterMark('pdf_container_view',this.textWatermarkStr)
243
- }
244
- }
245
- this.renderPages(pageIndex)
246
- },
247
- // 渲染需要展示的页面,不需展示的页码将其清除
248
- renderPages (pageIndex) {
249
- const pagesToRender = this.getRenderScope(pageIndex);
250
- for (const i of this.pages) {
251
- if (pagesToRender.some(p => { return p.pageNo == i.pageNo })) {
252
- if (i.loadStatus === true) {
253
- this.renderPageContent(i, i.pageNo)
254
- } else {
255
- this.renderPageLoading(i, i.pageNo)
256
- }
257
- } else {
258
- this.clearPage(i);
259
- }
260
- }
261
-
262
- },
263
- async renderPageContent (page, pageIndex) {
264
- const { pdfPage, pageNo, dom } = page;
265
- // dom 元素已存在,无须重新渲染,直接返回
266
- if ((dom && dom.children.length != 0) || page.loading) {
267
- return;
268
- }
269
- page.loading = true
270
- const viewport = pdfPage.getViewport({
271
- scale: this.scale,
272
- rotation: this.rotation,
273
- });
274
- // 创建新的canvas
275
- const canvas = document.createElement('canvas');
276
- const context = canvas.getContext('2d');
277
- // canvas.getContext('2d');
278
- canvas.height = this.pageSize.height;
279
- canvas.width = this.pageSize.width;
280
- canvas.style.position = 'relative'
281
- canvas.style.top = -3 + 'px'
282
- // 创建渲染的dom
283
- const pageDom = document.createElement('div');
284
- pageDom.style.position = 'absolute';
285
- pageDom.style.top = `${((pageNo - 1) * (this.pageSize.height + this.PAGE_INTVERVAL)) + this.PAGE_INTVERVAL}px`;
286
- pageDom.style.width = `${this.pageSize.width}px`;
287
- pageDom.style.height = `${this.pageSize.height}px`;
288
- pageDom.setAttribute('data-id', 'page' + pageNo)
289
- pageDom.appendChild(canvas);
290
- // 渲染内容
291
- let renderContext = {
292
- canvasContext: context,
293
- viewport: viewport,
294
- }
295
- await pdfPage.render(renderContext).promise.then(() => {
296
- return pdfPage.getTextContent()
297
- }).then(async (textContent) => {
298
- const textLayerDiv = document.createElement('div');
299
- textLayerDiv.setAttribute('class', 'textLayer');
300
- // 将文本图层div添加至每页pdf的div中
301
- // 创建新的TextLayerBuilder实例
302
- let textLayer = new TextLayerBuilder({
303
- textLayerDiv: textLayerDiv,
304
- pageIndex: pdfPage._pageIndex,
305
- viewport: viewport,
306
- });
307
- let findPage = this.currentPageAllLine.find(l => { return l.page == pageIndex })
308
- let rectdomTop = 0
309
- if (findPage) {
310
- let AllLines = findPage.allLines
311
- // setTimeout(() => {
312
- if (AllLines.length > 0) {
313
- for (let j = 0; j < AllLines.length; j++) {
314
- let lines = AllLines[j].lines
315
- let rectdom = document.createElement('div')
316
- rectdom.setAttribute('react-count', AllLines[j].pageCount);
317
- rectdom.style.position = 'absolute';
318
- rectdom.style.top = 0
319
- rectdom.style.left = 0
320
- rectdom.classList.add('rectdom')
321
- if (lines){
322
- for (let index = 0; index < lines.length; index++) {
323
- if (!/^\s+$/g.test(lines[index].content)) {
324
- let postionArr = lines[index].location
325
- let div = document.createElement('div')
326
- div.style.position = 'absolute';
327
- div.style.left = postionArr[0] * this.scale + 'px',
328
- // 后端返回的坐标有基线对齐的问题,top 值是后端算好(基线top - 文字高度),在此加上文字高度的 1/9 (大致比例)为实际展示出文字的top值
329
- div.style.top = postionArr[1] * this.scale + 'px'
330
- div.style.height = postionArr[3] * this.scale + 'px';
331
- div.style.width = postionArr[2] * this.scale + 'px'
332
- div.style.backgroundColor = 'rgba(54, 106, 255, 0.3)'
333
- div.classList.add('lineHeight')
334
- rectdom.appendChild(div)
335
- if (index == 0 && j == 0) {
336
- if (this.transformSalce !== null) {
337
- rectdomTop = postionArr[1] * this.scale * this.transformSalce
338
- } else {
339
- rectdomTop = postionArr[1] * this.scale
340
- }
341
- // if(this.isPC) {
342
- // rectdomTop = rectdomTop - 50 < 0 ? 0 : rectdomTop - 50
343
- // }
344
- }
345
- }
346
- }
347
- }
348
- if (rectdom.children && rectdom.children.length > 0) {
349
- pageDom.appendChild(rectdom)
350
- }
351
- }
352
- }
353
- }
354
- textLayer.setTextContent(textContent);
355
- textLayer.render()
356
- pageDom.appendChild(textLayerDiv);
357
-
358
- let backgroundDom = document.getElementById('backgroundLoad' + pageNo)
359
- if (backgroundDom) {
360
- this.contentView.removeChild(backgroundDom);
361
- }
362
- page.dom = await pageDom;
363
- page.loading = false
364
- this.contentView.appendChild(pageDom);
365
- let pdf_view = document.getElementsByClassName('pdf_view');
366
- if (pdf_view && pdf_view[0]){
367
- pdf_view[0].style.backgroundImage = 'none'
368
- }
369
- if (this.transformSalce !== null) {
370
- this.contentView.style.transform = `scale(${this.transformSalce}, ${this.transformSalce})`
371
- }
372
- if (this.changetoolbar) {
373
- setTimeout(() => {
374
- this.renderHighlights()
375
- this.changetoolbar = false
376
- }, 500)
377
- }
378
- if (this.fisrtLoad) {
379
- setTimeout(() => {
380
- let pageoffsetHeight = 0
381
- if (this.transformSalce !== null) {
382
- pageoffsetHeight = (this.pageSize.height + this.PAGE_INTVERVAL) * this.transformSalce
383
- } else {
384
- pageoffsetHeight = (this.pageSize.height + this.PAGE_INTVERVAL)
385
- }
386
- if (this.$refs.pdfView.clientHeight - pageoffsetHeight > 0 && pageIndex == 1) {
387
- const height = this.$refs.pdfView.clientHeight;
388
- let startNum = 0
389
- let endNum = 0
390
- if (this.transformSalce !== null) {
391
- startNum = Math.ceil(this.$refs.pdfView.scrollTop / ((this.pageSize.height + this.PAGE_INTVERVAL) * this.transformSalce))
392
- endNum = startNum + Math.ceil(height / ((this.pageSize.height + this.PAGE_INTVERVAL) * this.transformSalce))
393
- } else {
394
- startNum = Math.ceil(this.$refs.pdfView.scrollTop / (this.pageSize.height + this.PAGE_INTVERVAL))
395
- endNum = startNum + Math.ceil(height / (this.pageSize.height + this.PAGE_INTVERVAL))
396
-
397
- }
398
- for (let pageIndex = startNum; pageIndex <= endNum; pageIndex++) {
399
- if (pageIndex > 0 && pageIndex <= this.pages.length) {
400
- this.loadPdfData(pageIndex)
401
- }
402
- }
403
- }
404
- if (this.$refs.pdfView.scrollTop == Math.floor((pageNo - 1) * pageoffsetHeight)) {
405
- this.$refs.pdfView.scrollTop = rectdomTop
406
- this.fisrtLoad = false
407
- } else {
408
- this.$refs.pdfView.scrollTop = `${((pageNo - 1) * pageoffsetHeight) + rectdomTop - this.PAGE_INTVERVAL}`
409
- this.fisrtLoad = false
410
- }
411
- this.renderHighlights()
412
- // zoomElement(this.contentView)
413
- }, 100)
414
- }
415
- })
416
- },
417
- // 监听容器的滚动事件,触发 scrollPdf 方法
418
- // 这里加了防抖保证不会一次产生过多请求
419
- debounceScrollPdf: _.debounce(function (e, that) {
420
- if (this.fisrtLoad) {
421
- this.fisrtLoad = false
422
- return
423
- }
424
- const scrollTop = e.target.scrollTop;
425
- const height = e.target.clientHeight;
426
- let startNum = 0
427
- let endNum = 0
428
- if (this.transformSalce !== null) {
429
- startNum = Math.ceil(scrollTop / ((that.pageSize.height + that.PAGE_INTVERVAL) * this.transformSalce))
430
- endNum = startNum + Math.ceil(height / ((that.pageSize.height + that.PAGE_INTVERVAL) * this.transformSalce))
431
- } else {
432
- startNum = Math.ceil(scrollTop / (that.pageSize.height + that.PAGE_INTVERVAL))
433
- endNum = startNum + Math.ceil(height / (that.pageSize.height + that.PAGE_INTVERVAL))
434
- }
435
- for (let pageIndex = startNum; pageIndex <= endNum; pageIndex++) {
436
- if (pageIndex > 0 && pageIndex <= that.pages.length) {
437
- that.loadPdfData(pageIndex)
438
- }
439
- }
440
- }, 200),
441
- directScrolling (e, that) {
442
- if (this.fisrtLoad) {
443
- this.fisrtLoad = false
444
- return
445
- }
446
- const scrollTop = e.target.scrollTop;
447
- const height = e.target.clientHeight;
448
- // 根据内容可视区域中心点计算页码, 没有滚动时,指向第一页
449
- const pageIndex = scrollTop > 0 ?
450
- Math.ceil((scrollTop + (height / 2)) / (that.pageSize.height + that.PAGE_INTVERVAL)) :
451
- 1;
452
- this.loadPdfData(pageIndex)
453
- },
454
- pdfScroll (e) {
455
- if (this.preViewType !== 'pdf' || this.isTouchMoved) {
456
- return
457
- }
458
- if (this.scrollLeft != e.target.scrollLeft) {
459
- this.scrollLeft = e.target.scrollLeft
460
- }
461
- if (this.scrollTop != e.target.scrollTop) {
462
- this.scrollTop = e.target.scrollTop
463
- this.debounceScrollPdf(e, this)
464
- }
465
- },
466
- // 分片每次只做一次处理,所以不考虑多片情况
467
- loadBefore (pageIndex) {
468
- this.loadPdfData(pageIndex)
469
- },
470
- loadAfter (pageIndex) {
471
- this.loadPdfData(pageIndex)
472
- },
473
- // 首先我们获取到需要渲染的范围
474
- // 根据当前的可视范围内的页码,我们前后只保留 8 页
475
- getRenderScope (pageIndex) {
476
- const pagesToRender = [];
477
- let i = pageIndex - 1;
478
- let j = pageIndex + 1;
479
- // pageIndex - 1 表示当前页码数 对应的下标位置
480
- pagesToRender.push(this.pages[pageIndex - 1]);
481
- while (pagesToRender.length < 8 && pagesToRender.length < this.pages.length) {
482
- if (i > 0) {
483
- pagesToRender.push(this.pages[i - 1]);
484
- i -= 1;
485
- }
486
- if (pagesToRender.length >= 8) {
487
- break;
488
- }
489
- if (j <= this.pages.length) {
490
- pagesToRender.push(this.pages[j - 1]);
491
- j += 1;
492
- }
493
- }
494
- // for (let index = 0; index < array.length; index++) {
495
- // const element = array[index];
496
-
497
- // }
498
- return pagesToRender;
499
- },
500
-
501
- // 清除页面 dom
502
- clearPage (page) {
503
- if (this.contentView.contains(page.dom) && page.dom) {
504
- this.contentView.removeChild(page.dom);
505
- page.loadStatus = false
506
- page.loading = false
507
- page.dom = undefined;
508
- }
509
- },
510
- // 页面正在下载时渲染loading视图
511
- renderPageLoading (page) {
512
- const { pageNo, dom } = page;
513
- if (dom && dom.children.length != 0) {
514
- return;
515
- }
516
- let backgroundDom = document.getElementById('backgroundLoad' + pageNo)
517
- if (this.contentView.contains(backgroundDom)) {
518
- return
519
- }
520
- const pageDom = document.createElement('div');
521
- pageDom.style.width = `${this.pageSize.width}px`;
522
- pageDom.style.height = `${this.pageSize.height}px`;
523
- pageDom.style.position = 'absolute';
524
- pageDom.style.top = `${((pageNo - 1) * (this.pageSize.height + this.PAGE_INTVERVAL)) + this.PAGE_INTVERVAL
525
- }px`;
526
- pageDom.style.backgroundImage = `url('https://guoranopen-zjk.oss-cn-zhangjiakou.aliyuncs.com/cdn-common/images/loading.gif')`
527
- pageDom.style.backgroundPosition = 'center'
528
- pageDom.style.backgroundRepeat = 'no-repeat'
529
- pageDom.style.backgroundColor = '#FFF'
530
- pageDom.setAttribute('id', 'backgroundLoad' + pageNo)
531
- page.dom = pageDom;
532
- this.contentView.appendChild(pageDom);
533
- },
534
- prev () {
535
- this.currentPage--
536
- if (this.currentPage < 0) {
537
- this.currentPage = 0
538
- if (!this.isPC) {
539
- this.$toast({
540
- message: this.$t('dragonCommon.firstParagraph'),
541
- duration: 2000,
542
- })
543
- return
544
- }
545
- }
546
- if (this.preViewType == 'pdf') {
547
- this.scrollToUplaodePage(this.currentPage)
548
- } else {
549
- this.scrollToExcalTop(this.currentPage)
550
- }
551
- // this.getpdfResloutePage(this.cachePdf[this.currentPage - 1])
552
- },
553
- next () {
554
- this.currentPage++
555
- if (this.currentPage >= this.tagIds.length) {
556
- this.currentPage = this.tagIds.length - 1
557
- if (!this.isPC) {
558
- this.$toast({
559
- message: this.$t('dragonCommon.lastParagraph'),
560
- duration: 2000,
561
- })
562
- return
563
- }
564
- }
565
- if (this.preViewType == 'pdf') {
566
- this.scrollToUplaodePage(this.currentPage)
567
- } else {
568
- this.scrollToExcalTop(this.currentPage)
569
- }
570
- },
571
- currentChange (value) {
572
- this.currentPage = value - 1
573
- if (this.preViewType == 'pdf') {
574
- this.scrollToUplaodePage(this.currentPage)
575
- } else {
576
- this.scrollToExcalTop(this.currentPage)
577
- }
578
- },
579
- scrollToUplaodePage (currentPage) {
580
- this.changetoolbar = true
581
- if (this.preViewType !== 'pdf') {
582
- return
583
- }
584
-
585
- let pdfResloute = this.cachePdf[currentPage]
586
- this.identifyTextPostion.extractInfo = pdfResloute.extractInfo
587
- this.identifyTextPostion.left = pdfResloute.extractInfo.location[0]
588
- this.identifyTextPostion.top = pdfResloute.extractInfo.location[1]
589
- this.identifyTextPostion.width = pdfResloute.extractInfo.location[2]
590
- this.identifyTextPostion.height = pdfResloute.extractInfo.location[3]
591
- this.identifyTextPostion.page = pdfResloute.page
592
- this.identifyTextPostion.pageHeight = pdfResloute.pageHeight
593
- this.identifyTextPostion.pageWidth = pdfResloute.pageWidth
594
- // 在当前段落在最后一页pdf时,根据计算的高度并不能触发滚动,在此执行重新渲染方法,非次情况会执行两次,待优化
595
- this.$nextTick(() => {
596
- this.renderHighlights()
597
- })
598
- if (this.transformSalce !== null) {
599
- this.$refs.pdfView.scrollTop = `${((pdfResloute.page - 1) * (this.pageSize.height + this.PAGE_INTVERVAL) * this.transformSalce) + (this.identifyTextPostion.top * this.scale * this.transformSalce)}`
600
- } else {
601
- this.$refs.pdfView.scrollTop = `${((pdfResloute.page - 1) * (this.pageSize.height + this.PAGE_INTVERVAL)) + (this.identifyTextPostion.top * this.scale * this.transformSalce)}`
602
- }
603
- },
604
- scrollToExcalTop (currentPage) {
605
- for (let index = 0; index < this.allTr.length; index++) {
606
- if (index == currentPage) {
607
- Array.from(this.allTr[index].children).forEach(item => {
608
- item.style.background = 'rgba(255, 136, 0, 0.6)'
609
- item.classList.add('animation')
610
- setTimeout(() => {
611
- item.classList.remove('animation')
612
- }, 4000)
613
- })
614
- // getBoundingClientRect().top 当前元素距离屏幕顶部的高度 + 弹窗header 高度
615
- if (!this.isPC) {
616
- let top = this.allTr[index].getBoundingClientRect().top - this.$refs.pdfView.getBoundingClientRect().top
617
- this.$refs.pdfView.scrollTop = top
618
- } else {
619
- let top = this.allTr[index].getBoundingClientRect().top
620
- this.$refs.pdfView.scrollTop = top - 50
621
- }
622
- } else {
623
- Array.from(this.allTr[index].children).forEach(item => {
624
- item.style.background = 'rgba(54, 106, 255, 0.6)'
625
- item.classList.remove('animation')
626
- })
627
- }
628
- }
629
- },
630
- // pdf是否需要重新渲染高亮位置
631
- renderHighlights () {
632
- let lineHeightDom = Array.from(document.getElementsByClassName('rectdom'))
633
- if (lineHeightDom) {
634
- lineHeightDom.forEach((d) => {
635
- for (let i = 0; i < d.children.length; i++) {
636
- if (d.getAttribute('react-count') == this.currentPage) {
637
- d.children[i].style.backgroundColor = 'rgba(255, 136, 0, 0.3)'
638
- d.children[i].classList.add('animation')
639
- setTimeout(() => {
640
- d.children[i].classList.remove('animation')
641
- }, 4000)
642
- } else {
643
- d.children[i].style.backgroundColor = 'rgba(54, 106, 255, 0.3)'
644
- d.children[i].classList.remove('animation')
645
- }
646
- }
647
- })
648
- }
649
- },
650
- displayHiglight (pageIndex) {
651
- let lineHeightDom = Array.from(document.getElementsByClassName('rectdom'))
652
- if (lineHeightDom) {
653
- lineHeightDom.forEach((d) => {
654
- if (d.getAttribute('page-index') == pageIndex) {
655
- d.style.display = 'none'
656
- }
657
- })
658
- }
659
- },
660
- // 前端暂时缓存多页
661
- autoLoadMore (pageIndex) {
662
- let pdfResloute = this.cachePdf.find(cache => {
663
- return cache.page == pageIndex
664
- })
665
- if (pdfResloute) {
666
- this.getpdfResloutePage(pdfResloute)
667
- } else {
668
- this.loadPdfData(pageIndex)
669
- }
670
- },
671
- setPageAllLine (arr) {
672
- this.currentPageAllLine = []
673
- arr.forEach((item, index) => {
674
- let i = this.currentPageAllLine.findIndex(l => { return l.page && l.page == item.page })
675
- if (i != -1) {
676
- // this.currentPageAllLine[i].allLines.lines.push(item.extractInfo.lines)
677
- this.currentPageAllLine[i].allLines.push({
678
- pageCount: index,
679
- lines: item.extractInfo.lines ? item.extractInfo.lines : [{
680
- content:"测试内容填充,不必理会",
681
- location:item.extractInfo.location
682
- }]
683
- })
684
- } else {
685
- this.currentPageAllLine.push({
686
- page: item.page,
687
- allLines: [{
688
- pageCount: index,
689
- lines: item.extractInfo.lines ? item.extractInfo.lines : [{
690
- content:"测试内容填充,不必理会",
691
- location:item.extractInfo.location
692
- }]
693
- }],
694
- })
695
- }
696
- })
697
- },
698
- openTouch () {
699
- // this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行
700
- let that = this;
701
- this.$nextTick(() => {
702
- // setInterval(() => {
703
- // this.scale = this.scale + 0.1
704
- // that.pages.forEach((item, index) =>{
705
- // if(item.dom) {
706
- // item.dom.children.forEach( childDom =>{
707
- // if(childDom.getAttribute('react-count')) {
708
- // childDom.style.transform = "scale(" + this.scale + ")";
709
- // childDom.style.transformOrigin = "0px 0px 0px";
710
- // } else {
711
- // item.dom = null
712
- // this.startRenderPages(item.pdfPage, null, index)
713
- // }
714
- // } )
715
- // }
716
- // })
717
- // }, 100);
718
- // 获取放大或缩小的区域DOM
719
- let matrix_box = this.contentView
720
- matrix_box.addEventListener("touchstart", function (event) {
721
- this.isTouchMoved = true
722
- let touches = event.touches;
723
- let events = touches[0];
724
- let events2 = touches[1];
725
-
726
- // event.preventDefault();
727
-
728
- // 第一个触摸点的坐标
729
- that.displacement.pageX = events.pageX;
730
- that.displacement.pageY = events.pageY;
731
-
732
- that.displacement.moveable = true;
733
-
734
- if (events2) {
735
- that.displacement.pageX2 = events2.pageX;
736
- that.displacement.pageY2 = events2.pageY;
737
- }
738
-
739
- that.displacement.originScale = this.scale || 1;
740
- });
741
- document.addEventListener("touchmove", function (event) {
742
- if (!that.displacement.moveable) {
743
- return;
744
- }
745
- // event.preventDefault();
746
- let touches = event.touches;
747
- let events = touches[0];
748
- let events2 = touches[1];
749
- // 双指移动
750
- if (events2) {
751
- // 第2个指头坐标在touchmove时候获取
752
- if (!that.displacement.pageX2) {
753
- that.displacement.pageX2 = events2.pageX;
754
- }
755
- if (!that.displacement.pageY2) {
756
- that.displacement.pageY2 = events2.pageY;
757
- }
758
- // 双指缩放比例计算
759
- let zoom = that.getDistance({
760
- x: events.pageX,
761
- y: events.pageY
762
- },
763
- {
764
- x: events2.pageX,
765
- y: events2.pageY
766
- }
767
- ) / that.getDistance(
768
- {
769
- x: that.displacement.pageX,
770
- y: that.displacement.pageY
771
- },
772
- {
773
- x: that.displacement.pageX2,
774
- y: that.displacement.pageY2
775
- }
776
- );
777
- // 应用在元素上的缩放比例
778
- let newScale = that.displacement.originScale * zoom;
779
- // 最大缩放比例限制
780
- if (newScale > 2) {
781
- newScale = 2;
782
- }
783
- // 最大缩放比例限制
784
- if (newScale < 1) {
785
- newScale = 1;
786
- }
787
- // 记住使用的缩放值
788
- that.displacement.scale = newScale;
789
- // console.log(newScale);
790
- matrix_box.style.transform = "scale(" + newScale + ")";
791
- // 设置旋转元素的基点位置
792
- matrix_box.style.transformOrigin = "0px 0px 0px";
793
- }
794
- }, { passive: false });
795
- document.addEventListener('touchend', function () {
796
- that.isTouchMoved = false
797
- }, { passive: false })
798
- });
799
- },
800
- getDistance (start, stop) {
801
- // Math.hypot()计算参数的平方根
802
- return Math.hypot(stop.x - start.x, stop.y - start.y);
803
- },
804
- setupCanvas (canvas, width, height) {
805
- const dpr = 1;
806
- // const rect = canvas.getBoundingClientRect();
807
- canvas.width = width
808
- canvas.height = height
809
- const ctx = canvas.getContext('2d');
810
- ctx?.scale(dpr, dpr);
811
- return ctx;
812
- },
813
- changeScale (value) {
814
- if (value == 'zoom') {
815
- this.handScale = 'auto'
816
- this.transformSalce = (this.transformSalce + 0.2).toFixed(1)
817
- } else if (value == 'reduce') {
818
- if ((this.transformSalce - 0.2).toFixed(1) <= 0) {
819
- return
820
- }
821
- this.handScale = 'auto'
822
- this.transformSalce = (this.transformSalce - 0.2).toFixed(1)
823
- } else if (value == 'auto') {
824
- this.transformSalce = this.$refs.pdfView.clientWidth / this.pageSize.width
825
- } else if (value == 'reality') {
826
- this.transformSalce = 0.5
827
- } else {
828
- this.transformSalce = (value / 2).toFixed(1)
829
- }
830
- this.transformSalce = Number(this.transformSalce)
831
- this.contentView.style.transform = 'scale(' + this.transformSalce + ')';
832
- // this.getpdfResloutePage(this.cachePdf[0])
833
- },
834
- //添加水印
835
- watermark() {
836
- //默认设置
837
- var defaultSettings = {
838
- watermark_txt:"",
839
- watermark_x: 0,//水印起始位置x轴坐标
840
- watermark_y: 0,//水印起始位置Y轴坐标
841
- watermark_rows: 0,//水印行数
842
- watermark_cols: 0,//水印列数
843
- watermark_x_space: 40,//水印x轴间隔
844
- watermark_y_space: 60,//水印y轴间隔
845
- watermark_color: 'black',//水印字体颜色
846
- watermark_alpha: .3,//水印透明度
847
- watermark_fontsize: 12,//水印字体大小
848
- watermark_font: '微软雅黑',//水印字体
849
- watermark_width: 100,//水印宽度
850
- watermark_height: 80,//水印长度
851
- watermark_angle: 20,//水印倾斜度数***
852
- visitorWatermark_txt:""
853
- };
854
- if(this.knowledgeItem.textWatermarkValue){
855
- defaultSettings.watermark_txt = this.knowledgeItem.textWatermarkValue;
856
- }
857
- if (this.knowledgeItem.visitorWatermarkValue){
858
- defaultSettings.visitorWatermark_txt = this.knowledgeItem.visitorWatermarkValue
859
- }
860
- //采用配置项替换默认值,作用类似jquery.extend
861
- if (arguments.length === 1 && typeof arguments[0] === "object") {
862
- console.log("arguments = " + JSON.stringify(arguments[0]));
863
- // 获取参数配置
864
- var src = arguments[0];
865
- for (let key in src) {
866
- if (src[key] && defaultSettings[key] && src[key] === defaultSettings[key])
867
- continue;
868
- else if (src[key])
869
- defaultSettings[key] = src[key];
870
- }
871
- }
872
- var oTemp = document.createDocumentFragment();
873
- //获取页面最大宽度
874
- console.debug('pdf_view',document.getElementById('pdf_view'))
875
- let scrollWidth = document.getElementById('pdf_view').scrollWidth;
876
- let clientWidth = document.getElementById('pdf_view').clientWidth;
877
- var page_width = Math.max(scrollWidth, clientWidth);
878
-
879
- var cutWidth = page_width * 0.0150;
880
-
881
- page_width = page_width - cutWidth;
882
-
883
- //获取页面最大高度
884
- let height = parseInt(this.totalPageCount * this.pageSize.height)
885
- var page_height = Math.max(document.getElementById('pdf_container_view').scrollHeight,height);
886
-
887
- console.debug('page_height',page_height,this.totalPageCount * this.pageSize.height);
888
-
889
- // var page_height = document.body.scrollHeight+document.body.scrollTop;
890
-
891
- //如果将水印列数设置为0,或水印列数设置过大,超过页面最大宽度,则重新计算水印列数和水印x轴间隔
892
-
893
- if (defaultSettings.watermark_cols == 0 || (parseInt(defaultSettings.watermark_x + defaultSettings
894
- .watermark_width * defaultSettings.watermark_cols + defaultSettings.watermark_x_space *
895
- (defaultSettings.watermark_cols - 1)) > page_width)) {
896
- defaultSettings.watermark_cols = parseInt((page_width - defaultSettings.watermark_x + defaultSettings
897
- .watermark_x_space) / (defaultSettings.watermark_width + defaultSettings
898
- .watermark_x_space));
899
- defaultSettings.watermark_x_space = parseInt((page_width - defaultSettings.watermark_x -
900
- defaultSettings
901
- .watermark_width * defaultSettings.watermark_cols) / (defaultSettings.watermark_cols - 1));
902
- }
903
-
904
- //如果将水印行数设置为0,或水印行数设置过大,超过页面最大长度,则重新计算水印行数和水印y轴间隔
905
-
906
- if (defaultSettings.watermark_rows == 0 || (parseInt(defaultSettings.watermark_y + defaultSettings
907
-
908
- .watermark_height * defaultSettings.watermark_rows + defaultSettings.watermark_y_space * (
909
-
910
- defaultSettings.watermark_rows - 1)) > page_height)) {
911
-
912
- defaultSettings.watermark_rows = parseInt((defaultSettings.watermark_y_space + page_height -
913
-
914
- defaultSettings
915
-
916
- .watermark_y) / (defaultSettings.watermark_height + defaultSettings.watermark_y_space));
917
-
918
- defaultSettings.watermark_y_space = parseInt(((page_height - defaultSettings.watermark_y) -
919
-
920
- defaultSettings
921
-
922
- .watermark_height * defaultSettings.watermark_rows) / (defaultSettings.watermark_rows - 1));
923
-
924
- }
925
-
926
- var x;
927
-
928
- var y;
929
-
930
- for (var i = 0; i < defaultSettings.watermark_rows; i++) {
931
- y = defaultSettings.watermark_y + (defaultSettings.watermark_y_space + defaultSettings.watermark_height) * i;
932
- for (var j = 0; j < defaultSettings.watermark_cols; j++) {
933
- x = defaultSettings.watermark_x + (defaultSettings.watermark_width + defaultSettings.watermark_x_space) * j;
934
-
935
- var mask_div = document.createElement('div');
936
- mask_div.id = 'mask_div' + i + j;
937
- mask_div.className = 'mask_div';
938
-
939
- //注意看这里加了图片水印
940
- mask_div.style.webkitTransform = "rotate(-" + defaultSettings.watermark_angle + "deg)";
941
- mask_div.style.MozTransform = "rotate(-" + defaultSettings.watermark_angle + "deg)";
942
- mask_div.style.msTransform = "rotate(-" + defaultSettings.watermark_angle + "deg)";
943
- mask_div.style.OTransform = "rotate(-" + defaultSettings.watermark_angle + "deg)";
944
- mask_div.style.transform = "rotate(-" + defaultSettings.watermark_angle + "deg)";
945
- mask_div.style.visibility = "";
946
- mask_div.style.position = "absolute";
947
- //奇偶行错开,这样水印就不对齐,显的不呆板
948
- console.debug('x',x)
949
- if (i % 2 != 0) {
950
- mask_div.style.left = x + 'px';
951
- if (j % 2 != 0 && this.knowledgeItem.visitorWatermarkValue){
952
- mask_div.appendChild(document.createTextNode(defaultSettings.visitorWatermark_txt));
953
- } else {
954
- if (!this.knowledgeItem.textWatermarkValue){
955
- mask_div.appendChild(document.createTextNode(defaultSettings.visitorWatermark_txt));
956
- } else {
957
- mask_div.appendChild(document.createTextNode(defaultSettings.watermark_txt));
958
- }
959
- }
960
- } else {
961
- mask_div.style.left = x + 'px';
962
- if (j % 2 != 0 && this.knowledgeItem.textWatermarkValue){
963
- mask_div.appendChild(document.createTextNode(defaultSettings.watermark_txt));
964
- } else {
965
- if (!this.knowledgeItem.visitorWatermarkValue){
966
- mask_div.appendChild(document.createTextNode(defaultSettings.watermark_txt));
967
- } else {
968
- mask_div.appendChild(document.createTextNode(defaultSettings.visitorWatermark_txt));
969
- }
970
- }
971
- }
972
-
973
- mask_div.style.top = y + 'px';
974
- mask_div.style.overflow = "hidden";
975
- mask_div.style.zIndex = "9999";
976
- mask_div.style.pointerEvents = 'none'; //让水印不遮挡页面的点击事件
977
- mask_div.style.opacity = defaultSettings.watermark_alpha;
978
- mask_div.style.fontSize = defaultSettings.watermark_fontsize;
979
- mask_div.style.fontFamily = defaultSettings.watermark_font;
980
- mask_div.style.color = defaultSettings.watermark_color;
981
- mask_div.style.textAlign = "center";
982
- mask_div.style.width = defaultSettings.watermark_width + 'px';
983
- mask_div.style.height = defaultSettings.watermark_height + 'px';
984
- mask_div.style.display = "block";
985
- oTemp.appendChild(mask_div);
986
- }
987
- }
988
- let pageDom = document.getElementById('pdf_container_view')
989
- pageDom.appendChild(oTemp);
990
-
991
- },
992
- },
993
- computed: {
994
- perviewUrl () {
995
- return '/web/viewer.html?file=' + '/pdflist/pdf4split-1.pdf'
996
- },
997
- setHeight () {
998
- if (this.tagIds.length > 1) {
999
- if (this.isPC) {
1000
- return 'calc(100% - 110px)'
1001
- } else {
1002
- return 'calc(100% - 60px)'
1003
- }
1004
- } else {
1005
- if (this.isPC) {
1006
- return 'calc(100% - 50px)'
1007
- } else {
1008
- return '100%'
1009
- }
1010
- }
1011
- }
1012
- },
1013
- watch: {
1014
- tagIds: {
1015
- handler (value) {
1016
- if (value && value.length) {
1017
- // 在 pdf_view 下创建 所有canvs的容器
1018
- this.contentView = document.createElement('div')
1019
- this.contentView.setAttribute('id','contentView')
1020
- this.contentView.style.transformOrigin = '0px 0px 0px'
1021
- this.contentView.setAttribute('id','contentView');
1022
-
1023
- this.$http.get('/knowledge-api/knowledge/knowledge-part-location-info/list?ids=' + value.join(',')).then(res => {
1024
- // res.data = {"data":[{"id":"64591b7d8bb8ab1b91c65f24","knowledgeId":"64591a9c8da27649473f3b4b","mainId":"fb348d095c0b4fd7bbd37826563dac7d","page":3,"total":18,"pageHeight":540.0,"pageWidth":960.00946,"publicPageFileUrl":"https://askbot-pdf-all.oss-cn-zhangjiakou.aliyuncs.com/fb348d095c0b4fd7bbd37826563dac7d/2023/05/08/11/55/18/64591b638bb8ab1b91c65eed/3.pdf","extractInfo":{"location":[280.488,161.32,398.71573,61.99298],"content":"黄花城水长城旅游区位于北京市怀柔区九渡河镇境内,距北京市区65公里,是以奇而著称,融山川、碧水、古长城为一体的旅游休闲胜地。而这里的“三绝景”更是引人入","lines":[{"content":"黄花城水长城旅游区位于北京市怀柔区九渡河镇境内,距","location":[280.488,161.32,398.71573,15.9869995]},{"content":"北京市区65公里,是以奇而著称,融山川、碧水、古长","location":[283.691,184.30899,392.3055,15.9869995]},{"content":"城为一体的旅游休闲胜地。而这里的“三绝景”更是引人入","location":[282.699,207.32599,394.3033,15.9869995]}],"tagId":null}}],"code":"0","msg":null,"traceId":null}
1025
- // res.data = {"data":[{"id":"64590ce1eb1320043401cc90","knowledgeId":"64590cd5017b461d67e282e1","mainId":"fb348d095c0b4fd7bbd37826563dac7d","page":2,"total":5,"pageHeight":841.8898,"pageWidth":595.30396,"publicPageFileUrl":"https://askbot-pdf-all.oss-cn-zhangjiakou.aliyuncs.com/fb348d095c0b4fd7bbd37826563dac7d/2023/05/08/10/53/20/64590ce0eb1320043401cc7b/2.pdf","extractInfo":{"location":[89.32981,638.1907,415.15512,98.63251],"content":":北京地铁 13\r号线 :藤黄\r色 :西直门站—\r东直门站 :17 :41.\r5 :6\r准\rB :2002年\r09月\r28日 ","lines":[{"content":":北京地铁 13\r号线 ","location":[89.32981,638.1907,99.44599,98.63251]},{"content":":藤黄\r色 ","location":[188.7758,638.1907,46.79959,98.63251]},{"content":":西直门站—\r东直门站 ","location":[235.5754,638.1907,86.09996,98.63251]},{"content":":17 ","location":[321.67535,638.1907,36.200012,98.63251]},{"content":":41.\r5 ","location":[357.87537,638.1907,39.400696,98.63251]},{"content":":6\r准\rB ","location":[397.27606,638.1907,41.099,98.63251]},{"content":":2002年\r09月\r28日 ","location":[438.37506,638.1907,66.10986,98.63251]}],"tagId":null}}],"code":"0","msg":null,"traceId":null}
1026
- // res.data = {"data":[{"id":"64591b7d8bb8ab1b91c65f24","knowledgeId":"64591a9c8da27649473f3b4b","mainId":"fb348d095c0b4fd7bbd37826563dac7d","page":3,"total":18,"pageHeight":540.0,"pageWidth":960.00946,"publicPageFileUrl":"https://askbot-pdf-all.oss-cn-zhangjiakou.aliyuncs.com/fb348d095c0b4fd7bbd37826563dac7d/2023/05/08/11/55/18/64591b638bb8ab1b91c65eed/3.pdf","extractInfo":{"location":[280.488,161.32,398.71573,61.99298],"content":"黄花城水长城旅游区位于北京市怀柔区九渡河镇境内,距北京市区65公里,是以奇而著称,融山川、碧水、古长城为一体的旅游休闲胜地。而这里的“三绝景”更是引人入","lines":[{"content":"黄花城水长城旅游区位于北京市怀柔区九渡河镇境内,距","location":[280.488,161.32,398.71573,15.9869995]},{"content":"北京市区65公里,是以奇而著称,融山川、碧水、古长","location":[283.691,184.30899,392.3055,15.9869995]},{"content":"城为一体的旅游休闲胜地。而这里的“三绝景”更是引人入","location":[282.699,207.32599,394.3033,15.9869995]}],"tagId":null}}],"code":"0","msg":null,"traceId":null}
1027
- // res.data = {"data":[{"id":"6475eab868110215ab821a80","knowledgeId":"6475e7eac724c54c46cbfa2d","mainId":"5ecf2fcd704541149201ab9c1c31162d","page":0,"total":1,"pageHeight":0.0,"pageWidth":0.0,"publicPageFileUrl":"https://askbot-pdf-all.oss-cn-zhangjiakou.aliyuncs.com/5ecf2fcd704541149201ab9c1c31162d/2023/05/30/08/23/20/6475eab63339db423f26b196/0.html","extractInfo":{"location":null,"content":"产品:系统配置,产品型号:存储,VX30:4G+16G,VX50:16G+256G","lines":null,"tagId":"6475eab868110215ab821a80"}}],"code":"0","msg":null,"traceId":null}
1028
- // res.data = {"data":[{"id":"6475e9393339db423f26af01","knowledgeId":"6475e44fc724c54c46cbfa21","mainId":"5ecf2fcd704541149201ab9c1c31162d","page":2,"total":2,"pageHeight":510.25,"pageWidth":1559.05,"publicPageFileUrl":"https://askbot-pdf-all.oss-cn-zhangjiakou.aliyuncs.com/5ecf2fcd704541149201ab9c1c31162d/2023/05/30/08/00/29/6475e55d3339db423f26a9b8/2.pdf","extractInfo":{"location":[327.70532,288.0498,414.9734,12.241608],"content":"三、指示灯状态说明1.白色常亮:开机/开机中2.红色常亮:待机3.白色呼吸:息屏4.红色闪烁:升级1.LAN:通过网线连接到主机的Camera端口2.电源开关:电源切换开关","lines":[{"content":"三、指示灯状态说明","location":[634.3203,288.0498,108.3584,12.0]},{"content":"1.白色常亮:开机/开机中","location":[634.3203,320.08978,108.23407,9.0]},{"content":"2.红色常亮:待机","location":[634.3204,341.3298,78.597046,9.0]},{"content":"3.白色呼吸:息屏","location":[634.32043,362.45282,78.597046,9.0]},{"content":"4.红色闪烁:升级","location":[634.3205,383.6928,78.597046,9.0]},{"content":"1.LAN:通过网线连接到主机的","location":[327.70535,291.2914,144.35995,9.0]},{"content":"Camera端口","location":[327.70532,306.88843,55.322998,9.0]},{"content":"2.电源开关:电源切换开关","location":[482.74832,291.2914,105.36301,9.0]}],"tagId":null}}],"code":"0","msg":null,"traceId":null}
1029
- // if(value.length === 1) {
1030
- // this.$refs.pdfView.style.height = 'calc(100% - 50px)'
1031
- // }
1032
- // res.data = {
1033
- // "data": [
1034
- // {
1035
- // "id": "64e746120372d778849d2e8e",
1036
- // "knowledgeId": "64e30035edffac0ec96a2d39",
1037
- // "mainId": "e0f6898c6b0d47fa98e8f71ceab1bde8",
1038
- // "page": 14,
1039
- // "total": 60,
1040
- // "pageHeight": 728.504,
1041
- // "pageWidth": 515.906,
1042
- // "publicPageFileUrl": "https://askbot-pdf-all.oss-cn-zhangjiakou.aliyuncs.com/e0f6898c6b0d47fa98e8f71ceab1bde8/2023/08/21/02/12/07/64e300378c3dfb3bc434f51a/15.pdf",
1043
- // "extractInfo": {
1044
- // "location": [
1045
- // 52.665375,
1046
- // 312.01306,
1047
- // 404.98618,
1048
- // 142.5199
1049
- // ],
1050
- // "content": null,
1051
- // "lines": [
1052
- // {
1053
- // "content": null,
1054
- // "location": [
1055
- // 52.665375,
1056
- // 312.01306,
1057
- // 404.98618,
1058
- // 142.5199
1059
- // ]
1060
- // }
1061
- // ],
1062
- // "tagId": null
1063
- // },
1064
- // "block": {
1065
- // "type": "TEXT",
1066
- // "location": [
1067
- // 52.665375,
1068
- // 312.01306,
1069
- // 404.98618,
1070
- // 142.5199
1071
- // ],
1072
- // "color": "#366AFF",
1073
- // "flowChart": {
1074
- // "content": ""
1075
- // },
1076
- // "image": {
1077
- // "url": null,
1078
- // "desc": ""
1079
- // },
1080
- // "table": {
1081
- // "title": null,
1082
- // "table": null
1083
- // },
1084
- // "text": {
1085
- // "originText": "① 头部防护:安全帽\n佩戴要求:\n①存在坠物或对头部产生碰撞风险的作业场所需要佩戴安全帽 ;\n②安全帽必须戴正、戴牢、不能晃动,要系紧下颏带,调节好后箍以\n防安全帽脱落 ;\n③受强力撞击及超过有效期的安全帽必须更换。",
1086
- // "indexText": "① 头部防护:安全帽\n佩戴要求:\n①存在坠物或对头部产生碰撞风险的作业场所需要佩戴安全帽 ;\n②安全帽必须戴正、戴牢、不能晃动,要系紧下颏带,调节好后箍以\n防安全帽脱落 ;\n③受强力撞击及超过有效期的安全帽必须更换。",
1087
- // "lines": [
1088
- // {
1089
- // "location": [
1090
- // 69.08148,
1091
- // 368.92072,
1092
- // 65.90851,
1093
- // 10.5
1094
- // ]
1095
- // },
1096
- // {
1097
- // "location": [
1098
- // 86.290985,
1099
- // 384.67072,
1100
- // 31.5,
1101
- // 10.5
1102
- // ]
1103
- // },
1104
- // {
1105
- // "location": [
1106
- // 286.2992,
1107
- // 315.73584,
1108
- // 37.656006,
1109
- // 12.0
1110
- // ]
1111
- // },
1112
- // {
1113
- // "location": [
1114
- // 324.6939,
1115
- // 316.79932,
1116
- // 122.74487,
1117
- // 10.5
1118
- // ]
1119
- // },
1120
- // {
1121
- // "location": [
1122
- // 286.2954,
1123
- // 336.0458,
1124
- // 149.625,
1125
- // 10.5
1126
- // ]
1127
- // },
1128
- // {
1129
- // "location": [
1130
- // 286.2954,
1131
- // 356.0483,
1132
- // 161.15405,
1133
- // 10.5
1134
- // ]
1135
- // },
1136
- // {
1137
- // "location": [
1138
- // 286.2954,
1139
- // 376.0508,
1140
- // 161.15405,
1141
- // 10.5
1142
- // ]
1143
- // },
1144
- // {
1145
- // "location": [
1146
- // 286.2954,
1147
- // 396.0533,
1148
- // 76.125,
1149
- // 10.5
1150
- // ]
1151
- // },
1152
- // {
1153
- // "location": [
1154
- // 286.2954,
1155
- // 416.05582,
1156
- // 161.17517,
1157
- // 10.5
1158
- // ]
1159
- // },
1160
- // {
1161
- // "location": [
1162
- // 286.2954,
1163
- // 436.8038,
1164
- // 52.5,
1165
- // 10.5
1166
- // ]
1167
- // },
1168
- // {
1169
- // "location": [
1170
- // 338.7992,
1171
- // 435.73584,
1172
- // 12.0,
1173
- // 12.0
1174
- // ]
1175
- // }
1176
- // ]
1177
- // }
1178
- // }
1179
- // }
1180
- // ],
1181
- // "code": "0",
1182
- // "msg": null,
1183
- // "traceId": null
1184
- // }
1185
- if (res.data.code == 0) {
1186
- // tagIds 会按照gpt识别的生成有序的数组,前端直接按照下标的顺序取就可以了
1187
- // 缓存拿到的所有数据
1188
- this.cachePdf = res.data.data
1189
- let publicPageFileUrl = res.data.data && res.data.data[0] ? res.data.data[0].publicPageFileUrl : ''
1190
- this.currentPage = 0
1191
- if (publicPageFileUrl && publicPageFileUrl.substring(publicPageFileUrl.lastIndexOf('.')) === '.pdf') {
1192
- this.preViewType = 'pdf'
1193
- this.setPageAllLine(this.cachePdf)
1194
- this.getpdfResloutePage(res.data.data[0])
1195
- } else {
1196
- this.preViewType = 'excal'
1197
- this.$http.post(
1198
- '/knowledge-api/temporary-certificate/or-origin?expired=30',
1199
- publicPageFileUrl,
1200
- {
1201
- headers: {
1202
- "Content-Type": "application/json",
1203
- },
1204
- }).then(res => {
1205
- // 使用原声请求方式 axios会带有不需要的请求头
1206
- let xhr = new XMLHttpRequest();
1207
- xhr.open('GET', res.data || res.bodyText, true);
1208
- // 定义请求完成的处理函数,请求前也可以增加加载框/禁用下载按钮逻辑
1209
- xhr.onload = ({ currentTarget }) => {
1210
- // 请求完成
1211
- if (currentTarget.status === 200) { // 返回200
1212
- let pdf_view = document.getElementsByClassName('pdf_view');
1213
- if (pdf_view && pdf_view[0]){
1214
- pdf_view[0].style.backgroundImage = 'none'
1215
- }
1216
- this.contentView.innerHTML = currentTarget.response
1217
- this.contentView.style.padding = '10px'
1218
- // this.contentView.style.position = 'relative'
1219
- this.$refs.pdfView.style.backgroundColor = '#FFFFFF'
1220
- this.$refs.pdfView.appendChild(this.contentView)
1221
-
1222
- let allTr = Array.from(this.$refs.pdfView.getElementsByTagName('tr'))
1223
- this.allTr = []
1224
- for (let index = 0; index < allTr.length; index++) {
1225
- if (value.includes(allTr[index].getAttribute('tag-id'))) {
1226
- this.allTr.push(allTr[index])
1227
- }
1228
- }
1229
- this.currentChange(1)
1230
-
1231
- }
1232
- }
1233
- xhr.send();
1234
- })
1235
- }
1236
- } else {
1237
- let div = document.createElement('div')
1238
- div.innerText = this.$t('dragonCommon.fileloadException')
1239
- this.contentView.appendChild(div)
1240
- this.$refs.pdfView.appendChild(this.contentView)
1241
- }
1242
- })
1243
- }
1244
- },
1245
- deep: true,
1246
- immediate: true
1247
- }
1248
- },
1249
- mounted () {
1250
- this.$i18n.locale = sessionStorage.getItem("systemLanguage") || 'cn';
1251
- this.scaleList = [
1252
- {
1253
- label: this.$t('dragonCommon.scaleAuto'),
1254
- value: 'auto'
1255
- },
1256
- {
1257
- label: this.$t('dragonCommon.scaleReality'),
1258
- value: 'reality'
1259
- },
1260
- {
1261
- label: '100%',
1262
- value: 1
1263
- },
1264
- {
1265
- label: '120%',
1266
- value: 1.2
1267
- },
1268
- {
1269
- label: '150%',
1270
- value: 1.5
1271
- },
1272
- {
1273
- label: '170%',
1274
- value: 1.7
1275
- }
1276
- ,
1277
- {
1278
- label: '200%',
1279
- value: 2
1280
- }
1281
- ]
1282
- if (/(iPhone|iPad|iPod|iOS|Android)/i.test(navigator.userAgent)) {
1283
- this.isPC = false
1284
- } else {
1285
- this.isPC = true
1286
- }
1287
- }
1288
- }
1289
- </script>
1290
-
1291
- <style lang="less" scoped>
1292
- .pdf_view {
1293
- width: 100%;
1294
- // height: calc(100% - 110px);
1295
- height: 100%;
1296
- overflow: auto;
1297
- //overflow-y: scroll;
1298
- background-color: #f5f7fb;
1299
- // margin-bottom: 60px;
1300
- box-sizing: border-box;
1301
- // position: relative;
1302
- // > div {
1303
- // width: 100%;
1304
- // height: 100%;
1305
- // overflow: hidden;
1306
- // overflow-y: auto;
1307
- // position: relative;
1308
- // }
1309
- >iframe {
1310
- width: 100%;
1311
- height: 100%;
1312
- }
1313
-
1314
- a:link {
1315
- color: none;
1316
- }
1317
-
1318
- a:visited {
1319
- color: none;
1320
- }
1321
-
1322
- a:hover {
1323
- color: none;
1324
- }
1325
-
1326
- a:active {
1327
- color: none;
1328
- }
1329
- .btn_footer {
1330
- width: 100%;
1331
- height: 60px;
1332
- display: flex;
1333
- align-items: center;
1334
- justify-content: space-around;
1335
- position: absolute;
1336
- bottom: 0px;
1337
- left: 0;
1338
- z-index: 999;
1339
- background: #ffffff;
1340
-
1341
- .prev,
1342
- .next {
1343
- width: 35%;
1344
- height: 40px;
1345
- display: flex;
1346
- align-items: center;
1347
- justify-content: center;
1348
- border-radius: 50px;
1349
- cursor: pointer;
1350
- }
1351
-
1352
- .prev {
1353
- background: #F2F5FA;
1354
- color: #000;
1355
- }
1356
-
1357
- .next {
1358
- background: #366aff;
1359
- color: #ffffff;
1360
- }
1361
- }
1362
-
1363
- #pagination {
1364
- .total-class {
1365
- margin-right: 13px;
1366
- font-weight: 400;
1367
- }
1368
-
1369
- position: absolute;
1370
- bottom: 0px;
1371
- right: 0;
1372
- width: 100%;
1373
- display: flex;
1374
- align-items: center;
1375
- justify-content: center;
1376
- height: 50px;
1377
- background-color: white;
1378
- box-shadow: 0px 0px 18px 0px rgba(29, 55, 129, 0.07);
1379
- border-radius: 5px;
1380
- z-index: 1000;
1381
-
1382
-
1383
-
1384
- /deep/.el-pagination {
1385
- margin-right: 110px;
1386
- }
1387
-
1388
- /deep/.el-pager {
1389
- background: #EDF0F6;
1390
- border-radius: 15px;
1391
- }
1392
-
1393
- /deep/.el-pagination.is-background .btn-next {
1394
- width: 30px;
1395
- height: 30px;
1396
- background: #EDF0F6;
1397
- border-radius: 50%;
1398
- }
1399
-
1400
- /deep/.el-pagination .btn-next {
1401
- width: 30px;
1402
- height: 30px;
1403
- background: #EDF0F6;
1404
- border-radius: 50%;
1405
- padding-left: 0;
1406
- margin-left: 5px;
1407
- }
1408
-
1409
- /deep/.el-pagination .btn-prev {
1410
- width: 30px;
1411
- height: 30px;
1412
- background: #EDF0F6;
1413
- border-radius: 50%;
1414
- padding-right: 0;
1415
- margin-right: 5px;
1416
- }
1417
-
1418
- /deep/.el-pagination button {
1419
- padding: 0;
1420
- min-width: 30px;
1421
- }
1422
-
1423
- /deep/.el-pager li {
1424
- background: #EDF0F6;
1425
- height: 30px;
1426
- min-width: 30px;
1427
- line-height: 30px;
1428
- font-size: 12px;
1429
- color: #717b90;
1430
- }
1431
-
1432
- /deep/.el-pager li:first-child {
1433
- border-bottom-left-radius: 15px !important;
1434
- border-top-left-radius: 15px !important;
1435
- }
1436
-
1437
- /deep/.el-pager li:last-child {
1438
- border-top-right-radius: 15px !important;
1439
- border-bottom-right-radius: 15px !important;
1440
- }
1441
-
1442
- /deep/.el-pager li.active {
1443
- width: 30px;
1444
- height: 30px;
1445
- min-width: 30px;
1446
- background: #366AFF;
1447
- border: 3px solid #A1B9FF;
1448
- border-radius: 50%;
1449
- line-height: 24px;
1450
- color: white;
1451
- }
1452
-
1453
- /deep/.el-pagination.is-background .el-pager li:not(.disabled).active {
1454
- background: #366AFF;
1455
- }
1456
- }
1457
-
1458
- .change_scale {
1459
- width: 100%;
1460
- height: 50px;
1461
- position: absolute;
1462
- top: 50px;
1463
- left: 0;
1464
- background: #ffffff;
1465
- display: flex;
1466
- align-items: center;
1467
- padding: 0 10px;
1468
- box-sizing: border-box;
1469
-
1470
- section {
1471
- cursor: pointer;
1472
- width: 30px;
1473
- height: 30px;
1474
- margin-right: 5px;
1475
- border-radius: 5px;
1476
- display: flex;
1477
- align-items: center;
1478
- justify-content: center;
1479
-
1480
- i {
1481
- font-weight: 900;
1482
- }
1483
- }
1484
-
1485
- section:hover {
1486
- background: rgba(221, 222, 223, 1);
1487
- }
1488
- }
1489
- .pdf_container_view{
1490
- height: 100%;
1491
- width: 100%;
1492
- position: relative;
1493
- overflow: auto;
1494
- }
1495
- }
1496
- </style>
1497
- <style lang="less">
1498
- .animation {
1499
- animation-name: highlight;
1500
- animation-duration: 4s;
1501
- }
1502
-
1503
- @keyframes highlight {
1504
- 0% {
1505
- background: rgba(255, 136, 0, 0.3);
1506
- }
1507
-
1508
- 25% {
1509
- background: rgba(255, 136, 0, 0.6);
1510
- }
1511
-
1512
- 50% {
1513
- background: rgba(255, 136, 0, 0.3);
1514
- }
1515
-
1516
- 75% {
1517
- background: rgba(255, 136, 0, 0.6);
1518
- }
1519
-
1520
- 100% {
1521
- background: rgba(255, 136, 0, 0.3);
1522
- }
1523
- }</style>
1
+ <template>
2
+ <div class="pdf_view" id="pdf_view">
3
+ <div class="change_scale" v-if="isPC">
4
+ <section @click="changeScale('reduce')">
5
+ <i class="el-icon-minus"></i>
6
+ </section>
7
+ <el-divider direction="vertical"></el-divider>
8
+ <section @click="changeScale('zoom')">
9
+ <i class="el-icon-plus"></i>
10
+ </section>
11
+ <el-select size="small" v-model="handScale" @change="changeScale" :placeholder="$t('dragonCommon.selectScale')">
12
+ <el-option v-for="item in scaleList" :key="item.value" :label="item.label" :value="item.value">
13
+ </el-option>
14
+ </el-select>
15
+ </div>
16
+ <div class="pdf_container_view" id="pdf_container_view" @scroll="pdfScroll" ref="pdfView"></div>
17
+ <div class="btn_footer" v-if="tagIds.length > 1 && !isPC">
18
+ <div class="prev" @click="prev">{{ $t('dragonCommon.previous') }}</div>
19
+ <div class="next" @click="next">{{ $t('dragonCommon.next') }}</div>
20
+ </div>
21
+ <div id="pagination" v-if="tagIds.length > 1 && isPC">
22
+ <el-pagination
23
+ :current-page="currentPage + 1"
24
+ @current-change="currentChange"
25
+ @prev-click="prev"
26
+ @next-click="next"
27
+ layout="slot, prev, pager, next"
28
+ :page-size="1"
29
+ :total="tagIds.length"
30
+ >
31
+ <span class="total-class">{{ $t('dragonCommon.answersGeneratedByPre') }}{{tagIds.length}}{{ $t('dragonCommon.answersGeneratedByAfter') }}</span>
32
+ </el-pagination>
33
+ </div>
34
+ </div>
35
+ </template>
36
+ <script>
37
+ // :style="{
38
+ // marginBottom: tagIds.length > 1 ? '60px' : '0px',
39
+ // height: setHeight
40
+ // }"
41
+ import _ from 'lodash'
42
+ import { newInitWaterMark } from "../assets/js/common";
43
+ // import * as pdfjsLib from 'pdfjs-dist'
44
+ // pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdfjs-dist/build/pdf.worker';
45
+ // import { TextLayerBuilder } from "pdfjs-dist/web/pdf_viewer";
46
+ // EventBus pdf_viewer 支持绑定自定义事件,一版不做
47
+ // import 'pdfjs-dist/web/pdf_viewer.css'
48
+ /* eslint-disable */
49
+ const pdfjsLib = window['pdfjsLib']
50
+ if (pdfjsLib) {
51
+ pdfjsLib.GlobalWorkerOptions.workerSrc = window['pdfjs-dist/build/pdf.worker']
52
+ // 'pdfjs-dist/build/pdf.worker';
53
+ }
54
+ const { TextLayerBuilder } = window['pdfjs-dist/web/pdf_viewer']
55
+ const CSS_UNITS = 96.0 / 72.0
56
+ // import { zoomElement } from '../assets/js/hammer'
57
+ export default {
58
+ name: 'pdfView',
59
+ props: ['tagIds', 'isMessageRecord','fileName', "knowledgeItem",'textWatermarkStr'],
60
+ data () {
61
+ return {
62
+ url: '',
63
+ pages: [],
64
+ pageLoadStatus: {
65
+ WAIT: 0,
66
+ LOADED: 1,
67
+ },
68
+ scale: 1,
69
+ rotation: 0,
70
+ pageSize: {},
71
+ PAGE_INTVERVAL: 15,
72
+ SLICE_COUNT: 5,
73
+ contentView: null,
74
+ fisrtLoad: true,
75
+ TextLayerBuilder: null,
76
+ totalPageCount: 0,
77
+ identifyTextPostion: {
78
+ top: 0,
79
+ left: 0,
80
+ width: 100,
81
+ height: 0,
82
+ page: 1,
83
+ pageHeight: 0,
84
+ pageWidth: 0,
85
+ extractInfo: {},
86
+ currentPageAllLine: []
87
+ },
88
+ currentPageAllLine: [],
89
+ pdfUrl: '',
90
+ cachePdf: [],
91
+ newViewer: null,
92
+ currentPage: 0,
93
+ changetoolbar: false,
94
+ allTr: [],
95
+ preViewType: 'pdf',
96
+ displacement: {
97
+ pageX: 0,
98
+ pageY: 0,
99
+ moveable: false,
100
+ pageX2: 0,
101
+ pageY2: 0,
102
+ originScale: 1,
103
+ },
104
+ isTouchMoved: false,
105
+ transformSalce: null,
106
+ defaultTransform:0.8,
107
+ isPC: false,
108
+ handScale: 'auto',
109
+ scaleList: [],
110
+ scrollTop: 0,
111
+ scrollLeft: 0
112
+ }
113
+ },
114
+ methods: {
115
+ getpdfResloutePage (pdfResloute) {
116
+ // 根据当前页面宽度设置缩放比例
117
+ // this.scale = Math.round(this.$refs.pdfView.clientWidth / pdfResloute.pageWidth * 100) / 100
118
+ if (this.isMessageRecord) {
119
+ this.scale = Math.round(this.$refs.pdfView.clientWidth / pdfResloute.pageWidth * 100) / 100
120
+ } else {
121
+ this.scale = 2
122
+ }
123
+ // 从后端获取到当前分片后所有的pdf页码,初始化数组,数组下{} 对应每页pdf文件
124
+ this.pdfUrl = pdfResloute.publicPageFileUrl.substring(0, pdfResloute.publicPageFileUrl.lastIndexOf('/') + 1)
125
+ this.initPages(pdfResloute.total)
126
+ // 定位功能,加载对应页码位置
127
+ this.loadPdfData(pdfResloute.page)
128
+ },
129
+ async loadPdfData (loadPage) {
130
+ if (this.pages[loadPage - 1] && ((this.pages[loadPage - 1].dom && this.pages[loadPage - 1].dom.children.length > 0) || this.pages[loadPage - 1].loadStatus)) {
131
+ return
132
+ } else {
133
+ if (this.changetoolbar) {
134
+ this.$nextTick(() => {
135
+ this.renderHighlights()
136
+ })
137
+ this.changetoolbar = false
138
+ }
139
+ }
140
+ // 记录开始缓存的状态
141
+ // pdfjsLib.GlobalWorkerOptions.workerSrc = require("pdfjs-dist/legacy/build/pdf.worker.entry.js");
142
+ // 拿到第一个分片
143
+ const { startPage, url } = await this.fetchPdfFragment(loadPage);
144
+ let loadingTask = pdfjsLib.getDocument(url)
145
+ loadingTask.promise.then(async (pdfDoc) => {
146
+ // 将已经下载的分片保存到 pages 数组中
147
+ // for (let i = 0; i < pdfDoc.numPages; i += 1) {
148
+ // const pageIndex = startPage + i;
149
+ // const page = this.pages[pageIndex - 1];
150
+ // // // 不在缓存列表内,重新获取本页pdf
151
+ // // if (page.loadStatus !== this.pageLoadStatus.LOADED) {
152
+
153
+ // // } else {
154
+ // // if (this.changetoolbar) {
155
+ // // this.$nextTick(() => {
156
+ // // this.renderHighlights()
157
+ // // })
158
+ // // this.changetoolbar = false
159
+ // // }
160
+ // // }
161
+ // }
162
+ const page = this.pages[loadPage - 1]
163
+ await pdfDoc.getPage(1).then(async (pdfPage) => {
164
+ this.pages[loadPage - 1].loadStatus = true
165
+ this.pages[loadPage - 1].pdfPage = pdfPage;
166
+ // 通知可以进行渲染了
167
+ await this.startRenderPages(pdfPage, page, loadPage)
168
+ });
169
+ });
170
+ },
171
+ initPages (totalPage) {
172
+ // const pages = [];
173
+ this.totalPageCount = totalPage
174
+ for (let i = 0; i < totalPage; i += 1) {
175
+ this.pages.push({
176
+ pageNo: i + 1,
177
+ loadStatus: false,
178
+ pdfPage: null,
179
+ dom: null
180
+ });
181
+ }
182
+ },
183
+ async fetchPdfFragment (pageIndex) {
184
+ // 置换加签后的文件地址。
185
+ let obj = {}
186
+ await this.$http.post(
187
+ '/knowledge-api/temporary-certificate/or-origin?expired=30',
188
+ this.pdfUrl + pageIndex + '.pdf',
189
+ {
190
+ headers: {
191
+ "Content-Type": "application/json",
192
+ },
193
+ }).then(async res => {
194
+ if (res.bodyText) {
195
+ // 最后返回一个 包含这4个参数的对象
196
+ obj = await {
197
+ "startPage": pageIndex, // 分片的开始页码
198
+ "endPage": pageIndex + 5, // 分片结束页码
199
+ "totalPage": this.totalPageCount, // pdf 总页数
200
+ "url": res.bodyText // 分片内容下载地址
201
+ }
202
+ }
203
+ if (res.data) {
204
+ // 最后返回一个 包含这4个参数的对象
205
+ obj = await {
206
+ "startPage": pageIndex, // 分片的开始页码
207
+ "endPage": pageIndex + 5, // 分片结束页码
208
+ "totalPage": this.totalPageCount, // pdf 总页数
209
+ "url": res.data // 分片内容下载地址
210
+ }
211
+ }
212
+ })
213
+ return obj
214
+ },
215
+ startRenderPages (pdfPage, page, pageIndex) {
216
+ if (Object.keys(this.pageSize).length == 0) {
217
+ const viewport = pdfPage.getViewport({
218
+ scale: this.scale, // 缩放的比例
219
+ rotation: this.rotation, // 旋转的角度
220
+ });
221
+ // 记录pdf页面高度
222
+ const pageSize = {
223
+ width: viewport.width,
224
+ height: viewport.height,
225
+ }
226
+ this.pageSize = pageSize
227
+ // 创建内容绘制区,并设置大小
228
+ if (this.$refs.pdfView.clientWidth / this.pageSize.width >= 1 || this.isMessageRecord) {
229
+ this.contentView.style.width = `${pageSize.width - 10}px`;
230
+ this.contentView.style.height = `${(this.totalPageCount * (pageSize.height + this.PAGE_INTVERVAL)) + this.PAGE_INTVERVAL}px`;
231
+ } else {
232
+ this.transformSalce = this.$refs.pdfView.clientWidth / this.pageSize.width
233
+ this.contentView.style.width = `${pageSize.width * this.transformSalce - 10}px`;
234
+ this.contentView.style.height = `${(this.totalPageCount * (pageSize.height * (this.transformSalce) + this.PAGE_INTVERVAL)) + this.PAGE_INTVERVAL}px`;
235
+ }
236
+ this.contentView.style.margin = '0 auto 0'
237
+ this.contentView.style.position = 'relative'
238
+ this.contentView.style.paddingBottom = '60px'
239
+ // contentView.style.overflowY = 'auto'
240
+ this.$refs.pdfView.appendChild(this.contentView);
241
+ if (this.textWatermarkStr){
242
+ newInitWaterMark('pdf_container_view',this.textWatermarkStr)
243
+ }
244
+ }
245
+ this.renderPages(pageIndex)
246
+ },
247
+ // 渲染需要展示的页面,不需展示的页码将其清除
248
+ renderPages (pageIndex) {
249
+ const pagesToRender = this.getRenderScope(pageIndex);
250
+ for (const i of this.pages) {
251
+ if (pagesToRender.some(p => { return p.pageNo == i.pageNo })) {
252
+ if (i.loadStatus === true) {
253
+ this.renderPageContent(i, i.pageNo)
254
+ } else {
255
+ this.renderPageLoading(i, i.pageNo)
256
+ }
257
+ } else {
258
+ this.clearPage(i);
259
+ }
260
+ }
261
+
262
+ },
263
+ async renderPageContent (page, pageIndex) {
264
+ const { pdfPage, pageNo, dom } = page;
265
+ // dom 元素已存在,无须重新渲染,直接返回
266
+ if ((dom && dom.children.length != 0) || page.loading) {
267
+ return;
268
+ }
269
+ page.loading = true
270
+ const viewport = pdfPage.getViewport({
271
+ scale: this.scale,
272
+ rotation: this.rotation,
273
+ });
274
+ // 创建新的canvas
275
+ const canvas = document.createElement('canvas');
276
+ const context = canvas.getContext('2d');
277
+ // canvas.getContext('2d');
278
+ canvas.height = this.pageSize.height;
279
+ canvas.width = this.pageSize.width;
280
+ canvas.style.position = 'relative'
281
+ canvas.style.top = -3 + 'px'
282
+ // 创建渲染的dom
283
+ const pageDom = document.createElement('div');
284
+ pageDom.style.position = 'absolute';
285
+ pageDom.style.top = `${((pageNo - 1) * (this.pageSize.height + this.PAGE_INTVERVAL)) + this.PAGE_INTVERVAL}px`;
286
+ pageDom.style.width = `${this.pageSize.width}px`;
287
+ pageDom.style.height = `${this.pageSize.height}px`;
288
+ pageDom.setAttribute('data-id', 'page' + pageNo)
289
+ pageDom.appendChild(canvas);
290
+ // 渲染内容
291
+ let renderContext = {
292
+ canvasContext: context,
293
+ viewport: viewport,
294
+ }
295
+ await pdfPage.render(renderContext).promise.then(() => {
296
+ return pdfPage.getTextContent()
297
+ }).then(async (textContent) => {
298
+ const textLayerDiv = document.createElement('div');
299
+ textLayerDiv.setAttribute('class', 'textLayer');
300
+ // 将文本图层div添加至每页pdf的div中
301
+ // 创建新的TextLayerBuilder实例
302
+ let textLayer = new TextLayerBuilder({
303
+ textLayerDiv: textLayerDiv,
304
+ pageIndex: pdfPage._pageIndex,
305
+ viewport: viewport,
306
+ });
307
+ let findPage = this.currentPageAllLine.find(l => { return l.page == pageIndex })
308
+ let rectdomTop = 0
309
+ if (findPage) {
310
+ let AllLines = findPage.allLines
311
+ // setTimeout(() => {
312
+ if (AllLines.length > 0) {
313
+ for (let j = 0; j < AllLines.length; j++) {
314
+ let lines = AllLines[j].lines
315
+ let rectdom = document.createElement('div')
316
+ rectdom.setAttribute('react-count', AllLines[j].pageCount);
317
+ rectdom.style.position = 'absolute';
318
+ rectdom.style.top = 0
319
+ rectdom.style.left = 0
320
+ rectdom.classList.add('rectdom')
321
+ if (lines){
322
+ for (let index = 0; index < lines.length; index++) {
323
+ if (!/^\s+$/g.test(lines[index].content)) {
324
+ let postionArr = lines[index].location
325
+ let div = document.createElement('div')
326
+ div.style.position = 'absolute';
327
+ div.style.left = postionArr[0] * this.scale + 'px',
328
+ // 后端返回的坐标有基线对齐的问题,top 值是后端算好(基线top - 文字高度),在此加上文字高度的 1/9 (大致比例)为实际展示出文字的top值
329
+ div.style.top = postionArr[1] * this.scale + 'px'
330
+ div.style.height = postionArr[3] * this.scale + 'px';
331
+ div.style.width = postionArr[2] * this.scale + 'px'
332
+ div.style.backgroundColor = 'rgba(54, 106, 255, 0.3)'
333
+ div.classList.add('lineHeight')
334
+ rectdom.appendChild(div)
335
+ if (index == 0 && j == 0) {
336
+ if (this.transformSalce !== null) {
337
+ rectdomTop = postionArr[1] * this.scale * this.transformSalce
338
+ } else {
339
+ rectdomTop = postionArr[1] * this.scale
340
+ }
341
+ // if(this.isPC) {
342
+ // rectdomTop = rectdomTop - 50 < 0 ? 0 : rectdomTop - 50
343
+ // }
344
+ }
345
+ }
346
+ }
347
+ }
348
+ if (rectdom.children && rectdom.children.length > 0) {
349
+ pageDom.appendChild(rectdom)
350
+ }
351
+ }
352
+ }
353
+ }
354
+ textLayer.setTextContent(textContent);
355
+ textLayer.render()
356
+ pageDom.appendChild(textLayerDiv);
357
+
358
+ let backgroundDom = document.getElementById('backgroundLoad' + pageNo)
359
+ if (backgroundDom) {
360
+ this.contentView.removeChild(backgroundDom);
361
+ }
362
+ page.dom = await pageDom;
363
+ page.loading = false
364
+ this.contentView.appendChild(pageDom);
365
+ let pdf_view = document.getElementsByClassName('pdf_view');
366
+ if (pdf_view && pdf_view[0]){
367
+ pdf_view[0].style.backgroundImage = 'none'
368
+ }
369
+ if (this.transformSalce !== null) {
370
+ this.contentView.style.transform = `scale(${this.transformSalce}, ${this.transformSalce})`
371
+ }
372
+ if (this.changetoolbar) {
373
+ setTimeout(() => {
374
+ this.renderHighlights()
375
+ this.changetoolbar = false
376
+ }, 500)
377
+ }
378
+ if (this.fisrtLoad) {
379
+ setTimeout(() => {
380
+ let pageoffsetHeight = 0
381
+ if (this.transformSalce !== null) {
382
+ pageoffsetHeight = (this.pageSize.height + this.PAGE_INTVERVAL) * this.transformSalce
383
+ } else {
384
+ pageoffsetHeight = (this.pageSize.height + this.PAGE_INTVERVAL)
385
+ }
386
+ if (this.$refs.pdfView.clientHeight - pageoffsetHeight > 0 && pageIndex == 1) {
387
+ const height = this.$refs.pdfView.clientHeight;
388
+ let startNum = 0
389
+ let endNum = 0
390
+ if (this.transformSalce !== null) {
391
+ startNum = Math.ceil(this.$refs.pdfView.scrollTop / ((this.pageSize.height + this.PAGE_INTVERVAL) * this.transformSalce))
392
+ endNum = startNum + Math.ceil(height / ((this.pageSize.height + this.PAGE_INTVERVAL) * this.transformSalce))
393
+ } else {
394
+ startNum = Math.ceil(this.$refs.pdfView.scrollTop / (this.pageSize.height + this.PAGE_INTVERVAL))
395
+ endNum = startNum + Math.ceil(height / (this.pageSize.height + this.PAGE_INTVERVAL))
396
+
397
+ }
398
+ for (let pageIndex = startNum; pageIndex <= endNum; pageIndex++) {
399
+ if (pageIndex > 0 && pageIndex <= this.pages.length) {
400
+ this.loadPdfData(pageIndex)
401
+ }
402
+ }
403
+ }
404
+ if (this.$refs.pdfView.scrollTop == Math.floor((pageNo - 1) * pageoffsetHeight)) {
405
+ this.$refs.pdfView.scrollTop = rectdomTop
406
+ this.fisrtLoad = false
407
+ } else {
408
+ this.$refs.pdfView.scrollTop = `${((pageNo - 1) * pageoffsetHeight) + rectdomTop - this.PAGE_INTVERVAL}`
409
+ this.fisrtLoad = false
410
+ }
411
+ this.renderHighlights()
412
+ // zoomElement(this.contentView)
413
+ }, 100)
414
+ }
415
+ })
416
+ },
417
+ // 监听容器的滚动事件,触发 scrollPdf 方法
418
+ // 这里加了防抖保证不会一次产生过多请求
419
+ debounceScrollPdf: _.debounce(function (e, that) {
420
+ if (this.fisrtLoad) {
421
+ this.fisrtLoad = false
422
+ return
423
+ }
424
+ const scrollTop = e.target.scrollTop;
425
+ const height = e.target.clientHeight;
426
+ let startNum = 0
427
+ let endNum = 0
428
+ if (this.transformSalce !== null) {
429
+ startNum = Math.ceil(scrollTop / ((that.pageSize.height + that.PAGE_INTVERVAL) * this.transformSalce))
430
+ endNum = startNum + Math.ceil(height / ((that.pageSize.height + that.PAGE_INTVERVAL) * this.transformSalce))
431
+ } else {
432
+ startNum = Math.ceil(scrollTop / (that.pageSize.height + that.PAGE_INTVERVAL))
433
+ endNum = startNum + Math.ceil(height / (that.pageSize.height + that.PAGE_INTVERVAL))
434
+ }
435
+ for (let pageIndex = startNum; pageIndex <= endNum; pageIndex++) {
436
+ if (pageIndex > 0 && pageIndex <= that.pages.length) {
437
+ that.loadPdfData(pageIndex)
438
+ }
439
+ }
440
+ }, 200),
441
+ directScrolling (e, that) {
442
+ if (this.fisrtLoad) {
443
+ this.fisrtLoad = false
444
+ return
445
+ }
446
+ const scrollTop = e.target.scrollTop;
447
+ const height = e.target.clientHeight;
448
+ // 根据内容可视区域中心点计算页码, 没有滚动时,指向第一页
449
+ const pageIndex = scrollTop > 0 ?
450
+ Math.ceil((scrollTop + (height / 2)) / (that.pageSize.height + that.PAGE_INTVERVAL)) :
451
+ 1;
452
+ this.loadPdfData(pageIndex)
453
+ },
454
+ pdfScroll (e) {
455
+ if (this.preViewType !== 'pdf' || this.isTouchMoved) {
456
+ return
457
+ }
458
+ if (this.scrollLeft != e.target.scrollLeft) {
459
+ this.scrollLeft = e.target.scrollLeft
460
+ }
461
+ if (this.scrollTop != e.target.scrollTop) {
462
+ this.scrollTop = e.target.scrollTop
463
+ this.debounceScrollPdf(e, this)
464
+ }
465
+ },
466
+ // 分片每次只做一次处理,所以不考虑多片情况
467
+ loadBefore (pageIndex) {
468
+ this.loadPdfData(pageIndex)
469
+ },
470
+ loadAfter (pageIndex) {
471
+ this.loadPdfData(pageIndex)
472
+ },
473
+ // 首先我们获取到需要渲染的范围
474
+ // 根据当前的可视范围内的页码,我们前后只保留 8 页
475
+ getRenderScope (pageIndex) {
476
+ const pagesToRender = [];
477
+ let i = pageIndex - 1;
478
+ let j = pageIndex + 1;
479
+ // pageIndex - 1 表示当前页码数 对应的下标位置
480
+ pagesToRender.push(this.pages[pageIndex - 1]);
481
+ while (pagesToRender.length < 8 && pagesToRender.length < this.pages.length) {
482
+ if (i > 0) {
483
+ pagesToRender.push(this.pages[i - 1]);
484
+ i -= 1;
485
+ }
486
+ if (pagesToRender.length >= 8) {
487
+ break;
488
+ }
489
+ if (j <= this.pages.length) {
490
+ pagesToRender.push(this.pages[j - 1]);
491
+ j += 1;
492
+ }
493
+ }
494
+ // for (let index = 0; index < array.length; index++) {
495
+ // const element = array[index];
496
+
497
+ // }
498
+ return pagesToRender;
499
+ },
500
+
501
+ // 清除页面 dom
502
+ clearPage (page) {
503
+ if (this.contentView.contains(page.dom) && page.dom) {
504
+ this.contentView.removeChild(page.dom);
505
+ page.loadStatus = false
506
+ page.loading = false
507
+ page.dom = undefined;
508
+ }
509
+ },
510
+ // 页面正在下载时渲染loading视图
511
+ renderPageLoading (page) {
512
+ const { pageNo, dom } = page;
513
+ if (dom && dom.children.length != 0) {
514
+ return;
515
+ }
516
+ let backgroundDom = document.getElementById('backgroundLoad' + pageNo)
517
+ if (this.contentView.contains(backgroundDom)) {
518
+ return
519
+ }
520
+ const pageDom = document.createElement('div');
521
+ pageDom.style.width = `${this.pageSize.width}px`;
522
+ pageDom.style.height = `${this.pageSize.height}px`;
523
+ pageDom.style.position = 'absolute';
524
+ pageDom.style.top = `${((pageNo - 1) * (this.pageSize.height + this.PAGE_INTVERVAL)) + this.PAGE_INTVERVAL
525
+ }px`;
526
+ pageDom.style.backgroundImage = `url('https://guoranopen-zjk.oss-cn-zhangjiakou.aliyuncs.com/cdn-common/images/loading.gif')`
527
+ pageDom.style.backgroundPosition = 'center'
528
+ pageDom.style.backgroundRepeat = 'no-repeat'
529
+ pageDom.style.backgroundColor = '#FFF'
530
+ pageDom.setAttribute('id', 'backgroundLoad' + pageNo)
531
+ page.dom = pageDom;
532
+ this.contentView.appendChild(pageDom);
533
+ },
534
+ prev () {
535
+ this.currentPage--
536
+ if (this.currentPage < 0) {
537
+ this.currentPage = 0
538
+ if (!this.isPC) {
539
+ this.$toast({
540
+ message: this.$t('dragonCommon.firstParagraph'),
541
+ duration: 2000,
542
+ })
543
+ return
544
+ }
545
+ }
546
+ if (this.preViewType == 'pdf') {
547
+ this.scrollToUplaodePage(this.currentPage)
548
+ } else {
549
+ this.scrollToExcalTop(this.currentPage)
550
+ }
551
+ // this.getpdfResloutePage(this.cachePdf[this.currentPage - 1])
552
+ },
553
+ next () {
554
+ this.currentPage++
555
+ if (this.currentPage >= this.tagIds.length) {
556
+ this.currentPage = this.tagIds.length - 1
557
+ if (!this.isPC) {
558
+ this.$toast({
559
+ message: this.$t('dragonCommon.lastParagraph'),
560
+ duration: 2000,
561
+ })
562
+ return
563
+ }
564
+ }
565
+ if (this.preViewType == 'pdf') {
566
+ this.scrollToUplaodePage(this.currentPage)
567
+ } else {
568
+ this.scrollToExcalTop(this.currentPage)
569
+ }
570
+ },
571
+ currentChange (value) {
572
+ this.currentPage = value - 1
573
+ if (this.preViewType == 'pdf') {
574
+ this.scrollToUplaodePage(this.currentPage)
575
+ } else {
576
+ this.scrollToExcalTop(this.currentPage)
577
+ }
578
+ },
579
+ scrollToUplaodePage (currentPage) {
580
+ this.changetoolbar = true
581
+ if (this.preViewType !== 'pdf') {
582
+ return
583
+ }
584
+
585
+ let pdfResloute = this.cachePdf[currentPage]
586
+ this.identifyTextPostion.extractInfo = pdfResloute.extractInfo
587
+ this.identifyTextPostion.left = pdfResloute.extractInfo.location[0]
588
+ this.identifyTextPostion.top = pdfResloute.extractInfo.location[1]
589
+ this.identifyTextPostion.width = pdfResloute.extractInfo.location[2]
590
+ this.identifyTextPostion.height = pdfResloute.extractInfo.location[3]
591
+ this.identifyTextPostion.page = pdfResloute.page
592
+ this.identifyTextPostion.pageHeight = pdfResloute.pageHeight
593
+ this.identifyTextPostion.pageWidth = pdfResloute.pageWidth
594
+ // 在当前段落在最后一页pdf时,根据计算的高度并不能触发滚动,在此执行重新渲染方法,非次情况会执行两次,待优化
595
+ this.$nextTick(() => {
596
+ this.renderHighlights()
597
+ })
598
+ if (this.transformSalce !== null) {
599
+ this.$refs.pdfView.scrollTop = `${((pdfResloute.page - 1) * (this.pageSize.height + this.PAGE_INTVERVAL) * this.transformSalce) + (this.identifyTextPostion.top * this.scale * this.transformSalce)}`
600
+ } else {
601
+ this.$refs.pdfView.scrollTop = `${((pdfResloute.page - 1) * (this.pageSize.height + this.PAGE_INTVERVAL)) + (this.identifyTextPostion.top * this.scale * this.transformSalce)}`
602
+ }
603
+ },
604
+ scrollToExcalTop (currentPage) {
605
+ for (let index = 0; index < this.allTr.length; index++) {
606
+ if (index == currentPage) {
607
+ Array.from(this.allTr[index].children).forEach(item => {
608
+ item.style.background = 'rgba(255, 136, 0, 0.6)'
609
+ item.classList.add('animation')
610
+ setTimeout(() => {
611
+ item.classList.remove('animation')
612
+ }, 4000)
613
+ })
614
+ // getBoundingClientRect().top 当前元素距离屏幕顶部的高度 + 弹窗header 高度
615
+ if (!this.isPC) {
616
+ let top = this.allTr[index].getBoundingClientRect().top - this.$refs.pdfView.getBoundingClientRect().top
617
+ this.$refs.pdfView.scrollTop = top
618
+ } else {
619
+ let top = this.allTr[index].getBoundingClientRect().top
620
+ this.$refs.pdfView.scrollTop = top - 50
621
+ }
622
+ } else {
623
+ Array.from(this.allTr[index].children).forEach(item => {
624
+ item.style.background = 'rgba(54, 106, 255, 0.6)'
625
+ item.classList.remove('animation')
626
+ })
627
+ }
628
+ }
629
+ },
630
+ // pdf是否需要重新渲染高亮位置
631
+ renderHighlights () {
632
+ let lineHeightDom = Array.from(document.getElementsByClassName('rectdom'))
633
+ if (lineHeightDom) {
634
+ lineHeightDom.forEach((d) => {
635
+ for (let i = 0; i < d.children.length; i++) {
636
+ if (d.getAttribute('react-count') == this.currentPage) {
637
+ d.children[i].style.backgroundColor = 'rgba(255, 136, 0, 0.3)'
638
+ d.children[i].classList.add('animation')
639
+ setTimeout(() => {
640
+ d.children[i].classList.remove('animation')
641
+ }, 4000)
642
+ } else {
643
+ d.children[i].style.backgroundColor = 'rgba(54, 106, 255, 0.3)'
644
+ d.children[i].classList.remove('animation')
645
+ }
646
+ }
647
+ })
648
+ }
649
+ },
650
+ displayHiglight (pageIndex) {
651
+ let lineHeightDom = Array.from(document.getElementsByClassName('rectdom'))
652
+ if (lineHeightDom) {
653
+ lineHeightDom.forEach((d) => {
654
+ if (d.getAttribute('page-index') == pageIndex) {
655
+ d.style.display = 'none'
656
+ }
657
+ })
658
+ }
659
+ },
660
+ // 前端暂时缓存多页
661
+ autoLoadMore (pageIndex) {
662
+ let pdfResloute = this.cachePdf.find(cache => {
663
+ return cache.page == pageIndex
664
+ })
665
+ if (pdfResloute) {
666
+ this.getpdfResloutePage(pdfResloute)
667
+ } else {
668
+ this.loadPdfData(pageIndex)
669
+ }
670
+ },
671
+ setPageAllLine (arr) {
672
+ this.currentPageAllLine = []
673
+ arr.forEach((item, index) => {
674
+ let i = this.currentPageAllLine.findIndex(l => { return l.page && l.page == item.page })
675
+ if (i != -1) {
676
+ // this.currentPageAllLine[i].allLines.lines.push(item.extractInfo.lines)
677
+ this.currentPageAllLine[i].allLines.push({
678
+ pageCount: index,
679
+ lines: item.extractInfo.lines ? item.extractInfo.lines : [{
680
+ content:"测试内容填充,不必理会",
681
+ location:item.extractInfo.location
682
+ }]
683
+ })
684
+ } else {
685
+ this.currentPageAllLine.push({
686
+ page: item.page,
687
+ allLines: [{
688
+ pageCount: index,
689
+ lines: item.extractInfo.lines ? item.extractInfo.lines : [{
690
+ content:"测试内容填充,不必理会",
691
+ location:item.extractInfo.location
692
+ }]
693
+ }],
694
+ })
695
+ }
696
+ })
697
+ },
698
+ openTouch () {
699
+ // this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行
700
+ let that = this;
701
+ this.$nextTick(() => {
702
+ // setInterval(() => {
703
+ // this.scale = this.scale + 0.1
704
+ // that.pages.forEach((item, index) =>{
705
+ // if(item.dom) {
706
+ // item.dom.children.forEach( childDom =>{
707
+ // if(childDom.getAttribute('react-count')) {
708
+ // childDom.style.transform = "scale(" + this.scale + ")";
709
+ // childDom.style.transformOrigin = "0px 0px 0px";
710
+ // } else {
711
+ // item.dom = null
712
+ // this.startRenderPages(item.pdfPage, null, index)
713
+ // }
714
+ // } )
715
+ // }
716
+ // })
717
+ // }, 100);
718
+ // 获取放大或缩小的区域DOM
719
+ let matrix_box = this.contentView
720
+ matrix_box.addEventListener("touchstart", function (event) {
721
+ this.isTouchMoved = true
722
+ let touches = event.touches;
723
+ let events = touches[0];
724
+ let events2 = touches[1];
725
+
726
+ // event.preventDefault();
727
+
728
+ // 第一个触摸点的坐标
729
+ that.displacement.pageX = events.pageX;
730
+ that.displacement.pageY = events.pageY;
731
+
732
+ that.displacement.moveable = true;
733
+
734
+ if (events2) {
735
+ that.displacement.pageX2 = events2.pageX;
736
+ that.displacement.pageY2 = events2.pageY;
737
+ }
738
+
739
+ that.displacement.originScale = this.scale || 1;
740
+ });
741
+ document.addEventListener("touchmove", function (event) {
742
+ if (!that.displacement.moveable) {
743
+ return;
744
+ }
745
+ // event.preventDefault();
746
+ let touches = event.touches;
747
+ let events = touches[0];
748
+ let events2 = touches[1];
749
+ // 双指移动
750
+ if (events2) {
751
+ // 第2个指头坐标在touchmove时候获取
752
+ if (!that.displacement.pageX2) {
753
+ that.displacement.pageX2 = events2.pageX;
754
+ }
755
+ if (!that.displacement.pageY2) {
756
+ that.displacement.pageY2 = events2.pageY;
757
+ }
758
+ // 双指缩放比例计算
759
+ let zoom = that.getDistance({
760
+ x: events.pageX,
761
+ y: events.pageY
762
+ },
763
+ {
764
+ x: events2.pageX,
765
+ y: events2.pageY
766
+ }
767
+ ) / that.getDistance(
768
+ {
769
+ x: that.displacement.pageX,
770
+ y: that.displacement.pageY
771
+ },
772
+ {
773
+ x: that.displacement.pageX2,
774
+ y: that.displacement.pageY2
775
+ }
776
+ );
777
+ // 应用在元素上的缩放比例
778
+ let newScale = that.displacement.originScale * zoom;
779
+ // 最大缩放比例限制
780
+ if (newScale > 2) {
781
+ newScale = 2;
782
+ }
783
+ // 最大缩放比例限制
784
+ if (newScale < 1) {
785
+ newScale = 1;
786
+ }
787
+ // 记住使用的缩放值
788
+ that.displacement.scale = newScale;
789
+ // console.log(newScale);
790
+ matrix_box.style.transform = "scale(" + newScale + ")";
791
+ // 设置旋转元素的基点位置
792
+ matrix_box.style.transformOrigin = "0px 0px 0px";
793
+ }
794
+ }, { passive: false });
795
+ document.addEventListener('touchend', function () {
796
+ that.isTouchMoved = false
797
+ }, { passive: false })
798
+ });
799
+ },
800
+ getDistance (start, stop) {
801
+ // Math.hypot()计算参数的平方根
802
+ return Math.hypot(stop.x - start.x, stop.y - start.y);
803
+ },
804
+ setupCanvas (canvas, width, height) {
805
+ const dpr = 1;
806
+ // const rect = canvas.getBoundingClientRect();
807
+ canvas.width = width
808
+ canvas.height = height
809
+ const ctx = canvas.getContext('2d');
810
+ ctx?.scale(dpr, dpr);
811
+ return ctx;
812
+ },
813
+ changeScale (value) {
814
+ if (value == 'zoom') {
815
+ this.handScale = 'auto'
816
+ this.transformSalce = (this.transformSalce + 0.2).toFixed(1)
817
+ } else if (value == 'reduce') {
818
+ if ((this.transformSalce - 0.2).toFixed(1) <= 0) {
819
+ return
820
+ }
821
+ this.handScale = 'auto'
822
+ this.transformSalce = (this.transformSalce - 0.2).toFixed(1)
823
+ } else if (value == 'auto') {
824
+ this.transformSalce = this.$refs.pdfView.clientWidth / this.pageSize.width
825
+ } else if (value == 'reality') {
826
+ this.transformSalce = 0.5
827
+ } else {
828
+ this.transformSalce = (value / 2).toFixed(1)
829
+ }
830
+ this.transformSalce = Number(this.transformSalce)
831
+ this.contentView.style.transform = 'scale(' + this.transformSalce + ')';
832
+ // this.getpdfResloutePage(this.cachePdf[0])
833
+ },
834
+ //添加水印
835
+ watermark() {
836
+ //默认设置
837
+ var defaultSettings = {
838
+ watermark_txt:"",
839
+ watermark_x: 0,//水印起始位置x轴坐标
840
+ watermark_y: 0,//水印起始位置Y轴坐标
841
+ watermark_rows: 0,//水印行数
842
+ watermark_cols: 0,//水印列数
843
+ watermark_x_space: 40,//水印x轴间隔
844
+ watermark_y_space: 60,//水印y轴间隔
845
+ watermark_color: 'black',//水印字体颜色
846
+ watermark_alpha: .3,//水印透明度
847
+ watermark_fontsize: 12,//水印字体大小
848
+ watermark_font: '微软雅黑',//水印字体
849
+ watermark_width: 100,//水印宽度
850
+ watermark_height: 80,//水印长度
851
+ watermark_angle: 20,//水印倾斜度数***
852
+ visitorWatermark_txt:""
853
+ };
854
+ if(this.knowledgeItem.textWatermarkValue){
855
+ defaultSettings.watermark_txt = this.knowledgeItem.textWatermarkValue;
856
+ }
857
+ if (this.knowledgeItem.visitorWatermarkValue){
858
+ defaultSettings.visitorWatermark_txt = this.knowledgeItem.visitorWatermarkValue
859
+ }
860
+ //采用配置项替换默认值,作用类似jquery.extend
861
+ if (arguments.length === 1 && typeof arguments[0] === "object") {
862
+ console.log("arguments = " + JSON.stringify(arguments[0]));
863
+ // 获取参数配置
864
+ var src = arguments[0];
865
+ for (let key in src) {
866
+ if (src[key] && defaultSettings[key] && src[key] === defaultSettings[key])
867
+ continue;
868
+ else if (src[key])
869
+ defaultSettings[key] = src[key];
870
+ }
871
+ }
872
+ var oTemp = document.createDocumentFragment();
873
+ //获取页面最大宽度
874
+ console.debug('pdf_view',document.getElementById('pdf_view'))
875
+ let scrollWidth = document.getElementById('pdf_view').scrollWidth;
876
+ let clientWidth = document.getElementById('pdf_view').clientWidth;
877
+ var page_width = Math.max(scrollWidth, clientWidth);
878
+
879
+ var cutWidth = page_width * 0.0150;
880
+
881
+ page_width = page_width - cutWidth;
882
+
883
+ //获取页面最大高度
884
+ let height = parseInt(this.totalPageCount * this.pageSize.height)
885
+ var page_height = Math.max(document.getElementById('pdf_container_view').scrollHeight,height);
886
+
887
+ console.debug('page_height',page_height,this.totalPageCount * this.pageSize.height);
888
+
889
+ // var page_height = document.body.scrollHeight+document.body.scrollTop;
890
+
891
+ //如果将水印列数设置为0,或水印列数设置过大,超过页面最大宽度,则重新计算水印列数和水印x轴间隔
892
+
893
+ if (defaultSettings.watermark_cols == 0 || (parseInt(defaultSettings.watermark_x + defaultSettings
894
+ .watermark_width * defaultSettings.watermark_cols + defaultSettings.watermark_x_space *
895
+ (defaultSettings.watermark_cols - 1)) > page_width)) {
896
+ defaultSettings.watermark_cols = parseInt((page_width - defaultSettings.watermark_x + defaultSettings
897
+ .watermark_x_space) / (defaultSettings.watermark_width + defaultSettings
898
+ .watermark_x_space));
899
+ defaultSettings.watermark_x_space = parseInt((page_width - defaultSettings.watermark_x -
900
+ defaultSettings
901
+ .watermark_width * defaultSettings.watermark_cols) / (defaultSettings.watermark_cols - 1));
902
+ }
903
+
904
+ //如果将水印行数设置为0,或水印行数设置过大,超过页面最大长度,则重新计算水印行数和水印y轴间隔
905
+
906
+ if (defaultSettings.watermark_rows == 0 || (parseInt(defaultSettings.watermark_y + defaultSettings
907
+
908
+ .watermark_height * defaultSettings.watermark_rows + defaultSettings.watermark_y_space * (
909
+
910
+ defaultSettings.watermark_rows - 1)) > page_height)) {
911
+
912
+ defaultSettings.watermark_rows = parseInt((defaultSettings.watermark_y_space + page_height -
913
+
914
+ defaultSettings
915
+
916
+ .watermark_y) / (defaultSettings.watermark_height + defaultSettings.watermark_y_space));
917
+
918
+ defaultSettings.watermark_y_space = parseInt(((page_height - defaultSettings.watermark_y) -
919
+
920
+ defaultSettings
921
+
922
+ .watermark_height * defaultSettings.watermark_rows) / (defaultSettings.watermark_rows - 1));
923
+
924
+ }
925
+
926
+ var x;
927
+
928
+ var y;
929
+
930
+ for (var i = 0; i < defaultSettings.watermark_rows; i++) {
931
+ y = defaultSettings.watermark_y + (defaultSettings.watermark_y_space + defaultSettings.watermark_height) * i;
932
+ for (var j = 0; j < defaultSettings.watermark_cols; j++) {
933
+ x = defaultSettings.watermark_x + (defaultSettings.watermark_width + defaultSettings.watermark_x_space) * j;
934
+
935
+ var mask_div = document.createElement('div');
936
+ mask_div.id = 'mask_div' + i + j;
937
+ mask_div.className = 'mask_div';
938
+
939
+ //注意看这里加了图片水印
940
+ mask_div.style.webkitTransform = "rotate(-" + defaultSettings.watermark_angle + "deg)";
941
+ mask_div.style.MozTransform = "rotate(-" + defaultSettings.watermark_angle + "deg)";
942
+ mask_div.style.msTransform = "rotate(-" + defaultSettings.watermark_angle + "deg)";
943
+ mask_div.style.OTransform = "rotate(-" + defaultSettings.watermark_angle + "deg)";
944
+ mask_div.style.transform = "rotate(-" + defaultSettings.watermark_angle + "deg)";
945
+ mask_div.style.visibility = "";
946
+ mask_div.style.position = "absolute";
947
+ //奇偶行错开,这样水印就不对齐,显的不呆板
948
+ console.debug('x',x)
949
+ if (i % 2 != 0) {
950
+ mask_div.style.left = x + 'px';
951
+ if (j % 2 != 0 && this.knowledgeItem.visitorWatermarkValue){
952
+ mask_div.appendChild(document.createTextNode(defaultSettings.visitorWatermark_txt));
953
+ } else {
954
+ if (!this.knowledgeItem.textWatermarkValue){
955
+ mask_div.appendChild(document.createTextNode(defaultSettings.visitorWatermark_txt));
956
+ } else {
957
+ mask_div.appendChild(document.createTextNode(defaultSettings.watermark_txt));
958
+ }
959
+ }
960
+ } else {
961
+ mask_div.style.left = x + 'px';
962
+ if (j % 2 != 0 && this.knowledgeItem.textWatermarkValue){
963
+ mask_div.appendChild(document.createTextNode(defaultSettings.watermark_txt));
964
+ } else {
965
+ if (!this.knowledgeItem.visitorWatermarkValue){
966
+ mask_div.appendChild(document.createTextNode(defaultSettings.watermark_txt));
967
+ } else {
968
+ mask_div.appendChild(document.createTextNode(defaultSettings.visitorWatermark_txt));
969
+ }
970
+ }
971
+ }
972
+
973
+ mask_div.style.top = y + 'px';
974
+ mask_div.style.overflow = "hidden";
975
+ mask_div.style.zIndex = "9999";
976
+ mask_div.style.pointerEvents = 'none'; //让水印不遮挡页面的点击事件
977
+ mask_div.style.opacity = defaultSettings.watermark_alpha;
978
+ mask_div.style.fontSize = defaultSettings.watermark_fontsize;
979
+ mask_div.style.fontFamily = defaultSettings.watermark_font;
980
+ mask_div.style.color = defaultSettings.watermark_color;
981
+ mask_div.style.textAlign = "center";
982
+ mask_div.style.width = defaultSettings.watermark_width + 'px';
983
+ mask_div.style.height = defaultSettings.watermark_height + 'px';
984
+ mask_div.style.display = "block";
985
+ oTemp.appendChild(mask_div);
986
+ }
987
+ }
988
+ let pageDom = document.getElementById('pdf_container_view')
989
+ pageDom.appendChild(oTemp);
990
+
991
+ },
992
+ },
993
+ computed: {
994
+ perviewUrl () {
995
+ return '/web/viewer.html?file=' + '/pdflist/pdf4split-1.pdf'
996
+ },
997
+ setHeight () {
998
+ if (this.tagIds.length > 1) {
999
+ if (this.isPC) {
1000
+ return 'calc(100% - 110px)'
1001
+ } else {
1002
+ return 'calc(100% - 60px)'
1003
+ }
1004
+ } else {
1005
+ if (this.isPC) {
1006
+ return 'calc(100% - 50px)'
1007
+ } else {
1008
+ return '100%'
1009
+ }
1010
+ }
1011
+ }
1012
+ },
1013
+ watch: {
1014
+ tagIds: {
1015
+ handler (value) {
1016
+ if (value && value.length) {
1017
+ // 在 pdf_view 下创建 所有canvs的容器
1018
+ this.contentView = document.createElement('div')
1019
+ this.contentView.setAttribute('id','contentView')
1020
+ this.contentView.style.transformOrigin = '0px 0px 0px'
1021
+ this.contentView.setAttribute('id','contentView');
1022
+
1023
+ this.$http.get('/knowledge-api/knowledge/knowledge-part-location-info/list?ids=' + value.join(',')).then(res => {
1024
+ // res.data = {"data":[{"id":"64591b7d8bb8ab1b91c65f24","knowledgeId":"64591a9c8da27649473f3b4b","mainId":"fb348d095c0b4fd7bbd37826563dac7d","page":3,"total":18,"pageHeight":540.0,"pageWidth":960.00946,"publicPageFileUrl":"https://askbot-pdf-all.oss-cn-zhangjiakou.aliyuncs.com/fb348d095c0b4fd7bbd37826563dac7d/2023/05/08/11/55/18/64591b638bb8ab1b91c65eed/3.pdf","extractInfo":{"location":[280.488,161.32,398.71573,61.99298],"content":"黄花城水长城旅游区位于北京市怀柔区九渡河镇境内,距北京市区65公里,是以奇而著称,融山川、碧水、古长城为一体的旅游休闲胜地。而这里的“三绝景”更是引人入","lines":[{"content":"黄花城水长城旅游区位于北京市怀柔区九渡河镇境内,距","location":[280.488,161.32,398.71573,15.9869995]},{"content":"北京市区65公里,是以奇而著称,融山川、碧水、古长","location":[283.691,184.30899,392.3055,15.9869995]},{"content":"城为一体的旅游休闲胜地。而这里的“三绝景”更是引人入","location":[282.699,207.32599,394.3033,15.9869995]}],"tagId":null}}],"code":"0","msg":null,"traceId":null}
1025
+ // res.data = {"data":[{"id":"64590ce1eb1320043401cc90","knowledgeId":"64590cd5017b461d67e282e1","mainId":"fb348d095c0b4fd7bbd37826563dac7d","page":2,"total":5,"pageHeight":841.8898,"pageWidth":595.30396,"publicPageFileUrl":"https://askbot-pdf-all.oss-cn-zhangjiakou.aliyuncs.com/fb348d095c0b4fd7bbd37826563dac7d/2023/05/08/10/53/20/64590ce0eb1320043401cc7b/2.pdf","extractInfo":{"location":[89.32981,638.1907,415.15512,98.63251],"content":":北京地铁 13\r号线 :藤黄\r色 :西直门站—\r东直门站 :17 :41.\r5 :6\r准\rB :2002年\r09月\r28日 ","lines":[{"content":":北京地铁 13\r号线 ","location":[89.32981,638.1907,99.44599,98.63251]},{"content":":藤黄\r色 ","location":[188.7758,638.1907,46.79959,98.63251]},{"content":":西直门站—\r东直门站 ","location":[235.5754,638.1907,86.09996,98.63251]},{"content":":17 ","location":[321.67535,638.1907,36.200012,98.63251]},{"content":":41.\r5 ","location":[357.87537,638.1907,39.400696,98.63251]},{"content":":6\r准\rB ","location":[397.27606,638.1907,41.099,98.63251]},{"content":":2002年\r09月\r28日 ","location":[438.37506,638.1907,66.10986,98.63251]}],"tagId":null}}],"code":"0","msg":null,"traceId":null}
1026
+ // res.data = {"data":[{"id":"64591b7d8bb8ab1b91c65f24","knowledgeId":"64591a9c8da27649473f3b4b","mainId":"fb348d095c0b4fd7bbd37826563dac7d","page":3,"total":18,"pageHeight":540.0,"pageWidth":960.00946,"publicPageFileUrl":"https://askbot-pdf-all.oss-cn-zhangjiakou.aliyuncs.com/fb348d095c0b4fd7bbd37826563dac7d/2023/05/08/11/55/18/64591b638bb8ab1b91c65eed/3.pdf","extractInfo":{"location":[280.488,161.32,398.71573,61.99298],"content":"黄花城水长城旅游区位于北京市怀柔区九渡河镇境内,距北京市区65公里,是以奇而著称,融山川、碧水、古长城为一体的旅游休闲胜地。而这里的“三绝景”更是引人入","lines":[{"content":"黄花城水长城旅游区位于北京市怀柔区九渡河镇境内,距","location":[280.488,161.32,398.71573,15.9869995]},{"content":"北京市区65公里,是以奇而著称,融山川、碧水、古长","location":[283.691,184.30899,392.3055,15.9869995]},{"content":"城为一体的旅游休闲胜地。而这里的“三绝景”更是引人入","location":[282.699,207.32599,394.3033,15.9869995]}],"tagId":null}}],"code":"0","msg":null,"traceId":null}
1027
+ // res.data = {"data":[{"id":"6475eab868110215ab821a80","knowledgeId":"6475e7eac724c54c46cbfa2d","mainId":"5ecf2fcd704541149201ab9c1c31162d","page":0,"total":1,"pageHeight":0.0,"pageWidth":0.0,"publicPageFileUrl":"https://askbot-pdf-all.oss-cn-zhangjiakou.aliyuncs.com/5ecf2fcd704541149201ab9c1c31162d/2023/05/30/08/23/20/6475eab63339db423f26b196/0.html","extractInfo":{"location":null,"content":"产品:系统配置,产品型号:存储,VX30:4G+16G,VX50:16G+256G","lines":null,"tagId":"6475eab868110215ab821a80"}}],"code":"0","msg":null,"traceId":null}
1028
+ // res.data = {"data":[{"id":"6475e9393339db423f26af01","knowledgeId":"6475e44fc724c54c46cbfa21","mainId":"5ecf2fcd704541149201ab9c1c31162d","page":2,"total":2,"pageHeight":510.25,"pageWidth":1559.05,"publicPageFileUrl":"https://askbot-pdf-all.oss-cn-zhangjiakou.aliyuncs.com/5ecf2fcd704541149201ab9c1c31162d/2023/05/30/08/00/29/6475e55d3339db423f26a9b8/2.pdf","extractInfo":{"location":[327.70532,288.0498,414.9734,12.241608],"content":"三、指示灯状态说明1.白色常亮:开机/开机中2.红色常亮:待机3.白色呼吸:息屏4.红色闪烁:升级1.LAN:通过网线连接到主机的Camera端口2.电源开关:电源切换开关","lines":[{"content":"三、指示灯状态说明","location":[634.3203,288.0498,108.3584,12.0]},{"content":"1.白色常亮:开机/开机中","location":[634.3203,320.08978,108.23407,9.0]},{"content":"2.红色常亮:待机","location":[634.3204,341.3298,78.597046,9.0]},{"content":"3.白色呼吸:息屏","location":[634.32043,362.45282,78.597046,9.0]},{"content":"4.红色闪烁:升级","location":[634.3205,383.6928,78.597046,9.0]},{"content":"1.LAN:通过网线连接到主机的","location":[327.70535,291.2914,144.35995,9.0]},{"content":"Camera端口","location":[327.70532,306.88843,55.322998,9.0]},{"content":"2.电源开关:电源切换开关","location":[482.74832,291.2914,105.36301,9.0]}],"tagId":null}}],"code":"0","msg":null,"traceId":null}
1029
+ // if(value.length === 1) {
1030
+ // this.$refs.pdfView.style.height = 'calc(100% - 50px)'
1031
+ // }
1032
+ // res.data = {
1033
+ // "data": [
1034
+ // {
1035
+ // "id": "64e746120372d778849d2e8e",
1036
+ // "knowledgeId": "64e30035edffac0ec96a2d39",
1037
+ // "mainId": "e0f6898c6b0d47fa98e8f71ceab1bde8",
1038
+ // "page": 14,
1039
+ // "total": 60,
1040
+ // "pageHeight": 728.504,
1041
+ // "pageWidth": 515.906,
1042
+ // "publicPageFileUrl": "https://askbot-pdf-all.oss-cn-zhangjiakou.aliyuncs.com/e0f6898c6b0d47fa98e8f71ceab1bde8/2023/08/21/02/12/07/64e300378c3dfb3bc434f51a/15.pdf",
1043
+ // "extractInfo": {
1044
+ // "location": [
1045
+ // 52.665375,
1046
+ // 312.01306,
1047
+ // 404.98618,
1048
+ // 142.5199
1049
+ // ],
1050
+ // "content": null,
1051
+ // "lines": [
1052
+ // {
1053
+ // "content": null,
1054
+ // "location": [
1055
+ // 52.665375,
1056
+ // 312.01306,
1057
+ // 404.98618,
1058
+ // 142.5199
1059
+ // ]
1060
+ // }
1061
+ // ],
1062
+ // "tagId": null
1063
+ // },
1064
+ // "block": {
1065
+ // "type": "TEXT",
1066
+ // "location": [
1067
+ // 52.665375,
1068
+ // 312.01306,
1069
+ // 404.98618,
1070
+ // 142.5199
1071
+ // ],
1072
+ // "color": "#366AFF",
1073
+ // "flowChart": {
1074
+ // "content": ""
1075
+ // },
1076
+ // "image": {
1077
+ // "url": null,
1078
+ // "desc": ""
1079
+ // },
1080
+ // "table": {
1081
+ // "title": null,
1082
+ // "table": null
1083
+ // },
1084
+ // "text": {
1085
+ // "originText": "① 头部防护:安全帽\n佩戴要求:\n①存在坠物或对头部产生碰撞风险的作业场所需要佩戴安全帽 ;\n②安全帽必须戴正、戴牢、不能晃动,要系紧下颏带,调节好后箍以\n防安全帽脱落 ;\n③受强力撞击及超过有效期的安全帽必须更换。",
1086
+ // "indexText": "① 头部防护:安全帽\n佩戴要求:\n①存在坠物或对头部产生碰撞风险的作业场所需要佩戴安全帽 ;\n②安全帽必须戴正、戴牢、不能晃动,要系紧下颏带,调节好后箍以\n防安全帽脱落 ;\n③受强力撞击及超过有效期的安全帽必须更换。",
1087
+ // "lines": [
1088
+ // {
1089
+ // "location": [
1090
+ // 69.08148,
1091
+ // 368.92072,
1092
+ // 65.90851,
1093
+ // 10.5
1094
+ // ]
1095
+ // },
1096
+ // {
1097
+ // "location": [
1098
+ // 86.290985,
1099
+ // 384.67072,
1100
+ // 31.5,
1101
+ // 10.5
1102
+ // ]
1103
+ // },
1104
+ // {
1105
+ // "location": [
1106
+ // 286.2992,
1107
+ // 315.73584,
1108
+ // 37.656006,
1109
+ // 12.0
1110
+ // ]
1111
+ // },
1112
+ // {
1113
+ // "location": [
1114
+ // 324.6939,
1115
+ // 316.79932,
1116
+ // 122.74487,
1117
+ // 10.5
1118
+ // ]
1119
+ // },
1120
+ // {
1121
+ // "location": [
1122
+ // 286.2954,
1123
+ // 336.0458,
1124
+ // 149.625,
1125
+ // 10.5
1126
+ // ]
1127
+ // },
1128
+ // {
1129
+ // "location": [
1130
+ // 286.2954,
1131
+ // 356.0483,
1132
+ // 161.15405,
1133
+ // 10.5
1134
+ // ]
1135
+ // },
1136
+ // {
1137
+ // "location": [
1138
+ // 286.2954,
1139
+ // 376.0508,
1140
+ // 161.15405,
1141
+ // 10.5
1142
+ // ]
1143
+ // },
1144
+ // {
1145
+ // "location": [
1146
+ // 286.2954,
1147
+ // 396.0533,
1148
+ // 76.125,
1149
+ // 10.5
1150
+ // ]
1151
+ // },
1152
+ // {
1153
+ // "location": [
1154
+ // 286.2954,
1155
+ // 416.05582,
1156
+ // 161.17517,
1157
+ // 10.5
1158
+ // ]
1159
+ // },
1160
+ // {
1161
+ // "location": [
1162
+ // 286.2954,
1163
+ // 436.8038,
1164
+ // 52.5,
1165
+ // 10.5
1166
+ // ]
1167
+ // },
1168
+ // {
1169
+ // "location": [
1170
+ // 338.7992,
1171
+ // 435.73584,
1172
+ // 12.0,
1173
+ // 12.0
1174
+ // ]
1175
+ // }
1176
+ // ]
1177
+ // }
1178
+ // }
1179
+ // }
1180
+ // ],
1181
+ // "code": "0",
1182
+ // "msg": null,
1183
+ // "traceId": null
1184
+ // }
1185
+ if (res.data.code == 0) {
1186
+ // tagIds 会按照gpt识别的生成有序的数组,前端直接按照下标的顺序取就可以了
1187
+ // 缓存拿到的所有数据
1188
+ this.cachePdf = res.data.data
1189
+ let publicPageFileUrl = res.data.data && res.data.data[0] ? res.data.data[0].publicPageFileUrl : ''
1190
+ this.currentPage = 0
1191
+ if (publicPageFileUrl && publicPageFileUrl.substring(publicPageFileUrl.lastIndexOf('.')) === '.pdf') {
1192
+ this.preViewType = 'pdf'
1193
+ this.setPageAllLine(this.cachePdf)
1194
+ this.getpdfResloutePage(res.data.data[0])
1195
+ } else {
1196
+ this.preViewType = 'excal'
1197
+ this.$http.post(
1198
+ '/knowledge-api/temporary-certificate/or-origin?expired=30',
1199
+ publicPageFileUrl,
1200
+ {
1201
+ headers: {
1202
+ "Content-Type": "application/json",
1203
+ },
1204
+ }).then(res => {
1205
+ // 使用原声请求方式 axios会带有不需要的请求头
1206
+ let xhr = new XMLHttpRequest();
1207
+ xhr.open('GET', res.data || res.bodyText, true);
1208
+ // 定义请求完成的处理函数,请求前也可以增加加载框/禁用下载按钮逻辑
1209
+ xhr.onload = ({ currentTarget }) => {
1210
+ // 请求完成
1211
+ if (currentTarget.status === 200) { // 返回200
1212
+ let pdf_view = document.getElementsByClassName('pdf_view');
1213
+ if (pdf_view && pdf_view[0]){
1214
+ pdf_view[0].style.backgroundImage = 'none'
1215
+ }
1216
+ this.contentView.innerHTML = currentTarget.response
1217
+ this.contentView.style.padding = '10px'
1218
+ // this.contentView.style.position = 'relative'
1219
+ this.$refs.pdfView.style.backgroundColor = '#FFFFFF'
1220
+ this.$refs.pdfView.appendChild(this.contentView)
1221
+
1222
+ let allTr = Array.from(this.$refs.pdfView.getElementsByTagName('tr'))
1223
+ this.allTr = []
1224
+ for (let index = 0; index < allTr.length; index++) {
1225
+ if (value.includes(allTr[index].getAttribute('tag-id'))) {
1226
+ this.allTr.push(allTr[index])
1227
+ }
1228
+ }
1229
+ this.currentChange(1)
1230
+
1231
+ }
1232
+ }
1233
+ xhr.send();
1234
+ })
1235
+ }
1236
+ } else {
1237
+ let div = document.createElement('div')
1238
+ div.innerText = this.$t('dragonCommon.fileloadException')
1239
+ this.contentView.appendChild(div)
1240
+ this.$refs.pdfView.appendChild(this.contentView)
1241
+ }
1242
+ })
1243
+ }
1244
+ },
1245
+ deep: true,
1246
+ immediate: true
1247
+ }
1248
+ },
1249
+ mounted () {
1250
+ this.$i18n.locale = sessionStorage.getItem("systemLanguage") || 'cn';
1251
+ this.scaleList = [
1252
+ {
1253
+ label: this.$t('dragonCommon.scaleAuto'),
1254
+ value: 'auto'
1255
+ },
1256
+ {
1257
+ label: this.$t('dragonCommon.scaleReality'),
1258
+ value: 'reality'
1259
+ },
1260
+ {
1261
+ label: '100%',
1262
+ value: 1
1263
+ },
1264
+ {
1265
+ label: '120%',
1266
+ value: 1.2
1267
+ },
1268
+ {
1269
+ label: '150%',
1270
+ value: 1.5
1271
+ },
1272
+ {
1273
+ label: '170%',
1274
+ value: 1.7
1275
+ }
1276
+ ,
1277
+ {
1278
+ label: '200%',
1279
+ value: 2
1280
+ }
1281
+ ]
1282
+ if (/(iPhone|iPad|iPod|iOS|Android)/i.test(navigator.userAgent)) {
1283
+ this.isPC = false
1284
+ } else {
1285
+ this.isPC = true
1286
+ }
1287
+ }
1288
+ }
1289
+ </script>
1290
+
1291
+ <style lang="less" scoped>
1292
+ .pdf_view {
1293
+ width: 100%;
1294
+ // height: calc(100% - 110px);
1295
+ height: 100%;
1296
+ overflow: auto;
1297
+ //overflow-y: scroll;
1298
+ background-color: #f5f7fb;
1299
+ // margin-bottom: 60px;
1300
+ box-sizing: border-box;
1301
+ // position: relative;
1302
+ // > div {
1303
+ // width: 100%;
1304
+ // height: 100%;
1305
+ // overflow: hidden;
1306
+ // overflow-y: auto;
1307
+ // position: relative;
1308
+ // }
1309
+ >iframe {
1310
+ width: 100%;
1311
+ height: 100%;
1312
+ }
1313
+
1314
+ a:link {
1315
+ color: none;
1316
+ }
1317
+
1318
+ a:visited {
1319
+ color: none;
1320
+ }
1321
+
1322
+ a:hover {
1323
+ color: none;
1324
+ }
1325
+
1326
+ a:active {
1327
+ color: none;
1328
+ }
1329
+ .btn_footer {
1330
+ width: 100%;
1331
+ height: 60px;
1332
+ display: flex;
1333
+ align-items: center;
1334
+ justify-content: space-around;
1335
+ position: absolute;
1336
+ bottom: 0px;
1337
+ left: 0;
1338
+ z-index: 999;
1339
+ background: #ffffff;
1340
+
1341
+ .prev,
1342
+ .next {
1343
+ width: 35%;
1344
+ height: 40px;
1345
+ display: flex;
1346
+ align-items: center;
1347
+ justify-content: center;
1348
+ border-radius: 50px;
1349
+ cursor: pointer;
1350
+ }
1351
+
1352
+ .prev {
1353
+ background: #F2F5FA;
1354
+ color: #000;
1355
+ }
1356
+
1357
+ .next {
1358
+ background: #366aff;
1359
+ color: #ffffff;
1360
+ }
1361
+ }
1362
+
1363
+ #pagination {
1364
+ .total-class {
1365
+ margin-right: 13px;
1366
+ font-weight: 400;
1367
+ }
1368
+
1369
+ position: absolute;
1370
+ bottom: 0px;
1371
+ right: 0;
1372
+ width: 100%;
1373
+ display: flex;
1374
+ align-items: center;
1375
+ justify-content: center;
1376
+ height: 50px;
1377
+ background-color: white;
1378
+ box-shadow: 0px 0px 18px 0px rgba(29, 55, 129, 0.07);
1379
+ border-radius: 5px;
1380
+ z-index: 1000;
1381
+
1382
+
1383
+
1384
+ /deep/.el-pagination {
1385
+ margin-right: 110px;
1386
+ }
1387
+
1388
+ /deep/.el-pager {
1389
+ background: #EDF0F6;
1390
+ border-radius: 15px;
1391
+ }
1392
+
1393
+ /deep/.el-pagination.is-background .btn-next {
1394
+ width: 30px;
1395
+ height: 30px;
1396
+ background: #EDF0F6;
1397
+ border-radius: 50%;
1398
+ }
1399
+
1400
+ /deep/.el-pagination .btn-next {
1401
+ width: 30px;
1402
+ height: 30px;
1403
+ background: #EDF0F6;
1404
+ border-radius: 50%;
1405
+ padding-left: 0;
1406
+ margin-left: 5px;
1407
+ }
1408
+
1409
+ /deep/.el-pagination .btn-prev {
1410
+ width: 30px;
1411
+ height: 30px;
1412
+ background: #EDF0F6;
1413
+ border-radius: 50%;
1414
+ padding-right: 0;
1415
+ margin-right: 5px;
1416
+ }
1417
+
1418
+ /deep/.el-pagination button {
1419
+ padding: 0;
1420
+ min-width: 30px;
1421
+ }
1422
+
1423
+ /deep/.el-pager li {
1424
+ background: #EDF0F6;
1425
+ height: 30px;
1426
+ min-width: 30px;
1427
+ line-height: 30px;
1428
+ font-size: 12px;
1429
+ color: #717b90;
1430
+ }
1431
+
1432
+ /deep/.el-pager li:first-child {
1433
+ border-bottom-left-radius: 15px !important;
1434
+ border-top-left-radius: 15px !important;
1435
+ }
1436
+
1437
+ /deep/.el-pager li:last-child {
1438
+ border-top-right-radius: 15px !important;
1439
+ border-bottom-right-radius: 15px !important;
1440
+ }
1441
+
1442
+ /deep/.el-pager li.active {
1443
+ width: 30px;
1444
+ height: 30px;
1445
+ min-width: 30px;
1446
+ background: #366AFF;
1447
+ border: 3px solid #A1B9FF;
1448
+ border-radius: 50%;
1449
+ line-height: 24px;
1450
+ color: white;
1451
+ }
1452
+
1453
+ /deep/.el-pagination.is-background .el-pager li:not(.disabled).active {
1454
+ background: #366AFF;
1455
+ }
1456
+ }
1457
+
1458
+ .change_scale {
1459
+ width: 100%;
1460
+ height: 50px;
1461
+ position: absolute;
1462
+ top: 50px;
1463
+ left: 0;
1464
+ background: #ffffff;
1465
+ display: flex;
1466
+ align-items: center;
1467
+ padding: 0 10px;
1468
+ box-sizing: border-box;
1469
+
1470
+ section {
1471
+ cursor: pointer;
1472
+ width: 30px;
1473
+ height: 30px;
1474
+ margin-right: 5px;
1475
+ border-radius: 5px;
1476
+ display: flex;
1477
+ align-items: center;
1478
+ justify-content: center;
1479
+
1480
+ i {
1481
+ font-weight: 900;
1482
+ }
1483
+ }
1484
+
1485
+ section:hover {
1486
+ background: rgba(221, 222, 223, 1);
1487
+ }
1488
+ }
1489
+ .pdf_container_view{
1490
+ height: 100%;
1491
+ width: 100%;
1492
+ position: relative;
1493
+ overflow: auto;
1494
+ }
1495
+ }
1496
+ </style>
1497
+ <style lang="less">
1498
+ .animation {
1499
+ animation-name: highlight;
1500
+ animation-duration: 4s;
1501
+ }
1502
+
1503
+ @keyframes highlight {
1504
+ 0% {
1505
+ background: rgba(255, 136, 0, 0.3);
1506
+ }
1507
+
1508
+ 25% {
1509
+ background: rgba(255, 136, 0, 0.6);
1510
+ }
1511
+
1512
+ 50% {
1513
+ background: rgba(255, 136, 0, 0.3);
1514
+ }
1515
+
1516
+ 75% {
1517
+ background: rgba(255, 136, 0, 0.6);
1518
+ }
1519
+
1520
+ 100% {
1521
+ background: rgba(255, 136, 0, 0.3);
1522
+ }
1523
+ }</style>