askbot-dragon 1.7.49-beta → 1.7.52-beta

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