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